xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Scheduler/VsyncSchedule.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2021 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <functional>
20*38e8c45fSAndroid Build Coastguard Worker #include <memory>
21*38e8c45fSAndroid Build Coastguard Worker #include <string>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <ThreadContext.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <ftl/enum.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <ftl/optional.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayId.h>
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/Features.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/IVsyncSource.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/Time.h>
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker #include "ThreadContext.h"
34*38e8c45fSAndroid Build Coastguard Worker #include "VSyncTracker.h"
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker namespace android {
37*38e8c45fSAndroid Build Coastguard Worker class EventThreadTest;
38*38e8c45fSAndroid Build Coastguard Worker class VsyncScheduleTest;
39*38e8c45fSAndroid Build Coastguard Worker }
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker namespace android::fuzz {
42*38e8c45fSAndroid Build Coastguard Worker class SchedulerFuzzer;
43*38e8c45fSAndroid Build Coastguard Worker }
44*38e8c45fSAndroid Build Coastguard Worker 
45*38e8c45fSAndroid Build Coastguard Worker namespace android::scheduler {
46*38e8c45fSAndroid Build Coastguard Worker 
47*38e8c45fSAndroid Build Coastguard Worker // TODO(b/185535769): Rename classes, and remove aliases.
48*38e8c45fSAndroid Build Coastguard Worker class VSyncDispatch;
49*38e8c45fSAndroid Build Coastguard Worker class VSyncTracker;
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker class VsyncController;
52*38e8c45fSAndroid Build Coastguard Worker using VsyncDispatch = VSyncDispatch;
53*38e8c45fSAndroid Build Coastguard Worker using VsyncTracker = VSyncTracker;
54*38e8c45fSAndroid Build Coastguard Worker 
55*38e8c45fSAndroid Build Coastguard Worker // Schedule that synchronizes to hardware VSYNC of a physical display.
56*38e8c45fSAndroid Build Coastguard Worker class VsyncSchedule final : public IVsyncSource {
57*38e8c45fSAndroid Build Coastguard Worker public:
58*38e8c45fSAndroid Build Coastguard Worker     using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>;
59*38e8c45fSAndroid Build Coastguard Worker 
60*38e8c45fSAndroid Build Coastguard Worker     VsyncSchedule(ftl::NonNull<DisplayModePtr> modePtr, FeatureFlags, RequestHardwareVsync);
61*38e8c45fSAndroid Build Coastguard Worker     ~VsyncSchedule();
62*38e8c45fSAndroid Build Coastguard Worker 
63*38e8c45fSAndroid Build Coastguard Worker     // IVsyncSource overrides:
64*38e8c45fSAndroid Build Coastguard Worker     Period period() const override;
65*38e8c45fSAndroid Build Coastguard Worker     TimePoint vsyncDeadlineAfter(TimePoint,
66*38e8c45fSAndroid Build Coastguard Worker                                  ftl::Optional<TimePoint> lastVsyncOpt = {}) const override;
67*38e8c45fSAndroid Build Coastguard Worker     Period minFramePeriod() const override;
68*38e8c45fSAndroid Build Coastguard Worker 
69*38e8c45fSAndroid Build Coastguard Worker     // Inform the schedule that the display mode changed the schedule needs to recalibrate
70*38e8c45fSAndroid Build Coastguard Worker     // itself to the new vsync period. The schedule will end the period transition internally.
71*38e8c45fSAndroid Build Coastguard Worker     // This will enable hardware VSYNCs in order to calibrate.
72*38e8c45fSAndroid Build Coastguard Worker     //
73*38e8c45fSAndroid Build Coastguard Worker     // \param [in] DisplayModePtr  The mode that the display is changing to.
74*38e8c45fSAndroid Build Coastguard Worker     // \param [in] force    True to force a transition even if it is not a
75*38e8c45fSAndroid Build Coastguard Worker     //                      change.
76*38e8c45fSAndroid Build Coastguard Worker     void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force);
77*38e8c45fSAndroid Build Coastguard Worker 
78*38e8c45fSAndroid Build Coastguard Worker     // Pass a VSYNC sample to VsyncController. Return true if
79*38e8c45fSAndroid Build Coastguard Worker     // VsyncController detected that the VSYNC period changed. Enable or disable
80*38e8c45fSAndroid Build Coastguard Worker     // hardware VSYNCs depending on whether more samples are needed.
81*38e8c45fSAndroid Build Coastguard Worker     bool addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod);
82*38e8c45fSAndroid Build Coastguard Worker 
83*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/185535769): Hide behind API.
getTracker()84*38e8c45fSAndroid Build Coastguard Worker     VsyncTracker& getTracker() const { return *mTracker; }
getTracker()85*38e8c45fSAndroid Build Coastguard Worker     VsyncTracker& getTracker() { return *mTracker; }
getController()86*38e8c45fSAndroid Build Coastguard Worker     VsyncController& getController() { return *mController; }
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/185535769): Once these are hidden behind the API, they may no
89*38e8c45fSAndroid Build Coastguard Worker     // longer need to be shared_ptrs.
90*38e8c45fSAndroid Build Coastguard Worker     using DispatchPtr = std::shared_ptr<VsyncDispatch>;
91*38e8c45fSAndroid Build Coastguard Worker     using TrackerPtr = std::shared_ptr<VsyncTracker>;
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/185535769): Remove once VsyncSchedule owns all registrations.
getDispatch()94*38e8c45fSAndroid Build Coastguard Worker     DispatchPtr getDispatch() { return mDispatch; }
95*38e8c45fSAndroid Build Coastguard Worker 
96*38e8c45fSAndroid Build Coastguard Worker     void dump(std::string&) const;
97*38e8c45fSAndroid Build Coastguard Worker 
98*38e8c45fSAndroid Build Coastguard Worker     // Turn on hardware VSYNCs, unless mHwVsyncState is Disallowed, in which
99*38e8c45fSAndroid Build Coastguard Worker     // case this call is ignored.
100*38e8c45fSAndroid Build Coastguard Worker     void enableHardwareVsync() EXCLUDES(mHwVsyncLock);
101*38e8c45fSAndroid Build Coastguard Worker 
102*38e8c45fSAndroid Build Coastguard Worker     // Disable hardware VSYNCs. If `disallow` is true, future calls to
103*38e8c45fSAndroid Build Coastguard Worker     // enableHardwareVsync are ineffective until isHardwareVsyncAllowed is
104*38e8c45fSAndroid Build Coastguard Worker     // called with `makeAllowed` set to true.
105*38e8c45fSAndroid Build Coastguard Worker     void disableHardwareVsync(bool disallow) EXCLUDES(mHwVsyncLock);
106*38e8c45fSAndroid Build Coastguard Worker 
107*38e8c45fSAndroid Build Coastguard Worker     // If true, enableHardwareVsync can enable hardware VSYNC (if not already
108*38e8c45fSAndroid Build Coastguard Worker     // enabled). If false, enableHardwareVsync does nothing.
109*38e8c45fSAndroid Build Coastguard Worker     bool isHardwareVsyncAllowed(bool makeAllowed) EXCLUDES(mHwVsyncLock);
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker     void setPendingHardwareVsyncState(bool enabled) REQUIRES(kMainThreadContext);
112*38e8c45fSAndroid Build Coastguard Worker 
113*38e8c45fSAndroid Build Coastguard Worker     bool getPendingHardwareVsyncState() const REQUIRES(kMainThreadContext);
114*38e8c45fSAndroid Build Coastguard Worker 
getPhysicalDisplayId()115*38e8c45fSAndroid Build Coastguard Worker     PhysicalDisplayId getPhysicalDisplayId() const { return mId; }
116*38e8c45fSAndroid Build Coastguard Worker 
117*38e8c45fSAndroid Build Coastguard Worker protected:
118*38e8c45fSAndroid Build Coastguard Worker     using ControllerPtr = std::unique_ptr<VsyncController>;
119*38e8c45fSAndroid Build Coastguard Worker 
NoOpRequestHardwareVsync(PhysicalDisplayId,bool)120*38e8c45fSAndroid Build Coastguard Worker     static void NoOpRequestHardwareVsync(PhysicalDisplayId, bool) {}
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker     // For tests.
123*38e8c45fSAndroid Build Coastguard Worker     VsyncSchedule(PhysicalDisplayId, TrackerPtr, DispatchPtr, ControllerPtr,
124*38e8c45fSAndroid Build Coastguard Worker                   RequestHardwareVsync = NoOpRequestHardwareVsync);
125*38e8c45fSAndroid Build Coastguard Worker 
126*38e8c45fSAndroid Build Coastguard Worker private:
127*38e8c45fSAndroid Build Coastguard Worker     friend class TestableScheduler;
128*38e8c45fSAndroid Build Coastguard Worker     friend class android::EventThreadTest;
129*38e8c45fSAndroid Build Coastguard Worker     friend class android::VsyncScheduleTest;
130*38e8c45fSAndroid Build Coastguard Worker     friend class android::fuzz::SchedulerFuzzer;
131*38e8c45fSAndroid Build Coastguard Worker 
132*38e8c45fSAndroid Build Coastguard Worker     static TrackerPtr createTracker(ftl::NonNull<DisplayModePtr> modePtr);
133*38e8c45fSAndroid Build Coastguard Worker     static DispatchPtr createDispatch(TrackerPtr);
134*38e8c45fSAndroid Build Coastguard Worker     static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags);
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker     void enableHardwareVsyncLocked() REQUIRES(mHwVsyncLock);
137*38e8c45fSAndroid Build Coastguard Worker 
138*38e8c45fSAndroid Build Coastguard Worker     mutable std::mutex mHwVsyncLock;
139*38e8c45fSAndroid Build Coastguard Worker     enum class HwVsyncState {
140*38e8c45fSAndroid Build Coastguard Worker         // Hardware VSYNCs are currently enabled.
141*38e8c45fSAndroid Build Coastguard Worker         Enabled,
142*38e8c45fSAndroid Build Coastguard Worker 
143*38e8c45fSAndroid Build Coastguard Worker         // Hardware VSYNCs are currently disabled. They can be enabled by a call
144*38e8c45fSAndroid Build Coastguard Worker         // to `enableHardwareVsync`.
145*38e8c45fSAndroid Build Coastguard Worker         Disabled,
146*38e8c45fSAndroid Build Coastguard Worker 
147*38e8c45fSAndroid Build Coastguard Worker         // Hardware VSYNCs are not currently allowed (e.g. because the display
148*38e8c45fSAndroid Build Coastguard Worker         // is off).
149*38e8c45fSAndroid Build Coastguard Worker         Disallowed,
150*38e8c45fSAndroid Build Coastguard Worker 
151*38e8c45fSAndroid Build Coastguard Worker         ftl_last = Disallowed,
152*38e8c45fSAndroid Build Coastguard Worker     };
153*38e8c45fSAndroid Build Coastguard Worker     HwVsyncState mHwVsyncState GUARDED_BY(mHwVsyncLock) = HwVsyncState::Disallowed;
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker     // Pending state, in case an attempt is made to set the state while the
156*38e8c45fSAndroid Build Coastguard Worker     // device is off.
157*38e8c45fSAndroid Build Coastguard Worker     HwVsyncState mPendingHwVsyncState GUARDED_BY(kMainThreadContext) = HwVsyncState::Disabled;
158*38e8c45fSAndroid Build Coastguard Worker 
159*38e8c45fSAndroid Build Coastguard Worker     class PredictedVsyncTracer;
160*38e8c45fSAndroid Build Coastguard Worker     using TracerPtr = std::unique_ptr<PredictedVsyncTracer>;
161*38e8c45fSAndroid Build Coastguard Worker 
162*38e8c45fSAndroid Build Coastguard Worker     const PhysicalDisplayId mId;
163*38e8c45fSAndroid Build Coastguard Worker     const RequestHardwareVsync mRequestHardwareVsync;
164*38e8c45fSAndroid Build Coastguard Worker     const TrackerPtr mTracker;
165*38e8c45fSAndroid Build Coastguard Worker     const DispatchPtr mDispatch;
166*38e8c45fSAndroid Build Coastguard Worker     const ControllerPtr mController;
167*38e8c45fSAndroid Build Coastguard Worker     const TracerPtr mTracer;
168*38e8c45fSAndroid Build Coastguard Worker };
169*38e8c45fSAndroid Build Coastguard Worker 
170*38e8c45fSAndroid Build Coastguard Worker } // namespace android::scheduler
171