SF: disable HW vsync while dozing
It cancels any in-progress resync when display goes to sleep, then
it avoids any unexpected wake up due to delayed frames once device
has just switched to ambient mode.
In DOZE_SUSPEND, screen displays a still image in a self-refresh mode,
so there is no need to keep aligned with HW vsync. At the opposite, DOZE
mode is used to refresh the screen in Ambient (i.e. watchface refresh,
nofications, app updates in ambi-active), hence resync SF to HW vsync.
Bug: 35998607
Bug: 36215242
Change-Id: I22cd8f84e9aca04b4f657fe07785751cf31a7c68
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 746d3d9..73f3f68 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3198,6 +3198,22 @@
getHwComposer().setPowerMode(type, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
+ } else if (mode == HWC_POWER_MODE_DOZE) {
+ // Update display while dozing
+ getHwComposer().setPowerMode(type, mode);
+ if (type == DisplayDevice::DISPLAY_PRIMARY) {
+ // FIXME: eventthread only knows about the main display right now
+ mEventThread->onScreenAcquired();
+ resyncToHardwareVsync(true);
+ }
+ } else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
+ // Leave display going to doze
+ if (type == DisplayDevice::DISPLAY_PRIMARY) {
+ disableHardwareVsync(true); // also cancels any in-progress resync
+ // FIXME: eventthread only knows about the main display right now
+ mEventThread->onScreenReleased();
+ }
+ getHwComposer().setPowerMode(type, mode);
} else {
getHwComposer().setPowerMode(type, mode);
}