我正在开发带有“模糊工具”的照片编辑器应用,该应用可让用户模糊照片。为此,我在原始图像上绘制了另一个“模糊层”,并使用不透明度/ alpha显示模糊点。
我的着色器代码:
precision mediump float;
uniform float aRadius;
uniform vec2 aTouchPosition;
uniform sampler2D inputImageTexture;
varying vec2 textureCoordinate;
void main() {
float dist = distance(aTouchPosition, gl_FragCoord.xy);
if(dist <= aRadius)
gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
else
gl_FragColor = vec4(0., 0., 0., 0.);
}
每次用户触摸时,我都会将点放置到数组中,然后放置到着色器中:
protected void onDrawFrame() {
if (textures == null) return;
shader.useProgram();
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glUniformMatrix4fv(shader.uMVPMatrix, 1, false, mScratchMatrix, 0);
GLES20.glEnableVertexAttribArray(shader.position);
GLES20.glVertexAttribPointer(shader.position, COORDINATE_PER_VERTEX, GLES20.GL_FLOAT, false, VERTEX_STRIDE, mCubeCoordArray);
GLES20.glEnableVertexAttribArray(shader.inputTextureCoordinate);
GLES20.glVertexAttribPointer(shader.inputTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mTexCoordArray);
for (int i = 0; i < listCurrent.size(); i++) {
PaintData.Position pos = listCurrent.get(i);
GLES20.glUniform1f(shader.aRadius, pos.size);
GLES20.glUniform2f(shader.touchPosition, pos.x, pos.y);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
listCurrent.clear();
GLES20.glDisableVertexAttribArray(shader.position);
GLES20.glDisableVertexAttribArray(shader.inputTextureCoordinate);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
}
当用户触摸绘制时,它会根据长或短的路径生成大约20-100点。仍然可以,但是当用户保存并恢复编辑时,我必须在单个帧(第一帧)中恢复大量点。这会导致错误并使我的应用程序崩溃。
W / Adreno-GSL::ioctl fd 115代码0xc040094a (IOCTL_KGSL_GPU_COMMAND)失败:错误35资源死锁将 发生
W / Adreno-GSL::panel.gpuSnapshotPath是 未设置。不生成用户快照
经过一番调查,我发现:
对于每个点,它必须绘制整个屏幕(而不是应该绘制的微小模糊点)。
=>如何通过仅绘制需要显示模糊点的一部分屏幕来优化此效果
第一次完成调用onDrawFrame()
函数(使用模糊点执行所有glDrawArrays()
)后,我的应用锁定并等待2秒以执行mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)
函数,之后它崩溃了。
=>如何优化交换功能?
答案 0 :(得分:1)
我遇到了类似的问题,在this论坛帖子上偶然发现了答案#10。
似乎每帧中排队的命令太多,从而导致GPU冻结。对我而言,解决此问题的方法是在几次GL调用之后,总是调用glFinish()(等待所有之前排队的命令执行完毕)或glFlush()(强制执行排队的命令)。