From 091661334b25c1bc282463d13622236b1ac79e64 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Wed, 19 Oct 2016 13:53:33 -0700 Subject: [PATCH] Camera2 Legacy: catch more surface abandoned error Bug: 30140107 Change-Id: Ia293bdbb85c8078e17def55db9c599cfe70458db --- .../camera2/legacy/SurfaceTextureRenderer.java | 40 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java index e0d3905ea942..a05a8ec00e79 100644 --- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java @@ -248,7 +248,8 @@ public class SurfaceTextureRenderer { return program; } - private void drawFrame(SurfaceTexture st, int width, int height, int flipType) { + private void drawFrame(SurfaceTexture st, int width, int height, int flipType) + throws LegacyExceptionUtils.BufferQueueAbandonedException { checkGlError("onDrawFrame start"); st.getTransformMatrix(mSTMatrix); @@ -343,7 +344,7 @@ public class SurfaceTextureRenderer { /*offset*/ 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /*offset*/ 0, /*count*/ 4); - checkGlError("glDrawArrays"); + checkGlDrawError("glDrawArrays"); } /** @@ -548,7 +549,29 @@ public class SurfaceTextureRenderer { private void checkGlError(String msg) { int error; while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { - throw new IllegalStateException(msg + ": GLES20 error: 0x" + Integer.toHexString(error)); + throw new IllegalStateException( + msg + ": GLES20 error: 0x" + Integer.toHexString(error)); + } + } + + private void checkGlDrawError(String msg) + throws LegacyExceptionUtils.BufferQueueAbandonedException { + int error; + boolean surfaceAbandoned = false; + boolean glError = false; + while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { + if (error == GLES20.GL_OUT_OF_MEMORY) { + surfaceAbandoned = true; + } else { + glError = true; + } + } + if (glError) { + throw new IllegalStateException( + msg + ": GLES20 error: 0x" + Integer.toHexString(error)); + } + if (surfaceAbandoned) { + throw new LegacyExceptionUtils.BufferQueueAbandonedException(); } } @@ -759,9 +782,14 @@ public class SurfaceTextureRenderer { if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) { makeCurrent(holder.eglSurface); // glReadPixels reads from the bottom of the buffer, so add an extra vertical flip - drawFrame(mSurfaceTexture, holder.width, holder.height, - (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ? - FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL); + try { + drawFrame(mSurfaceTexture, holder.width, holder.height, + (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ? + FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + // Should never hit this. + throw new IllegalStateException("Surface abandoned, skipping drawFrame...", e); + } mPBufferPixels.clear(); GLES20.glReadPixels(/*x*/ 0, /*y*/ 0, holder.width, holder.height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPBufferPixels); -- 2.11.0