Support repurposing idle timer to work with kernel timer.
Idle timer would instead enable/disable hw vsyncs in accordance with
inactivity.
Bug: 130684082
Test: systrace
Change-Id: I289600fc41b7ded863c9486cf6c2ab6155b06550
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 88d2638..b91c66e 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -73,6 +73,7 @@
mEventControlThread = std::make_unique<impl::EventControlThread>(function);
mSetIdleTimerMs = set_idle_timer_ms(0);
+ mSupportKernelTimer = support_kernel_idle_timer(false);
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.set_idle_timer_ms", value, "0");
@@ -82,10 +83,20 @@
}
if (mSetIdleTimerMs > 0) {
- mIdleTimer =
- std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(mSetIdleTimerMs),
- [this] { resetTimerCallback(); },
- [this] { expiredTimerCallback(); });
+ if (mSupportKernelTimer) {
+ mIdleTimer =
+ std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(
+ mSetIdleTimerMs),
+ [this] { resetKernelTimerCallback(); },
+ [this] {
+ expiredKernelTimerCallback();
+ });
+ } else {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(
+ mSetIdleTimerMs),
+ [this] { resetTimerCallback(); },
+ [this] { expiredTimerCallback(); });
+ }
mIdleTimer->start();
}
}
@@ -344,6 +355,11 @@
mChangeRefreshRateCallback = changeRefreshRateCallback;
}
+void Scheduler::setGetVsyncPeriodCallback(const GetVsyncPeriod&& getVsyncPeriod) {
+ std::lock_guard<std::mutex> lock(mCallbackLock);
+ mGetVsyncPeriod = getVsyncPeriod;
+}
+
void Scheduler::updateFrameSkipping(const int64_t skipCount) {
ATRACE_INT("FrameSkipCount", skipCount);
if (mSkipCount != skipCount) {
@@ -360,17 +376,30 @@
}
void Scheduler::resetTimerCallback() {
- // We do not notify the applications about config changes when idle timer is reset.
timerChangeRefreshRate(IdleTimerState::RESET);
ATRACE_INT("ExpiredIdleTimer", 0);
}
+void Scheduler::resetKernelTimerCallback() {
+ ATRACE_INT("ExpiredKernelIdleTimer", 0);
+ std::lock_guard<std::mutex> lock(mCallbackLock);
+ if (mGetVsyncPeriod) {
+ resyncToHardwareVsync(false, mGetVsyncPeriod());
+ }
+}
+
void Scheduler::expiredTimerCallback() {
- // We do not notify the applications about config changes when idle timer expires.
timerChangeRefreshRate(IdleTimerState::EXPIRED);
ATRACE_INT("ExpiredIdleTimer", 1);
}
+void Scheduler::expiredKernelTimerCallback() {
+ ATRACE_INT("ExpiredKernelIdleTimer", 1);
+ // Disable HW Vsync if the timer expired, as we don't need it
+ // enabled if we're not pushing frames.
+ disableHardwareVsync(false);
+}
+
std::string Scheduler::doDump() {
std::ostringstream stream;
stream << "+ Idle timer interval: " << mSetIdleTimerMs << " ms" << std::endl;