Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +50 −33 Original line number Diff line number Diff line Loading @@ -38,10 +38,14 @@ class Predictor; class Flattener { public: 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: // Collection of tunables which are backed by sysprops struct Tunables { // Tunables that are specific to scheduling when a cached set should be rendered struct RenderScheduling { // 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: Loading @@ -52,21 +56,38 @@ public: // // 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 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. // 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. // 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); static const constexpr std::chrono::milliseconds kDefaultActiveLayerTimeout = 150ms; static const constexpr bool kDefaultEnableHolePunch = true; // Threshold for determing whether a layer is active. A layer whose properties, including // the buffer, have not changed in at least this time is considered inactive and is // therefore a candidate for flattening. const std::chrono::milliseconds mActiveLayerTimeout; // Toggles for scheduling when it's safe to render a cached set. // See: RenderScheduling const std::optional<RenderScheduling> mRenderScheduling; // True if the hole punching feature should be enabled. const bool mEnableHolePunch; }; Flattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables); void setDisplaySize(ui::Size size) { mDisplaySize = size; Loading Loading @@ -177,8 +198,7 @@ private: void buildCachedSets(std::chrono::steady_clock::time_point now); renderengine::RenderEngine& mRenderEngine; const bool mEnableHolePunch; const std::optional<CachedSetRenderSchedulingTunables> mCachedSetRenderSchedulingTunables; const Tunables mTunables; TexturePool mTexturePool; Loading @@ -202,9 +222,6 @@ private: size_t mCachedSetCreationCount = 0; size_t mCachedSetCreationCost = 0; std::unordered_map<size_t, size_t> mInvalidatedCachedSetAges; std::chrono::nanoseconds mActiveLayerTimeout = kActiveLayerTimeout; static constexpr auto kActiveLayerTimeout = std::chrono::nanoseconds(150ms); }; } // namespace compositionengine::impl::planner Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h +3 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ namespace compositionengine::impl::planner { // heuristically determining the composition strategy of the current layer stack, // and flattens inactive layers into an override buffer so it can be used // as a more efficient representation of parts of the layer stack. // Implicitly, layer caching must also be enabled for the Planner to have any effect // E.g., setprop debug.sf.enable_layer_caching 1, or // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>] class Planner { public: Planner(renderengine::RenderEngine& renderengine); Loading services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +9 −18 Original line number Diff line number Diff line Loading @@ -60,19 +60,8 @@ bool isSameStack(const std::vector<const LayerState*>& incomingLayers, } // namespace Flattener::Flattener( renderengine::RenderEngine& renderEngine, bool enableHolePunch, std::optional<CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables) : mRenderEngine(renderEngine), mEnableHolePunch(enableHolePunch), mCachedSetRenderSchedulingTunables(cachedSetRenderSchedulingTunables), mTexturePool(mRenderEngine) { const int timeoutInMs = base::GetIntProperty(std::string("debug.sf.layer_caching_active_layer_timeout_ms"), 0); if (timeoutInMs != 0) { mActiveLayerTimeout = std::chrono::milliseconds(timeoutInMs); } } Flattener::Flattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables) : mRenderEngine(renderEngine), mTunables(tunables), mTexturePool(mRenderEngine) {} NonBufferHash Flattener::flattenLayers(const std::vector<const LayerState*>& layers, NonBufferHash hash, time_point now) { Loading Loading @@ -128,14 +117,14 @@ void Flattener::renderCachedSets( // If we have a render deadline, and the flattener is configured to skip rendering if we don't // have enough time, then we skip rendering the cached set if we think that we'll steal too much // time from the next frame. if (renderDeadline && mCachedSetRenderSchedulingTunables) { if (renderDeadline && mTunables.mRenderScheduling) { if (const auto estimatedRenderFinish = now + mCachedSetRenderSchedulingTunables->cachedSetRenderDuration; now + mTunables.mRenderScheduling->cachedSetRenderDuration; estimatedRenderFinish > *renderDeadline) { mNewCachedSet->incrementSkipCount(); if (mNewCachedSet->getSkipCount() <= mCachedSetRenderSchedulingTunables->maxDeferRenderAttempts) { mTunables.mRenderScheduling->maxDeferRenderAttempts) { ATRACE_FORMAT("DeadlinePassed: exceeded deadline by: %d us", std::chrono::duration_cast<std::chrono::microseconds>( estimatedRenderFinish - *renderDeadline) Loading Loading @@ -420,8 +409,10 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { bool runHasFirstLayer = false; for (auto currentSet = mLayers.cbegin(); currentSet != mLayers.cend(); ++currentSet) { const bool layerIsInactive = now - currentSet->getLastUpdate() > mActiveLayerTimeout; const bool layerIsInactive = now - currentSet->getLastUpdate() > mTunables.mActiveLayerTimeout; const bool layerHasBlur = currentSet->hasBlurBehind(); if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { if (isPartOfRun) { Loading Loading @@ -522,7 +513,7 @@ void Flattener::buildCachedSets(time_point now) { mNewCachedSet->addBackgroundBlurLayer(*bestRun->getBlurringLayer()); } if (mEnableHolePunch && bestRun->getHolePunchCandidate() && if (mTunables.mEnableHolePunch && bestRun->getHolePunchCandidate() && bestRun->getHolePunchCandidate()->requiresHolePunch()) { // Add the pip layer to mNewCachedSet, but in a special way - it should // replace the buffer with a clear round rect. Loading services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp +22 −12 Original line number Diff line number Diff line Loading @@ -32,36 +32,46 @@ namespace android::compositionengine::impl::planner { namespace { std::optional<Flattener::CachedSetRenderSchedulingTunables> buildFlattenerTuneables() { std::optional<Flattener::Tunables::RenderScheduling> buildRenderSchedulingTunables() { if (!base::GetBoolProperty(std::string("debug.sf.enable_cached_set_render_scheduling"), true)) { return std::nullopt; } auto renderDuration = std::chrono::nanoseconds( const auto renderDuration = std::chrono::nanoseconds( base::GetUintProperty<uint64_t>(std::string("debug.sf.cached_set_render_duration_ns"), Flattener::CachedSetRenderSchedulingTunables:: Flattener::Tunables::RenderScheduling:: kDefaultCachedSetRenderDuration.count())); auto maxDeferRenderAttempts = base::GetUintProperty< const auto maxDeferRenderAttempts = base::GetUintProperty< size_t>(std::string("debug.sf.cached_set_max_defer_render_attmpts"), Flattener::CachedSetRenderSchedulingTunables::kDefaultMaxDeferRenderAttempts); Flattener::Tunables::RenderScheduling::kDefaultMaxDeferRenderAttempts); return std::make_optional<Flattener::CachedSetRenderSchedulingTunables>( Flattener::CachedSetRenderSchedulingTunables{ return std::make_optional<Flattener::Tunables::RenderScheduling>( Flattener::Tunables::RenderScheduling{ .cachedSetRenderDuration = renderDuration, .maxDeferRenderAttempts = maxDeferRenderAttempts, }); } Flattener::Tunables buildFlattenerTuneables() { const auto activeLayerTimeout = std::chrono::milliseconds( base::GetIntProperty<int32_t>(std::string( "debug.sf.layer_caching_active_layer_timeout_ms"), Flattener::Tunables::kDefaultActiveLayerTimeout.count())); const auto enableHolePunch = base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), Flattener::Tunables::kDefaultEnableHolePunch); return Flattener::Tunables{ .mActiveLayerTimeout = activeLayerTimeout, .mRenderScheduling = buildRenderSchedulingTunables(), .mEnableHolePunch = enableHolePunch, }; } } // namespace Planner::Planner(renderengine::RenderEngine& renderEngine) // Implicitly, layer caching must also be enabled for the hole punch or // predictor to have any effect. // E.g., setprop debug.sf.enable_layer_caching 1, or // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>] : mFlattener(renderEngine, base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), true), buildFlattenerTuneables()) { mPredictorEnabled = base::GetBoolProperty(std::string("debug.sf.enable_planner_prediction"), false); Loading services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +15 −12 Original line number Diff line number Diff line Loading @@ -47,23 +47,24 @@ namespace { class TestableFlattener : public Flattener { public: TestableFlattener(renderengine::RenderEngine& renderEngine, bool enableHolePunch, std::optional<Flattener::CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables = std::nullopt) : Flattener(renderEngine, enableHolePunch, cachedSetRenderSchedulingTunables) {} TestableFlattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables) : Flattener(renderEngine, tunables) {} const std::optional<CachedSet>& getNewCachedSetForTesting() const { return mNewCachedSet; } }; class FlattenerTest : public testing::Test { public: FlattenerTest() : FlattenerTest(std::nullopt) {} FlattenerTest() : FlattenerTest(Flattener::Tunables{ .mActiveLayerTimeout = 100ms, .mRenderScheduling = std::nullopt, .mEnableHolePunch = true, }) {} void SetUp() override; protected: FlattenerTest(std::optional<Flattener::CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables) : mFlattener(std::make_unique<TestableFlattener>(mRenderEngine, true, cachedSetRenderSchedulingTunables)) {} FlattenerTest(const Flattener::Tunables& tunables) : mFlattener(std::make_unique<TestableFlattener>(mRenderEngine, tunables)) {} void initializeOverrideBuffer(const std::vector<const LayerState*>& layers); void initializeFlattener(const std::vector<const LayerState*>& layers); void expectAllLayersFlattened(const std::vector<const LayerState*>& layers); Loading Loading @@ -899,11 +900,13 @@ class FlattenerRenderSchedulingTest : public FlattenerTest { public: FlattenerRenderSchedulingTest() : FlattenerTest( Flattener::CachedSetRenderSchedulingTunables{.cachedSetRenderDuration = Flattener::Tunables{.mActiveLayerTimeout = 100ms, .mRenderScheduling = Flattener::Tunables:: RenderScheduling{.cachedSetRenderDuration = kCachedSetRenderDuration, .maxDeferRenderAttempts = kMaxDeferRenderAttempts}) { } kMaxDeferRenderAttempts}, .mEnableHolePunch = true}) {} }; TEST_F(FlattenerRenderSchedulingTest, flattenLayers_renderCachedSets_defersUpToMaxAttempts) { Loading Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +50 −33 Original line number Diff line number Diff line Loading @@ -38,10 +38,14 @@ class Predictor; class Flattener { public: 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: // Collection of tunables which are backed by sysprops struct Tunables { // Tunables that are specific to scheduling when a cached set should be rendered struct RenderScheduling { // 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: Loading @@ -52,21 +56,38 @@ public: // // 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 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. // 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. // 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); static const constexpr std::chrono::milliseconds kDefaultActiveLayerTimeout = 150ms; static const constexpr bool kDefaultEnableHolePunch = true; // Threshold for determing whether a layer is active. A layer whose properties, including // the buffer, have not changed in at least this time is considered inactive and is // therefore a candidate for flattening. const std::chrono::milliseconds mActiveLayerTimeout; // Toggles for scheduling when it's safe to render a cached set. // See: RenderScheduling const std::optional<RenderScheduling> mRenderScheduling; // True if the hole punching feature should be enabled. const bool mEnableHolePunch; }; Flattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables); void setDisplaySize(ui::Size size) { mDisplaySize = size; Loading Loading @@ -177,8 +198,7 @@ private: void buildCachedSets(std::chrono::steady_clock::time_point now); renderengine::RenderEngine& mRenderEngine; const bool mEnableHolePunch; const std::optional<CachedSetRenderSchedulingTunables> mCachedSetRenderSchedulingTunables; const Tunables mTunables; TexturePool mTexturePool; Loading @@ -202,9 +222,6 @@ private: size_t mCachedSetCreationCount = 0; size_t mCachedSetCreationCost = 0; std::unordered_map<size_t, size_t> mInvalidatedCachedSetAges; std::chrono::nanoseconds mActiveLayerTimeout = kActiveLayerTimeout; static constexpr auto kActiveLayerTimeout = std::chrono::nanoseconds(150ms); }; } // namespace compositionengine::impl::planner Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h +3 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ namespace compositionengine::impl::planner { // heuristically determining the composition strategy of the current layer stack, // and flattens inactive layers into an override buffer so it can be used // as a more efficient representation of parts of the layer stack. // Implicitly, layer caching must also be enabled for the Planner to have any effect // E.g., setprop debug.sf.enable_layer_caching 1, or // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>] class Planner { public: Planner(renderengine::RenderEngine& renderengine); Loading
services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +9 −18 Original line number Diff line number Diff line Loading @@ -60,19 +60,8 @@ bool isSameStack(const std::vector<const LayerState*>& incomingLayers, } // namespace Flattener::Flattener( renderengine::RenderEngine& renderEngine, bool enableHolePunch, std::optional<CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables) : mRenderEngine(renderEngine), mEnableHolePunch(enableHolePunch), mCachedSetRenderSchedulingTunables(cachedSetRenderSchedulingTunables), mTexturePool(mRenderEngine) { const int timeoutInMs = base::GetIntProperty(std::string("debug.sf.layer_caching_active_layer_timeout_ms"), 0); if (timeoutInMs != 0) { mActiveLayerTimeout = std::chrono::milliseconds(timeoutInMs); } } Flattener::Flattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables) : mRenderEngine(renderEngine), mTunables(tunables), mTexturePool(mRenderEngine) {} NonBufferHash Flattener::flattenLayers(const std::vector<const LayerState*>& layers, NonBufferHash hash, time_point now) { Loading Loading @@ -128,14 +117,14 @@ void Flattener::renderCachedSets( // If we have a render deadline, and the flattener is configured to skip rendering if we don't // have enough time, then we skip rendering the cached set if we think that we'll steal too much // time from the next frame. if (renderDeadline && mCachedSetRenderSchedulingTunables) { if (renderDeadline && mTunables.mRenderScheduling) { if (const auto estimatedRenderFinish = now + mCachedSetRenderSchedulingTunables->cachedSetRenderDuration; now + mTunables.mRenderScheduling->cachedSetRenderDuration; estimatedRenderFinish > *renderDeadline) { mNewCachedSet->incrementSkipCount(); if (mNewCachedSet->getSkipCount() <= mCachedSetRenderSchedulingTunables->maxDeferRenderAttempts) { mTunables.mRenderScheduling->maxDeferRenderAttempts) { ATRACE_FORMAT("DeadlinePassed: exceeded deadline by: %d us", std::chrono::duration_cast<std::chrono::microseconds>( estimatedRenderFinish - *renderDeadline) Loading Loading @@ -420,8 +409,10 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { bool runHasFirstLayer = false; for (auto currentSet = mLayers.cbegin(); currentSet != mLayers.cend(); ++currentSet) { const bool layerIsInactive = now - currentSet->getLastUpdate() > mActiveLayerTimeout; const bool layerIsInactive = now - currentSet->getLastUpdate() > mTunables.mActiveLayerTimeout; const bool layerHasBlur = currentSet->hasBlurBehind(); if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { if (isPartOfRun) { Loading Loading @@ -522,7 +513,7 @@ void Flattener::buildCachedSets(time_point now) { mNewCachedSet->addBackgroundBlurLayer(*bestRun->getBlurringLayer()); } if (mEnableHolePunch && bestRun->getHolePunchCandidate() && if (mTunables.mEnableHolePunch && bestRun->getHolePunchCandidate() && bestRun->getHolePunchCandidate()->requiresHolePunch()) { // Add the pip layer to mNewCachedSet, but in a special way - it should // replace the buffer with a clear round rect. Loading
services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp +22 −12 Original line number Diff line number Diff line Loading @@ -32,36 +32,46 @@ namespace android::compositionengine::impl::planner { namespace { std::optional<Flattener::CachedSetRenderSchedulingTunables> buildFlattenerTuneables() { std::optional<Flattener::Tunables::RenderScheduling> buildRenderSchedulingTunables() { if (!base::GetBoolProperty(std::string("debug.sf.enable_cached_set_render_scheduling"), true)) { return std::nullopt; } auto renderDuration = std::chrono::nanoseconds( const auto renderDuration = std::chrono::nanoseconds( base::GetUintProperty<uint64_t>(std::string("debug.sf.cached_set_render_duration_ns"), Flattener::CachedSetRenderSchedulingTunables:: Flattener::Tunables::RenderScheduling:: kDefaultCachedSetRenderDuration.count())); auto maxDeferRenderAttempts = base::GetUintProperty< const auto maxDeferRenderAttempts = base::GetUintProperty< size_t>(std::string("debug.sf.cached_set_max_defer_render_attmpts"), Flattener::CachedSetRenderSchedulingTunables::kDefaultMaxDeferRenderAttempts); Flattener::Tunables::RenderScheduling::kDefaultMaxDeferRenderAttempts); return std::make_optional<Flattener::CachedSetRenderSchedulingTunables>( Flattener::CachedSetRenderSchedulingTunables{ return std::make_optional<Flattener::Tunables::RenderScheduling>( Flattener::Tunables::RenderScheduling{ .cachedSetRenderDuration = renderDuration, .maxDeferRenderAttempts = maxDeferRenderAttempts, }); } Flattener::Tunables buildFlattenerTuneables() { const auto activeLayerTimeout = std::chrono::milliseconds( base::GetIntProperty<int32_t>(std::string( "debug.sf.layer_caching_active_layer_timeout_ms"), Flattener::Tunables::kDefaultActiveLayerTimeout.count())); const auto enableHolePunch = base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), Flattener::Tunables::kDefaultEnableHolePunch); return Flattener::Tunables{ .mActiveLayerTimeout = activeLayerTimeout, .mRenderScheduling = buildRenderSchedulingTunables(), .mEnableHolePunch = enableHolePunch, }; } } // namespace Planner::Planner(renderengine::RenderEngine& renderEngine) // Implicitly, layer caching must also be enabled for the hole punch or // predictor to have any effect. // E.g., setprop debug.sf.enable_layer_caching 1, or // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>] : mFlattener(renderEngine, base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), true), buildFlattenerTuneables()) { mPredictorEnabled = base::GetBoolProperty(std::string("debug.sf.enable_planner_prediction"), false); Loading
services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +15 −12 Original line number Diff line number Diff line Loading @@ -47,23 +47,24 @@ namespace { class TestableFlattener : public Flattener { public: TestableFlattener(renderengine::RenderEngine& renderEngine, bool enableHolePunch, std::optional<Flattener::CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables = std::nullopt) : Flattener(renderEngine, enableHolePunch, cachedSetRenderSchedulingTunables) {} TestableFlattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables) : Flattener(renderEngine, tunables) {} const std::optional<CachedSet>& getNewCachedSetForTesting() const { return mNewCachedSet; } }; class FlattenerTest : public testing::Test { public: FlattenerTest() : FlattenerTest(std::nullopt) {} FlattenerTest() : FlattenerTest(Flattener::Tunables{ .mActiveLayerTimeout = 100ms, .mRenderScheduling = std::nullopt, .mEnableHolePunch = true, }) {} void SetUp() override; protected: FlattenerTest(std::optional<Flattener::CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables) : mFlattener(std::make_unique<TestableFlattener>(mRenderEngine, true, cachedSetRenderSchedulingTunables)) {} FlattenerTest(const Flattener::Tunables& tunables) : mFlattener(std::make_unique<TestableFlattener>(mRenderEngine, tunables)) {} void initializeOverrideBuffer(const std::vector<const LayerState*>& layers); void initializeFlattener(const std::vector<const LayerState*>& layers); void expectAllLayersFlattened(const std::vector<const LayerState*>& layers); Loading Loading @@ -899,11 +900,13 @@ class FlattenerRenderSchedulingTest : public FlattenerTest { public: FlattenerRenderSchedulingTest() : FlattenerTest( Flattener::CachedSetRenderSchedulingTunables{.cachedSetRenderDuration = Flattener::Tunables{.mActiveLayerTimeout = 100ms, .mRenderScheduling = Flattener::Tunables:: RenderScheduling{.cachedSetRenderDuration = kCachedSetRenderDuration, .maxDeferRenderAttempts = kMaxDeferRenderAttempts}) { } kMaxDeferRenderAttempts}, .mEnableHolePunch = true}) {} }; TEST_F(FlattenerRenderSchedulingTest, flattenLayers_renderCachedSets_defersUpToMaxAttempts) { Loading