Make shouldBeSeamless an enum
We change theboolean shouldBeSemaless to an enum with
three values. This introduces a third value "Default" which
indicates that the layer doesn't have a preference for
seamlessness. This is the default value for Surfaces which
haven't called setFrameRate, or have called setFrameRate(0).
Bug: 161776961
Test: presubmit
Change-Id: I157e332e82e95badc928d6a8135e657cd6984db4
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index b872d7a..4ebab3e 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -27,6 +27,14 @@
#define LOG_TAG "RefreshRateConfigs"
namespace android::scheduler {
+namespace {
+std::string formatLayerInfo(const RefreshRateConfigs::LayerRequirement& layer, float weight) {
+ return base::StringPrintf("%s (type=%s, weight=%.2f seamlessness=%s) %.2fHz",
+ layer.name.c_str(),
+ RefreshRateConfigs::layerVoteTypeString(layer.vote).c_str(), weight,
+ toString(layer.seamlessness).c_str(), layer.desiredRefreshRate);
+}
+} // namespace
using AllRefreshRatesMapType = RefreshRateConfigs::AllRefreshRatesMapType;
using RefreshRate = RefreshRateConfigs::RefreshRate;
@@ -170,7 +178,7 @@
maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
}
- if (!layer.shouldBeSeamless) {
+ if (layer.seamlessness == Seamlessness::SeamedAndSeamless) {
seamedLayers++;
}
}
@@ -229,27 +237,38 @@
auto weight = layer.weight;
for (auto i = 0u; i < scores.size(); i++) {
- // If there are no layers with shouldBeSeamless=false and the current
- // config group is different from the default one, this means a layer with
- // shouldBeSeamless=false has just disappeared and we should switch back to
- // the default config group.
- const bool isSeamlessSwitch = seamedLayers > 0
- ? scores[i].first->getConfigGroup() == mCurrentRefreshRate->getConfigGroup()
- : scores[i].first->getConfigGroup() == defaultConfig->getConfigGroup();
+ const bool isSeamlessSwitch =
+ scores[i].first->getConfigGroup() == mCurrentRefreshRate->getConfigGroup();
- if (layer.shouldBeSeamless && !isSeamlessSwitch) {
- ALOGV("%s (weight %.2f) ignores %s (group=%d) to avoid non-seamless switch."
- "Current config = %s",
- layer.name.c_str(), weight, scores[i].first->name.c_str(),
- scores[i].first->getConfigGroup(), mCurrentRefreshRate->toString().c_str());
+ if (layer.seamlessness == Seamlessness::OnlySeamless && !isSeamlessSwitch) {
+ ALOGV("%s ignores %s to avoid non-seamless switch. Current config = %s",
+ formatLayerInfo(layer, weight).c_str(), scores[i].first->toString().c_str(),
+ mCurrentRefreshRate->toString().c_str());
continue;
}
- if (!layer.shouldBeSeamless && !isSeamlessSwitch && !layer.focused) {
- ALOGV("%s (weight %.2f) ignores %s (group=%d) because it's not focused"
- " and the switch is going to be seamed. Current config = %s",
- layer.name.c_str(), weight, scores[i].first->name.c_str(),
- scores[i].first->getConfigGroup(), mCurrentRefreshRate->toString().c_str());
+ if (layer.seamlessness == Seamlessness::SeamedAndSeamless && !isSeamlessSwitch &&
+ !layer.focused) {
+ ALOGV("%s ignores %s because it's not focused and the switch is going to be seamed."
+ " Current config = %s",
+ formatLayerInfo(layer, weight).c_str(), scores[i].first->toString().c_str(),
+ mCurrentRefreshRate->toString().c_str());
+ continue;
+ }
+
+ // Layers with default seamlessness vote for the current config group if
+ // there are layers with seamlessness=SeamedAndSeamless and for the default
+ // config group otherwise. In second case, if the current config group is different
+ // from the default, this means a layer with seamlessness=SeamedAndSeamless has just
+ // disappeared.
+ const bool isInPolicyForDefault = seamedLayers > 0
+ ? scores[i].first->getConfigGroup() == mCurrentRefreshRate->getConfigGroup()
+ : scores[i].first->getConfigGroup() == defaultConfig->getConfigGroup();
+
+ if (layer.seamlessness == Seamlessness::Default && !isInPolicyForDefault &&
+ !layer.focused) {
+ ALOGV("%s ignores %s. Current config = %s", formatLayerInfo(layer, weight).c_str(),
+ scores[i].first->toString().c_str(), mCurrentRefreshRate->toString().c_str());
continue;
}
@@ -267,7 +286,7 @@
const auto ratio = scores[i].first->fps / scores.back().first->fps;
// use ratio^2 to get a lower score the more we get further from peak
const auto layerScore = ratio * ratio;
- ALOGV("%s (Max, weight %.2f) gives %s score of %.2f", layer.name.c_str(), weight,
+ ALOGV("%s gives %s score of %.2f", formatLayerInfo(layer, weight).c_str(),
scores[i].first->name.c_str(), layerScore);
scores[i].second += weight * layerScore;
continue;
@@ -290,9 +309,8 @@
static_cast<float>(actualLayerPeriod));
}();
- ALOGV("%s (ExplicitDefault, weight %.2f) %.2fHz gives %s score of %.2f",
- layer.name.c_str(), weight, 1e9f / layerPeriod, scores[i].first->name.c_str(),
- layerScore);
+ ALOGV("%s gives %s score of %.2f", formatLayerInfo(layer, weight).c_str(),
+ scores[i].first->name.c_str(), layerScore);
scores[i].second += weight * layerScore;
continue;
}
@@ -332,8 +350,7 @@
// Slightly prefer seamless switches.
constexpr float kSeamedSwitchPenalty = 0.95f;
const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty;
- ALOGV("%s (%s, weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(),
- layerVoteTypeString(layer.vote).c_str(), weight, 1e9f / layerPeriod,
+ ALOGV("%s gives %s score of %.2f", formatLayerInfo(layer, weight).c_str(),
scores[i].first->name.c_str(), layerScore);
scores[i].second += weight * layerScore * seamlessness;
continue;