diff options
author | Daniel Lam <dalam@google.com> | 2012-03-26 20:37:15 -0700 |
---|---|---|
committer | Daniel Lam <dalam@google.com> | 2012-04-02 14:55:01 -0700 |
commit | 9abe1ebc9575dc5a19bf1dfce6e9b02e03374457 (patch) | |
tree | c363e3977311b0bc9d929cf9103e2bb3101e76d3 /libs/gui/SurfaceTexture.cpp | |
parent | 0e1080f887bcd80c75910cabe7b2eca224bf739c (diff) | |
download | frameworks_native-9abe1ebc9575dc5a19bf1dfce6e9b02e03374457.zip frameworks_native-9abe1ebc9575dc5a19bf1dfce6e9b02e03374457.tar.gz frameworks_native-9abe1ebc9575dc5a19bf1dfce6e9b02e03374457.tar.bz2 |
Fixed disconnect bug in SurfaceTexture
BufferQueue's disconnect could race with updateTexImage
where invalid buffers could be released. Additionally
fixed similar bug with setBufferCount. Tests were added
to stress the disconnect mechanism.
Change-Id: I9afa4c64f3e025984e8a9e8d924852a71d044716
Diffstat (limited to 'libs/gui/SurfaceTexture.cpp')
-rw-r--r-- | libs/gui/SurfaceTexture.cpp | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 18c86fa..dd96f84 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -176,6 +176,8 @@ status_t SurfaceTexture::updateTexImage() { ST_LOGV("updateTexImage"); Mutex::Autolock lock(mMutex); + status_t err = NO_ERROR; + if (mAbandoned) { ST_LOGE("updateTexImage: SurfaceTexture is abandoned!"); return NO_INIT; @@ -269,11 +271,17 @@ status_t SurfaceTexture::updateTexImage() { mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0); - // Release the old buffer + // release old buffer if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { - mBufferQueue->releaseBuffer(mCurrentTexture, dpy, - mEGLSlots[mCurrentTexture].mFence); + status_t status = mBufferQueue->releaseBuffer(mCurrentTexture, dpy, mEGLSlots[mCurrentTexture].mFence); + mEGLSlots[mCurrentTexture].mFence = EGL_NO_SYNC_KHR; + if (status == BufferQueue::STALE_BUFFER_SLOT) { + freeBufferLocked(mCurrentTexture); + } else if (status != OK) { + ST_LOGE("updateTexImage: released invalid buffer"); + err = status; + } } // Update the SurfaceTexture state. @@ -289,7 +297,7 @@ status_t SurfaceTexture::updateTexImage() { glBindTexture(mTexTarget, mTexName); } - return OK; + return err; } status_t SurfaceTexture::detachFromContext() { @@ -630,6 +638,9 @@ bool SurfaceTexture::isSynchronousMode() const { void SurfaceTexture::freeBufferLocked(int slotIndex) { ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); mEGLSlots[slotIndex].mGraphicBuffer = 0; + if (slotIndex == mCurrentTexture) { + mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; + } if (mEGLSlots[slotIndex].mEglImage != EGL_NO_IMAGE_KHR) { EGLImageKHR img = mEGLSlots[slotIndex].mEglImage; if (img != EGL_NO_IMAGE_KHR) { @@ -693,12 +704,6 @@ sp<BufferQueue> SurfaceTexture::getBufferQueue() const { } // Used for refactoring, should not be in final interface -status_t SurfaceTexture::setBufferCount(int bufferCount) { - Mutex::Autolock lock(mMutex); - return mBufferQueue->setBufferCount(bufferCount); -} - -// Used for refactoring, should not be in final interface status_t SurfaceTexture::connect(int api, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { Mutex::Autolock lock(mMutex); @@ -737,8 +742,6 @@ void SurfaceTexture::onBuffersReleased() { freeBufferLocked(i); } } - - mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; } void SurfaceTexture::dump(String8& result) const |