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

Commit 853ebb9e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow for solid color layers to start some candidate cached sets."

parents cf6b4b40 028676ae
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -73,8 +73,9 @@ private:
    void writeOutputIndependentGeometryStateToHWC(HWC2::Layer*, const LayerFECompositionState&,
    void writeOutputIndependentGeometryStateToHWC(HWC2::Layer*, const LayerFECompositionState&,
                                                  bool skipLayer);
                                                  bool skipLayer);
    void writeOutputDependentPerFrameStateToHWC(HWC2::Layer*);
    void writeOutputDependentPerFrameStateToHWC(HWC2::Layer*);
    void writeOutputIndependentPerFrameStateToHWC(HWC2::Layer*, const LayerFECompositionState&,
    void writeOutputIndependentPerFrameStateToHWC(
                                                  bool skipLayer);
            HWC2::Layer*, const LayerFECompositionState&,
            Hwc2::IComposerClient::Composition compositionType, bool skipLayer);
    void writeSolidColorStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeSolidColorStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeSidebandStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeSidebandStateToHWC(HWC2::Layer*, const LayerFECompositionState&);
    void writeBufferStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer);
    void writeBufferStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer);
+29 −11
Original line number Original line Diff line number Diff line
@@ -134,21 +134,22 @@ private:
        class Builder {
        class Builder {
        private:
        private:
            std::vector<CachedSet>::const_iterator mStart;
            std::vector<CachedSet>::const_iterator mStart;
            std::vector<size_t> mLengths;
            int32_t mNumSets = 0;
            const CachedSet* mHolePunchCandidate = nullptr;
            const CachedSet* mHolePunchCandidate = nullptr;
            const CachedSet* mBlurringLayer = nullptr;
            const CachedSet* mBlurringLayer = nullptr;
            bool mBuilt = false;


        public:
        public:
            // Initializes a Builder a CachedSet to start from.
            // Initializes a Builder a CachedSet to start from.
            // This start iterator must be an iterator for mLayers
            // This start iterator must be an iterator for mLayers
            void init(const std::vector<CachedSet>::const_iterator& start) {
            void init(const std::vector<CachedSet>::const_iterator& start) {
                mStart = start;
                mStart = start;
                mLengths.push_back(start->getLayerCount());
                mNumSets = 1;
            }
            }


            // Appends a new CachedSet to the end of the run
            // Appends a new CachedSet to the end of the run
            // The provided length must be the size of the next sequential CachedSet in layers
            // The provided length must be the size of the next sequential CachedSet in layers
            void append(size_t length) { mLengths.push_back(length); }
            void increment() { mNumSets++; }


            // Sets the hole punch candidate for the Run.
            // Sets the hole punch candidate for the Run.
            void setHolePunchCandidate(const CachedSet* holePunchCandidate) {
            void setHolePunchCandidate(const CachedSet* holePunchCandidate) {
@@ -161,19 +162,36 @@ private:


            // Builds a Run instance, if a valid Run may be built.
            // Builds a Run instance, if a valid Run may be built.
            std::optional<Run> validateAndBuild() {
            std::optional<Run> validateAndBuild() {
                if (mLengths.size() == 0) {
                const bool built = mBuilt;
                mBuilt = true;
                if (mNumSets <= 0 || built) {
                    return std::nullopt;
                    return std::nullopt;
                }
                }
                // Runs of length 1 which are hole punch candidates are allowed if the candidate is

                // going to be used.
                const bool requiresHolePunch =
                if (mLengths.size() == 1 &&
                        mHolePunchCandidate && mHolePunchCandidate->requiresHolePunch();
                    (!mHolePunchCandidate || !(mHolePunchCandidate->requiresHolePunch()))) {

                if (!requiresHolePunch) {
                    // If we don't require a hole punch, then treat solid color layers at the front
                    // to be "cheap", so remove them from the candidate cached set.
                    while (mNumSets > 1 && mStart->getLayerCount() == 1 &&
                           mStart->getFirstLayer().getBuffer() == nullptr) {
                        mStart++;
                        mNumSets--;
                    }

                    // Only allow for single cached sets if a hole punch is required. If we're here,
                    // then we don't require a hole punch, so don't build a run.
                    if (mNumSets <= 1) {
                        return std::nullopt;
                        return std::nullopt;
                    }
                    }
                }


                return Run(mStart,
                return Run(mStart,
                           std::reduce(mLengths.cbegin(), mLengths.cend(), 0u,
                           std::reduce(mStart, mStart + mNumSets, 0u,
                                       [](size_t left, size_t right) { return left + right; }),
                                       [](size_t length, const CachedSet& set) {
                                           return length + set.getLayerCount();
                                       }),
                           mHolePunchCandidate, mBlurringLayer);
                           mHolePunchCandidate, mBlurringLayer);
            }
            }


+11 −9
Original line number Original line Diff line number Diff line
@@ -347,6 +347,10 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t


    auto requestedCompositionType = outputIndependentState->compositionType;
    auto requestedCompositionType = outputIndependentState->compositionType;


    if (requestedCompositionType == hal::Composition::SOLID_COLOR && state.overrideInfo.buffer) {
        requestedCompositionType = hal::Composition::DEVICE;
    }

    // TODO(b/181172795): We now update geometry for all flattened layers. We should update it
    // TODO(b/181172795): We now update geometry for all flattened layers. We should update it
    // only when the geometry actually changes
    // only when the geometry actually changes
    const bool isOverridden =
    const bool isOverridden =
@@ -359,13 +363,15 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t
    }
    }


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


    writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough,
    writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough,
                              skipLayer);
                              skipLayer);


    // Always set the layer color after setting the composition type.
    if (requestedCompositionType == hal::Composition::SOLID_COLOR) {
        writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState);
        writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState);
    }


    editState().hwc->stateOverridden = isOverridden;
    editState().hwc->stateOverridden = isOverridden;
    editState().hwc->layerSkipped = skipLayer;
    editState().hwc->layerSkipped = skipLayer;
@@ -477,7 +483,7 @@ void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer)


void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
        HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState,
        HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState,
        bool skipLayer) {
        hal::Composition compositionType, bool skipLayer) {
    switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) {
    switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) {
        case hal::Error::NONE:
        case hal::Error::NONE:
            break;
            break;
@@ -501,7 +507,7 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
    }
    }


    // Content-specific per-frame state
    // Content-specific per-frame state
    switch (outputIndependentState.compositionType) {
    switch (compositionType) {
        case hal::Composition::SOLID_COLOR:
        case hal::Composition::SOLID_COLOR:
            // For compatibility, should be written AFTER the composition type.
            // For compatibility, should be written AFTER the composition type.
            break;
            break;
@@ -521,10 +527,6 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC(


void OutputLayer::writeSolidColorStateToHWC(HWC2::Layer* hwcLayer,
void OutputLayer::writeSolidColorStateToHWC(HWC2::Layer* hwcLayer,
                                            const LayerFECompositionState& outputIndependentState) {
                                            const LayerFECompositionState& outputIndependentState) {
    if (outputIndependentState.compositionType != hal::Composition::SOLID_COLOR) {
        return;
    }

    hal::Color color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)),
    hal::Color color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)),
                        static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)),
                        static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)),
                        static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)),
                        static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)),
+5 −10
Original line number Original line Diff line number Diff line
@@ -425,11 +425,7 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const {
        if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) &&
        if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) &&
            !currentSet->hasUnsupportedDataspace()) {
            !currentSet->hasUnsupportedDataspace()) {
            if (isPartOfRun) {
            if (isPartOfRun) {
                builder.append(currentSet->getLayerCount());
                builder.increment();
            } else {
                // Runs can't start with a non-buffer layer
                if (currentSet->getFirstLayer().getBuffer() == nullptr) {
                    ALOGV("[%s] Skipping initial non-buffer layer", __func__);
            } else {
            } else {
                builder.init(currentSet);
                builder.init(currentSet);
                if (firstLayer) {
                if (firstLayer) {
@@ -437,7 +433,6 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const {
                }
                }
                isPartOfRun = true;
                isPartOfRun = true;
            }
            }
            }
        } else if (isPartOfRun) {
        } else if (isPartOfRun) {
            builder.setHolePunchCandidate(&(*currentSet));
            builder.setHolePunchCandidate(&(*currentSet));


+16 −0
Original line number Original line Diff line number Diff line
@@ -1109,6 +1109,22 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) {
                                 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
                                 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
}
}


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

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

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

TEST_F(OutputLayerWriteStateToHWCTest, previousOverriddenLayerSendsSurfaceDamage) {
TEST_F(OutputLayerWriteStateToHWCTest, previousOverriddenLayerSendsSurfaceDamage) {
    mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
    mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
    mOutputLayer.editState().hwc->stateOverridden = true;
    mOutputLayer.editState().hwc->stateOverridden = true;
Loading