Add frame rate compatibility GTE logic
Bug: 306080972
Test: atest libsurfaceflinger_unittest
Test: atest SetFrameRateTest
Change-Id: I65551be0f96fd7d4137e49259436e1a9c74bfe90
diff --git a/services/surfaceflinger/Scheduler/FrameRateCompatibility.h b/services/surfaceflinger/Scheduler/FrameRateCompatibility.h
index 405c982..d8c408f 100644
--- a/services/surfaceflinger/Scheduler/FrameRateCompatibility.h
+++ b/services/surfaceflinger/Scheduler/FrameRateCompatibility.h
@@ -29,6 +29,8 @@
ExactOrMultiple, // Layer needs the exact frame rate (or a multiple of it) to present the
// content properly. Any other value will result in a pull down.
+ Gte, // Layer needs greater than or equal to the frame rate.
+
NoVote, // Layer doesn't have any requirements for the refresh rate and
// should not be considered when the display refresh rate is determined.
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index d309adc..9c00302 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -278,6 +278,8 @@
return LayerVoteType::NoVote;
case Layer::FrameRateCompatibility::Exact:
return LayerVoteType::ExplicitExact;
+ case Layer::FrameRateCompatibility::Gte:
+ return LayerVoteType::ExplicitGte;
}
}();
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index 71ad451..d3ff236 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -485,6 +485,8 @@
return FrameRateCompatibility::Exact;
case ANATIVEWINDOW_FRAME_RATE_MIN:
return FrameRateCompatibility::Min;
+ case ANATIVEWINDOW_FRAME_RATE_GTE:
+ return FrameRateCompatibility::Gte;
case ANATIVEWINDOW_FRAME_RATE_NO_VOTE:
return FrameRateCompatibility::NoVote;
default:
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 6a7063e..e06221a 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -332,6 +332,15 @@
return calculateNonExactMatchingDefaultLayerScoreLocked(displayPeriod, layerPeriod);
}
+ if (layer.vote == LayerVoteType::ExplicitGte) {
+ using fps_approx_ops::operator>=;
+ if (refreshRate >= layer.desiredRefreshRate) {
+ return 1.0f;
+ } else {
+ return calculateDistanceScoreLocked(layer.desiredRefreshRate, refreshRate);
+ }
+ }
+
if (layer.vote == LayerVoteType::ExplicitExactOrMultiple ||
layer.vote == LayerVoteType::Heuristic) {
using fps_approx_ops::operator<;
@@ -390,13 +399,20 @@
return 0;
}
-float RefreshRateSelector::calculateDistanceScoreFromMax(Fps refreshRate) const {
- const auto& maxFps = mAppRequestFrameRates.back().fps;
- const float ratio = refreshRate.getValue() / maxFps.getValue();
- // Use ratio^2 to get a lower score the more we get further from peak
+float RefreshRateSelector::calculateDistanceScoreLocked(Fps referenceRate, Fps refreshRate) const {
+ using fps_approx_ops::operator>=;
+ const float ratio = referenceRate >= refreshRate
+ ? refreshRate.getValue() / referenceRate.getValue()
+ : referenceRate.getValue() / refreshRate.getValue();
+ // Use ratio^2 to get a lower score the more we get further from the reference rate.
return ratio * ratio;
}
+float RefreshRateSelector::calculateDistanceScoreFromMaxLocked(Fps refreshRate) const {
+ const auto& maxFps = mAppRequestFrameRates.back().fps;
+ return calculateDistanceScoreLocked(maxFps, refreshRate);
+}
+
float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate,
bool isSeamlessSwitch) const {
// Slightly prefer seamless switches.
@@ -421,7 +437,7 @@
// If the layer wants Max, give higher score to the higher refresh rate
if (layer.vote == LayerVoteType::Max) {
- return calculateDistanceScoreFromMax(refreshRate);
+ return calculateDistanceScoreFromMaxLocked(refreshRate);
}
if (layer.vote == LayerVoteType::ExplicitExact) {
@@ -489,6 +505,7 @@
int explicitDefaultVoteLayers = 0;
int explicitExactOrMultipleVoteLayers = 0;
int explicitExact = 0;
+ int explicitGteLayers = 0;
int explicitCategoryVoteLayers = 0;
int seamedFocusedLayers = 0;
int categorySmoothSwitchOnlyLayers = 0;
@@ -513,6 +530,9 @@
case LayerVoteType::ExplicitExact:
explicitExact++;
break;
+ case LayerVoteType::ExplicitGte:
+ explicitGteLayers++;
+ break;
case LayerVoteType::ExplicitCategory:
explicitCategoryVoteLayers++;
if (layer.frameRateCategory == FrameRateCategory::NoPreference) {
@@ -535,7 +555,7 @@
}
const bool hasExplicitVoteLayers = explicitDefaultVoteLayers > 0 ||
- explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 ||
+ explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 || explicitGteLayers > 0 ||
explicitCategoryVoteLayers > 0;
const Policy* policy = getCurrentPolicyLocked();
@@ -688,6 +708,7 @@
case LayerVoteType::Max:
case LayerVoteType::ExplicitDefault:
case LayerVoteType::ExplicitExact:
+ case LayerVoteType::ExplicitGte:
case LayerVoteType::ExplicitCategory:
return false;
}
@@ -1081,7 +1102,7 @@
return;
}
- float score = calculateDistanceScoreFromMax(frameRateMode.fps);
+ float score = calculateDistanceScoreFromMaxLocked(frameRateMode.fps);
if (ascending) {
score = 1.0f / score;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.h b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
index 40e9a83..9f6a29c 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
@@ -149,6 +149,7 @@
// ExactOrMultiple compatibility
ExplicitExact, // Specific refresh rate that was provided by the app with
// Exact compatibility
+ ExplicitGte, // Greater than or equal to frame rate provided by the app
ExplicitCategory, // Specific frame rate category was provided by the app
ftl_last = ExplicitCategory
@@ -460,7 +461,11 @@
bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock);
// Returns the refresh rate score as a ratio to max refresh rate, which has a score of 1.
- float calculateDistanceScoreFromMax(Fps refreshRate) const REQUIRES(mLock);
+ float calculateDistanceScoreFromMaxLocked(Fps refreshRate) const REQUIRES(mLock);
+
+ // Returns the refresh rate score based on its distance from the reference rate.
+ float calculateDistanceScoreLocked(Fps referenceRate, Fps refreshRate) const REQUIRES(mLock);
+
// calculates a score for a layer. Used to determine the display refresh rate
// and the frame rate override for certains applications.
float calculateLayerScoreLocked(const LayerRequirement&, Fps refreshRate,