diff options
5 files changed, 282 insertions, 7 deletions
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 6a0ea221cc..46252e139f 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -12,7 +12,10 @@ aconfig_declarations { name: "surfaceflinger_flags", package: "com.android.graphics.surfaceflinger.flags", container: "system", - srcs: ["surfaceflinger_flags.aconfig"], + srcs: [ + "surfaceflinger_flags.aconfig", + "surfaceflinger_flags_new.aconfig", + ], } cc_aconfig_library { diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp index 93350b5798..ffd3463296 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp @@ -948,17 +948,43 @@ auto RefreshRateSelector::getFrameRateOverrides(const std::vector<LayerRequireme const auto layersByUid = groupLayersByUid(layers); UidToFrameRateOverride frameRateOverrides; for (const auto& [uid, layersWithSameUid] : layersByUid) { - // Layers with ExplicitExactOrMultiple expect touch boost - const bool hasExplicitExactOrMultiple = - std::any_of(layersWithSameUid.cbegin(), layersWithSameUid.cend(), - [](const auto& layer) { - return layer->vote == LayerVoteType::ExplicitExactOrMultiple; - }); + // Look for cases that should not have frame rate overrides. + bool hasExplicitExactOrMultiple = false; + bool hasExplicitDefault = false; + bool hasHighHint = false; + for (const auto& layer : layersWithSameUid) { + switch (layer->vote) { + case LayerVoteType::ExplicitExactOrMultiple: + hasExplicitExactOrMultiple = true; + break; + case LayerVoteType::ExplicitDefault: + hasExplicitDefault = true; + break; + case LayerVoteType::ExplicitCategory: + if (layer->frameRateCategory == FrameRateCategory::HighHint) { + hasHighHint = true; + } + break; + default: + // No action + break; + } + if (hasExplicitExactOrMultiple && hasExplicitDefault && hasHighHint) { + break; + } + } + // Layers with ExplicitExactOrMultiple expect touch boost if (globalSignals.touch && hasExplicitExactOrMultiple) { continue; } + // Mirrors getRankedFrameRates. If there is no ExplicitDefault, expect touch boost and + // skip frame rate override. + if (hasHighHint && !hasExplicitDefault) { + continue; + } + for (auto& [_, score] : scoredFrameRates) { score = 0; } diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig index eda067423f..5174fa7fb1 100644 --- a/services/surfaceflinger/surfaceflinger_flags.aconfig +++ b/services/surfaceflinger/surfaceflinger_flags.aconfig @@ -1,3 +1,5 @@ +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + package: "com.android.graphics.surfaceflinger.flags" container: "system" @@ -25,6 +27,8 @@ flag { is_fixed_read_only: true } +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + flag { name: "enable_layer_command_batching" namespace: "core_graphics" @@ -49,6 +53,8 @@ flag { is_fixed_read_only: true } +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + flag { name: "hotplug2" namespace: "core_graphics" @@ -73,6 +79,8 @@ flag { is_fixed_read_only: true } +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + flag { name: "refresh_rate_overlay_on_external_display" namespace: "core_graphics" @@ -98,6 +106,8 @@ flag { # is_fixed_read_only: true # } +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + flag { name: "cache_when_source_crop_layer_only_moved" namespace: "core_graphics" @@ -130,6 +140,8 @@ flag { is_fixed_read_only: true } +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + flag { name: "game_default_frame_rate" namespace: "game" @@ -162,6 +174,8 @@ flag { is_fixed_read_only: true } +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + flag { name: "renderable_buffer_usage" namespace: "core_graphics" @@ -184,6 +198,8 @@ flag { } } +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig + flag { name: "dont_skip_on_early_ro" namespace: "core_graphics" @@ -205,3 +221,5 @@ flag { purpose: PURPOSE_BUGFIX } } + +# This file is locked and should not be changed. Use surfaceflinger_flags_new.aconfig diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig new file mode 100644 index 0000000000..5451752d91 --- /dev/null +++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig @@ -0,0 +1,13 @@ +# IMPORTANT - please keep alphabetize to reduce merge conflicts + +package: "com.android.graphics.surfaceflinger.flags" +container: "system" + +flag { + name: "dont_skip_on_early_ro2" + namespace: "core_graphics" + description: "This flag is guarding the behaviour where SurfaceFlinger is trying to opportunistically present a frame when the configuration change from late to early" + bug: "273702768" +} # dont_skip_on_early_ro2 + +# IMPORTANT - please keep alphabetize to reduce merge conflicts diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp index 39a8aacaf8..0a6e3054dd 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp @@ -3159,6 +3159,210 @@ TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_twoUids) { EXPECT_TRUE(frameRateOverrides.empty()); } +TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_withFrameRateCategory) { + if (GetParam() == Config::FrameRateOverride::Disabled) { + return; + } + + ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates || + GetParam() == Config::FrameRateOverride::AppOverride || + GetParam() == Config::FrameRateOverride::Enabled); + + auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); + + std::vector<LayerRequirement> layers = {{.ownerUid = 1234, .weight = 1.f}, + {.ownerUid = 1234, .weight = 1.f}}; + + // HighHint case with touch boost and thus should skip frame rate override. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitCategory High"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::High; + auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_TRUE(frameRateOverrides.empty()); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_TRUE(frameRateOverrides.empty()); + + // HighHint case with touch boost and thus should skip frame rate override. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitCategory Normal"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::Normal; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_TRUE(frameRateOverrides.empty()); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_TRUE(frameRateOverrides.empty()); + + // HighHint case with touch boost and thus should skip frame rate override. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitCategory Low"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::Low; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_TRUE(frameRateOverrides.empty()); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_TRUE(frameRateOverrides.empty()); + + // HighHint case with touch boost and thus should skip frame rate override. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitCategory NoPreference"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::NoPreference; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_TRUE(frameRateOverrides.empty()); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_TRUE(frameRateOverrides.empty()); + + // HighHint case *without* touch boost has frame rate override. + // For example, game and touch interaction. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitDefault 60"; + layers[1].vote = LayerVoteType::ExplicitDefault; + layers[1].desiredRefreshRate = 60_Hz; + layers[1].frameRateCategory = FrameRateCategory::Default; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + + // HighHint case with touch boost and thus should skip frame rate override. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitExactOrMultiple 30"; + layers[1].vote = LayerVoteType::ExplicitExactOrMultiple; + layers[1].desiredRefreshRate = 30_Hz; + layers[1].frameRateCategory = FrameRateCategory::Default; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_TRUE(frameRateOverrides.empty()); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_TRUE(frameRateOverrides.empty()); + + // HighHint case with touch boost and thus should skip frame rate override. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitExact 60"; + layers[1].vote = LayerVoteType::ExplicitExact; + layers[1].desiredRefreshRate = 60_Hz; + layers[1].frameRateCategory = FrameRateCategory::Default; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_TRUE(frameRateOverrides.empty()); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_TRUE(frameRateOverrides.empty()); + + // HighHint case with touch boost and thus should skip frame rate override. + layers[0].name = "ExplicitCategory HighHint"; + layers[0].vote = LayerVoteType::ExplicitCategory; + layers[0].desiredRefreshRate = 0_Hz; + layers[0].frameRateCategory = FrameRateCategory::HighHint; + layers[1].name = "ExplicitGte 60"; + layers[1].vote = LayerVoteType::ExplicitGte; + layers[1].desiredRefreshRate = 60_Hz; + layers[1].frameRateCategory = FrameRateCategory::Default; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_TRUE(frameRateOverrides.empty()); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_TRUE(frameRateOverrides.empty()); + + // ExplicitCategory case that expects no global touch boost and thus has frame rate override. + layers[0].name = "ExplicitDefault 60"; + layers[0].vote = LayerVoteType::ExplicitDefault; + layers[0].desiredRefreshRate = 60_Hz; + layers[0].frameRateCategory = FrameRateCategory::Default; + layers[1].name = "ExplicitCategory High"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::High; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(120_Hz, frameRateOverrides.at(1234)); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(120_Hz, frameRateOverrides.at(1234)); + + // ExplicitCategory case that expects no global touch boost and thus has frame rate override. + layers[0].name = "ExplicitDefault 60"; + layers[0].vote = LayerVoteType::ExplicitDefault; + layers[0].desiredRefreshRate = 60_Hz; + layers[0].frameRateCategory = FrameRateCategory::Default; + layers[1].name = "ExplicitCategory Normal"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::Normal; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + + // ExplicitCategory case that expects no global touch boost and thus has frame rate override. + layers[0].name = "ExplicitDefault 60"; + layers[0].vote = LayerVoteType::ExplicitDefault; + layers[0].desiredRefreshRate = 60_Hz; + layers[0].frameRateCategory = FrameRateCategory::Default; + layers[1].name = "ExplicitCategory Low"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::Low; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + + // ExplicitCategory case that expects no global touch boost and thus has frame rate override. + layers[0].name = "ExplicitDefault 60"; + layers[0].vote = LayerVoteType::ExplicitDefault; + layers[0].desiredRefreshRate = 60_Hz; + layers[0].frameRateCategory = FrameRateCategory::Default; + layers[1].name = "ExplicitCategory NoPreference"; + layers[1].vote = LayerVoteType::ExplicitCategory; + layers[1].desiredRefreshRate = 0_Hz; + layers[1].frameRateCategory = FrameRateCategory::NoPreference; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); +} + TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_touch) { if (GetParam() == Config::FrameRateOverride::Disabled) { return; @@ -3204,6 +3408,17 @@ TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_touch) { frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); EXPECT_TRUE(frameRateOverrides.empty()); + + layers[0].vote = LayerVoteType::ExplicitGte; + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); + + frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); + EXPECT_EQ(1u, frameRateOverrides.size()); + ASSERT_EQ(1u, frameRateOverrides.count(1234)); + EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_DivisorIsNotDisplayRefreshRate) { |