Skip to content

Commit f1e868f

Browse files
Sunita NadampalliJamie Gennis
authored andcommitted
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>
1 parent 6a54a99 commit f1e868f

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

include/gui/SurfaceTexture.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ class SurfaceTexture : public BnSurfaceTexture {
271271
mRequestBufferCalled(false),
272272
mTransform(0),
273273
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
274-
mTimestamp(0) {
274+
mTimestamp(0),
275+
mFrameNumber(0) {
275276
mCrop.makeInvalid();
276277
}
277278

@@ -340,6 +341,10 @@ class SurfaceTexture : public BnSurfaceTexture {
340341
// mTimestamp is the current timestamp for this buffer slot. This gets
341342
// to set by queueBuffer each time this slot is queued.
342343
int64_t mTimestamp;
344+
345+
// mFrameNumber is the number of the queued frame for this slot.
346+
uint64_t mFrameNumber;
347+
343348
};
344349

345350
// mSlots is the array of buffer slots that must be mirrored on the client
@@ -476,6 +481,12 @@ class SurfaceTexture : public BnSurfaceTexture {
476481
// around a GL driver limitation on the number of FBO attachments, which the
477482
// browser's tile cache exceeds.
478483
const GLenum mTexTarget;
484+
485+
// mFrameCounter is the free running counter, incremented for every buffer queued
486+
// with the surface Texture.
487+
uint64_t mFrameCounter;
488+
489+
479490
};
480491

481492
// ----------------------------------------------------------------------------

libs/gui/SurfaceTexture.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
112112
mAllowSynchronousMode(allowSynchronousMode),
113113
mConnectedApi(NO_CONNECTED_API),
114114
mAbandoned(false),
115-
mTexTarget(texTarget) {
115+
mTexTarget(texTarget),
116+
mFrameCounter(0) {
116117
// Choose a name using the PID and a process-unique ID.
117118
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
118119

@@ -260,7 +261,8 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
260261

261262
status_t returnFlags(OK);
262263

263-
int found, foundSync;
264+
int found = -1;
265+
int foundSync = -1;
264266
int dequeuedCount = 0;
265267
bool tryAgain = true;
266268
while (tryAgain) {
@@ -333,9 +335,14 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
333335
}
334336
} else {
335337
if (state == BufferSlot::FREE) {
336-
foundSync = i;
337-
found = i;
338-
break;
338+
/** For Asynchronous mode, we need to return the oldest of free buffers
339+
* There is only one instance when the Framecounter overflows, this logic
340+
* might return the earlier buffer to client. Which is a negligible impact
341+
**/
342+
if (found < 0 || mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
343+
foundSync = i;
344+
found = i;
345+
}
339346
}
340347
}
341348
}
@@ -527,6 +534,9 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
527534
mSlots[buf].mTransform = mNextTransform;
528535
mSlots[buf].mScalingMode = mNextScalingMode;
529536
mSlots[buf].mTimestamp = timestamp;
537+
mFrameCounter++;
538+
mSlots[buf].mFrameNumber = mFrameCounter;
539+
530540
mDequeueCondition.signal();
531541

532542
*outWidth = mDefaultWidth;
@@ -560,6 +570,7 @@ void SurfaceTexture::cancelBuffer(int buf) {
560570
return;
561571
}
562572
mSlots[buf].mBufferState = BufferSlot::FREE;
573+
mSlots[buf].mFrameNumber = 0;
563574
mDequeueCondition.signal();
564575
}
565576

@@ -893,6 +904,7 @@ void SurfaceTexture::setFrameAvailableListener(
893904
void SurfaceTexture::freeBufferLocked(int i) {
894905
mSlots[i].mGraphicBuffer = 0;
895906
mSlots[i].mBufferState = BufferSlot::FREE;
907+
mSlots[i].mFrameNumber = 0;
896908
if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
897909
eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
898910
mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;

0 commit comments

Comments
 (0)