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

Commit f06d1361 authored by Leon Scroggins's avatar Leon Scroggins Committed by Android (Google) Code Review
Browse files

Merge "Set blockingRegion for DISPLAY_DECORATION layers"

parents 89ef5267 9a0afda7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -90,6 +90,10 @@ struct OutputLayerCompositionState {
    // The dataspace for this layer
    ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};

    // A hint to the HWC that this region is transparent and may be skipped in
    // order to save power.
    Region outputSpaceBlockingRegionHint;

    // Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState
    struct {
        std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
+17 −5
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@

#include "TracedOrdinal.h"

using aidl::android::hardware::graphics::composer3::Composition;

namespace android::compositionengine {

Output::~Output() = default;
@@ -529,11 +531,18 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,

    /*
     * transparentRegion: area of a surface that is hinted to be completely
     * transparent. This is only used to tell when the layer has no visible non-
     * transparent regions and can be removed from the layer list. It does not
     * affect the visibleRegion of this layer or any layers beneath it. The hint
     * may not be correct if apps don't respect the SurfaceView restrictions
     * (which, sadly, some don't).
     * transparent.
     * This is used to tell when the layer has no visible non-transparent
     * regions and can be removed from the layer list. It does not affect the
     * visibleRegion of this layer or any layers beneath it. The hint may not
     * be correct if apps don't respect the SurfaceView restrictions (which,
     * sadly, some don't).
     *
     * In addition, it is used on DISPLAY_DECORATION layers to specify the
     * blockingRegion, allowing the DPU to skip it to save power. Once we have
     * hardware that supports a blockingRegion on frames with AFBC, it may be
     * useful to use this for other layers, too, so long as we can prevent
     * regressions on b/7179570.
     */
    Region transparentRegion;

@@ -674,6 +683,9 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
    outputLayerState.outputSpaceVisibleRegion = outputState.transform.transform(
            visibleNonShadowRegion.intersect(outputState.layerStackSpace.getContent()));
    outputLayerState.shadowRegion = shadowRegion;
    outputLayerState.outputSpaceBlockingRegionHint =
            layerFEState->compositionType == Composition::DISPLAY_DECORATION ? transparentRegion
                                                                             : Region();
}

void Output::setReleasedLayers(const compositionengine::CompositionRefreshArgs&) {
+8 −0
Original line number Diff line number Diff line
@@ -484,6 +484,14 @@ void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer)
        visibleRegion.dump(LOG_TAG);
    }

    if (auto error =
                hwcLayer->setBlockingRegion(outputDependentState.outputSpaceBlockingRegionHint);
        error != hal::Error::NONE) {
        ALOGE("[%s] Failed to set blocking region: %s (%d)", getLayerFE().getDebugName(),
              to_string(error).c_str(), static_cast<int32_t>(error));
        outputDependentState.outputSpaceBlockingRegionHint.dump(LOG_TAG);
    }

    const auto dataspace = outputDependentState.overrideInfo.buffer
            ? outputDependentState.overrideInfo.dataspace
            : outputDependentState.dataspace;
+21 −1
Original line number Diff line number Diff line
@@ -846,7 +846,8 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
                                   ui::Dataspace dataspace = kDataspace,
                                   const Region& visibleRegion = kOutputSpaceVisibleRegion,
                                   const Region& surfaceDamage = kSurfaceDamage,
                                   float whitePointNits = kWhitePointNits) {
                                   float whitePointNits = kWhitePointNits,
                                   const Region& blockingRegion = Region()) {
        EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(visibleRegion))).WillOnce(Return(kError));
        EXPECT_CALL(*mHwcLayer, setDataspace(dataspace)).WillOnce(Return(kError));
        EXPECT_CALL(*mHwcLayer, setWhitePointNits(whitePointNits)).WillOnce(Return(kError));
@@ -855,6 +856,8 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
                                         ? hal::Error::UNSUPPORTED
                                         : hal::Error::NONE));
        EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(surfaceDamage))).WillOnce(Return(kError));
        EXPECT_CALL(*mHwcLayer, setBlockingRegion(RegionEq(blockingRegion)))
                .WillOnce(Return(kError));
    }

    void expectSetCompositionTypeCall(Composition compositionType) {
@@ -1278,6 +1281,23 @@ TEST_F(OutputLayerWriteStateToHWCTest, roundedCornersPeekingThroughAllowsDeviceC
    EXPECT_EQ(Composition::DEVICE, mOutputLayer.getState().hwc->hwcCompositionType);
}

TEST_F(OutputLayerWriteStateToHWCTest, setBlockingRegion) {
    mLayerFEState.compositionType = Composition::DISPLAY_DECORATION;
    const auto blockingRegion = Region(Rect(0, 0, 1000, 1000));
    mOutputLayer.editState().outputSpaceBlockingRegionHint = blockingRegion;

    expectGeometryCommonCalls();
    expectPerFrameCommonCalls(SimulateUnsupported::None, kDataspace, kOutputSpaceVisibleRegion,
                              kSurfaceDamage, kWhitePointNits, blockingRegion);
    expectSetHdrMetadataAndBufferCalls();
    EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false));
    expectSetCompositionTypeCall(Composition::DISPLAY_DECORATION);

    mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
                                 /*zIsOverridden*/ false, /*isPeekingThrough*/
                                 false);
}

/*
 * OutputLayer::writeCursorPositionToHWC()
 */
+31 −1
Original line number Diff line number Diff line
@@ -1291,7 +1291,7 @@ struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
        mLayer.layerFEState.contentDirty = true;
        mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
        mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
        mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
        mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;

        mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
        mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
@@ -1309,6 +1309,7 @@ struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
    static const Region kRightHalfBoundsNoRotation;
    static const Region kLowerHalfBoundsNoRotation;
    static const Region kFullBounds90Rotation;
    static const Region kTransparentRegionHint;

    StrictMock<OutputPartialMock> mOutput;
    LayerFESet mGeomSnapshots;
@@ -1326,6 +1327,8 @@ const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
        Region(Rect(50, 0, 100, 200));
const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
        Region(Rect(0, 0, 200, 100));
const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
        Region(Rect(0, 0, 100, 100));

TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
    EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
@@ -1749,6 +1752,33 @@ TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadow
    ensureOutputLayerIfVisible();
}

TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
    mLayer.layerFEState.isOpaque = false;
    mLayer.layerFEState.contentDirty = true;
    mLayer.layerFEState.compositionType =
            aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;

    EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
            .WillOnce(Return(&mLayer.outputLayer));
    ensureOutputLayerIfVisible();

    EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
                RegionEq(kTransparentRegionHint));
}

TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
    mLayer.layerFEState.isOpaque = false;
    mLayer.layerFEState.contentDirty = true;

    EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
            .WillOnce(Return(&mLayer.outputLayer));
    ensureOutputLayerIfVisible();

    EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
}

/*
 * Output::present()
 */