@@ -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(
897908void 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