Skip to content

Commit fd6b64f

Browse files
Jamie GennisAndroid (Google) Code Review
authored andcommitted
Merge "SurfaceTexture: Fix to return the oldest of free buffers to Client on Dequeue call" into ics-mr1
2 parents 7dc81e0 + f1e868f commit fd6b64f

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
@@ -116,7 +116,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
116116
mAllowSynchronousMode(allowSynchronousMode),
117117
mConnectedApi(NO_CONNECTED_API),
118118
mAbandoned(false),
119-
mTexTarget(texTarget) {
119+
mTexTarget(texTarget),
120+
mFrameCounter(0) {
120121
// Choose a name using the PID and a process-unique ID.
121122
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
122123

@@ -264,7 +265,8 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
264265

265266
status_t returnFlags(OK);
266267

267-
int found, foundSync;
268+
int found = -1;
269+
int foundSync = -1;
268270
int dequeuedCount = 0;
269271
bool tryAgain = true;
270272
while (tryAgain) {
@@ -337,9 +339,14 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
337339
}
338340
} else {
339341
if (state == BufferSlot::FREE) {
340-
foundSync = i;
341-
found = i;
342-
break;
342+
/** For Asynchronous mode, we need to return the oldest of free buffers
343+
* There is only one instance when the Framecounter overflows, this logic
344+
* might return the earlier buffer to client. Which is a negligible impact
345+
**/
346+
if (found < 0 || mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
347+
foundSync = i;
348+
found = i;
349+
}
343350
}
344351
}
345352
}
@@ -531,6 +538,9 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
531538
mSlots[buf].mTransform = mNextTransform;
532539
mSlots[buf].mScalingMode = mNextScalingMode;
533540
mSlots[buf].mTimestamp = timestamp;
541+
mFrameCounter++;
542+
mSlots[buf].mFrameNumber = mFrameCounter;
543+
534544
mDequeueCondition.signal();
535545

536546
*outWidth = mDefaultWidth;
@@ -564,6 +574,7 @@ void SurfaceTexture::cancelBuffer(int buf) {
564574
return;
565575
}
566576
mSlots[buf].mBufferState = BufferSlot::FREE;
577+
mSlots[buf].mFrameNumber = 0;
567578
mDequeueCondition.signal();
568579
}
569580

@@ -897,6 +908,7 @@ void SurfaceTexture::setFrameAvailableListener(
897908
void SurfaceTexture::freeBufferLocked(int i) {
898909
mSlots[i].mGraphicBuffer = 0;
899910
mSlots[i].mBufferState = BufferSlot::FREE;
911+
mSlots[i].mFrameNumber = 0;
900912
if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
901913
eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
902914
mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;

0 commit comments

Comments
 (0)