SurfaceFlinger: update the refresh rate overlay based on kernel idle timer
The frameworks maintains its own copy of inactivity timer to track the
kernel idle timer. Update the refresh rate overlay based on that timer.
Test: Enable refresh rate overlay from developer options
Bug: 149710432
Change-Id: I6c50d64575149317106f72fecdd50cef4e08db6a
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 3a44332..a0d63ba 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -512,6 +512,8 @@
// need to update the DispSync model anyway.
disableHardwareVsync(false /* makeUnavailable */);
}
+
+ mSchedulerCallback.kernelTimerChanged(state == TimerState::Expired);
}
void Scheduler::idleTimerCallback(TimerState state) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 46d1a5e..6ffda78 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -51,6 +51,7 @@
virtual void changeRefreshRate(const scheduler::RefreshRateConfigs::RefreshRate&,
scheduler::RefreshRateConfigEvent) = 0;
virtual void repaintEverythingForHWC() = 0;
+ virtual void kernelTimerChanged(bool expired) = 0;
};
class Scheduler {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ce0a8a1..cf5e0ec 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -216,6 +216,7 @@
const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
const String16 sDump("android.permission.DUMP");
+const char* KERNEL_IDLE_TIMER_PROP = "vendor.display.enable_kernel_idle_timer";
// ---------------------------------------------------------------------------
int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
@@ -5106,6 +5107,36 @@
mEventQueue->invalidate();
}
+void SurfaceFlinger::kernelTimerChanged(bool expired) {
+ static bool updateOverlay =
+ property_get_bool("debug.sf.kernel_idle_timer_update_overlay", true);
+ if (!updateOverlay || !mRefreshRateOverlay) return;
+
+ // Update the overlay on the main thread to avoid race conditions with
+ // mRefreshRateConfigs->getCurrentRefreshRate()
+ postMessageAsync(new LambdaMessage([this, expired]() NO_THREAD_SAFETY_ANALYSIS {
+ if (mRefreshRateOverlay) {
+ const auto kernelTimerEnabled = property_get_bool(KERNEL_IDLE_TIMER_PROP, false);
+ const bool timerExpired = kernelTimerEnabled && expired;
+ const auto& current = [this]() {
+ std::lock_guard<std::mutex> lock(mActiveConfigLock);
+ if (mDesiredActiveConfigChanged) {
+ return mRefreshRateConfigs->getRefreshRateFromConfigId(
+ mDesiredActiveConfig.configId);
+ }
+
+ return mRefreshRateConfigs->getCurrentRefreshRate();
+ }();
+ const auto& min = mRefreshRateConfigs->getMinRefreshRate();
+
+ if (current != min) {
+ mRefreshRateOverlay->changeRefreshRate(timerExpired ? min : current);
+ mEventQueue->invalidate();
+ }
+ }
+ }));
+}
+
// A simple RAII class to disconnect from an ANativeWindow* when it goes out of scope
class WindowDisconnector {
public:
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c79621b..07232d4 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -524,6 +524,8 @@
void changeRefreshRate(const Scheduler::RefreshRate&, Scheduler::ConfigEvent) override;
// force full composition on all displays without resetting the scheduler idle timer.
void repaintEverythingForHWC() override;
+ // Called when kernel idle timer has expired. Used to update the refresh rate overlay.
+ void kernelTimerChanged(bool expired) override;
/* ------------------------------------------------------------------------
* Message handling
*/
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 52da34b..b0b51bd 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -92,6 +92,7 @@
private:
void changeRefreshRate(const RefreshRate&, ConfigEvent) override {}
void repaintEverythingForHWC() override {}
+ void kernelTimerChanged(bool /*expired*/) override {}
};
} // namespace android