Android OpenGLES错误:将会发生资源死锁

时间:2019-11-20 08:34:34

标签: android graphics opengl-es opengl-es-2.0

我正在开发带有“模糊工具”的照片编辑器应用,该应用可让用户模糊照片。为此,我在原始图像上绘制了另一个“模糊层”,并使用不透明度/ 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)函数,之后它崩溃了。

    =>如何优化交换功能?

1 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,在this论坛帖子上偶然发现了答案#10。

似乎每帧中排队的命令太多,从而导致GPU冻结。对我而言,解决此问题的方法是在几次GL调用之后,总是调用glFinish()(等待所有之前排队的命令执行完毕)或glFlush()(强制执行排队的命令)。