diff options
| -rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 8 | ||||
| -rw-r--r-- | libs/gui/tests/BLASTBufferQueue_test.cpp | 77 |
2 files changed, 80 insertions, 5 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 379b090c5b..406272c479 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -456,10 +456,10 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback. incStrong((void*)transactionCallbackThunk); + const bool sizeHasChanged = mRequestedSize != mSize; + mSize = mRequestedSize; + const bool updateDestinationFrame = sizeHasChanged || !mLastBufferInfo.hasBuffer; Rect crop = computeCrop(bufferItem); - const bool updateDestinationFrame = - bufferItem.mScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE || - !mLastBufferInfo.hasBuffer; mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(), bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform, bufferItem.mScalingMode, crop); @@ -572,7 +572,6 @@ void BLASTBufferQueue::setNextTransaction(SurfaceComposerClient::Transaction* t) bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { if (item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) { - mSize = mRequestedSize; // Only reject buffers if scaling mode is freeze. return false; } @@ -586,7 +585,6 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { } ui::Size bufferSize(bufWidth, bufHeight); if (mRequestedSize != mSize && mRequestedSize == bufferSize) { - mSize = mRequestedSize; return false; } diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index 26d902d849..b474086d1d 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -672,6 +672,83 @@ TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) { /*border*/ 0, /*outsideRegion*/ true)); } +// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and +// scale the buffer properly when the mode changes to SCALE_TO_WINDOW +TEST_F(BLASTBufferQueueTest, ScalingModeChanges) { + uint8_t r = 255; + uint8_t g = 0; + uint8_t b = 0; + + BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4); + sp<IGraphicBufferProducer> igbProducer; + setUpProducer(adapter, igbProducer); + { + int slot; + sp<Fence> fence; + sp<GraphicBuffer> buf; + auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4, + PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr); + ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret); + ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf)); + + uint32_t* bufData; + buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN), + reinterpret_cast<void**>(&bufData)); + fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b); + buf->unlock(); + + IGraphicBufferProducer::QueueBufferOutput qbOutput; + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, {}, + NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, + Fence::NO_FENCE); + igbProducer->queueBuffer(slot, input, &qbOutput); + adapter.waitForCallbacks(); + } + // capture screen and verify that it is red + ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); + + ASSERT_NO_FATAL_FAILURE( + checkScreenCapture(r, g, b, + {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4})); + + // update the size to half the display and dequeue a buffer quarter of the display. + adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2); + + { + int slot; + sp<Fence> fence; + sp<GraphicBuffer> buf; + auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8, + PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr); + ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret); + ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf)); + + uint32_t* bufData; + buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN), + reinterpret_cast<void**>(&bufData)); + g = 255; + fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b); + buf->unlock(); + + IGraphicBufferProducer::QueueBufferOutput qbOutput; + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, {}, + NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, + 0, Fence::NO_FENCE); + igbProducer->queueBuffer(slot, input, &qbOutput); + adapter.waitForCallbacks(); + } + // capture screen and verify that it is red + ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); + // verify we still scale the buffer to the new size (half the screen height) + ASSERT_NO_FATAL_FAILURE( + checkScreenCapture(r, g, b, + {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2})); +} + class TestProducerListener : public BnProducerListener { public: sp<IGraphicBufferProducer> mIgbp; |