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

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

Merge changes I09a74538,I08d96b38,Ic1d3344b

* changes:
  SurfaceTexture: disable a failing test.
  SurfaceTexture: fix an error check in dequeueBuffer.
  SurfaceTexture: clean up some comments, tests, etc.
parents ff0e8443 8dda6b7b
Loading
Loading
Loading
Loading
+45 −20
Original line number Diff line number Diff line
@@ -197,8 +197,9 @@ private:
              mEglDisplay(EGL_NO_DISPLAY),
              mBufferState(BufferSlot::FREE),
              mRequestBufferCalled(false),
              mLastQueuedTransform(0),
              mLastQueuedTimestamp(0) {
              mTransform(0),
              mTimestamp(0) {
            mCrop.makeInvalid();
        }

        // mGraphicBuffer points to the buffer allocated for this slot or is NULL
@@ -211,32 +212,56 @@ private:
        // mEglDisplay is the EGLDisplay used to create mEglImage.
        EGLDisplay mEglDisplay;

        // mBufferState indicates whether the slot is currently accessible to a
        // client and should not be used by the SurfaceTexture object. It gets
        // set to true when dequeueBuffer returns the slot and is reset to false
        // when the client calls either queueBuffer or cancelBuffer on the slot.
        enum { DEQUEUED=-2, FREE=-1, QUEUED=0 };
        int8_t mBufferState;
        // BufferState represents the different states in which a buffer slot
        // can be.
        enum BufferState {
            // FREE indicates that the buffer is not currently being used and
            // will not be used in the future until it gets dequeued and
            // subseqently queued by the client.
            FREE = 0,

            // DEQUEUED indicates that the buffer has been dequeued by the
            // client, but has not yet been queued or canceled. The buffer is
            // considered 'owned' by the client, and the server should not use
            // it for anything.
            //
            // Note that when in synchronous-mode (mSynchronousMode == true),
            // the buffer that's currently attached to the texture may be
            // dequeued by the client.  That means that the current buffer can
            // be in either the DEQUEUED or QUEUED state.  In asynchronous mode,
            // however, the current buffer is always in the QUEUED state.
            DEQUEUED = 1,

            // QUEUED indicates that the buffer has been queued by the client,
            // and has not since been made available for the client to dequeue.
            // Attaching the buffer to the texture does NOT transition the
            // buffer away from the QUEUED state. However, in Synchronous mode
            // the current buffer may be dequeued by the client under some
            // circumstances. See the note about the current buffer in the
            // documentation for DEQUEUED.
            QUEUED = 2,
        };

        // mBufferState is the current state of this buffer slot.
        BufferState mBufferState;

        // mRequestBufferCalled is used for validating that the client did
        // call requestBuffer() when told to do so. Technically this is not
        // needed but useful for debugging and catching client bugs.
        bool mRequestBufferCalled;

        // mLastQueuedCrop is the crop rectangle for the buffer that was most
        // recently queued. This gets set to mNextCrop each time queueBuffer gets
        // called.
        Rect mLastQueuedCrop;
        // mCrop is the current crop rectangle for this buffer slot. This gets
        // set to mNextCrop each time queueBuffer gets called for this buffer.
        Rect mCrop;

        // mLastQueuedTransform is the transform identifier for the buffer that was
        // most recently queued. This gets set to mNextTransform each time
        // queueBuffer gets called.
        uint32_t mLastQueuedTransform;
        // mTransform is the current transform flags for this buffer slot. This
        // gets set to mNextTransform each time queueBuffer gets called for this
        // slot.
        uint32_t mTransform;

        // mLastQueuedTimestamp is the timestamp for the buffer that was most
        // recently queued. This gets set by queueBuffer.
        int64_t mLastQueuedTimestamp;
        // mTimestamp is the current timestamp for this buffer slot. This gets
        // to set by queueBuffer each time this slot is queued.
        int64_t mTimestamp;
    };

    // mSlots is the array of buffer slots that must be mirrored on the client
+56 −54
Original line number Diff line number Diff line
@@ -285,6 +285,10 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
            return -EINVAL;
        }

        // See whether a buffer has been queued since the last setBufferCount so
        // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
        bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
        if (bufferHasBeenQueued) {
            // make sure the client is not trying to dequeue more buffers
            // than allowed.
            const int avail = mBufferCount - (dequeuedCount+1);
@@ -292,8 +296,8 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
                LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
                        MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
                        dequeuedCount);
            // TODO: Enable this error report after we fix issue 4435022
            // return -EBUSY;
                return -EBUSY;
            }
        }

        // we're in synchronous mode and didn't find a buffer, we need to wait
@@ -403,8 +407,8 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
            LOGE("queueBuffer: slot %d is current!", buf);
            return -EINVAL;
        } else if (!mSlots[buf].mRequestBufferCalled) {
        LOGE("queueBuffer: slot %d was enqueued without requesting a buffer",
                buf);
            LOGE("queueBuffer: slot %d was enqueued without requesting a "
                    "buffer", buf);
            return -EINVAL;
        }

@@ -429,9 +433,9 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
        }

        mSlots[buf].mBufferState = BufferSlot::QUEUED;
    mSlots[buf].mLastQueuedCrop = mNextCrop;
    mSlots[buf].mLastQueuedTransform = mNextTransform;
    mSlots[buf].mLastQueuedTimestamp = timestamp;
        mSlots[buf].mCrop = mNextCrop;
        mSlots[buf].mTransform = mNextTransform;
        mSlots[buf].mTimestamp = timestamp;
        mDequeueCondition.signal();
    } // scope for the lock

@@ -540,9 +544,9 @@ status_t SurfaceTexture::updateTexImage() {
        mCurrentTexture = buf;
        mCurrentTextureTarget = target;
        mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
        mCurrentCrop = mSlots[buf].mLastQueuedCrop;
        mCurrentTransform = mSlots[buf].mLastQueuedTransform;
        mCurrentTimestamp = mSlots[buf].mLastQueuedTimestamp;
        mCurrentCrop = mSlots[buf].mCrop;
        mCurrentTransform = mSlots[buf].mTransform;
        mCurrentTimestamp = mSlots[buf].mTimestamp;
        mDequeueCondition.signal();
    } else {
        // We always bind the texture even if we don't update its contents.
@@ -826,12 +830,10 @@ void SurfaceTexture::dump(String8& result, const char* prefix,
        const BufferSlot& slot(mSlots[i]);
        snprintf(buffer, SIZE,
                "%s%s[%02d] state=%-8s, crop=[%d,%d,%d,%d], transform=0x%02x, "
                "timestamp=%lld\n"
                ,
                "timestamp=%lld\n",
                prefix, (i==mCurrentTexture)?">":" ", i, stateName(slot.mBufferState),
                slot.mLastQueuedCrop.left, slot.mLastQueuedCrop.top,
                slot.mLastQueuedCrop.right, slot.mLastQueuedCrop.bottom,
                slot.mLastQueuedTransform, slot.mLastQueuedTimestamp
                slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, slot.mCrop.bottom,
                slot.mTransform, slot.mTimestamp
        );
        result.append(buffer);
    }
+2 −1
Original line number Diff line number Diff line
@@ -117,7 +117,8 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
            mReqFormat, mReqUsage);
    if (result < 0) {
        LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
             "failed: %d", result, mReqWidth, mReqHeight, mReqFormat, mReqUsage);
             "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
             result);
        return result;
    }
    sp<GraphicBuffer>& gbuf(mSlots[buf]);
+14 −3
Original line number Diff line number Diff line
@@ -400,7 +400,9 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
}

TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDequeueCurrent) {
// XXX: We currently have no hardware that properly handles dequeuing the
// buffer that is currently bound to the texture.
TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
    sp<ANativeWindow> anw(mSTC);
    sp<SurfaceTexture> st(mST);
    android_native_buffer_t* buf[3];
@@ -429,10 +431,13 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
    android_native_buffer_t* buf[3];
    ASSERT_EQ(OK, st->setSynchronousMode(true));
    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));

    // We should be able to dequeue all the buffers before we've queued any.
    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
    EXPECT_EQ(-EBUSY, anw->dequeueBuffer(anw.get(), &buf[2]));
    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));

    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[2]));
    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));

    EXPECT_EQ(OK, st->updateTexImage());
@@ -440,11 +445,17 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {

    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));

    // Once we've queued a buffer, however we should not be able to dequeue more
    // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
    EXPECT_EQ(-EBUSY, anw->dequeueBuffer(anw.get(), &buf[1]));

    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[2]));
}

TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeWaitRetire) {
// XXX: This is not expected to pass until the synchronization hacks are removed
// from the SurfaceTexture class.
TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
    sp<ANativeWindow> anw(mSTC);
    sp<SurfaceTexture> st(mST);