summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorSunita Nadampalli <sunitan@ti.com>2011-11-09 18:23:41 -0600
committerJamie Gennis <jgennis@google.com>2011-11-15 11:43:35 -0800
commitf1e868f68204bf469a0c162b84af0e651d513ac8 (patch)
tree23a997a5d68fb46652460aa233ec3dd0133652f3 /libs
parent6a54a997e3dc71c5b9c5a1c7829bc3eb35404e92 (diff)
downloadframeworks_base-f1e868f68204bf469a0c162b84af0e651d513ac8.zip
frameworks_base-f1e868f68204bf469a0c162b84af0e651d513ac8.tar.gz
frameworks_base-f1e868f68204bf469a0c162b84af0e651d513ac8.tar.bz2
SurfaceTexture: Fix to return the oldest of free buffers to Client on Dequeue call
Surface Texture dequeue logic is modified to return the oldest of the free buffers to Client on dequeue call. Currently dequeue method is returning the first buffer index which is free. The parsing is done in ascending order of the buffer slot indices. This leads to returning the buffer which has been just queued to composer, and hence display, and this defeats the purpose of having minimum dequeue count as 2 in asynchrnouse mode. This is fixed by checking all the free slots and returning the oldest buffer. Change-Id: Ibbac10593c3994c278c601af0480b171635ecdd4 Signed-off-by: Sunita Nadampalli <sunitan@ti.com>
Diffstat (limited to 'libs')
-rw-r--r--libs/gui/SurfaceTexture.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 6f84206..3c0d475 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -112,7 +112,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
mAllowSynchronousMode(allowSynchronousMode),
mConnectedApi(NO_CONNECTED_API),
mAbandoned(false),
- mTexTarget(texTarget) {
+ mTexTarget(texTarget),
+ mFrameCounter(0) {
// Choose a name using the PID and a process-unique ID.
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
@@ -260,7 +261,8 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
status_t returnFlags(OK);
- int found, foundSync;
+ int found = -1;
+ int foundSync = -1;
int dequeuedCount = 0;
bool tryAgain = true;
while (tryAgain) {
@@ -333,9 +335,14 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
}
} else {
if (state == BufferSlot::FREE) {
- foundSync = i;
- found = i;
- break;
+ /** For Asynchronous mode, we need to return the oldest of free buffers
+ * There is only one instance when the Framecounter overflows, this logic
+ * might return the earlier buffer to client. Which is a negligible impact
+ **/
+ if (found < 0 || mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
+ foundSync = i;
+ found = i;
+ }
}
}
}
@@ -527,6 +534,9 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
mSlots[buf].mTransform = mNextTransform;
mSlots[buf].mScalingMode = mNextScalingMode;
mSlots[buf].mTimestamp = timestamp;
+ mFrameCounter++;
+ mSlots[buf].mFrameNumber = mFrameCounter;
+
mDequeueCondition.signal();
*outWidth = mDefaultWidth;
@@ -560,6 +570,7 @@ void SurfaceTexture::cancelBuffer(int buf) {
return;
}
mSlots[buf].mBufferState = BufferSlot::FREE;
+ mSlots[buf].mFrameNumber = 0;
mDequeueCondition.signal();
}
@@ -893,6 +904,7 @@ void SurfaceTexture::setFrameAvailableListener(
void SurfaceTexture::freeBufferLocked(int i) {
mSlots[i].mGraphicBuffer = 0;
mSlots[i].mBufferState = BufferSlot::FREE;
+ mSlots[i].mFrameNumber = 0;
if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;