Merge "SurfaceTexture: Fix to return the oldest of free buffers to Client on Dequeue call" into ics-mr1

This commit is contained in:
Jamie Gennis 2011-11-16 11:34:30 -08:00 committed by Android (Google) Code Review
commit c1ef3c4d7d
2 changed files with 29 additions and 6 deletions

View File

@ -271,7 +271,8 @@ private:
mRequestBufferCalled(false), mRequestBufferCalled(false),
mTransform(0), mTransform(0),
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mTimestamp(0) { mTimestamp(0),
mFrameNumber(0) {
mCrop.makeInvalid(); mCrop.makeInvalid();
} }
@ -340,6 +341,10 @@ private:
// mTimestamp is the current timestamp for this buffer slot. This gets // mTimestamp is the current timestamp for this buffer slot. This gets
// to set by queueBuffer each time this slot is queued. // to set by queueBuffer each time this slot is queued.
int64_t mTimestamp; int64_t mTimestamp;
// mFrameNumber is the number of the queued frame for this slot.
uint64_t mFrameNumber;
}; };
// mSlots is the array of buffer slots that must be mirrored on the client // mSlots is the array of buffer slots that must be mirrored on the client
@ -476,6 +481,12 @@ private:
// around a GL driver limitation on the number of FBO attachments, which the // around a GL driver limitation on the number of FBO attachments, which the
// browser's tile cache exceeds. // browser's tile cache exceeds.
const GLenum mTexTarget; const GLenum mTexTarget;
// mFrameCounter is the free running counter, incremented for every buffer queued
// with the surface Texture.
uint64_t mFrameCounter;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -116,7 +116,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
mAllowSynchronousMode(allowSynchronousMode), mAllowSynchronousMode(allowSynchronousMode),
mConnectedApi(NO_CONNECTED_API), mConnectedApi(NO_CONNECTED_API),
mAbandoned(false), mAbandoned(false),
mTexTarget(texTarget) { mTexTarget(texTarget),
mFrameCounter(0) {
// Choose a name using the PID and a process-unique ID. // Choose a name using the PID and a process-unique ID.
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
@ -264,7 +265,8 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
status_t returnFlags(OK); status_t returnFlags(OK);
int found, foundSync; int found = -1;
int foundSync = -1;
int dequeuedCount = 0; int dequeuedCount = 0;
bool tryAgain = true; bool tryAgain = true;
while (tryAgain) { while (tryAgain) {
@ -337,9 +339,14 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
} }
} else { } else {
if (state == BufferSlot::FREE) { if (state == BufferSlot::FREE) {
foundSync = i; /** For Asynchronous mode, we need to return the oldest of free buffers
found = i; * There is only one instance when the Framecounter overflows, this logic
break; * 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;
}
} }
} }
} }
@ -531,6 +538,9 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
mSlots[buf].mTransform = mNextTransform; mSlots[buf].mTransform = mNextTransform;
mSlots[buf].mScalingMode = mNextScalingMode; mSlots[buf].mScalingMode = mNextScalingMode;
mSlots[buf].mTimestamp = timestamp; mSlots[buf].mTimestamp = timestamp;
mFrameCounter++;
mSlots[buf].mFrameNumber = mFrameCounter;
mDequeueCondition.signal(); mDequeueCondition.signal();
*outWidth = mDefaultWidth; *outWidth = mDefaultWidth;
@ -564,6 +574,7 @@ void SurfaceTexture::cancelBuffer(int buf) {
return; return;
} }
mSlots[buf].mBufferState = BufferSlot::FREE; mSlots[buf].mBufferState = BufferSlot::FREE;
mSlots[buf].mFrameNumber = 0;
mDequeueCondition.signal(); mDequeueCondition.signal();
} }
@ -897,6 +908,7 @@ void SurfaceTexture::setFrameAvailableListener(
void SurfaceTexture::freeBufferLocked(int i) { void SurfaceTexture::freeBufferLocked(int i) {
mSlots[i].mGraphicBuffer = 0; mSlots[i].mGraphicBuffer = 0;
mSlots[i].mBufferState = BufferSlot::FREE; mSlots[i].mBufferState = BufferSlot::FREE;
mSlots[i].mFrameNumber = 0;
if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) { if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage); eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
mSlots[i].mEglImage = EGL_NO_IMAGE_KHR; mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;