diff options
11 files changed, 255 insertions, 3 deletions
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index 8fc9cba794..450ba1d841 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -167,6 +167,27 @@ void LayerHistory::setDefaultFrameRateCompatibility(int32_t id, info->setDefaultLayerVote(getVoteType(frameRateCompatibility, contentDetectionEnabled)); } +void LayerHistory::setLayerProperties(int32_t id, const LayerProps& properties) { + std::lock_guard lock(mLock); + + auto [found, layerPair] = findLayer(id); + if (found == LayerStatus::NotFound) { + // Offscreen layer + ALOGV("%s: %d not registered", __func__, id); + return; + } + + const auto& info = layerPair->second; + info->setProperties(properties); + + // Activate layer if inactive and visible. + if (found == LayerStatus::LayerInInactiveMap && info->isVisible()) { + mActiveLayerInfos.insert( + {id, std::make_pair(layerPair->first, std::move(layerPair->second))}); + mInactiveLayerInfos.erase(id); + } +} + auto LayerHistory::summarize(const RefreshRateSelector& selector, nsecs_t now) -> Summary { ATRACE_CALL(); Summary summary; diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h index bac1ec639a..5a9445bcaf 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.h +++ b/services/surfaceflinger/Scheduler/LayerHistory.h @@ -73,7 +73,7 @@ public: // does not set a preference for refresh rate. void setDefaultFrameRateCompatibility(int32_t id, FrameRateCompatibility frameRateCompatibility, bool contentDetectionEnabled); - + void setLayerProperties(int32_t id, const LayerProps&); using Summary = std::vector<RefreshRateSelector::LayerRequirement>; // Rebuilds sets of active/inactive layers, and accumulates stats for active layers. diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp index 8d18769e5a..bf3a7bc8b7 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp @@ -75,6 +75,10 @@ void LayerInfo::setLastPresentTime(nsecs_t lastPresentTime, nsecs_t now, LayerUp } } +void LayerInfo::setProperties(const android::scheduler::LayerProps& properties) { + *mLayerProps = properties; +} + bool LayerInfo::isFrameTimeValid(const FrameTimeData& frameTime) const { return frameTime.queueTime >= std::chrono::duration_cast<std::chrono::nanoseconds>( mFrameTimeValidSince.time_since_epoch()) diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h index 03ab0df3cd..d24fc33491 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.h +++ b/services/surfaceflinger/Scheduler/LayerInfo.h @@ -182,6 +182,8 @@ public: // layer can go back to whatever vote it had before the app voted for it. void setDefaultLayerVote(LayerHistory::LayerVoteType type) { mDefaultVote = type; } + void setProperties(const LayerProps&); + // Resets the layer vote to its default. void resetLayerVote() { mLayerVote = {mDefaultVote, Fps(), Seamlessness::Default, FrameRateCategory::Default}; diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 56a4ae2569..f41243cb32 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -654,6 +654,10 @@ void Scheduler::setDefaultFrameRateCompatibility( mFeatures.test(Feature::kContentDetection)); } +void Scheduler::setLayerProperties(int32_t id, const android::scheduler::LayerProps& properties) { + mLayerHistory.setLayerProperties(id, properties); +} + void Scheduler::chooseRefreshRateForContent( const surfaceflinger::frontend::LayerHierarchy* hierarchy, bool updateAttachedChoreographer) { diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index a02180af8d..c78051a278 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -234,6 +234,7 @@ public: nsecs_t now, LayerHistory::LayerUpdateType) EXCLUDES(mDisplayLock); void setModeChangePending(bool pending); void setDefaultFrameRateCompatibility(int32_t id, scheduler::FrameRateCompatibility); + void setLayerProperties(int32_t id, const LayerProps&); void deregisterLayer(Layer*); void onLayerDestroyed(Layer*) EXCLUDES(mChoreographerLock); diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Fps.h b/services/surfaceflinger/Scheduler/include/scheduler/Fps.h index 19e951abb2..2806450c5f 100644 --- a/services/surfaceflinger/Scheduler/include/scheduler/Fps.h +++ b/services/surfaceflinger/Scheduler/include/scheduler/Fps.h @@ -83,7 +83,7 @@ struct FpsRanges { }; // The frame rate category of a Layer. -enum class FrameRateCategory { +enum class FrameRateCategory : int32_t { Default, NoPreference, Low, diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 4d02b44201..529dc1b4f4 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2219,7 +2219,8 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { snapshot->changes.any(Changes::Geometry)); const bool hasChanges = - snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation) || + snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation | + Changes::Geometry | Changes::Visibility) || (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) != 0; @@ -2250,6 +2251,10 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { .isFrontBuffered = snapshot->isFrontBuffered(), }; + if (snapshot->changes.any(Changes::Geometry | Changes::Visibility)) { + mScheduler->setLayerProperties(snapshot->sequence, layerProps); + } + if (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) { mScheduler->setDefaultFrameRateCompatibility(snapshot->sequence, snapshot->defaultFrameRateCompatibility); diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp index 190c0e8c10..befef482b9 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp @@ -839,6 +839,81 @@ TEST_F(LayerHistoryIntegrationTest, DISABLED_smallDirtyInMultiLayer) { ASSERT_EQ(30_Hz, summary[0].desiredRefreshRate); } +TEST_F(LayerHistoryIntegrationTest, hidingLayerUpdatesLayerHistory) { + createLegacyAndFrontedEndLayer(1); + nsecs_t time = systemTime(); + updateLayerSnapshotsAndLayerHistory(time); + EXPECT_EQ(1u, layerCount()); + EXPECT_EQ(0u, activeLayerCount()); + + setBuffer(1); + updateLayerSnapshotsAndLayerHistory(time); + auto summary = summarizeLayerHistory(time); + ASSERT_EQ(1u, summary.size()); + EXPECT_EQ(LayerHistory::LayerVoteType::Max, summary[0].vote); + EXPECT_EQ(1u, activeLayerCount()); + + hideLayer(1); + updateLayerSnapshotsAndLayerHistory(time); + + summary = summarizeLayerHistory(time); + EXPECT_TRUE(summary.empty()); + EXPECT_EQ(0u, activeLayerCount()); +} + +TEST_F(LayerHistoryIntegrationTest, showingLayerUpdatesLayerHistory) { + createLegacyAndFrontedEndLayer(1); + nsecs_t time = systemTime(); + updateLayerSnapshotsAndLayerHistory(time); + EXPECT_EQ(1u, layerCount()); + EXPECT_EQ(0u, activeLayerCount()); + hideLayer(1); + setBuffer(1); + updateLayerSnapshotsAndLayerHistory(time); + auto summary = summarizeLayerHistory(time); + EXPECT_TRUE(summary.empty()); + EXPECT_EQ(0u, activeLayerCount()); + + showLayer(1); + updateLayerSnapshotsAndLayerHistory(time); + + summary = summarizeLayerHistory(time); + ASSERT_EQ(1u, summary.size()); + EXPECT_EQ(LayerHistory::LayerVoteType::Max, summary[0].vote); + EXPECT_EQ(1u, activeLayerCount()); +} + +TEST_F(LayerHistoryIntegrationTest, updatingGeometryUpdatesWeight) { + createLegacyAndFrontedEndLayer(1); + nsecs_t time = systemTime(); + updateLayerSnapshotsAndLayerHistory(time); + EXPECT_EQ(1u, layerCount()); + EXPECT_EQ(0u, activeLayerCount()); + + setBuffer(1, + std::make_shared< + renderengine::mock::FakeExternalTexture>(100U /*width*/, 100U /*height*/, 1, + HAL_PIXEL_FORMAT_RGBA_8888, + GRALLOC_USAGE_PROTECTED /*usage*/)); + mFlinger.setLayerHistoryDisplayArea(100 * 100); + updateLayerSnapshotsAndLayerHistory(time); + auto summary = summarizeLayerHistory(time); + ASSERT_EQ(1u, summary.size()); + EXPECT_EQ(LayerHistory::LayerVoteType::Max, summary[0].vote); + EXPECT_EQ(1u, activeLayerCount()); + + auto startingWeight = summary[0].weight; + + setMatrix(1, 0.1f, 0.f, 0.f, 0.1f); + updateLayerSnapshotsAndLayerHistory(time); + + summary = summarizeLayerHistory(time); + ASSERT_EQ(1u, summary.size()); + EXPECT_EQ(LayerHistory::LayerVoteType::Max, summary[0].vote); + EXPECT_EQ(1u, activeLayerCount()); + EXPECT_GT(startingWeight, summary[0].weight); +} + class LayerHistoryIntegrationTestParameterized : public LayerHistoryIntegrationTest, public testing::WithParamInterface<std::chrono::nanoseconds> {}; diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp index 57babafac3..2cc6dc7721 100644 --- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp @@ -789,6 +789,143 @@ TEST_F(LayerSnapshotTest, frameRateSelectionStrategy) { EXPECT_EQ(getSnapshot({.id = 1221})->frameRateSelectionStrategy, scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // ROOT + // ├── 1 + // │ ├── 11 + // │ │ └── 111 + // │ ├── 12 (frame rate set to default with strategy default) + // │ │ ├── 121 + // │ │ └── 122 (frame rate set to 123.f) + // │ │ └── 1221 + // │ └── 13 + // └── 2 + setFrameRate(12, -1.f, 0, 0); + setFrameRateSelectionStrategy(12, 0 /* Default */); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + // verify parent 1 gets no vote + EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, + scheduler::FrameRateCompatibility::NoVote); + EXPECT_FALSE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // verify layer 12 and all descendants (121, 122, 1221) get the requested vote + EXPECT_FALSE(getSnapshot({.id = 12})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 12})->frameRate.vote.type, + scheduler::FrameRateCompatibility::NoVote); + EXPECT_EQ(getSnapshot({.id = 12})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 12})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_FALSE(getSnapshot({.id = 121})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 121})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_EQ(getSnapshot({.id = 121})->frameRate.vote.type, + scheduler::FrameRateCompatibility::Default); + EXPECT_TRUE(getSnapshot({.id = 121})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.rate.getValue(), 123.f); + EXPECT_EQ(getSnapshot({.id = 122})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.vote.rate.getValue(), 123.f); + EXPECT_EQ(getSnapshot({.id = 1221})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); +} + +TEST_F(LayerSnapshotTest, frameRateSelectionStrategyWithCategory) { + // ROOT + // ├── 1 + // │ ├── 11 + // │ │ └── 111 + // │ ├── 12 (frame rate category set to high with strategy OverrideChildren) + // │ │ ├── 121 + // │ │ └── 122 (frame rate set to 123.f but should be overridden by layer 12) + // │ │ └── 1221 + // │ └── 13 + // └── 2 + setFrameRateCategory(12, 4 /* high */); + setFrameRate(122, 123.f, 0, 0); + setFrameRateSelectionStrategy(12, 1 /* OverrideChildren */); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + // verify parent 1 gets no vote + EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, + scheduler::FrameRateCompatibility::NoVote); + EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // verify layer 12 and all descendants (121, 122, 1221) get the requested vote + EXPECT_EQ(getSnapshot({.id = 12})->frameRate.category, FrameRateCategory::High); + EXPECT_EQ(getSnapshot({.id = 12})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 12})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 121})->frameRate.category, FrameRateCategory::High); + EXPECT_EQ(getSnapshot({.id = 121})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 121})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 122})->frameRate.category, FrameRateCategory::High); + EXPECT_EQ(getSnapshot({.id = 122})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.category, FrameRateCategory::High); + EXPECT_EQ(getSnapshot({.id = 1221})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // ROOT + // ├── 1 + // │ ├── 11 + // │ │ └── 111 + // │ ├── 12 (frame rate category to default with strategy default) + // │ │ ├── 121 + // │ │ └── 122 (frame rate set to 123.f) + // │ │ └── 1221 + // │ └── 13 + // └── 2 + setFrameRateCategory(12, 0 /* default */); + setFrameRateSelectionStrategy(12, 0 /* Default */); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + // verify parent 1 gets no vote + EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, + scheduler::FrameRateCompatibility::NoVote); + EXPECT_EQ(getSnapshot({.id = 1})->frameRate.category, FrameRateCategory::Default); + EXPECT_FALSE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // verify layer 12 and all descendants (121, 122, 1221) get the requested vote + EXPECT_FALSE(getSnapshot({.id = 12})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 12})->frameRate.vote.type, + scheduler::FrameRateCompatibility::NoVote); + EXPECT_EQ(getSnapshot({.id = 12})->frameRate.category, FrameRateCategory::Default); + EXPECT_EQ(getSnapshot({.id = 12})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 12})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_FALSE(getSnapshot({.id = 12})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 121})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_EQ(getSnapshot({.id = 121})->frameRate.category, FrameRateCategory::Default); + EXPECT_EQ(getSnapshot({.id = 121})->frameRate.vote.type, + scheduler::FrameRateCompatibility::Default); + EXPECT_TRUE(getSnapshot({.id = 121})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.rate.getValue(), 123.f); + EXPECT_EQ(getSnapshot({.id = 122})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_EQ(getSnapshot({.id = 122})->frameRate.category, FrameRateCategory::Default); + EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.vote.rate.getValue(), 123.f); + EXPECT_EQ(getSnapshot({.id = 1221})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.category, FrameRateCategory::Default); + EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); } TEST_F(LayerSnapshotTest, skipRoundCornersWhenProtected) { diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index d0b2199c58..bca14f5217 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -623,6 +623,9 @@ public: void releaseLegacyLayer(uint32_t sequence) { mFlinger->mLegacyLayers.erase(sequence); }; + auto setLayerHistoryDisplayArea(uint32_t displayArea) { + return mFlinger->mScheduler->onActiveDisplayAreaChanged(displayArea); + }; auto updateLayerHistory(nsecs_t now) { return mFlinger->updateLayerHistory(now); }; auto setDaltonizerType(ColorBlindnessType type) { mFlinger->mDaltonizer.setType(type); |