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

Commit 96ca45c4 authored by Alec Mouri's avatar Alec Mouri
Browse files

Don't send override buffer down to HWC if the layer would be skipped

Consider a set of five cached layers. Because ComposerResources' caches
are scoped per-layer and does not globally track buffers, the override
buffer for each layer needs to be re-imported, and a previous override
buffer needs to be freed, if the new override buffer changed between
frames. This causes a lot of churn in validate(), up to double CPU time
in the hot path.

Instead, we shouldn't override the buffer if a layer would be skipped.
In the aforementioned example, this would cause 1 buffers-worth of chrun
when importing, rather than 5.

Bug: 190654391
Test: Perfetto trace
Change-Id: I907b0c4c340fd99a0023429a8ad740ecc9208815
parent cda04d4f
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -73,10 +73,11 @@ private:
    void writeOutputIndependentGeometryStateToHWC(HWC2::Layer*, const LayerFECompositionState&,
                                                  bool skipLayer);
    void writeOutputDependentPerFrameStateToHWC(HWC2::Layer*);
    void writeOutputIndependentPerFrameStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeOutputIndependentPerFrameStateToHWC(HWC2::Layer*, const LayerFECompositionState&,
                                                  bool skipLayer);
    void writeSolidColorStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeSidebandStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeBufferStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeBufferStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer);
    void writeCompositionTypeToHWC(HWC2::Layer*, Hwc2::IComposerClient::Composition,
                                   bool isPeekingThrough, bool skipLayer);
    void detectDisallowedCompositionTypeChange(Hwc2::IComposerClient::Composition from,
+7 −5
Original line number Diff line number Diff line
@@ -349,7 +349,7 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t
    }

    writeOutputDependentPerFrameStateToHWC(hwcLayer.get());
    writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState);
    writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, skipLayer);

    writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough,
                              skipLayer);
@@ -471,7 +471,8 @@ void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer)
}

void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
        HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) {
        HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState,
        bool skipLayer) {
    switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) {
        case hal::Error::NONE:
            break;
@@ -504,7 +505,7 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
            break;
        case hal::Composition::CURSOR:
        case hal::Composition::DEVICE:
            writeBufferStateToHWC(hwcLayer, outputIndependentState);
            writeBufferStateToHWC(hwcLayer, outputIndependentState, skipLayer);
            break;
        case hal::Composition::INVALID:
        case hal::Composition::CLIENT:
@@ -541,7 +542,8 @@ void OutputLayer::writeSidebandStateToHWC(HWC2::Layer* hwcLayer,
}

void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
                                        const LayerFECompositionState& outputIndependentState) {
                                        const LayerFECompositionState& outputIndependentState,
                                        bool skipLayer) {
    auto supportedPerFrameMetadata =
            getOutput().getDisplayColorProfile()->getSupportedPerFrameMetadata();
    if (auto error = hwcLayer->setPerFrameMetadata(supportedPerFrameMetadata,
@@ -554,7 +556,7 @@ void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
    sp<GraphicBuffer> buffer = outputIndependentState.buffer;
    sp<Fence> acquireFence = outputIndependentState.acquireFence;
    int slot = outputIndependentState.bufferSlot;
    if (getState().overrideInfo.buffer != nullptr) {
    if (getState().overrideInfo.buffer != nullptr && !skipLayer) {
        buffer = getState().overrideInfo.buffer->getBuffer();
        acquireFence = getState().overrideInfo.acquireFence;
        slot = HwcBufferCache::FLATTENER_CACHING_SLOT;
+17 −0
Original line number Diff line number Diff line
@@ -699,6 +699,7 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
            Hwc2::IComposerClient::BlendMode::PREMULTIPLIED;
    static constexpr float kAlpha = 51.f;
    static constexpr float kOverrideAlpha = 1.f;
    static constexpr float kSkipAlpha = 0.f;
    static constexpr ui::Dataspace kDataspace = static_cast<ui::Dataspace>(71);
    static constexpr ui::Dataspace kOverrideDataspace = static_cast<ui::Dataspace>(72);
    static constexpr int kSupportedPerFrameMetadata = 101;
@@ -1055,6 +1056,22 @@ TEST_F(OutputLayerWriteStateToHWCTest, perFrameStateDoesNotIncludeMetadataIfPres
                                 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
}

TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerDoesNotSendBuffer) {
    mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
    includeOverrideInfo();

    expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
                              kOverrideBlendMode, kSkipAlpha);
    expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
                              kOverrideSurfaceDamage);
    expectSetHdrMetadataAndBufferCalls();
    expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
    EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false));

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

TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) {
    mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
    includeOverrideInfo();