Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1ef3c4d authored by Jamie Gennis's avatar Jamie Gennis Committed by Android (Google) Code Review
Browse files

Merge "SurfaceTexture: Fix to return the oldest of free buffers to Client on...

Merge "SurfaceTexture: Fix to return the oldest of free buffers to Client on Dequeue call" into ics-mr1
parents dfc09922 a929748d
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -271,7 +271,8 @@ private:
              mRequestBufferCalled(false),
              mTransform(0),
              mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
              mTimestamp(0) {
              mTimestamp(0),
              mFrameNumber(0) {
            mCrop.makeInvalid();
        }

@@ -340,6 +341,10 @@ private:
        // mTimestamp is the current timestamp for this buffer slot. This gets
        // to set by queueBuffer each time this slot is queued.
        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
@@ -476,6 +481,12 @@ private:
    // around a GL driver limitation on the number of FBO attachments, which the
    // browser's tile cache exceeds.
    const GLenum mTexTarget;

    // mFrameCounter is the free running counter, incremented for every buffer queued
    // with the surface Texture.
    uint64_t mFrameCounter;


};

// ----------------------------------------------------------------------------
+17 −5
Original line number Diff line number Diff line
@@ -116,7 +116,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());

@@ -264,7 +265,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) {
@@ -337,9 +339,14 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
                }
            } else {
                if (state == BufferSlot::FREE) {
                    /** 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;
                    break;
                    }
                }
            }
        }
@@ -531,6 +538,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;
@@ -564,6 +574,7 @@ void SurfaceTexture::cancelBuffer(int buf) {
        return;
    }
    mSlots[buf].mBufferState = BufferSlot::FREE;
    mSlots[buf].mFrameNumber = 0;
    mDequeueCondition.signal();
}

@@ -897,6 +908,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;