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

Commit 1d07b101 authored by Vishnu Nair's avatar Vishnu Nair Committed by Automerger Merge Worker
Browse files

BlastBufferQueue: Fix scaling when buffer scaling mode changes am: 932f6aee am: fec689d8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15952944

Change-Id: I664321549f871fe5d38eec82de13f82f1678b562
parents 5f6fa3e0 fec689d8
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -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;
    }

+77 −0
Original line number Diff line number Diff line
@@ -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;