summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-05-18 16:50:58 -0700
committerMathias Agopian <mathias@google.com>2012-05-18 16:50:58 -0700
commit7e477bfe11f8bb31622353b64e85721df3cf9702 (patch)
tree63c57cd819b0ea00c595674c230f8232ab3cf17d
parentf899e4113a5b5545cd91b4625514d0ab0d33751c (diff)
downloadframeworks_native-7e477bfe11f8bb31622353b64e85721df3cf9702.zip
frameworks_native-7e477bfe11f8bb31622353b64e85721df3cf9702.tar.gz
frameworks_native-7e477bfe11f8bb31622353b64e85721df3cf9702.tar.bz2
make sure BufferQueue releases newly acquired buffers on failures
this prevents SurfaceTexture producer to hang in dequeueBuffer() when something goes wrong in the consumer. only the consumer gets an error and the current frame is kept instead of the new one. the producer is unaware of the problem. Bug: 6476587 Change-Id: Ie6db5526632aabc3e60229b93dfe29c19491ade4
-rw-r--r--libs/gui/SurfaceTexture.cpp52
1 files changed, 28 insertions, 24 deletions
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index feaf07a..30c0d9b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -235,36 +235,39 @@ status_t SurfaceTexture::updateTexImage() {
if (image == EGL_NO_IMAGE_KHR) {
if (mEGLSlots[buf].mGraphicBuffer == NULL) {
ST_LOGE("updateTexImage: buffer at slot %d is null", buf);
- return BAD_VALUE;
- }
- image = createImage(dpy, mEGLSlots[buf].mGraphicBuffer);
- mEGLSlots[buf].mEglImage = image;
- if (image == EGL_NO_IMAGE_KHR) {
- // NOTE: if dpy was invalid, createImage() is guaranteed to
- // fail. so we'd end up here.
- return UNKNOWN_ERROR;
+ err = BAD_VALUE;
+ } else {
+ image = createImage(dpy, mEGLSlots[buf].mGraphicBuffer);
+ mEGLSlots[buf].mEglImage = image;
+ if (image == EGL_NO_IMAGE_KHR) {
+ // NOTE: if dpy was invalid, createImage() is guaranteed to
+ // fail. so we'd end up here.
+ err = UNKNOWN_ERROR;
+ }
}
}
- GLint error;
- while ((error = glGetError()) != GL_NO_ERROR) {
- ST_LOGW("updateTexImage: clearing GL error: %#04x", error);
- }
+ if (err == NO_ERROR) {
+ GLint error;
+ while ((error = glGetError()) != GL_NO_ERROR) {
+ ST_LOGW("updateTexImage: clearing GL error: %#04x", error);
+ }
- glBindTexture(mTexTarget, mTexName);
- glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image);
+ glBindTexture(mTexTarget, mTexName);
+ glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image);
- while ((error = glGetError()) != GL_NO_ERROR) {
- ST_LOGE("updateTexImage: error binding external texture image %p "
- "(slot %d): %#04x", image, buf, error);
- err = UNKNOWN_ERROR;
- }
+ while ((error = glGetError()) != GL_NO_ERROR) {
+ ST_LOGE("updateTexImage: error binding external texture image %p "
+ "(slot %d): %#04x", image, buf, error);
+ err = UNKNOWN_ERROR;
+ }
- if (err == OK) {
- err = syncForReleaseLocked(dpy);
+ if (err == NO_ERROR) {
+ err = syncForReleaseLocked(dpy);
+ }
}
- if (err != OK) {
+ if (err != NO_ERROR) {
// Release the buffer we just acquired. It's not safe to
// release the old buffer, so instead we just drop the new frame.
mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence);
@@ -279,12 +282,13 @@ status_t SurfaceTexture::updateTexImage() {
// release old buffer
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- status_t status = 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) {
+ } else if (status != NO_ERROR) {
ST_LOGE("updateTexImage: released invalid buffer");
err = status;
}