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