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

Commit 0bc0915f authored by Valerie Hau's avatar Valerie Hau
Browse files

Modifying BufferStateLayer crop to be within buffer bounds

Bug: 120920503
Test: build
Change-Id: I99ea2b3275e87a4d1cf295c7a917d4ec0fd5c0d1
parent 0510d906
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#include <private/gui/SyncFeatures.h>
#include <renderengine/Image.h>

#include <limits>

namespace android {

// clang-format off
@@ -347,6 +349,22 @@ Rect BufferStateLayer::getDrawingCrop() const {

    if (s.crop.isEmpty() && s.buffer) {
        return s.buffer->getBounds();
    } else if (s.buffer) {
        Rect crop = s.crop;
        crop.left = std::max(crop.left, 0);
        crop.top = std::max(crop.top, 0);
        uint32_t bufferWidth = s.buffer->getWidth();
        uint32_t bufferHeight = s.buffer->getHeight();
        if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
            bufferWidth <= std::numeric_limits<int32_t>::max()) {
            crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
            crop.bottom = std::min(crop.bottom, static_cast<int32_t>(bufferHeight));
        }
        if (!crop.isValid()) {
            // Crop rect is out of bounds, return whole buffer
            return s.buffer->getBounds();
        }
        return crop;
    }
    return s.crop;
}
+46 −16
Original line number Diff line number Diff line
@@ -1710,22 +1710,52 @@ TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferQueue) {
    shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
}

// TODO (marissaw): change Layer to make crop to be in bounds instead of passing a bad crop to hwc
// TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferState) {
//    sp<SurfaceControl> layer;
//    ASSERT_NO_FATAL_FAILURE(
//            layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
//    ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
//
//    Transaction()
//            .setCrop(layer, Rect(-128, -64, 128, 64))
//            .setFrame(layer, Rect(0, 0, 32, 32))
//            .apply();
//    auto shot = screenshot();
//    shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
//    shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
//}
//
TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferState) {
    sp<SurfaceControl> layer;
    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", mDisplayWidth, mDisplayHeight / 2,
                                                ISurfaceComposerClient::eFXSurfaceBufferState));
    sp<GraphicBuffer> buffer =
            new GraphicBuffer(mDisplayWidth, mDisplayHeight / 2, PIXEL_FORMAT_RGBA_8888, 1,
                              BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
                                      BufferUsage::COMPOSER_OVERLAY,
                              "test");
    fillGraphicBufferColor(buffer, Rect(0, 0, mDisplayWidth, mDisplayHeight / 4), Color::BLUE);
    fillGraphicBufferColor(buffer, Rect(0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2),
                           Color::RED);

    Transaction().setBuffer(layer, buffer).apply();

    // Partially out of bounds in the negative (upper left) direction
    Transaction().setCrop(layer, Rect(-128, -128, mDisplayWidth, mDisplayHeight / 4)).apply();
    {
        SCOPED_TRACE("out of bounds, negative (upper left) direction");
        auto shot = screenshot();
        shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::BLUE);
        shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::BLACK);
    }

    // Partially out of bounds in the positive (lower right) direction
    Transaction()
            .setCrop(layer, Rect(0, mDisplayHeight / 4, mDisplayWidth + 1, mDisplayHeight))
            .apply();
    {
        SCOPED_TRACE("out of bounds, positive (lower right) direction");
        auto shot = screenshot();
        shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::RED);
        shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::BLACK);
    }

    // Fully out of buffer space bounds
    Transaction().setCrop(layer, Rect(-128, -128, -1, -1)).apply();
    {
        SCOPED_TRACE("Fully out of bounds");
        auto shot = screenshot();
        shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight / 4), Color::BLUE);
        shot->expectColor(Rect(0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2),
                          Color::RED);
    }
}

TEST_F(LayerTransactionTest, SetCropWithTranslation_BufferQueue) {
    sp<SurfaceControl> layer;
    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));