Reduce more power advisor churn
* Use chrono time types consistently to avoid a bug with comparing
milliseconds with nanoseconds
* Change the update imminent timeout callback to use a while loop
instead of an if-statement to guard against spurious wakeups.
Saves 2% of instructions and ~5% of cpu cycles
Bug: 231628914
Test: bouncy ball
Change-Id: Id61020e60825347dcf94794b92f8bc04c1455cfa
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index bfdf667..b5678b4 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -64,9 +64,10 @@
PowerAdvisor::~PowerAdvisor() = default;
namespace {
-int32_t getUpdateTimeout() {
+std::chrono::milliseconds getUpdateTimeout() {
// Default to a timeout of 80ms if nothing else is specified
- static int32_t timeout = sysprop::display_update_imminent_timeout_ms(80);
+ static std::chrono::milliseconds timeout =
+ std::chrono::milliseconds(sysprop::display_update_imminent_timeout_ms(80));
return timeout;
}
@@ -81,21 +82,23 @@
} // namespace
PowerAdvisor::PowerAdvisor(SurfaceFlinger& flinger) : mFlinger(flinger) {
- if (getUpdateTimeout()) {
- mScreenUpdateTimer.emplace("UpdateImminentTimer",
- OneShotTimer::Interval(getUpdateTimeout()),
+ if (getUpdateTimeout() > 0ms) {
+ mScreenUpdateTimer.emplace("UpdateImminentTimer", getUpdateTimeout(),
/* resetCallback */ nullptr,
/* timeoutCallback */
[this] {
- const nsecs_t timeSinceLastUpdate =
- systemTime() - mLastScreenUpdatedTime.load();
- if (timeSinceLastUpdate < getUpdateTimeout()) {
+ while (true) {
+ auto timeSinceLastUpdate = std::chrono::nanoseconds(
+ systemTime() - mLastScreenUpdatedTime.load());
+ if (timeSinceLastUpdate >= getUpdateTimeout()) {
+ break;
+ }
// We may try to disable expensive rendering and allow
// for sending DISPLAY_UPDATE_IMMINENT hints too early if
// we idled very shortly after updating the screen, so
// make sure we wait enough time.
- std::this_thread::sleep_for(std::chrono::nanoseconds(
- getUpdateTimeout() - timeSinceLastUpdate));
+ std::this_thread::sleep_for(getUpdateTimeout() -
+ timeSinceLastUpdate);
}
mSendUpdateImminent.store(true);
mFlinger.disableExpensiveRendering();