From d11b044864be525a1646f93106ab496195bb8239 Mon Sep 17 00:00:00 2001 From: Ian Elliott Date: Tue, 18 Jul 2017 11:05:49 -0600 Subject: [PATCH] Have the Surface class track the buffer age. Have the Surface class track the buffer age, so that Surface::query() can return the buffer age without having to use a binder call to BufferQueueProducer::query(). The idea is for BufferQueueProducer::dequeueBuffer() to return the value, which the Surface class will cache for later use by Surface::query(). Bug: b/27903668 Test: Use systrace to no ensure query binder call after dequeueBuffer. Change-Id: I106a7bd27461d381f0bd84df70d804de56a128ab --- libs/gui/BufferQueueProducer.cpp | 11 +- libs/gui/IGraphicBufferProducer.cpp | 32 +++-- libs/gui/Surface.cpp | 43 ++++--- .../bufferqueue/1.0/H2BGraphicBufferProducer.cpp | 12 +- libs/gui/include/gui/BufferQueueProducer.h | 7 +- libs/gui/include/gui/IGraphicBufferProducer.h | 6 +- libs/gui/include/gui/Surface.h | 4 + .../gui/bufferqueue/1.0/H2BGraphicBufferProducer.h | 6 +- libs/gui/tests/BufferItemConsumer_test.cpp | 4 +- libs/gui/tests/BufferQueue_test.cpp | 132 ++++++++++----------- libs/gui/tests/IGraphicBufferProducer_test.cpp | 93 ++++++++------- libs/gui/tests/Malicious.cpp | 10 +- libs/gui/tests/StreamSplitter_test.cpp | 25 ++-- .../buffer_hub_queue_producer.cpp | 2 +- .../private/dvr/buffer_hub_queue_producer.h | 1 + .../tests/buffer_hub_queue_producer-test.cpp | 16 +-- .../DisplayHardware/VirtualDisplaySurface.cpp | 19 +-- .../DisplayHardware/VirtualDisplaySurface.h | 6 +- services/surfaceflinger/MonitoredProducer.cpp | 10 +- services/surfaceflinger/MonitoredProducer.h | 6 +- 20 files changed, 244 insertions(+), 201 deletions(-) diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 3d94a029e5..3424012acf 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -347,10 +347,10 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller, return NO_ERROR; } -status_t BufferQueueProducer::dequeueBuffer(int *outSlot, - sp *outFence, uint32_t width, uint32_t height, - PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps) { +status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp* outFence, + uint32_t width, uint32_t height, PixelFormat format, + uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) { ATRACE_CALL(); { // Autolock scope Mutex::Autolock lock(mCore->mMutex); @@ -558,6 +558,9 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, mSlots[*outSlot].mFrameNumber, mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); + if (outBufferAge) { + *outBufferAge = mCore->mBufferAge; + } addAndGetFrameTimestamps(nullptr, outTimestamps); return returnFlags; diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 1b0fe06810..8406a52544 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -124,9 +124,9 @@ public: return result; } - virtual status_t dequeueBuffer(int *buf, sp* fence, uint32_t width, - uint32_t height, PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps) { + virtual status_t dequeueBuffer(int* buf, sp* fence, uint32_t width, uint32_t height, + PixelFormat format, uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) { Parcel data, reply; bool getFrameTimestamps = (outTimestamps != nullptr); @@ -149,6 +149,17 @@ public: fence->clear(); return result; } + if (outBufferAge) { + result = reply.readUint64(outBufferAge); + } else { + // Read the value even if outBufferAge is nullptr: + uint64_t bufferAge; + result = reply.readUint64(&bufferAge); + } + if (result != NO_ERROR) { + ALOGE("IGBP::dequeueBuffer failed to read buffer age: %d", result); + return result; + } if (getFrameTimestamps) { result = reply.read(*outTimestamps); if (result != NO_ERROR) { @@ -516,11 +527,10 @@ public: return mBase->setAsyncMode(async); } - status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, uint32_t h, - PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps) override { - return mBase->dequeueBuffer( - slot, fence, w, h, format, usage, outTimestamps); + status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, uint32_t h, PixelFormat format, + uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) override { + return mBase->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, outTimestamps); } status_t detachBuffer(int slot) override { @@ -655,16 +665,18 @@ status_t BnGraphicBufferProducer::onTransact( uint32_t height = data.readUint32(); PixelFormat format = static_cast(data.readInt32()); uint64_t usage = data.readUint64(); + uint64_t bufferAge = 0; bool getTimestamps = data.readBool(); int buf = 0; sp fence = Fence::NO_FENCE; FrameEventHistoryDelta frameTimestamps; - int result = dequeueBuffer(&buf, &fence, width, height, format, - usage, getTimestamps ? &frameTimestamps : nullptr); + int result = dequeueBuffer(&buf, &fence, width, height, format, usage, &bufferAge, + getTimestamps ? &frameTimestamps : nullptr); reply->writeInt32(buf); reply->write(*fence); + reply->writeUint64(bufferAge); if (getTimestamps) { reply->write(frameTimestamps); } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 409a3cb076..78eb69d132 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -44,21 +44,19 @@ namespace android { -Surface::Surface( - const sp& bufferProducer, - bool controlledByApp) - : mGraphicBufferProducer(bufferProducer), - mCrop(Rect::EMPTY_RECT), - mGenerationNumber(0), - mSharedBufferMode(false), - mAutoRefresh(false), - mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), - mSharedBufferHasBeenQueued(false), - mQueriedSupportedTimestamps(false), - mFrameTimestampsSupportsPresent(false), - mEnableFrameTimestamps(false), - mFrameEventHistory(std::make_unique()) -{ +Surface::Surface(const sp& bufferProducer, bool controlledByApp) + : mGraphicBufferProducer(bufferProducer), + mCrop(Rect::EMPTY_RECT), + mBufferAge(0), + mGenerationNumber(0), + mSharedBufferMode(false), + mAutoRefresh(false), + mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), + mSharedBufferHasBeenQueued(false), + mQueriedSupportedTimestamps(false), + mFrameTimestampsSupportsPresent(false), + mEnableFrameTimestamps(false), + mFrameEventHistory(std::make_unique()) { // Initialize the ANativeWindow function pointers. ANativeWindow::setSwapInterval = hook_setSwapInterval; ANativeWindow::dequeueBuffer = hook_dequeueBuffer; @@ -506,9 +504,10 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { nsecs_t startTime = systemTime(); FrameEventHistoryDelta frameTimestamps; - status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, - reqWidth, reqHeight, reqFormat, reqUsage, - enableFrameTimestamps ? &frameTimestamps : nullptr); + status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight, + reqFormat, reqUsage, &mBufferAge, + enableFrameTimestamps ? &frameTimestamps + : nullptr); mLastDequeueDuration = systemTime() - startTime; if (result < 0) { @@ -845,6 +844,14 @@ int Surface::query(int what, int* value) const { } return err; } + case NATIVE_WINDOW_BUFFER_AGE: { + if (mBufferAge > INT32_MAX) { + *value = 0; + } else { + *value = static_cast(mBufferAge); + } + return NO_ERROR; + } case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: { int64_t durationUs = mLastDequeueDuration / 1000; *value = durationUs > std::numeric_limits::max() ? diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp index 7c0552e0dc..4a023a6425 100644 --- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp +++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp @@ -989,10 +989,10 @@ status_t H2BGraphicBufferProducer::setAsyncMode(bool async) { } // FIXME: usage bits truncated -- needs a 64-bits usage version -status_t H2BGraphicBufferProducer::dequeueBuffer( - int* slot, sp* fence, - uint32_t w, uint32_t h, ::android::PixelFormat format, - uint64_t usage, FrameEventHistoryDelta* outTimestamps) { +status_t H2BGraphicBufferProducer::dequeueBuffer(int* slot, sp* fence, uint32_t w, + uint32_t h, ::android::PixelFormat format, + uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) { *fence = new Fence(); status_t fnStatus; status_t transStatus = toStatusT(mBase->dequeueBuffer( @@ -1016,6 +1016,10 @@ status_t H2BGraphicBufferProducer::dequeueBuffer( fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus; } })); + if (outBufferAge) { + // Since the HAL version doesn't return the buffer age, set it to 0: + *outBufferAge = 0; + } return transStatus == NO_ERROR ? fnStatus : transStatus; } diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h index 0f8917aa6d..d6f215e2c6 100644 --- a/libs/gui/include/gui/BufferQueueProducer.h +++ b/libs/gui/include/gui/BufferQueueProducer.h @@ -80,9 +80,10 @@ public: // // In both cases, the producer will need to call requestBuffer to get a // GraphicBuffer handle for the returned slot. - virtual status_t dequeueBuffer(int *outSlot, sp* outFence, - uint32_t width, uint32_t height, PixelFormat format, - uint64_t usage, FrameEventHistoryDelta* outTimestamps) override; + virtual status_t dequeueBuffer(int* outSlot, sp* outFence, uint32_t width, + uint32_t height, PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) override; // See IGraphicBufferProducer::detachBuffer virtual status_t detachBuffer(int slot); diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h index 6d16e7426c..f231f951e7 100644 --- a/libs/gui/include/gui/IGraphicBufferProducer.h +++ b/libs/gui/include/gui/IGraphicBufferProducer.h @@ -194,9 +194,9 @@ public: // // All other negative values are an unknown error returned downstream // from the graphics allocator (typically errno). - virtual status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, - uint32_t h, PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps) = 0; + virtual status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, uint32_t h, + PixelFormat format, uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) = 0; // detachBuffer attempts to remove all ownership of the buffer in the given // slot from the buffer queue. If this call succeeds, the slot will be diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 0f7e12a228..60eac0cf92 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -403,6 +403,10 @@ protected: // (the change since the previous frame) passed in by the producer. Region mDirtyRegion; + // mBufferAge tracks the age of the contents of the most recently dequeued + // buffer as the number of frames that have elapsed since it was last queued + uint64_t mBufferAge; + // Stores the current generation number. See setGenerationNumber and // IGraphicBufferProducer::setGenerationNumber for more information. uint32_t mGenerationNumber; diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h index c3a9d443ec..c1c3ae730d 100644 --- a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h +++ b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h @@ -64,9 +64,9 @@ struct H2BGraphicBufferProducer : public ::android::H2BConverter< status_t requestBuffer(int slot, sp* buf) override; status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override; status_t setAsyncMode(bool async) override; - status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, - uint32_t h, ::android::PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps) override; + status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, uint32_t h, + ::android::PixelFormat format, uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) override; status_t detachBuffer(int slot) override; status_t detachNextBuffer(sp* outBuffer, sp* outFence) override; diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp index d64e530488..b87cbbdec8 100644 --- a/libs/gui/tests/BufferItemConsumer_test.cpp +++ b/libs/gui/tests/BufferItemConsumer_test.cpp @@ -76,8 +76,8 @@ class BufferItemConsumerTest : public ::testing::Test { int slot; sp outFence; - status_t ret = mProducer->dequeueBuffer(&slot, &outFence, kWidth, - kHeight, 0, 0, nullptr); + status_t ret = mProducer->dequeueBuffer(&slot, &outFence, kWidth, kHeight, 0, 0, + nullptr, nullptr); ASSERT_GE(ret, 0); ALOGV("dequeueBuffer: slot=%d", slot); diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 4220aafa07..9a208593ab 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -144,8 +144,8 @@ TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); uint32_t* dataIn; @@ -188,16 +188,16 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { for (int i = 0; i < 2; i++) { ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, - GRALLOC_USAGE_SW_READ_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); } ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, - GRALLOC_USAGE_SW_READ_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); @@ -239,8 +239,8 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3)); for (int i = 0; i < 3; i++) { ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, - GRALLOC_USAGE_SW_READ_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); @@ -275,8 +275,8 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { BufferItem item; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, - GRALLOC_USAGE_SW_READ_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); @@ -285,8 +285,8 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { for (int i = 0; i < 2; i++) { ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, - GRALLOC_USAGE_SW_READ_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); @@ -335,8 +335,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); ASSERT_EQ(OK, mProducer->detachBuffer(slot)); @@ -384,8 +384,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); IGraphicBufferProducer::QueueBufferInput input(0, false, HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), @@ -420,8 +420,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { EGL_NO_SYNC_KHR, Fence::NO_FENCE)); ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); uint32_t* dataOut; @@ -443,8 +443,8 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); uint32_t* dataIn; @@ -492,22 +492,24 @@ TEST_F(BufferQueueTest, TestDisallowingAllocation) { sp buffer; // This should return an error since it would require an allocation ASSERT_EQ(OK, mProducer->allowAllocation(false)); - ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, - 0, GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + ASSERT_EQ(WOULD_BLOCK, + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); // This should succeed, now that we've lifted the prohibition ASSERT_EQ(OK, mProducer->allowAllocation(true)); ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); // Release the previous buffer back to the BufferQueue mProducer->cancelBuffer(slot, fence); // This should fail since we're requesting a different size ASSERT_EQ(OK, mProducer->allowAllocation(false)); - ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, - WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + ASSERT_EQ(WOULD_BLOCK, + mProducer->dequeueBuffer(&slot, &fence, WIDTH * 2, HEIGHT * 2, 0, + GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr)); } TEST_F(BufferQueueTest, TestGenerationNumbers) { @@ -524,7 +526,7 @@ TEST_F(BufferQueueTest, TestGenerationNumbers) { int slot; sp fence; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); sp buffer; ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); @@ -567,7 +569,7 @@ TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr)); + mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer)); // Queue the buffer @@ -581,8 +583,7 @@ TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) { // always the same one and because async mode gets enabled. int slot; for (int i = 0; i < 5; i++) { - ASSERT_EQ(OK, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(sharedSlot, slot); ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); } @@ -619,7 +620,7 @@ TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr)); + mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer)); // Queue the buffer @@ -646,8 +647,7 @@ TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) { // always return the same one. int slot; for (int i = 0; i < 5; i++) { - ASSERT_EQ(OK, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(sharedSlot, slot); ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); } @@ -686,7 +686,7 @@ TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr)); + mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer)); // Enable shared buffer mode @@ -703,8 +703,7 @@ TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) { // always the same one and because async mode gets enabled. int slot; for (int i = 0; i < 5; i++) { - ASSERT_EQ(OK, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(sharedSlot, slot); ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); } @@ -739,8 +738,7 @@ TEST_F(BufferQueueTest, TestTimeouts) { for (int i = 0; i < 5; ++i) { int slot = BufferQueue::INVALID_BUFFER_SLOT; sp fence = Fence::NO_FENCE; - auto result = mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr); + auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr); if (i < 2) { ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result); @@ -767,8 +765,7 @@ TEST_F(BufferQueueTest, TestTimeouts) { for (int i = 0; i < 2; ++i) { int slot = BufferQueue::INVALID_BUFFER_SLOT; sp fence = Fence::NO_FENCE; - ASSERT_EQ(OK, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); IGraphicBufferProducer::QueueBufferInput input(0ull, true, HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT, @@ -779,8 +776,7 @@ TEST_F(BufferQueueTest, TestTimeouts) { int slot = BufferQueue::INVALID_BUFFER_SLOT; sp fence = Fence::NO_FENCE; auto startTime = systemTime(); - ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_GE(systemTime() - startTime, TIMEOUT); // We're technically attaching the same buffer multiple times (since we @@ -801,7 +797,7 @@ TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) { int slot = BufferQueue::INVALID_BUFFER_SLOT; sp sourceFence; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0, nullptr)); + mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0, nullptr, nullptr)); sp buffer; ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); ASSERT_EQ(OK, mProducer->detachBuffer(slot)); @@ -824,7 +820,7 @@ TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) { int slot = BufferQueue::INVALID_BUFFER_SLOT; sp fence; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); sp firstBuffer; ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer)); @@ -836,7 +832,7 @@ TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) { // Dequeue a second buffer slot = BufferQueue::INVALID_BUFFER_SLOT; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); sp secondBuffer; ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer)); @@ -887,8 +883,8 @@ TEST_F(BufferQueueTest, TestOccupancyHistory) { int slots[3] = {}; mProducer->setMaxDequeuedBufferCount(3); for (size_t i = 0; i < 3; ++i) { - status_t result = mProducer->dequeueBuffer(&slots[i], &fence, - 0, 0, 0, 0, nullptr); + status_t result = + mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr); ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result); ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer)); } @@ -901,8 +897,7 @@ TEST_F(BufferQueueTest, TestOccupancyHistory) { // The first segment is a two-buffer segment, so we only put one buffer into // the queue at a time for (size_t i = 0; i < 5; ++i) { - ASSERT_EQ(OK, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, @@ -917,17 +912,16 @@ TEST_F(BufferQueueTest, TestOccupancyHistory) { // two-buffer segment, but then at the end, we put two buffers in the queue // at the same time before draining it. for (size_t i = 0; i < 5; ++i) { - ASSERT_EQ(OK, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); std::this_thread::sleep_for(16ms); } - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, @@ -942,11 +936,10 @@ TEST_F(BufferQueueTest, TestOccupancyHistory) { // The third segment is a triple-buffer segment, so the queue is switching // between one buffer and two buffers deep. - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); for (size_t i = 0; i < 5; ++i) { - ASSERT_EQ(OK, mProducer->dequeueBuffer( - &slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, @@ -1026,8 +1019,8 @@ TEST_F(BufferQueueTest, TestDiscardFreeBuffers) { int slots[4] = {}; mProducer->setMaxDequeuedBufferCount(4); for (size_t i = 0; i < 4; ++i) { - status_t result = mProducer->dequeueBuffer(&slots[i], &fence, - 0, 0, 0, 0, nullptr); + status_t result = + mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr); ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result); ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer)); } @@ -1038,14 +1031,14 @@ TEST_F(BufferQueueTest, TestDiscardFreeBuffers) { // Get buffers in all states: dequeued, filled, acquired, free // Fill 3 buffers - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); // Dequeue 1 buffer - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); // Acquire and free 1 buffer ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); @@ -1104,8 +1097,8 @@ TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) { int slots[2] = {}; ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2)); for (size_t i = 0; i < 2; ++i) { - status_t result = mProducer->dequeueBuffer(&slots[i], &fence, - 0, 0, 0, 0, nullptr); + status_t result = + mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr); ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result); ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer)); } @@ -1115,10 +1108,10 @@ TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) { // Fill 2 buffers without consumer consuming them. Verify that all // queued buffer returns proper bufferReplaced flag - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); ASSERT_EQ(false, output.bufferReplaced); - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); ASSERT_EQ(true, output.bufferReplaced); } @@ -1140,8 +1133,7 @@ TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) { NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); // Dequeue, request, and queue one buffer - status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, - nullptr); + status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr); ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); @@ -1156,7 +1148,7 @@ TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) { EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); // Dequeue and queue the buffer again - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); // Acquire and release the buffer again. Upon acquiring, the buffer handle @@ -1168,7 +1160,7 @@ TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) { EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); // Dequeue and queue the buffer again - ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr)); + ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr)); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); // Disconnect the producer end. This should clear all of the slots and mark diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index bcfc91c3f5..dd23bd4cb2 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -194,7 +194,8 @@ protected: }; status_t dequeueBuffer(uint32_t w, uint32_t h, uint32_t format, uint32_t usage, DequeueBufferResult* result) { - return mProducer->dequeueBuffer(&result->slot, &result->fence, w, h, format, usage, nullptr); + return mProducer->dequeueBuffer(&result->slot, &result->fence, w, h, format, usage, + nullptr, nullptr); } void setupDequeueRequestBuffer(int *slot, sp *fence, @@ -206,9 +207,12 @@ protected: ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(slot, fence, DEFAULT_WIDTH, - DEFAULT_HEIGHT, DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, nullptr))); + + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(slot, fence, DEFAULT_WIDTH, DEFAULT_HEIGHT, + DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, + nullptr, nullptr))); EXPECT_LE(0, *slot); EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, *slot); @@ -343,11 +347,11 @@ TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) { int dequeuedSlot = -1; sp dequeuedFence; - - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, - DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, - TEST_PRODUCER_USAGE_BITS, nullptr))); + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH, + DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr))); EXPECT_LE(0, dequeuedSlot); EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot); @@ -403,10 +407,11 @@ TEST_F(IGraphicBufferProducerTest, Queue_ReturnsError) { int dequeuedSlot = -1; sp dequeuedFence; - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, - DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, - TEST_PRODUCER_USAGE_BITS, nullptr))); + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH, + DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr))); // Slot was enqueued without requesting a buffer { @@ -472,10 +477,11 @@ TEST_F(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) { int dequeuedSlot = -1; sp dequeuedFence; - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, - DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, - TEST_PRODUCER_USAGE_BITS, nullptr))); + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH, + DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr))); // No return code, but at least test that it doesn't blow up... // TODO: add a return code @@ -519,12 +525,11 @@ TEST_F(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Succeeds) { int dequeuedSlot = -1; sp dequeuedFence; for (int i = 0; i < maxBuffers; ++i) { - - EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, - DEFAULT_WIDTH, DEFAULT_HEIGHT, - DEFAULT_FORMAT, - TEST_PRODUCER_USAGE_BITS, nullptr))) + EXPECT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH, + DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr))) << "iteration: " << i << ", slot: " << dequeuedSlot; } @@ -557,11 +562,11 @@ TEST_F(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) { int dequeuedSlot = -1; sp dequeuedFence; for (int i = 0; i < 2; i++) { - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, - DEFAULT_WIDTH, DEFAULT_HEIGHT, - DEFAULT_FORMAT, - TEST_PRODUCER_USAGE_BITS, nullptr))) + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH, + DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr))) << "slot: " << dequeuedSlot; } @@ -593,10 +598,11 @@ TEST_F(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) { // Should now be able to queue/dequeue as many buffers as we want without // blocking for (int i = 0; i < 5; ++i) { - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, - DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, - TEST_PRODUCER_USAGE_BITS, nullptr))) + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH, + DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr))) << "slot : " << dequeuedSlot; ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer)); ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output)); @@ -610,10 +616,11 @@ TEST_F(IGraphicBufferProducerTest, SetAsyncMode_Fails) { int dequeuedSlot = -1; sp dequeuedFence; - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, - DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, - TEST_PRODUCER_USAGE_BITS, nullptr))) + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH, + DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr))) << "slot: " << dequeuedSlot; } @@ -630,8 +637,9 @@ TEST_F(IGraphicBufferProducerTest, int slot = -1; sp fence; - ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, - DEFAULT_HEIGHT, DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, nullptr)); + ASSERT_EQ(NO_INIT, + mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, + TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)); } TEST_F(IGraphicBufferProducerTest, @@ -649,10 +657,11 @@ TEST_F(IGraphicBufferProducerTest, int slot = -1; sp fence; - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, - DEFAULT_HEIGHT, DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, - nullptr))); + ASSERT_EQ(OK, + ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & + (mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT, + DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, + nullptr, nullptr))); EXPECT_LE(0, slot); EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, slot); diff --git a/libs/gui/tests/Malicious.cpp b/libs/gui/tests/Malicious.cpp index 6bc3ccf53d..2b9fd5d4b6 100644 --- a/libs/gui/tests/Malicious.cpp +++ b/libs/gui/tests/Malicious.cpp @@ -38,8 +38,10 @@ public: } status_t setAsyncMode(bool async) override { return mProducer->setAsyncMode(async); } status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, uint32_t h, PixelFormat format, - uint64_t usage, FrameEventHistoryDelta* outTimestamps) override { - return mProducer->dequeueBuffer(slot, fence, w, h, format, usage, outTimestamps); + uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) override { + return mProducer->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, + outTimestamps); } status_t detachBuffer(int slot) override { return mProducer->detachBuffer(slot); } status_t detachNextBuffer(sp* outBuffer, sp* outFence) override { @@ -105,10 +107,10 @@ public: // Override dequeueBuffer, optionally corrupting the returned slot number status_t dequeueBuffer(int* buf, sp* fence, uint32_t width, uint32_t height, - PixelFormat format, uint64_t usage, + PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps) override { EXPECT_EQ(BUFFER_NEEDS_REALLOCATION, - mProducer->dequeueBuffer(buf, fence, width, height, format, usage, + mProducer->dequeueBuffer(buf, fence, width, height, format, usage, outBufferAge, outTimestamps)); EXPECT_EQ(mExpectedSlot, *buf); if (mMaliciousValue != 0) { diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp index e2f494898e..ad6e051684 100644 --- a/libs/gui/tests/StreamSplitter_test.cpp +++ b/libs/gui/tests/StreamSplitter_test.cpp @@ -82,8 +82,8 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, inputProducer->requestBuffer(slot, &buffer)); uint32_t* dataIn; @@ -116,8 +116,8 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { // This should succeed even with allocation disabled since it will have // received the buffer back from the output BufferQueue ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); } TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { @@ -154,8 +154,8 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, inputProducer->requestBuffer(slot, &buffer)); uint32_t* dataIn; @@ -191,8 +191,8 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { // This should succeed even with allocation disabled since it will have // received the buffer back from the output BufferQueues ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); } TEST_F(StreamSplitterTest, OutputAbandonment) { @@ -218,8 +218,8 @@ TEST_F(StreamSplitterTest, OutputAbandonment) { sp fence; sp buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); ASSERT_EQ(OK, inputProducer->requestBuffer(slot, &buffer)); // Abandon the output @@ -231,8 +231,9 @@ TEST_F(StreamSplitterTest, OutputAbandonment) { ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); // Input should be abandoned - ASSERT_EQ(NO_INIT, inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, - GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr)); + ASSERT_EQ(NO_INIT, + inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr)); } } // namespace android diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp index b44e55c75e..6613add0a1 100644 --- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp +++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp @@ -131,7 +131,7 @@ status_t BufferHubQueueProducer::setAsyncMode(bool async) { status_t BufferHubQueueProducer::dequeueBuffer( int* out_slot, sp* out_fence, uint32_t width, uint32_t height, - PixelFormat format, uint64_t usage, + PixelFormat format, uint64_t usage, uint64_t* /*outBufferAge*/, FrameEventHistoryDelta* /* out_timestamps */) { ALOGD_IF(TRACE, "dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage); diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h index 638a56caef..d33a831469 100644 --- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h +++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h @@ -43,6 +43,7 @@ class BufferHubQueueProducer : public BnGraphicBufferProducer { // See |IGraphicBufferProducer::dequeueBuffer| status_t dequeueBuffer(int* out_slot, sp* out_fence, uint32_t width, uint32_t height, PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps) override; // See |IGraphicBufferProducer::detachBuffer| diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp index c7692d05b0..8f55125125 100644 --- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp +++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp @@ -117,9 +117,9 @@ class BufferHubQueueProducerTest : public ::testing::Test { ASSERT_NE(nullptr, outSlot); ASSERT_NE(nullptr, outFence); - int ret = mProducer->dequeueBuffer(outSlot, outFence, kDefaultWidth, - kDefaultHeight, kDefaultFormat, - kTestProducerUsageBits, nullptr); + int ret = mProducer->dequeueBuffer( + outSlot, outFence, kDefaultWidth, kDefaultHeight, kDefaultFormat, + kTestProducerUsageBits, nullptr, nullptr); // BUFFER_NEEDS_REALLOCATION can be either on or off. ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret); @@ -440,9 +440,10 @@ TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) { sp fence; for (int i = 0; i < 2; i++) { ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer( - &slot, &fence, kDefaultWidth, kDefaultHeight, - kDefaultFormat, kTestProducerUsageBits, nullptr))) + (mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth, + kDefaultHeight, kDefaultFormat, + kTestProducerUsageBits, + nullptr, nullptr))) << "slot: " << slot; } @@ -458,7 +459,8 @@ TEST_F(BufferHubQueueProducerTest, ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth, kDefaultHeight, kDefaultFormat, - kTestProducerUsageBits, nullptr)); + kTestProducerUsageBits, + nullptr, nullptr)); } TEST_F(BufferHubQueueProducerTest, diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index c129ae546c..34f1cecfde 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -345,8 +345,9 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source, PixelFormat format, uint64_t usage, int* sslot, sp* fence) { LOG_FATAL_IF(mDisplayId < 0, "mDisplayId=%d but should not be < 0.", mDisplayId); - status_t result = mSource[source]->dequeueBuffer(sslot, fence, - mSinkBufferWidth, mSinkBufferHeight, format, usage, nullptr); + status_t result = + mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight, + format, usage, nullptr, nullptr); if (result < 0) return result; int pslot = mapSource2ProducerSlot(source, *sslot); @@ -384,12 +385,13 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source, return result; } -status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, - uint32_t w, uint32_t h, PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps) { +status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, uint32_t w, uint32_t h, + PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) { if (mDisplayId < 0) { - return mSource[SOURCE_SINK]->dequeueBuffer( - pslot, fence, w, h, format, usage, outTimestamps); + return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, w, h, format, usage, outBufferAge, + outTimestamps); } VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, @@ -449,6 +451,9 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, *pslot = mapSource2ProducerSlot(source, sslot); } } + if (outBufferAge) { + *outBufferAge = 0; + } return result; } diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 7f8b39b62b..ac200caea5 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -104,9 +104,9 @@ private: virtual status_t requestBuffer(int pslot, sp* outBuf); virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers); virtual status_t setAsyncMode(bool async); - virtual status_t dequeueBuffer(int* pslot, sp* fence, uint32_t w, - uint32_t h, PixelFormat format, uint64_t usage, - FrameEventHistoryDelta *outTimestamps); + virtual status_t dequeueBuffer(int* pslot, sp* fence, uint32_t w, uint32_t h, + PixelFormat format, uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps); virtual status_t detachBuffer(int slot); virtual status_t detachNextBuffer(sp* outBuffer, sp* outFence); diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp index e717632c0f..d1038202d4 100644 --- a/services/surfaceflinger/MonitoredProducer.cpp +++ b/services/surfaceflinger/MonitoredProducer.cpp @@ -68,11 +68,11 @@ status_t MonitoredProducer::setAsyncMode(bool async) { return mProducer->setAsyncMode(async); } -status_t MonitoredProducer::dequeueBuffer(int* slot, sp* fence, - uint32_t w, uint32_t h, PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps) { - return mProducer->dequeueBuffer( - slot, fence, w, h, format, usage, outTimestamps); +status_t MonitoredProducer::dequeueBuffer(int* slot, sp* fence, uint32_t w, uint32_t h, + PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) { + return mProducer->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, outTimestamps); } status_t MonitoredProducer::detachBuffer(int slot) { diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h index 58b9bc4e2e..ff7f0f0e8c 100644 --- a/services/surfaceflinger/MonitoredProducer.h +++ b/services/surfaceflinger/MonitoredProducer.h @@ -39,9 +39,9 @@ public: virtual status_t requestBuffer(int slot, sp* buf); virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers); virtual status_t setAsyncMode(bool async); - virtual status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, - uint32_t h, PixelFormat format, uint64_t usage, - FrameEventHistoryDelta* outTimestamps); + virtual status_t dequeueBuffer(int* slot, sp* fence, uint32_t w, uint32_t h, + PixelFormat format, uint64_t usage, uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps); virtual status_t detachBuffer(int slot); virtual status_t detachNextBuffer(sp* outBuffer, sp* outFence); -- 2.11.0