Fix getFrameTimestamp test flakes.
This fixes both the dEQP CTS flakes relating to
compositor timing and the lib_gui test flakes that
don't initialize properly.
Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*
Bug: 35995043
Change-Id: If8e59f0dc9a916bab28bd1a36190cef9a56cb64f
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b93de7e..98f6a70 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1113,7 +1113,7 @@
}
void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
- std::lock_guard<std::mutex> lock(mCompositeTimingLock);
+ std::lock_guard<std::mutex> lock(mCompositorTimingLock);
*compositorTiming = mCompositorTiming;
}
@@ -1410,34 +1410,39 @@
mCompositePresentTimes.pop();
}
+ setCompositorTimingSnapped(
+ vsyncPhase, vsyncInterval, compositeToPresentLatency);
+}
+
+void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
+ nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
// Integer division and modulo round toward 0 not -inf, so we need to
// treat negative and positive offsets differently.
- nsecs_t idealLatency = (sfVsyncPhaseOffsetNs >= 0) ?
+ nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
(vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
((-sfVsyncPhaseOffsetNs) % vsyncInterval);
+ // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
+ if (idealLatency <= 0) {
+ idealLatency = vsyncInterval;
+ }
+
// Snap the latency to a value that removes scheduling jitter from the
// composition and present times, which often have >1ms of jitter.
// Reducing jitter is important if an app attempts to extrapolate
// something (such as user input) to an accurate diasplay time.
// Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
// with (presentLatency % interval).
- nsecs_t snappedCompositeToPresentLatency = -1;
- if (compositeToPresentLatency >= 0) {
- nsecs_t bias = vsyncInterval / 2;
- int64_t extraVsyncs =
- (compositeToPresentLatency - idealLatency + bias) /
- vsyncInterval;
- nsecs_t extraLatency = extraVsyncs * vsyncInterval;
- snappedCompositeToPresentLatency = idealLatency + extraLatency;
- }
+ nsecs_t bias = vsyncInterval / 2;
+ int64_t extraVsyncs =
+ (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
+ nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
+ idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
- std::lock_guard<std::mutex> lock(mCompositeTimingLock);
+ std::lock_guard<std::mutex> lock(mCompositorTimingLock);
mCompositorTiming.deadline = vsyncPhase - idealLatency;
mCompositorTiming.interval = vsyncInterval;
- if (snappedCompositeToPresentLatency >= 0) {
- mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
- }
+ mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
}
void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
@@ -1484,10 +1489,15 @@
// since updateCompositorTiming has snapping logic.
updateCompositorTiming(
vsyncPhase, vsyncInterval, refreshStartTime, displayFenceTime);
+ CompositorTiming compositorTiming;
+ {
+ std::lock_guard<std::mutex> lock(mCompositorTimingLock);
+ compositorTiming = mCompositorTiming;
+ }
mDrawingState.traverseInZOrder([&](Layer* layer) {
bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
- *presentFenceTime, *retireFenceTime, mCompositorTiming);
+ *presentFenceTime, *retireFenceTime, compositorTiming);
if (frameLatched) {
recordBufferingStats(layer->getName().string(),
layer->getOccupancyHistory(false));
@@ -2966,10 +2976,9 @@
const nsecs_t period = activeConfig->getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(period);
- {
- std::lock_guard<std::mutex> lock(mCompositeTimingLock);
- mCompositorTiming.interval = period;
- }
+ // Use phase of 0 since phase is not known.
+ // Use latency of 0, which will snap to the ideal latency.
+ setCompositorTimingSnapped(0, period, 0);
}
void SurfaceFlinger::initializeDisplays() {