summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h3
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h3
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Display.cpp5
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp2
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp7
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp2
7 files changed, 24 insertions, 0 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
index a0606b48f0..289cb119ca 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
@@ -79,6 +79,9 @@ struct CompositionRefreshArgs {
// If set, causes the dirty regions to flash with the delay
std::optional<std::chrono::microseconds> devOptFlashDirtyRegionsDelay;
+
+ // The earliest time to send the present command to the HAL
+ std::chrono::steady_clock::time_point earliestPresentTime;
};
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index 8f767d37f6..f0ef6d6e7d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -115,6 +115,9 @@ struct OutputCompositionState {
// Current target dataspace
ui::Dataspace targetDataspace{ui::Dataspace::UNKNOWN};
+ // The earliest time to send the present command to the HAL
+ std::chrono::steady_clock::time_point earliestPresentTime;
+
// Debugging
void dump(std::string& result) const;
};
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index a605fe1dc3..1ffb1c8e2d 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -367,6 +367,11 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
return fences;
}
+ {
+ ATRACE_NAME("wait for earliest present time");
+ std::this_thread::sleep_until(getState().earliestPresentTime);
+ }
+
auto& hwc = getCompositionEngine().getHwComposer();
hwc.presentAndGetReleaseFences(*halDisplayIdOpt);
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 3468b204fc..faa4b74c28 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -711,6 +711,8 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr
return;
}
+ editState().earliestPresentTime = refreshArgs.earliestPresentTime;
+
sp<GraphicBuffer> previousOverride = nullptr;
for (auto* layer : getOutputLayersOrderedByZ()) {
bool skipLayer = false;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 1d25c7247f..57bd045945 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -927,4 +927,11 @@ void Scheduler::setPreferredRefreshRateForUid(FrameRateOverride frameRateOverrid
}
}
+std::chrono::steady_clock::time_point Scheduler::getPreviousVsyncFrom(
+ nsecs_t expectedPresentTime) const {
+ const auto presentTime = std::chrono::nanoseconds(expectedPresentTime);
+ const auto vsyncPeriod = std::chrono::nanoseconds(mVsyncSchedule.tracker->currentPeriod());
+ return std::chrono::steady_clock::time_point(presentTime - vsyncPeriod);
+}
+
} // namespace android
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 4d1f3c6572..49d3d93f36 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -149,6 +149,8 @@ public:
bool isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const
EXCLUDES(mFrameRateOverridesMutex);
+ std::chrono::steady_clock::time_point getPreviousVsyncFrom(nsecs_t expectedPresentTime) const;
+
void dump(std::string&) const;
void dump(ConnectionHandle, std::string&) const;
void dumpVsync(std::string&) const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7076124754..1e3402a72d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1972,6 +1972,8 @@ void SurfaceFlinger::onMessageRefresh() {
std::chrono::milliseconds(mDebugRegion > 1 ? mDebugRegion : 0);
}
+ refreshArgs.earliestPresentTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime);
+
mGeometryInvalid = false;
// Store the present time just before calling to the composition engine so we could notify