Loading services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h +3 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ struct CompositionRefreshArgs { // The earliest time to send the present command to the HAL std::chrono::steady_clock::time_point earliestPresentTime; // The predicted next invalidation time std::optional<std::chrono::steady_clock::time_point> nextInvalidateTime; }; } // namespace android::compositionengine services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h +1 −1 Original line number Diff line number Diff line Loading @@ -286,7 +286,7 @@ protected: virtual std::optional<base::unique_fd> composeSurfaces( const Region&, const compositionengine::CompositionRefreshArgs& refreshArgs) = 0; virtual void postFramebuffer() = 0; virtual void renderCachedSets() = 0; virtual void renderCachedSets(const CompositionRefreshArgs&) = 0; virtual void chooseCompositionStrategy() = 0; virtual bool getSkipColorTransform() const = 0; virtual FrameFences presentAndGetFrameFences() = 0; Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h +1 −1 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ public: std::optional<base::unique_fd> composeSurfaces( const Region&, const compositionengine::CompositionRefreshArgs& refreshArgs) override; void postFramebuffer() override; void renderCachedSets() override; void renderCachedSets(const CompositionRefreshArgs&) override; void cacheClientCompositionRequests(uint32_t) override; // Testing Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +4 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public: mDrawFence = nullptr; mBlurLayer = nullptr; mHolePunchLayer = nullptr; mSkipCount = 0; mLayers.insert(mLayers.end(), other.mLayers.cbegin(), other.mLayers.cend()); Region boundingRegion; Loading @@ -107,6 +108,8 @@ public: mVisibleRegion.orSelf(other.mVisibleRegion); } void incrementAge() { ++mAge; } void incrementSkipCount() { mSkipCount++; } size_t getSkipCount() { return mSkipCount; } // Renders the cached set with the supplied output composition state. void render(renderengine::RenderEngine& re, TexturePool& texturePool, Loading Loading @@ -155,6 +158,7 @@ private: Rect mBounds = Rect::EMPTY_RECT; Region mVisibleRegion; size_t mAge = 0; size_t mSkipCount = 0; // TODO(b/190411067): This is a shared pointer only because CachedSets are copied into different // containers in the Flattener. Logically this should have unique ownership otherwise. Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +38 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <compositionengine/impl/planner/CachedSet.h> #include <compositionengine/impl/planner/LayerState.h> #include <chrono> #include <numeric> #include <vector> Loading @@ -37,7 +38,35 @@ class Predictor; class Flattener { public: Flattener(renderengine::RenderEngine& renderEngine, bool enableHolePunch = false); struct CachedSetRenderSchedulingTunables { // This default assumes that rendering a cached set takes about 3ms. That time is then cut // in half - the next frame using the cached set would have the same workload, meaning that // composition cost is the same. This is best illustrated with the following example: // // Suppose we're at a 120hz cadence so SurfaceFlinger is budgeted 8.3ms per-frame. If // renderCachedSets costs 3ms, then two consecutive frames have timings: // // First frame: Start at 0ms, end at 6.8ms. // renderCachedSets: Start at 6.8ms, end at 9.8ms. // Second frame: Start at 9.8ms, end at 16.6ms. // // Now the second frame won't render a cached set afterwards, but the first frame didn't // really steal time from the second frame. static const constexpr std::chrono::nanoseconds kDefaultCachedSetRenderDuration = 1500us; static const constexpr size_t kDefaultMaxDeferRenderAttempts = 240; // Duration allocated for rendering a cached set. If we don't have enough time for rendering // a cached set, then rendering is deferred to another frame. const std::chrono::nanoseconds cachedSetRenderDuration; // Maximum of times that we defer rendering a cached set. If we defer rendering a cached set // too many times, then render it anyways so that future frames would benefit from the // flattened cached set. const size_t maxDeferRenderAttempts; }; Flattener(renderengine::RenderEngine& renderEngine, bool enableHolePunch = false, std::optional<CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables = std::nullopt); void setDisplaySize(ui::Size size) { mDisplaySize = size; Loading @@ -48,16 +77,14 @@ public: std::chrono::steady_clock::time_point now); // Renders the newest cached sets with the supplied output composition state void renderCachedSets(const OutputCompositionState& outputState); void renderCachedSets(const OutputCompositionState& outputState, std::optional<std::chrono::steady_clock::time_point> renderDeadline); 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; Loading Loading @@ -149,9 +176,15 @@ private: renderengine::RenderEngine& mRenderEngine; const bool mEnableHolePunch; const std::optional<CachedSetRenderSchedulingTunables> mCachedSetRenderSchedulingTunables; TexturePool mTexturePool; protected: // mNewCachedSet must be destroyed before mTexturePool is. std::optional<CachedSet> mNewCachedSet; private: ui::Size mDisplaySize; NonBufferHash mCurrentGeometry; Loading Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h +3 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ struct CompositionRefreshArgs { // The earliest time to send the present command to the HAL std::chrono::steady_clock::time_point earliestPresentTime; // The predicted next invalidation time std::optional<std::chrono::steady_clock::time_point> nextInvalidateTime; }; } // namespace android::compositionengine
services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h +1 −1 Original line number Diff line number Diff line Loading @@ -286,7 +286,7 @@ protected: virtual std::optional<base::unique_fd> composeSurfaces( const Region&, const compositionengine::CompositionRefreshArgs& refreshArgs) = 0; virtual void postFramebuffer() = 0; virtual void renderCachedSets() = 0; virtual void renderCachedSets(const CompositionRefreshArgs&) = 0; virtual void chooseCompositionStrategy() = 0; virtual bool getSkipColorTransform() const = 0; virtual FrameFences presentAndGetFrameFences() = 0; Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h +1 −1 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ public: std::optional<base::unique_fd> composeSurfaces( const Region&, const compositionengine::CompositionRefreshArgs& refreshArgs) override; void postFramebuffer() override; void renderCachedSets() override; void renderCachedSets(const CompositionRefreshArgs&) override; void cacheClientCompositionRequests(uint32_t) override; // Testing Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +4 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public: mDrawFence = nullptr; mBlurLayer = nullptr; mHolePunchLayer = nullptr; mSkipCount = 0; mLayers.insert(mLayers.end(), other.mLayers.cbegin(), other.mLayers.cend()); Region boundingRegion; Loading @@ -107,6 +108,8 @@ public: mVisibleRegion.orSelf(other.mVisibleRegion); } void incrementAge() { ++mAge; } void incrementSkipCount() { mSkipCount++; } size_t getSkipCount() { return mSkipCount; } // Renders the cached set with the supplied output composition state. void render(renderengine::RenderEngine& re, TexturePool& texturePool, Loading Loading @@ -155,6 +158,7 @@ private: Rect mBounds = Rect::EMPTY_RECT; Region mVisibleRegion; size_t mAge = 0; size_t mSkipCount = 0; // TODO(b/190411067): This is a shared pointer only because CachedSets are copied into different // containers in the Flattener. Logically this should have unique ownership otherwise. Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +38 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <compositionengine/impl/planner/CachedSet.h> #include <compositionengine/impl/planner/LayerState.h> #include <chrono> #include <numeric> #include <vector> Loading @@ -37,7 +38,35 @@ class Predictor; class Flattener { public: Flattener(renderengine::RenderEngine& renderEngine, bool enableHolePunch = false); struct CachedSetRenderSchedulingTunables { // This default assumes that rendering a cached set takes about 3ms. That time is then cut // in half - the next frame using the cached set would have the same workload, meaning that // composition cost is the same. This is best illustrated with the following example: // // Suppose we're at a 120hz cadence so SurfaceFlinger is budgeted 8.3ms per-frame. If // renderCachedSets costs 3ms, then two consecutive frames have timings: // // First frame: Start at 0ms, end at 6.8ms. // renderCachedSets: Start at 6.8ms, end at 9.8ms. // Second frame: Start at 9.8ms, end at 16.6ms. // // Now the second frame won't render a cached set afterwards, but the first frame didn't // really steal time from the second frame. static const constexpr std::chrono::nanoseconds kDefaultCachedSetRenderDuration = 1500us; static const constexpr size_t kDefaultMaxDeferRenderAttempts = 240; // Duration allocated for rendering a cached set. If we don't have enough time for rendering // a cached set, then rendering is deferred to another frame. const std::chrono::nanoseconds cachedSetRenderDuration; // Maximum of times that we defer rendering a cached set. If we defer rendering a cached set // too many times, then render it anyways so that future frames would benefit from the // flattened cached set. const size_t maxDeferRenderAttempts; }; Flattener(renderengine::RenderEngine& renderEngine, bool enableHolePunch = false, std::optional<CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables = std::nullopt); void setDisplaySize(ui::Size size) { mDisplaySize = size; Loading @@ -48,16 +77,14 @@ public: std::chrono::steady_clock::time_point now); // Renders the newest cached sets with the supplied output composition state void renderCachedSets(const OutputCompositionState& outputState); void renderCachedSets(const OutputCompositionState& outputState, std::optional<std::chrono::steady_clock::time_point> renderDeadline); 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; Loading Loading @@ -149,9 +176,15 @@ private: renderengine::RenderEngine& mRenderEngine; const bool mEnableHolePunch; const std::optional<CachedSetRenderSchedulingTunables> mCachedSetRenderSchedulingTunables; TexturePool mTexturePool; protected: // mNewCachedSet must be destroyed before mTexturePool is. std::optional<CachedSet> mNewCachedSet; private: ui::Size mDisplaySize; NonBufferHash mCurrentGeometry; Loading