summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2011-08-17 15:42:04 -0700
committerMathias Agopian <mathias@google.com>2011-08-17 15:49:13 -0700
commit8618ebcc5d20a5983da1fc6200d50c3662aca6e3 (patch)
tree56e364cad0f30931fb430f68bb7d40f483d68e8e
parent1a227437be33157175b4de5f47d08a02647ee71a (diff)
downloadframeworks_base-8618ebcc5d20a5983da1fc6200d50c3662aca6e3.zip
frameworks_base-8618ebcc5d20a5983da1fc6200d50c3662aca6e3.tar.gz
frameworks_base-8618ebcc5d20a5983da1fc6200d50c3662aca6e3.tar.bz2
don't return the current buffer from dequeueBuffer
we were not reseting mCurrentTexture in some situations which in turn caused dequeueBuffers() return a "FREE" buffer that was also current. Very often it was harmless, but it created a race with updateTexImage() which could cause the following queueBuffers() to fail. Bug: 5156325 Change-Id: If15a31dc869117543d220d6e5562c57116cbabdb
-rw-r--r--include/gui/SurfaceTexture.h2
-rw-r--r--libs/gui/SurfaceTexture.cpp27
2 files changed, 24 insertions, 5 deletions
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index a6fb12e..493993d 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -275,7 +275,7 @@ private:
enum BufferState {
// FREE indicates that the buffer is not currently being used and
// will not be used in the future until it gets dequeued and
- // subseqently queued by the client.
+ // subsequently queued by the client.
FREE = 0,
// DEQUEUED indicates that the buffer has been dequeued by the
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index b2441ce..ac9b33b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -36,6 +36,10 @@
#include <utils/Log.h>
#include <utils/String8.h>
+
+#define ALLOW_DEQUEUE_CURRENT_BUFFER false
+
+
namespace android {
// Transform matrices
@@ -294,9 +298,22 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
if (state == BufferSlot::DEQUEUED) {
dequeuedCount++;
}
- if (state == BufferSlot::FREE /*|| i == mCurrentTexture*/) {
- foundSync = i;
- if (i != mCurrentTexture) {
+
+ // if buffer is FREE it CANNOT be current
+ LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
+ "dequeueBuffer: buffer %d is both FREE and current!", i);
+
+ if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
+ if (state == BufferSlot::FREE || i == mCurrentTexture) {
+ foundSync = i;
+ if (i != mCurrentTexture) {
+ found = i;
+ break;
+ }
+ }
+ } else {
+ if (state == BufferSlot::FREE) {
+ foundSync = i;
found = i;
break;
}
@@ -325,7 +342,7 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
}
// we're in synchronous mode and didn't find a buffer, we need to wait
- // for for some buffers to be consumed
+ // for some buffers to be consumed
tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
if (tryAgain) {
mDequeueCondition.wait(mMutex);
@@ -846,6 +863,7 @@ void SurfaceTexture::freeBufferLocked(int i) {
void SurfaceTexture::freeAllBuffersLocked() {
LOGW_IF(!mQueue.isEmpty(),
"freeAllBuffersLocked called but mQueue is not empty");
+ mCurrentTexture = INVALID_BUFFER_SLOT;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
freeBufferLocked(i);
}
@@ -859,6 +877,7 @@ void SurfaceTexture::freeAllBuffersExceptHeadLocked() {
Fifo::iterator front(mQueue.begin());
head = *front;
}
+ mCurrentTexture = INVALID_BUFFER_SLOT;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (i != head) {
freeBufferLocked(i);