Skip to content

Commit b0721d4

Browse files
jackpalAndroid (Google) Code Review
authored andcommitted
Merge "Make GLSurfaceView handle eglSwapBuffers errors more robustly."
2 parents 54e1553 + db6c78b commit b0721d4

File tree

1 file changed

+31
-34
lines changed

1 file changed

+31
-34
lines changed

opengl/java/android/opengl/GLSurfaceView.java

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)