SF: DispSync should sync to activeConfig period
HWC@2.4 has the getDisplayVSyncPeriod method added, which was
being queried around rate-change events, and the returned value
was sent to the DispSync system as the period to synchronize to.
Some devices will have irregular vsync intervals coming out of certain
power-saving states, and the HWC was reporting an irregular vsync
period, relative to the activeConfig's period. This could manifest as
transient de-synchronization in DispSync (currently used code), and
in the VSyncReactor system (switched off) a bad rate would be adopted.
Fixes: 147734678
Test: uibench with VSyncReactor system
Test: uibench with DispSync system
Change-Id: Ia98b3f09893004b4420487385e0d1653dcfd2d8d
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 20b6238..1334a16 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -14,11 +14,13 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#undef LOG_TAG
#define LOG_TAG "VSyncReactor"
//#define LOG_NDEBUG 0
#include "VSyncReactor.h"
#include <log/log.h>
+#include <utils/Trace.h>
#include "TimeKeeper.h"
#include "VSyncDispatch.h"
#include "VSyncTracker.h"
@@ -186,6 +188,7 @@
}
void VSyncReactor::setPeriod(nsecs_t period) {
+ ATRACE_INT64("VSR-setPeriod", period);
std::lock_guard lk(mMutex);
mLastHwVsync.reset();
if (period == getPeriod()) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1796476..ed222a6 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -875,7 +875,7 @@
repaintEverythingForHWC();
// Start receiving vsync samples now, so that we can detect a period
// switch.
- mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
+ mScheduler->resyncToHardwareVsync(true, refreshRate.vsyncPeriod);
// As we called to set period, we will call to onRefreshRateChangeCompleted once
// DispSync model is locked.
mVSyncModulator->onRefreshRateChangeInitiated();
@@ -952,9 +952,9 @@
mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
mDesiredActiveConfigChanged = false;
- mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
- auto refreshRate =
+ auto const refreshRate =
mRefreshRateConfigs->getRefreshRateFromConfigId(mDesiredActiveConfig.configId);
+ mScheduler->resyncToHardwareVsync(true, refreshRate.vsyncPeriod);
mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
}