diff options
author | Ady Abraham <adyabr@google.com> | 2020-06-26 23:18:40 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-06-26 23:18:40 +0000 |
commit | 18c692ccd16ff35ad3214ee7342feab48a6b3d9e (patch) | |
tree | 33b488af07354de0682410fccc45fbb721f8a816 | |
parent | 175ed63abfe34ea639d8d21363aab20771db27a7 (diff) | |
parent | aae5ed5b7ad78f4a6fba62556d875ae95e7f9987 (diff) | |
download | native-18c692ccd16ff35ad3214ee7342feab48a6b3d9e.tar.gz |
Merge "SurfaceFlinger: only focused layers can use appRequestRange" into rvc-dev
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 19 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 10 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerHistory.cpp | 7 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerHistoryV2.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateConfigs.h | 19 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp | 47 |
7 files changed, 94 insertions, 26 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 13049eddf2..03903f6d07 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1325,6 +1325,10 @@ int32_t Layer::getFrameRateSelectionPriority() const { return Layer::PRIORITY_UNSET; } +bool Layer::isLayerFocusedBasedOnPriority(int32_t priority) { + return priority == PRIORITY_FOCUSED_WITH_MODE || priority == PRIORITY_FOCUSED_WITHOUT_MODE; +}; + uint32_t Layer::getLayerStack() const { auto p = mDrawingParent.promote(); if (p == nullptr) { @@ -1558,7 +1562,7 @@ void Layer::miniDumpHeader(std::string& result) { result.append("-------------------------------"); result.append("-------------------------------"); result.append("-------------------------------"); - result.append("---------\n"); + result.append("-------------------\n"); result.append(" Layer name\n"); result.append(" Z | "); result.append(" Window Type | "); @@ -1566,12 +1570,12 @@ void Layer::miniDumpHeader(std::string& result) { result.append(" Transform | "); result.append(" Disp Frame (LTRB) | "); result.append(" Source Crop (LTRB) | "); - result.append(" Frame Rate (Explicit)\n"); + result.append(" Frame Rate (Explicit) [Focused]\n"); result.append("-------------------------------"); result.append("-------------------------------"); result.append("-------------------------------"); result.append("-------------------------------"); - result.append("---------\n"); + result.append("-------------------\n"); } std::string Layer::frameRateCompatibilityString(Layer::FrameRateCompatibility compatibility) { @@ -1622,17 +1626,20 @@ void Layer::miniDump(std::string& result, const DisplayDevice& display) const { crop.bottom); if (layerState.frameRate.rate != 0 || layerState.frameRate.type != FrameRateCompatibility::Default) { - StringAppendF(&result, "% 6.2ffps %15s\n", layerState.frameRate.rate, + StringAppendF(&result, "% 6.2ffps %15s", layerState.frameRate.rate, frameRateCompatibilityString(layerState.frameRate.type).c_str()); } else { - StringAppendF(&result, "\n"); + StringAppendF(&result, " "); } + const auto focused = isLayerFocusedBasedOnPriority(getFrameRateSelectionPriority()); + StringAppendF(&result, " [%s]\n", focused ? "*" : " "); + result.append("- - - - - - - - - - - - - - - - "); result.append("- - - - - - - - - - - - - - - - "); result.append("- - - - - - - - - - - - - - - - "); result.append("- - - - - - - - - - - - - - - - "); - result.append("- - -\n"); + result.append("- - - - - - - -\n"); } void Layer::dumpFrameStats(std::string& result) const { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 068424bd80..2c90c92f6c 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -94,7 +94,16 @@ struct LayerCreationArgs { class Layer : public virtual RefBase, compositionengine::LayerFE { static std::atomic<int32_t> sSequence; + // The following constants represent priority of the window. SF uses this information when + // deciding which window has a priority when deciding about the refresh rate of the screen. + // Priority 0 is considered the highest priority. -1 means that the priority is unset. static constexpr int32_t PRIORITY_UNSET = -1; + // Windows that are in focus and voted for the preferred mode ID + static constexpr int32_t PRIORITY_FOCUSED_WITH_MODE = 0; + // // Windows that are in focus, but have not requested a specific mode ID. + static constexpr int32_t PRIORITY_FOCUSED_WITHOUT_MODE = 1; + // Windows that are not in focus, but voted for a specific mode ID. + static constexpr int32_t PRIORITY_NOT_FOCUSED_WITH_MODE = 2; public: mutable bool contentDirty{false}; @@ -400,6 +409,7 @@ public: // If the variable is not set on the layer, it traverses up the tree to inherit the frame // rate priority from its parent. virtual int32_t getFrameRateSelectionPriority() const; + static bool isLayerFocusedBasedOnPriority(int32_t priority); virtual ui::Dataspace getDataSpace() const { return ui::Dataspace::UNKNOWN; } diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index 292510978d..ecf2597b8c 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -109,6 +109,8 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) { auto layer = weakLayer.promote(); // Only use the layer if the reference still exists. if (layer || CC_UNLIKELY(mTraceEnabled)) { + const auto layerFocused = + Layer::isLayerFocusedBasedOnPriority(layer->getFrameRateSelectionPriority()); // Check if frame rate was set on layer. const auto frameRate = layer->getFrameRateForLayerTree(); if (frameRate.rate > 0.f) { @@ -122,11 +124,12 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) { return LayerVoteType::NoVote; } }(); - summary.push_back({layer->getName(), voteType, frameRate.rate, /* weight */ 1.0f}); + summary.push_back({layer->getName(), voteType, frameRate.rate, /* weight */ 1.0f, + layerFocused}); } else if (recent) { summary.push_back({layer->getName(), LayerVoteType::Heuristic, info->getRefreshRate(now), - /* weight */ 1.0f}); + /* weight */ 1.0f, layerFocused}); } if (CC_UNLIKELY(mTraceEnabled)) { diff --git a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp index ee612b0732..aa04bd7a58 100644 --- a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp @@ -125,9 +125,10 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) { continue; } - // TODO(b/144307188): This needs to be plugged into layer summary as - // an additional parameter. - ALOGV("Layer has priority: %d", strong->getFrameRateSelectionPriority()); + const auto frameRateSelectionPriority = strong->getFrameRateSelectionPriority(); + const auto layerFocused = Layer::isLayerFocusedBasedOnPriority(frameRateSelectionPriority); + ALOGV("%s has priority: %d %s focused", strong->getName().c_str(), + frameRateSelectionPriority, layerFocused ? "" : "not"); const auto [type, refreshRate] = info->getRefreshRate(now); // Skip NoVote layer as those don't have any requirements @@ -143,7 +144,7 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) { const float layerArea = transformed.getWidth() * transformed.getHeight(); float weight = mDisplayArea ? layerArea / mDisplayArea : 0.0f; - summary.push_back({strong->getName(), type, refreshRate, weight}); + summary.push_back({strong->getName(), type, refreshRate, weight, layerFocused}); if (CC_UNLIKELY(mTraceEnabled)) { trace(layer, *info, type, static_cast<int>(std::round(refreshRate))); diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index a6036c6b37..053d0a7a39 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -212,10 +212,11 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( bool inPrimaryRange = scores[i].first->inPolicy(policy->primaryRange.min, policy->primaryRange.max); if ((primaryRangeIsSingleRate || !inPrimaryRange) && - layer.vote != LayerVoteType::ExplicitDefault && - layer.vote != LayerVoteType::ExplicitExactOrMultiple) { - // Only layers with explicit frame rate settings are allowed to score refresh rates - // outside the primary range. + !(layer.focused && + (layer.vote == LayerVoteType::ExplicitDefault || + layer.vote == LayerVoteType::ExplicitExactOrMultiple))) { + // Only focused layers with explicit frame rate settings are allowed to score + // refresh rates outside the primary range. continue; } diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h index 8a51b85207..27bf0ecf9f 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h @@ -195,15 +195,22 @@ public: // Captures the layer requirements for a refresh rate. This will be used to determine the // display refresh rate. struct LayerRequirement { - std::string name; // Layer's name. Used for debugging purposes. - LayerVoteType vote; // Layer vote type. - float desiredRefreshRate; // Layer's desired refresh rate, if applicable. - float weight; // Layer's weight in the range of [0, 1]. The higher the weight the more - // impact this layer would have on choosing the refresh rate. + // Layer's name. Used for debugging purposes. + std::string name; + // Layer vote type. + LayerVoteType vote = LayerVoteType::NoVote; + // Layer's desired refresh rate, if applicable. + float desiredRefreshRate = 0.0f; + // Layer's weight in the range of [0, 1]. The higher the weight the more impact this layer + // would have on choosing the refresh rate. + float weight = 0.0f; + // Whether layer is in focus or not based on WindowManager's state + bool focused = false; bool operator==(const LayerRequirement& other) const { return name == other.name && vote == other.vote && - desiredRefreshRate == other.desiredRefreshRate && weight == other.weight; + desiredRefreshRate == other.desiredRefreshRate && weight == other.weight && + focused == other.focused; } bool operator!=(const LayerRequirement& other) const { return !(*this == other); } diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index fed591cb19..03d4460b15 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -292,7 +292,8 @@ TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent) { /*currentConfigId=*/HWC_CONFIG_ID_60); const auto makeLayerRequirements = [](float refreshRate) -> std::vector<LayerRequirement> { - return {{"testLayer", LayerVoteType::Heuristic, refreshRate, 1.0f}}; + return {{"testLayer", LayerVoteType::Heuristic, refreshRate, /*weight*/ 1.0f, + /*focused*/ false}}; }; EXPECT_EQ(mExpected90Config, @@ -1132,6 +1133,7 @@ TEST_F(RefreshRateConfigsTest, lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = 60.0f; lr.name = "60Hz ExplicitExactOrMultiple"; + lr.focused = true; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = true}, &consideredSignals)); @@ -1140,6 +1142,7 @@ TEST_F(RefreshRateConfigsTest, lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = 60.0f; lr.name = "60Hz ExplicitDefault"; + lr.focused = true; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = true}, &consideredSignals)); @@ -1162,18 +1165,20 @@ TEST_F(RefreshRateConfigsTest, lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = 90.0f; lr.name = "90Hz ExplicitExactOrMultiple"; + lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true})); lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = 90.0f; lr.name = "90Hz ExplicitDefault"; + lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true})); } TEST_F(RefreshRateConfigsTest, - getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitLayers) { + getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_90); @@ -1194,30 +1199,55 @@ TEST_F(RefreshRateConfigsTest, lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = 60.0f; lr.name = "60Hz ExplicitExactOrMultiple"; + lr.focused = false; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + lr.focused = true; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = 60.0f; lr.name = "60Hz ExplicitDefault"; + lr.focused = false; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + lr.focused = true; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Heuristic; lr.desiredRefreshRate = 60.0f; lr.name = "60Hz Heuristic"; + lr.focused = false; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; lr.desiredRefreshRate = 60.0f; lr.name = "60Hz Max"; + lr.focused = false; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Min; lr.desiredRefreshRate = 60.0f; lr.name = "60Hz Min"; + lr.focused = false; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } @@ -1256,10 +1286,11 @@ TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { // Return the config ID from calling getBestRefreshRate() for a single layer with the // given voteType and fps. - auto getFrameRate = [&](LayerVoteType voteType, float fps, - bool touchActive = false) -> HwcConfigIndexType { + auto getFrameRate = [&](LayerVoteType voteType, float fps, bool touchActive = false, + bool focused = true) -> HwcConfigIndexType { layers[0].vote = voteType; layers[0].desiredRefreshRate = fps; + layers[0].focused = focused; return refreshRateConfigs->getBestRefreshRate(layers, {.touch = touchActive, .idle = false}) .getConfigId(); }; @@ -1277,6 +1308,14 @@ TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitDefault, 90.f)); EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90.f)); + // Layers not focused are not allowed to override primary config + EXPECT_EQ(HWC_CONFIG_ID_60, + getFrameRate(LayerVoteType::ExplicitDefault, 90.f, /*touch=*/false, + /*focused=*/false)); + EXPECT_EQ(HWC_CONFIG_ID_60, + getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90.f, /*touch=*/false, + /*focused=*/false)); + // Touch boost should be restricted to the primary range. EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, 90.f, /*touch=*/true)); // When we're higher than the primary range max due to a layer frame rate setting, touch boost |