SF: Use default minimal refresh rate between frames
When calculating duplicate frames make sure the minimal period
is at least Fps(120).toPeriodNsecs(). It's not okay to use
min period equal to the max refresh rate at layer creation,
because the supported refresh rates can change. E.g. initially
it can be 24hz and later (bacause another display is plugged)
it can be 60hz, which will cause a lot of frames to be considered
as duplicates.
Bug: 159590486
Test: presubmit
Change-Id: I4424c05012925273ed6ea8254fb975bf8fe7d058
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index 82a2ead..170933d 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -86,9 +86,8 @@
LayerHistory::~LayerHistory() = default;
-void LayerHistory::registerLayer(Layer* layer, Fps highRefreshRate, LayerVoteType type) {
- const nsecs_t highRefreshRatePeriod = highRefreshRate.getPeriodNsecs();
- auto info = std::make_unique<LayerInfo>(layer->getName(), highRefreshRatePeriod, type);
+void LayerHistory::registerLayer(Layer* layer, LayerVoteType type) {
+ auto info = std::make_unique<LayerInfo>(layer->getName(), type);
std::lock_guard lock(mLock);
mLayerInfos.emplace_back(layer, std::move(info));
}
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h
index 4214bab..bae9b5a 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.h
+++ b/services/surfaceflinger/Scheduler/LayerHistory.h
@@ -46,7 +46,7 @@
~LayerHistory();
// Layers are unregistered when the weak reference expires.
- void registerLayer(Layer*, Fps highRefreshRate, LayerVoteType type);
+ void registerLayer(Layer*, LayerVoteType type);
// Sets the display size. Client is responsible for synchronization.
void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; }
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index 1c0065c..4b2862e 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -33,10 +33,8 @@
const RefreshRateConfigs* LayerInfo::sRefreshRateConfigs = nullptr;
bool LayerInfo::sTraceEnabled = false;
-LayerInfo::LayerInfo(const std::string& name, nsecs_t highRefreshRatePeriod,
- LayerHistory::LayerVoteType defaultVote)
+LayerInfo::LayerInfo(const std::string& name, LayerHistory::LayerVoteType defaultVote)
: mName(name),
- mHighRefreshRatePeriod(highRefreshRatePeriod),
mDefaultVote(defaultVote),
mLayerVote({defaultVote, Fps(0.0f)}),
mRefreshRateHistory(name) {}
@@ -133,7 +131,7 @@
}
totalQueueTimeDeltas +=
- std::max(((it + 1)->queueTime - it->queueTime), mHighRefreshRatePeriod);
+ std::max(((it + 1)->queueTime - it->queueTime), kMinPeriodBetweenFrames);
numFrames++;
if (!missingPresentTime && (it->presetTime == 0 || (it + 1)->presetTime == 0)) {
@@ -147,7 +145,7 @@
}
totalPresentTimeDeltas +=
- std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
+ std::max(((it + 1)->presetTime - it->presetTime), kMinPeriodBetweenFrames);
}
// Calculate the average frame time based on presentation timestamps. If those
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h
index 9304e62..427cc9e 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.h
+++ b/services/surfaceflinger/Scheduler/LayerInfo.h
@@ -70,8 +70,7 @@
sRefreshRateConfigs = &refreshRateConfigs;
}
- LayerInfo(const std::string& name, nsecs_t highRefreshRatePeriod,
- LayerHistory::LayerVoteType defaultVote);
+ LayerInfo(const std::string& name, LayerHistory::LayerVoteType defaultVote);
LayerInfo(const LayerInfo&) = delete;
LayerInfo& operator=(const LayerInfo&) = delete;
@@ -194,8 +193,9 @@
const std::string mName;
- // Used for sanitizing the heuristic data
- const nsecs_t mHighRefreshRatePeriod;
+ // Used for sanitizing the heuristic data. If two frames are less than
+ // this period apart from each other they'll be considered as duplicates.
+ static constexpr nsecs_t kMinPeriodBetweenFrames = Fps(120.f).getPeriodNsecs();
LayerHistory::LayerVoteType mDefaultVote;
LayerVote mLayerVote;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e5644c4..ab8bff1 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -551,23 +551,19 @@
void Scheduler::registerLayer(Layer* layer) {
if (!mLayerHistory) return;
- const auto maxFps = mRefreshRateConfigs.getMaxRefreshRate().getFps();
-
if (layer->getWindowType() == InputWindowInfo::Type::STATUS_BAR) {
- mLayerHistory->registerLayer(layer, maxFps, scheduler::LayerHistory::LayerVoteType::NoVote);
+ mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::NoVote);
} else if (!mOptions.useContentDetection) {
// If the content detection feature is off, all layers are registered at Max. We still keep
// the layer history, since we use it for other features (like Frame Rate API), so layers
// still need to be registered.
- mLayerHistory->registerLayer(layer, maxFps, scheduler::LayerHistory::LayerVoteType::Max);
+ mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::Max);
} else {
if (layer->getWindowType() == InputWindowInfo::Type::WALLPAPER) {
// Running Wallpaper at Min is considered as part of content detection.
- mLayerHistory->registerLayer(layer, maxFps,
- scheduler::LayerHistory::LayerVoteType::Min);
+ mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::Min);
} else {
- mLayerHistory->registerLayer(layer, maxFps,
- scheduler::LayerHistory::LayerVoteType::Heuristic);
+ mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::Heuristic);
}
}
}