1

I'm developing a photo editor app with "blur tool" which allow user to blur photos. To achieve that, I draw another "blur layer" over original image, and use opacity/alpha to show blur points.

My shader code:

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.);
}

Every time user touch, I put the points to an array, then put to shader:

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);
}

When user touch to draw, it generate about 20-100 points according to the path long or short. It's still OK, but when user save & restore editing, I must restore a huge amount of points in a single frame (the first frame). Which cause error and crash my app.

W/Adreno-GSL: : ioctl fd 115 code 0xc040094a (IOCTL_KGSL_GPU_COMMAND) failed: errno 35 Resource deadlock would occur

W/Adreno-GSL: : panel.gpuSnapshotPath is not set.not generating user snapshot


After some investigation, I see that:

  • For each point it must draw entire screen (instead of a tiny blur point which it should be drawn).

    => How can I optimize this by only draw a part of the screen which the blur point need to show)

  • After finish calling onDrawFrame() function the first time (which execute all glDrawArrays() with my blur points), my app lock & wait for 2 seconds to execute mEgl.eglSwapBuffers(mEglDisplay, mEglSurface) function, after that it crashed.

    => How can I optimize the swap function?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
nhoxbypass
  • 9,695
  • 11
  • 48
  • 71

1 Answers1

1

I had a similar issue and stumbled upon answer #10 on this forum post.

It seems like there are too many commands queued per frame, which somehow causes the gpu to freeze. What fixed the issue for me was always calling glFinish() (waiting until all previously queued commands have been executed) or glFlush() (forcing the execution of queued commands) after a couple of GL calls.

Dharman
  • 30,962
  • 25
  • 85
  • 135
MrFreak
  • 11
  • 1