SurfaceFlinger: fix setDesiredActiveConfig
setDesiredActiveConfig is trying to initiate a config change
even if the desired config is alreadt the active config. This creates
an issue where mVSyncModulator->onRefreshRateChangeInitiated() is called
but the counter part mVSyncModulator->onRefreshRateChangeCompleted()
is never called since the refresh rate never changed.
Test: collected systrace on taimen
Bug: 150647346
Change-Id: I2659183bf2a4e1676627d84379f4d533bdb9b5fc
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c995db4..27bd53c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -906,15 +906,24 @@
auto refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(info.configId);
ALOGV("setDesiredActiveConfig(%s)", refreshRate.name.c_str());
- // Don't check against the current mode yet. Worst case we set the desired
- // config twice. However event generation config might have changed so we need to update it
- // accordingly
std::lock_guard<std::mutex> lock(mActiveConfigLock);
- const Scheduler::ConfigEvent prevConfig = mDesiredActiveConfig.event;
- mDesiredActiveConfig = info;
- mDesiredActiveConfig.event = mDesiredActiveConfig.event | prevConfig;
+ if (mDesiredActiveConfigChanged) {
+ // If a config change is pending, just cache the latest request in
+ // mDesiredActiveConfig
+ const Scheduler::ConfigEvent prevConfig = mDesiredActiveConfig.event;
+ mDesiredActiveConfig = info;
+ mDesiredActiveConfig.event = mDesiredActiveConfig.event | prevConfig;
+ } else {
+ // Check is we are already at the desired config
+ const auto display = getDefaultDisplayDeviceLocked();
+ if (!display || display->getActiveConfig() == refreshRate.configId) {
+ return;
+ }
- if (!mDesiredActiveConfigChanged) {
+ // Initiate a config change.
+ mDesiredActiveConfigChanged = true;
+ mDesiredActiveConfig = info;
+
// This will trigger HWC refresh without resetting the idle timer.
repaintEverythingForHWC();
// Start receiving vsync samples now, so that we can detect a period
@@ -927,7 +936,6 @@
mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
}
- mDesiredActiveConfigChanged = true;
if (mRefreshRateOverlay) {
mRefreshRateOverlay->changeRefreshRate(refreshRate);