diff options
6 files changed, 115 insertions, 10 deletions
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index 069d89bc42..ff829143d3 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -21,6 +21,7 @@ #include "LayerHistory.h" #include <android-base/stringprintf.h> +#include <com_android_graphics_surfaceflinger_flags.h> #include <cutils/properties.h> #include <gui/TraceUtils.h> #include <utils/Log.h> @@ -39,8 +40,14 @@ namespace android::scheduler { namespace { +using namespace com::android::graphics::surfaceflinger; + bool isLayerActive(const LayerInfo& info, nsecs_t threshold) { - // Layers with an explicit frame rate or frame rate category are always kept active, + if (flags::misc1() && !info.isVisible()) { + return false; + } + + // Layers with an explicit frame rate or frame rate category are kept active, // but ignore NoVote. if (info.getSetFrameRateVote().isValid() && !info.getSetFrameRateVote().isNoVote()) { return true; diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp index 36f2475d8e..54e9022add 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp @@ -304,19 +304,22 @@ LayerInfo::RefreshRateVotes LayerInfo::getRefreshRateVote(const RefreshRateSelec if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) { if (mLayerVote.category != FrameRateCategory::Default) { - ATRACE_FORMAT_INSTANT("ExplicitCategory (%s)", + const auto voteType = mLayerVote.type == LayerHistory::LayerVoteType::NoVote + ? LayerHistory::LayerVoteType::NoVote + : LayerHistory::LayerVoteType::ExplicitCategory; + ATRACE_FORMAT_INSTANT("Vote %s (category=%s)", ftl::enum_string(voteType).c_str(), ftl::enum_string(mLayerVote.category).c_str()); - ALOGV("%s uses frame rate category: %d", mName.c_str(), - static_cast<int>(mLayerVote.category)); - votes.push_back({LayerHistory::LayerVoteType::ExplicitCategory, Fps(), - Seamlessness::Default, mLayerVote.category, + ALOGV("%s voted %s with category: %s", mName.c_str(), + ftl::enum_string(voteType).c_str(), + ftl::enum_string(mLayerVote.category).c_str()); + votes.push_back({voteType, Fps(), Seamlessness::Default, mLayerVote.category, mLayerVote.categorySmoothSwitchOnly}); } if (mLayerVote.fps.isValid() || mLayerVote.type != LayerHistory::LayerVoteType::ExplicitDefault) { ATRACE_FORMAT_INSTANT("Vote %s", ftl::enum_string(mLayerVote.type).c_str()); - ALOGV("%s voted %d ", mName.c_str(), static_cast<int>(mLayerVote.type)); + ALOGV("%s voted %d", mName.c_str(), static_cast<int>(mLayerVote.type)); votes.push_back(mLayerVote); } diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp index 1d23fb5f38..eb69d0bf22 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp @@ -401,7 +401,6 @@ float RefreshRateSelector::calculateDistanceScoreFromMax(Fps refreshRate) const float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate, bool isSeamlessSwitch) const { - ATRACE_CALL(); // Slightly prefer seamless switches. constexpr float kSeamedSwitchPenalty = 0.95f; const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty; diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp index 631adf11c8..2f6058f7a6 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp @@ -18,12 +18,14 @@ #define LOG_TAG "LayerHistoryIntegrationTest" #include <Layer.h> +#include <com_android_graphics_surfaceflinger_flags.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <log/log.h> #include <renderengine/mock/FakeExternalTexture.h> +#include "FlagUtils.h" #include "FpsOps.h" #include "LayerHierarchyTest.h" #include "Scheduler/LayerHistory.h" @@ -36,6 +38,7 @@ namespace android::scheduler { using android::mock::createDisplayMode; +using namespace com::android::graphics::surfaceflinger; class LayerHistoryIntegrationTest : public surfaceflinger::frontend::LayerSnapshotTestBase { protected: @@ -492,7 +495,9 @@ TEST_F(LayerHistoryIntegrationTest, inactiveLayers) { EXPECT_EQ(1, frequentLayerCount(time)); } -TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayer) { +TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayerIsActive) { + SET_FLAG_FOR_TEST(flags::misc1, false); + auto explicitVisiblelayer = createLegacyAndFrontedEndLayer(1); auto explicitInvisiblelayer = createLegacyAndFrontedEndLayer(2); hideLayer(2); @@ -515,6 +520,31 @@ TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayer) { EXPECT_EQ(2, frequentLayerCount(time)); } +TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayerIsNotActive) { + SET_FLAG_FOR_TEST(flags::misc1, true); + + auto explicitVisiblelayer = createLegacyAndFrontedEndLayer(1); + auto explicitInvisiblelayer = createLegacyAndFrontedEndLayer(2); + hideLayer(2); + setFrameRate(1, 60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); + setFrameRate(2, 90.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); + nsecs_t time = systemTime(); + + // Post a buffer to the layers to make them active + setBufferWithPresentTime(explicitVisiblelayer, time); + setBufferWithPresentTime(explicitInvisiblelayer, time); + + EXPECT_EQ(2u, layerCount()); + ASSERT_EQ(1u, summarizeLayerHistory(time).size()); + EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple, + summarizeLayerHistory(time)[0].vote); + EXPECT_EQ(60_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate); + EXPECT_EQ(1u, activeLayerCount()); + EXPECT_EQ(1, frequentLayerCount(time)); +} + TEST_F(LayerHistoryIntegrationTest, infrequentAnimatingLayer) { auto layer = createLegacyAndFrontedEndLayer(1); diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp index 33c1d86847..e8831ab51f 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp @@ -22,10 +22,12 @@ #define LOG_TAG "LayerHistoryTest" #include <Layer.h> +#include <com_android_graphics_surfaceflinger_flags.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <log/log.h> +#include "FlagUtils.h" #include "FpsOps.h" #include "Scheduler/LayerHistory.h" #include "Scheduler/LayerInfo.h" @@ -149,6 +151,8 @@ protected: namespace { +using namespace com::android::graphics::surfaceflinger; + TEST_F(LayerHistoryTest, singleLayerNoVoteDefaultCompatibility) { const auto layer = createLayer(); EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true)); @@ -555,6 +559,33 @@ TEST_F(LayerHistoryTest, oneLayerExplicitVoteWithCategory) { EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[0].frameRateCategory); } +TEST_F(LayerHistoryTest, oneLayerExplicitVoteWithCategoryNotVisibleDoesNotVote) { + SET_FLAG_FOR_TEST(flags::misc1, true); + + auto layer = createLayer(); + EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false)); + EXPECT_CALL(*layer, getFrameRateForLayerTree()) + .WillRepeatedly( + Return(Layer::FrameRate(12.34_Hz, Layer::FrameRateCompatibility::Default, + Seamlessness::OnlySeamless, FrameRateCategory::High))); + + EXPECT_EQ(1, layerCount()); + EXPECT_EQ(0, activeLayerCount()); + + nsecs_t time = systemTime(); + for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) { + history().record(layer->getSequence(), layer->getLayerProps(), time, time, + LayerHistory::LayerUpdateType::Buffer); + time += HI_FPS_PERIOD; + } + + // Layer is not visible, so the layer is moved to inactive, infrequent, and it will not have + // votes to consider for refresh rate selection. + ASSERT_EQ(0, summarizeLayerHistory(time).size()); + EXPECT_EQ(0, activeLayerCount()); + EXPECT_EQ(0, frequentLayerCount(time)); +} + TEST_F(LayerHistoryTest, multipleLayers) { auto layer1 = createLayer("A"); auto layer2 = createLayer("B"); @@ -780,6 +811,8 @@ TEST_F(LayerHistoryTest, inactiveLayers) { } TEST_F(LayerHistoryTest, invisibleExplicitLayer) { + SET_FLAG_FOR_TEST(flags::misc1, false); + auto explicitVisiblelayer = createLayer(); auto explicitInvisiblelayer = createLayer(); @@ -810,6 +843,39 @@ TEST_F(LayerHistoryTest, invisibleExplicitLayer) { EXPECT_EQ(2, frequentLayerCount(time)); } +TEST_F(LayerHistoryTest, invisibleExplicitLayerDoesNotVote) { + SET_FLAG_FOR_TEST(flags::misc1, true); + + auto explicitVisiblelayer = createLayer(); + auto explicitInvisiblelayer = createLayer(); + + EXPECT_CALL(*explicitVisiblelayer, isVisible()).WillRepeatedly(Return(true)); + EXPECT_CALL(*explicitVisiblelayer, getFrameRateForLayerTree()) + .WillRepeatedly(Return( + Layer::FrameRate(60_Hz, Layer::FrameRateCompatibility::ExactOrMultiple))); + + EXPECT_CALL(*explicitInvisiblelayer, isVisible()).WillRepeatedly(Return(false)); + EXPECT_CALL(*explicitInvisiblelayer, getFrameRateForLayerTree()) + .WillRepeatedly(Return( + Layer::FrameRate(90_Hz, Layer::FrameRateCompatibility::ExactOrMultiple))); + + nsecs_t time = systemTime(); + + // Post a buffer to the layers to make them active + history().record(explicitVisiblelayer->getSequence(), explicitVisiblelayer->getLayerProps(), + time, time, LayerHistory::LayerUpdateType::Buffer); + history().record(explicitInvisiblelayer->getSequence(), explicitInvisiblelayer->getLayerProps(), + time, time, LayerHistory::LayerUpdateType::Buffer); + + EXPECT_EQ(2, layerCount()); + ASSERT_EQ(1, summarizeLayerHistory(time).size()); + EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple, + summarizeLayerHistory(time)[0].vote); + EXPECT_EQ(60_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate); + EXPECT_EQ(1, activeLayerCount()); + EXPECT_EQ(1, frequentLayerCount(time)); +} + TEST_F(LayerHistoryTest, infrequentAnimatingLayer) { auto layer = createLayer(); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 8f1982d6c3..03af56cc71 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -271,7 +271,7 @@ public: resetScheduler(mScheduler); } - void setupMockScheduler(test::MockSchedulerOptions options = {}) { + void setupMockScheduler(surfaceflinger::test::MockSchedulerOptions options = {}) { using testing::_; using testing::Return; |