summaryrefslogtreecommitdiffstats
path: root/libs/gui/SurfaceTexture.cpp
diff options
context:
space:
mode:
authorDaniel Lam <dalam@google.com>2012-03-26 20:37:15 -0700
committerDaniel Lam <dalam@google.com>2012-04-02 14:55:01 -0700
commit9abe1ebc9575dc5a19bf1dfce6e9b02e03374457 (patch)
treec363e3977311b0bc9d929cf9103e2bb3101e76d3 /libs/gui/SurfaceTexture.cpp
parent0e1080f887bcd80c75910cabe7b2eca224bf739c (diff)
downloadframeworks_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.cpp27
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