SF: Pull CompositorTiming constructor to libgui
Clean up the snapping logic and add tests.
Bug: 185535769
Test: libgui_test
Change-Id: I08302d7c08a0932787e66203873b6aa6ff9f7a78
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9f1cf9c..bb58eb4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2344,39 +2344,6 @@
return compositeToPresentLatency;
}
-CompositorTiming SurfaceFlinger::makeCompositorTiming(nsecs_t vsyncDeadline, nsecs_t vsyncPeriod,
- nsecs_t compositeToPresentLatency) {
- // Avoid division by 0 by defaulting to 60Hz
- vsyncPeriod = vsyncPeriod ?: (60_Hz).getPeriodNsecs();
-
- // Integer division and modulo round toward 0 not -inf, so we need to
- // treat negative and positive offsets differently.
- nsecs_t idealLatency = (mVsyncConfiguration->getCurrentConfigs().late.sfOffset > 0)
- ? (vsyncPeriod -
- (mVsyncConfiguration->getCurrentConfigs().late.sfOffset % vsyncPeriod))
- : ((-mVsyncConfiguration->getCurrentConfigs().late.sfOffset) % vsyncPeriod);
-
- // Just in case mVsyncConfiguration->getCurrentConfigs().late.sf == -vsyncInterval.
- if (idealLatency <= 0) {
- idealLatency = vsyncPeriod;
- }
-
- // 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
- // mVsyncConfiguration->getCurrentConfigs().late.sf with (presentLatency % interval).
- const nsecs_t bias = vsyncPeriod / 2;
- const int64_t extraVsyncs = ((compositeToPresentLatency - idealLatency + bias) / vsyncPeriod);
- const nsecs_t snappedCompositeToPresentLatency =
- (extraVsyncs > 0) ? idealLatency + (extraVsyncs * vsyncPeriod) : idealLatency;
-
- return {.deadline = vsyncDeadline - idealLatency,
- .interval = vsyncPeriod,
- .presentLatency = snappedCompositeToPresentLatency};
-}
-
bool SurfaceFlinger::isHdrLayer(Layer* layer) const {
// Treat all layers as non-HDR if:
// 1. They do not have a valid HDR dataspace. Currently we treat those as PQ or HLG. and
@@ -2463,7 +2430,7 @@
// We use the CompositionEngine::getLastFrameRefreshTimestamp() which might
// be sampled a little later than when we started doing work for this frame,
- // but that should be okay since makeCompositorTiming has snapping logic.
+ // but that should be okay since CompositorTiming has snapping logic.
const nsecs_t compositeTime = mCompositionEngine->getLastFrameRefreshTimestamp();
const nsecs_t presentLatency =
trackPresentLatency(compositeTime, mPreviousPresentFences[0].fenceTime);
@@ -2471,9 +2438,10 @@
const auto& schedule = mScheduler->getVsyncSchedule();
const TimePoint vsyncDeadline = schedule.vsyncDeadlineAfter(TimePoint::fromNs(now));
const Period vsyncPeriod = schedule.period();
+ const nsecs_t vsyncPhase = mVsyncConfiguration->getCurrentConfigs().late.sfOffset;
- const CompositorTiming compositorTiming =
- makeCompositorTiming(vsyncDeadline.ns(), vsyncPeriod.ns(), presentLatency);
+ const CompositorTiming compositorTiming(vsyncDeadline.ns(), vsyncPeriod.ns(), vsyncPhase,
+ presentLatency);
for (const auto& layer: mLayersWithQueuedFrames) {
layer->onPostComposition(display, glCompositionDoneFenceTime,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0e5386f..71b9d5e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -31,6 +31,7 @@
#include <ftl/future.h>
#include <ftl/small_map.h>
#include <gui/BufferQueue.h>
+#include <gui/CompositorTiming.h>
#include <gui/FrameTimestamps.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ITransactionCompletedListener.h>
@@ -958,9 +959,6 @@
// Returns the composite-to-present latency of the latest presented frame.
nsecs_t trackPresentLatency(nsecs_t compositeTime, std::shared_ptr<FenceTime> presentFenceTime);
- CompositorTiming makeCompositorTiming(nsecs_t vsyncDeadline, nsecs_t vsyncPeriod,
- nsecs_t compositeToPresentLatency);
-
void postFrame() REQUIRES(kMainThreadContext);
/*
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index 69ef2bf..40281a7 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -630,9 +630,6 @@
mFlinger->postComposition();
mFlinger->trackPresentLatency(mFdp.ConsumeIntegral<nsecs_t>(), FenceTime::NO_FENCE);
- mFlinger->makeCompositorTiming(mFdp.ConsumeIntegral<nsecs_t>(),
- mFdp.ConsumeIntegral<nsecs_t>(),
- mFdp.ConsumeIntegral<nsecs_t>());
FTL_FAKE_GUARD(kMainThreadContext, mFlinger->postFrame());
mFlinger->calculateExpectedPresentTime({});
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
index 4aef017..b0a8a51 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -117,17 +117,18 @@
sp<Fence> fence = sp<Fence>::make();
const std::shared_ptr<FenceTime> fenceTime = std::make_shared<FenceTime>(fence);
- const CompositorTiming compositor = {mFdp.ConsumeIntegral<int64_t>(),
- mFdp.ConsumeIntegral<int64_t>(),
- mFdp.ConsumeIntegral<int64_t>()};
+ const CompositorTiming compositorTiming(mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>());
layer->onLayerDisplayed(ftl::yield<FenceResult>(fence).share());
layer->onLayerDisplayed(
ftl::yield<FenceResult>(base::unexpected(mFdp.ConsumeIntegral<status_t>())).share());
layer->releasePendingBuffer(mFdp.ConsumeIntegral<int64_t>());
- layer->finalizeFrameEventHistory(fenceTime, compositor);
- layer->onPostComposition(nullptr, fenceTime, fenceTime, compositor);
+ layer->finalizeFrameEventHistory(fenceTime, compositorTiming);
+ layer->onPostComposition(nullptr, fenceTime, fenceTime, compositorTiming);
layer->isBufferDue(mFdp.ConsumeIntegral<int64_t>());
layer->setTransform(mFdp.ConsumeIntegral<uint32_t>());