OSDN Git Service

Camera2 Legacy: catch more surface abandoned error
authorYin-Chia Yeh <yinchiayeh@google.com>
Wed, 19 Oct 2016 20:53:33 +0000 (13:53 -0700)
committerYin-Chia Yeh <yinchiayeh@google.com>
Fri, 21 Oct 2016 18:40:46 +0000 (11:40 -0700)
Bug: 30140107
Change-Id: Ia293bdbb85c8078e17def55db9c599cfe70458db

core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java

index e0d3905..a05a8ec 100644 (file)
@@ -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);