SurfaceFlinger: Handle EGL errors more cleanly
Adds some more safety checking for cases where we get an error while
trying to create the EGLImage. The checking puts the Layer into a
failed state after detecting an error, since the shadow queue may no
longer be synchronized.
Bug: 20957332
Change-Id: I68b4c40eab3e58731b875ed5752f2c7d17f14bcb
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2b733e9..8d8af52 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -84,7 +84,8 @@
mQueueItemLock(),
mQueueItemCondition(),
mQueueItems(),
- mLastFrameNumberReceived(0)
+ mLastFrameNumberReceived(0),
+ mUpdateTexImageFailed(false)
{
mCurrentCrop.makeInvalid();
mFlinger->getRenderEngine().genTextures(1, &mTextureName);
@@ -1314,6 +1315,24 @@
mQueueItems.removeAt(0);
android_atomic_dec(&mQueuedFrames);
return outDirtyRegion;
+ } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
+ // This can occur if something goes wrong when trying to create the
+ // EGLImage for this buffer. If this happens, the buffer has already
+ // been released, so we need to clean up the queue and bug out
+ // early.
+ {
+ Mutex::Autolock lock(mQueueItemLock);
+ mQueueItems.clear();
+ android_atomic_and(0, &mQueuedFrames);
+ }
+
+ // Once we have hit this state, the shadow queue may no longer
+ // correctly reflect the incoming BufferQueue's contents, so even if
+ // updateTexImage starts working, the only safe course of action is
+ // to continue to ignore updates.
+ mUpdateTexImageFailed = true;
+
+ return outDirtyRegion;
}
{ // Autolock scope