@@ -1130,36 +1130,13 @@ GL createGL() {
11301130
11311131 /**
11321132 * Display the current render surface.
1133- * @return false if the context has been lost .
1133+ * @return the EGL error code from eglSwapBuffers .
11341134 */
1135- public boolean swap () {
1135+ public int swap () {
11361136 if (! mEgl .eglSwapBuffers (mEglDisplay , mEglSurface )) {
1137-
1138- /*
1139- * Check for EGL_CONTEXT_LOST, which means the context
1140- * and all associated data were lost (For instance because
1141- * the device went to sleep). We need to sleep until we
1142- * get a new surface.
1143- */
1144- int error = mEgl .eglGetError ();
1145- switch (error ) {
1146- case EGL11 .EGL_CONTEXT_LOST :
1147- return false ;
1148- case EGL10 .EGL_BAD_CURRENT_SURFACE :
1149- // The current surface is bad, probably because the window manager has closed
1150- // the associated window. Ignore this error, on the assumption that the
1151- // application will be closed soon.
1152- break ;
1153- case EGL10 .EGL_BAD_NATIVE_WINDOW :
1154- // The native window is bad, probably because the window manager has closed it.
1155- // Ignore this error, on the assumption that the application will be closed
1156- // soon.
1157- break ;
1158- default :
1159- throwEglException ("eglSwapBuffers" , error );
1160- }
1137+ return mEgl .eglGetError ();
11611138 }
1162- return true ;
1139+ return EGL10 . EGL_SUCCESS ;
11631140 }
11641141
11651142 public void destroySurface () {
@@ -1366,6 +1343,7 @@ private void guardedRun() throws InterruptedException {
13661343 stopEglSurfaceLocked ();
13671344 }
13681345 mWaitingForSurface = true ;
1346+ mSurfaceIsBad = false ;
13691347 sGLThreadManager .notifyAll ();
13701348 }
13711349
@@ -1423,7 +1401,9 @@ private void guardedRun() throws InterruptedException {
14231401 h = mHeight ;
14241402 wantRenderNotification = true ;
14251403 if (LOG_SURFACE ) {
1426- Log .i ("GLThread" , "noticing that we want render notification tid=" + getId ());
1404+ Log .i ("GLThread" ,
1405+ "noticing that we want render notification tid="
1406+ + getId ());
14271407 }
14281408
14291409 // Destroy and recreate the EGL surface.
@@ -1444,6 +1424,7 @@ private void guardedRun() throws InterruptedException {
14441424 + " mHaveEglSurface: " + mHaveEglSurface
14451425 + " mPaused: " + mPaused
14461426 + " mHasSurface: " + mHasSurface
1427+ + " mSurfaceIsBad: " + mSurfaceIsBad
14471428 + " mWaitingForSurface: " + mWaitingForSurface
14481429 + " mWidth: " + mWidth
14491430 + " mHeight: " + mHeight
@@ -1509,11 +1490,26 @@ private void guardedRun() throws InterruptedException {
15091490 view .mRenderer .onDrawFrame (gl );
15101491 }
15111492 }
1512- if (!mEglHelper .swap ()) {
1513- if (LOG_SURFACE ) {
1514- Log .i ("GLThread" , "egl context lost tid=" + getId ());
1515- }
1516- lostEglContext = true ;
1493+ int swapError = mEglHelper .swap ();
1494+ switch (swapError ) {
1495+ case EGL10 .EGL_SUCCESS :
1496+ break ;
1497+ case EGL11 .EGL_CONTEXT_LOST :
1498+ if (LOG_SURFACE ) {
1499+ Log .i ("GLThread" , "egl context lost tid=" + getId ());
1500+ }
1501+ lostEglContext = true ;
1502+ break ;
1503+ default :
1504+ // Other errors typically mean that the current surface is bad,
1505+ // probably because the surfaceview surface has been destroyed,
1506+ // but we haven't been notified yet.
1507+ // Log the error to help developers understand why rendering stopped.
1508+ Log .w ("GLThread" , "eglSwapBuffers error: " + swapError +
1509+ ". Assume surfaceview surface is being destroyed. tid="
1510+ + getId ());
1511+ mSurfaceIsBad = true ;
1512+ break ;
15171513 }
15181514
15191515 if (wantRenderNotification ) {
@@ -1537,7 +1533,7 @@ public boolean ableToDraw() {
15371533 }
15381534
15391535 private boolean readyToDraw () {
1540- return (!mPaused ) && mHasSurface
1536+ return (!mPaused ) && mHasSurface && (! mSurfaceIsBad )
15411537 && (mWidth > 0 ) && (mHeight > 0 )
15421538 && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY ));
15431539 }
@@ -1707,6 +1703,7 @@ public void queueEvent(Runnable r) {
17071703 private boolean mRequestPaused ;
17081704 private boolean mPaused ;
17091705 private boolean mHasSurface ;
1706+ private boolean mSurfaceIsBad ;
17101707 private boolean mWaitingForSurface ;
17111708 private boolean mHaveEglContext ;
17121709 private boolean mHaveEglSurface ;
0 commit comments