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 allglDrawArrays()
with my blur points), my app lock & wait for 2 seconds to executemEgl.eglSwapBuffers(mEglDisplay, mEglSurface)
function, after that it crashed.=> How can I optimize the swap function?