diff options
| author | 2021-09-30 23:36:02 +0000 | |
|---|---|---|
| committer | 2021-09-30 23:36:02 +0000 | |
| commit | 1d07b101fb0b4c76ba4eacbb7abe514ccbb824c6 (patch) | |
| tree | c6ea49fa67b44daf0a0331ce5541b00c4e44d75e | |
| parent | 5f6fa3e0ade0a067b226f696d0520f1ece5f177a (diff) | |
| parent | fec689d8c3f00f11b84dfa508436a8786ae2a798 (diff) | |
BlastBufferQueue: Fix scaling when buffer scaling mode changes am: 932f6aee50 am: fec689d8c3
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15952944
Change-Id: I664321549f871fe5d38eec82de13f82f1678b562
| -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;  |