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

Commit f54453c8 authored by Alec Mouri's avatar Alec Mouri
Browse files

Improve blur caching heuristic

This allows for caching the following scenario where notification shade
applies a background blur radius: If the layers behind the notification
shade are not changing, the notification shade's blur radius not
changing, but the notification shade's buffer does change, then we want
to cache the contribution of the blur radius onto the resulting
CachedSet.

Bug: 187705068
Test: Enable blur and swipe notification shade very slowly

Change-Id: I7019be4b8438b79ebb29b2a05e8860916198f18f
parent f1804968
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -78,6 +78,30 @@ public:
    virtual void prepareCompositionState(StateSubset) = 0;

    struct ClientCompositionTargetSettings {
        enum class BlurSetting {
            Disabled,
            BackgroundBlurOnly,
            BlurRegionsOnly,
            Enabled,
        };

        friend std::string toString(BlurSetting blurSetting) {
            switch (blurSetting) {
                case BlurSetting::Enabled:
                    return "Enabled";
                case BlurSetting::BlurRegionsOnly:
                    return "BlurRegionsOnly";
                case BlurSetting::BackgroundBlurOnly:
                    return "BackgroundBlurOnly";
                case BlurSetting::Disabled:
                    return "Disabled";
            }
        }

        friend std::ostream& operator<<(std::ostream& os, const BlurSetting& setting) {
            return os << toString(setting);
        }

        // The clip region, or visible region that is being rendered to
        const Region& clip;

@@ -110,8 +134,8 @@ public:
        // This may be requested by the HWC
        const bool clearContent;

        // If set to true, change the layer settings to not use any blurs.
        const bool disableBlurs;
        // Configure layer settings for using blurs
        BlurSetting blurSetting;
    };

    // A superset of LayerSettings required by RenderEngine to compose a layer
@@ -186,6 +210,7 @@ static inline void PrintTo(const LayerFE::ClientCompositionTargetSettings& setti
    PrintTo(settings.dataspace, os);
    *os << "\n    .realContentIsVisible = " << settings.realContentIsVisible;
    *os << "\n    .clearContent = " << settings.clearContent;
    *os << "\n    .blurSetting = " << settings.blurSetting;
    *os << "\n}";
}

+7 −0
Original line number Diff line number Diff line
@@ -103,6 +103,13 @@ struct OutputLayerCompositionState {
        // be visible through it. Unowned - the OutputLayer's lifetime will
        // outlast this.)
        compositionengine::OutputLayer* peekThroughLayer = nullptr;
        // True when this layer's blur has been cached with a previous layer, so that this layer
        // does not need to request blurring.
        // TODO(b/188816867): support blur regions too, which are less likely to be common if a
        // device supports cross-window blurs. Blur region support should be doable, but we would
        // need to make sure that layer caching works well with the blur region transform passed
        // into RenderEngine
        bool disableBackgroundBlur = false;
    } overrideInfo;

    /*
+7 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ public:

        const LayerState* getState() const { return mState; }
        const std::string& getName() const { return mState->getName(); }
        int32_t getBackgroundBlurRadius() const { return mState->getBackgroundBlurRadius(); }
        Rect getDisplayFrame() const { return mState->getDisplayFrame(); }
        const Region& getVisibleRegion() const { return mState->getVisibleRegion(); }
        const sp<GraphicBuffer>& getBuffer() const {
@@ -91,6 +92,7 @@ public:
        mTexture = nullptr;
        mOutputDataspace = ui::Dataspace::UNKNOWN;
        mDrawFence = nullptr;
        mBlurLayer = nullptr;

        mLayers.insert(mLayers.end(), other.mLayers.cbegin(), other.mLayers.cend());
        Region boundingRegion;
@@ -123,9 +125,13 @@ public:
    // nothing (besides the hole punch layer) will be drawn behind it.
    void addHolePunchLayerIfFeasible(const CachedSet&, bool isFirstLayer);

    void addBackgroundBlurLayer(const CachedSet&);

    // Retrieve the layer that will be drawn behind this one.
    compositionengine::OutputLayer* getHolePunchLayer() const;

    compositionengine::OutputLayer* getBlurLayer() const;

private:
    CachedSet() = default;

@@ -135,6 +141,7 @@ private:

    // Unowned.
    const LayerState* mHolePunchLayer = nullptr;
    const LayerState* mBlurLayer = nullptr;
    Rect mBounds = Rect::EMPTY_RECT;
    Region mVisibleRegion;
    size_t mAge = 0;
+18 −4
Original line number Diff line number Diff line
@@ -51,6 +51,11 @@ public:
    void dump(std::string& result) const;
    void dumpLayers(std::string& result) const;

    const std::optional<CachedSet>& getNewCachedSetForTesting() const { return mNewCachedSet; }

protected:
    std::optional<CachedSet> mNewCachedSet;

private:
    size_t calculateDisplayCost(const std::vector<const LayerState*>& layers) const;

@@ -72,6 +77,7 @@ private:
            std::vector<CachedSet>::const_iterator mStart;
            std::vector<size_t> mLengths;
            const CachedSet* mHolePunchCandidate = nullptr;
            const CachedSet* mBlurringLayer = nullptr;

        public:
            // Initializes a Builder a CachedSet to start from.
@@ -90,6 +96,10 @@ private:
                mHolePunchCandidate = holePunchCandidate;
            }

            void setBlurringLayer(const CachedSet* blurringLayer) {
                mBlurringLayer = blurringLayer;
            }

            // Builds a Run instance, if a valid Run may be built.
            std::optional<Run> validateAndBuild() {
                if (mLengths.size() <= 1) {
@@ -99,7 +109,7 @@ private:
                return Run(mStart,
                           std::reduce(mLengths.cbegin(), mLengths.cend(), 0u,
                                       [](size_t left, size_t right) { return left + right; }),
                           mHolePunchCandidate);
                           mHolePunchCandidate, mBlurringLayer);
            }

            void reset() { *this = {}; }
@@ -112,14 +122,19 @@ private:
        size_t getLayerLength() const { return mLength; }
        // Gets the hole punch candidate for this Run.
        const CachedSet* getHolePunchCandidate() const { return mHolePunchCandidate; }
        const CachedSet* getBlurringLayer() const { return mBlurringLayer; }

    private:
        Run(std::vector<CachedSet>::const_iterator start, size_t length,
            const CachedSet* holePunchCandidate)
              : mStart(start), mLength(length), mHolePunchCandidate(holePunchCandidate) {}
            const CachedSet* holePunchCandidate, const CachedSet* blurringLayer)
              : mStart(start),
                mLength(length),
                mHolePunchCandidate(holePunchCandidate),
                mBlurringLayer(blurringLayer) {}
        const std::vector<CachedSet>::const_iterator mStart;
        const size_t mLength;
        const CachedSet* const mHolePunchCandidate;
        const CachedSet* const mBlurringLayer;

        friend class Builder;
    };
@@ -138,7 +153,6 @@ private:
    std::chrono::steady_clock::time_point mLastGeometryUpdate;

    std::vector<CachedSet> mLayers;
    std::optional<CachedSet> mNewCachedSet;

    // Statistics
    size_t mUnflattenedDisplayCost = 0;
+1 −0
Original line number Diff line number Diff line
@@ -231,6 +231,7 @@ public:
    bool hasBlurBehind() const {
        return mBackgroundBlurRadius.get() > 0 || !mBlurRegions.get().empty();
    }
    int32_t getBackgroundBlurRadius() const { return mBackgroundBlurRadius.get(); }
    hardware::graphics::composer::hal::Composition getCompositionType() const {
        return mCompositionType.get();
    }
Loading