SF: Move some Scheduler APIs to VsyncSchedule
Scheduler::getDisplayStatInfo forces callers to query both the deadline
and period, so split it into two VsyncSchedule APIs. Inline Scheduler::
getPreviousVsyncFrom.
Introduce <scheduler/Time.h> for type-safe, self-documenting wrappers
around std::chrono, which will gradually supersede nsecs_t (including
<scheduler/Fps.h> integration).
Clean up SF helpers for previous present fences. Remove the unnecessary
and inaccurate CompositorTiming initialization.
Bug: 185535769
Test: Perfetto timeline is green.
Change-Id: I22d8ad44ae37612e66f9d98fd4e7e1831951eb99
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index bbf4667..00250be 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -28,7 +28,6 @@
#include <ftl/fake_guard.h>
#include <gui/WindowInfo.h>
#include <system/window.h>
-#include <ui/DisplayStatInfo.h>
#include <utils/Timers.h>
#include <utils/Trace.h>
@@ -172,8 +171,7 @@
impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction() const {
return [this](uid_t uid) {
const Fps refreshRate = holdRefreshRateConfigs()->getActiveMode()->getFps();
- const auto currentPeriod =
- mVsyncSchedule->getTracker().currentPeriod() ?: refreshRate.getPeriodNsecs();
+ const nsecs_t currentPeriod = mVsyncSchedule->period().ns() ?: refreshRate.getPeriodNsecs();
const auto frameRate = getFrameRateOverride(uid);
if (!frameRate.has_value()) {
@@ -361,12 +359,6 @@
thread->setDuration(workDuration, readyDuration);
}
-DisplayStatInfo Scheduler::getDisplayStatInfo(nsecs_t now) {
- const auto vsyncTime = mVsyncSchedule->getTracker().nextAnticipatedVSyncTimeFrom(now);
- const auto vsyncPeriod = mVsyncSchedule->getTracker().currentPeriod();
- return DisplayStatInfo{.vsyncTime = vsyncTime, .vsyncPeriod = vsyncPeriod};
-}
-
ConnectionHandle Scheduler::enableVSyncInjection(bool enable) {
if (mInjectVSyncs == enable) {
return {};
@@ -776,11 +768,4 @@
mFrameRateOverrideMappings.setPreferredRefreshRateForUid(frameRateOverride);
}
-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->getTracker().currentPeriod());
- return std::chrono::steady_clock::time_point(presentTime - vsyncPeriod);
-}
-
} // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 587a773..444ec2a 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -32,9 +32,8 @@
#include <ui/GraphicTypes.h>
#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
-#include <ui/DisplayStatInfo.h>
-
#include <scheduler/Features.h>
+#include <scheduler/Time.h>
#include "EventThread.h"
#include "FrameRateOverrideMappings.h"
@@ -150,8 +149,6 @@
void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration);
- DisplayStatInfo getDisplayStatInfo(nsecs_t now);
-
// Returns injector handle if injection has toggled, or an invalid handle otherwise.
ConnectionHandle enableVSyncInjection(bool enable);
// Returns false if injection is disabled.
@@ -190,14 +187,12 @@
void setDisplayPowerMode(hal::PowerMode powerMode);
- VSyncDispatch& getVsyncDispatch() { return mVsyncSchedule->getDispatch(); }
+ VsyncSchedule& getVsyncSchedule() { return *mVsyncSchedule; }
// Returns true if a given vsync timestamp is considered valid vsync
// for a given uid
bool isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const;
- 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/Scheduler/VsyncSchedule.cpp b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
index 3a918a1..95bc31f 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
@@ -68,6 +68,14 @@
VsyncSchedule::VsyncSchedule(VsyncSchedule&&) = default;
VsyncSchedule::~VsyncSchedule() = default;
+Period VsyncSchedule::period() const {
+ return Period::fromNs(mTracker->currentPeriod());
+}
+
+TimePoint VsyncSchedule::vsyncDeadlineAfter(TimePoint timePoint) const {
+ return TimePoint::fromNs(mTracker->nextAnticipatedVSyncTimeFrom(timePoint.ns()));
+}
+
void VsyncSchedule::dump(std::string& out) const {
out.append("VsyncController:\n");
mController->dump(out);
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.h b/services/surfaceflinger/Scheduler/VsyncSchedule.h
index 0d9b114..8c17409 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.h
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.h
@@ -20,6 +20,7 @@
#include <string>
#include <scheduler/Features.h>
+#include <scheduler/Time.h>
namespace android::scheduler {
@@ -38,6 +39,9 @@
VsyncSchedule(VsyncSchedule&&);
~VsyncSchedule();
+ Period period() const;
+ TimePoint vsyncDeadlineAfter(TimePoint) const;
+
// TODO(b/185535769): Hide behind API.
const VsyncTracker& getTracker() const { return *mTracker; }
VsyncTracker& getTracker() { return *mTracker; }
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Time.h b/services/surfaceflinger/Scheduler/include/scheduler/Time.h
new file mode 100644
index 0000000..6fa548e
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/include/scheduler/Time.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <chrono>
+
+#include <utils/Timers.h>
+
+namespace android {
+namespace scheduler {
+
+// TODO(b/185535769): Pull Clock.h to libscheduler to reuse this.
+using SchedulerClock = std::chrono::high_resolution_clock;
+static_assert(SchedulerClock::is_steady);
+
+} // namespace scheduler
+
+struct Duration;
+
+struct TimePoint : scheduler::SchedulerClock::time_point {
+ explicit TimePoint(const Duration&);
+
+ // Implicit conversion from std::chrono counterpart.
+ constexpr TimePoint(scheduler::SchedulerClock::time_point p)
+ : scheduler::SchedulerClock::time_point(p) {}
+
+ static TimePoint fromNs(nsecs_t);
+
+ nsecs_t ns() const;
+};
+
+struct Duration : TimePoint::duration {
+ // Implicit conversion from std::chrono counterpart.
+ constexpr Duration(TimePoint::duration d) : TimePoint::duration(d) {}
+
+ static Duration fromNs(nsecs_t ns) { return {std::chrono::nanoseconds(ns)}; }
+
+ nsecs_t ns() const { return std::chrono::nanoseconds(*this).count(); }
+};
+
+using Period = Duration;
+
+inline TimePoint::TimePoint(const Duration& d) : scheduler::SchedulerClock::time_point(d) {}
+
+inline TimePoint TimePoint::fromNs(nsecs_t ns) {
+ return TimePoint(Duration::fromNs(ns));
+}
+
+inline nsecs_t TimePoint::ns() const {
+ return Duration(time_since_epoch()).ns();
+}
+
+} // namespace android