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
(cherry picked from commit 65476f3332)
This commit is contained in:
Dan Stoza 2015-05-14 09:27:25 -07:00
parent 9188b4bb5d
commit 59bfd2bbed
2 changed files with 21 additions and 1 deletions

View File

@ -84,7 +84,8 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
mQueueItemLock(), mQueueItemLock(),
mQueueItemCondition(), mQueueItemCondition(),
mQueueItems(), mQueueItems(),
mLastFrameNumberReceived(0) mLastFrameNumberReceived(0),
mUpdateTexImageFailed(false)
{ {
mCurrentCrop.makeInvalid(); mCurrentCrop.makeInvalid();
mFlinger->getRenderEngine().genTextures(1, &mTextureName); mFlinger->getRenderEngine().genTextures(1, &mTextureName);
@ -1313,6 +1314,24 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
Mutex::Autolock lock(mQueueItemLock); Mutex::Autolock lock(mQueueItemLock);
mQueueItems.removeAt(0); mQueueItems.removeAt(0);
android_atomic_dec(&mQueuedFrames); 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; return outDirtyRegion;
} }

View File

@ -419,6 +419,7 @@ private:
Condition mQueueItemCondition; Condition mQueueItemCondition;
Vector<BufferItem> mQueueItems; Vector<BufferItem> mQueueItems;
uint64_t mLastFrameNumberReceived; uint64_t mLastFrameNumberReceived;
bool mUpdateTexImageFailed; // This is only modified from the main thread
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------