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

Commit 0759734a authored by Chavi Weingarten's avatar Chavi Weingarten
Browse files

Intersect buffer crop with buffer size

If the layer has a buffer crop, it needs to be intersected with the
buffer size in case the crop passed in is larger than the buffer size

Test: ASurfaceControlTest
Test: LayerSnapshotTest
Fixes: 297171709
Change-Id: I62a0278a42a478ab31dd383f0a7b9741c5b6e8a8
parent 3582659a
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -466,12 +466,18 @@ Rect RequestedLayerState::getCroppedBufferSize(const Rect& bufferSize) const {
Rect RequestedLayerState::getBufferCrop() const {
    // this is the crop rectangle that applies to the buffer
    // itself (as opposed to the window)
    if (!bufferCrop.isEmpty()) {
        // if the buffer crop is defined, we use that
        return bufferCrop;
    if (!bufferCrop.isEmpty() && externalTexture != nullptr) {
        // if the buffer crop is defined and there's a valid buffer, intersect buffer size and crop
        // since the crop should never exceed the size of the buffer.
        Rect sizeAndCrop;
        externalTexture->getBounds().intersect(bufferCrop, &sizeAndCrop);
        return sizeAndCrop;
    } else if (externalTexture != nullptr) {
        // otherwise we use the whole buffer
        return externalTexture->getBounds();
    } else if (!bufferCrop.isEmpty()) {
        // if the buffer crop is defined, we use that
        return bufferCrop;
    } else {
        // if we don't have a buffer yet, we use an empty/invalid crop
        return Rect();
+11 −0
Original line number Diff line number Diff line
@@ -372,6 +372,17 @@ protected:
        mLifecycleManager.applyTransactions(transactions);
    }

    void setBufferCrop(uint32_t id, const Rect& bufferCrop) {
        std::vector<TransactionState> transactions;
        transactions.emplace_back();
        transactions.back().states.push_back({});

        transactions.back().states.front().state.what = layer_state_t::eBufferCropChanged;
        transactions.back().states.front().layerId = id;
        transactions.back().states.front().state.bufferCrop = bufferCrop;
        mLifecycleManager.applyTransactions(transactions);
    }

    void setDataspace(uint32_t id, ui::Dataspace dataspace) {
        std::vector<TransactionState> transactions;
        transactions.emplace_back();
+29 −0
Original line number Diff line number Diff line
@@ -783,4 +783,33 @@ TEST_F(LayerSnapshotTest, setRefreshRateIndicatorCompositionType) {
              aidl::android::hardware::graphics::composer3::Composition::REFRESH_RATE_INDICATOR);
}

TEST_F(LayerSnapshotTest, setBufferCrop) {
    // validate no buffer but has crop
    Rect crop = Rect(0, 0, 50, 50);
    setBufferCrop(1, crop);
    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
    EXPECT_EQ(getSnapshot(1)->geomContentCrop, crop);

    setBuffer(1,
              std::make_shared<renderengine::mock::FakeExternalTexture>(100U /*width*/,
                                                                        100U /*height*/,
                                                                        42ULL /* bufferId */,
                                                                        HAL_PIXEL_FORMAT_RGBA_8888,
                                                                        0 /*usage*/));
    // validate a buffer crop within the buffer bounds
    setBufferCrop(1, crop);
    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
    EXPECT_EQ(getSnapshot(1)->geomContentCrop, crop);

    // validate a buffer crop outside the buffer bounds
    crop = Rect(0, 0, 150, 150);
    setBufferCrop(1, crop);
    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
    EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100));

    // validate no buffer crop
    setBufferCrop(1, Rect());
    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
    EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100));
}
} // namespace android::surfaceflinger::frontend