diff options
author | Sunita Nadampalli <sunitan@ti.com> | 2011-11-09 18:23:41 -0600 |
---|---|---|
committer | Jamie Gennis <jgennis@google.com> | 2011-11-15 11:43:35 -0800 |
commit | f1e868f68204bf469a0c162b84af0e651d513ac8 (patch) | |
tree | 23a997a5d68fb46652460aa233ec3dd0133652f3 /libs | |
parent | 6a54a997e3dc71c5b9c5a1c7829bc3eb35404e92 (diff) | |
download | frameworks_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.cpp | 22 |
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; |