blob: 722ea0b836099686e1a8096ce060e4a8c51f1f6d [file] [log] [blame]
Dominik Laskowski068173d2021-08-11 17:22:59 -07001/*
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
Dominik Laskowski66295432023-03-14 12:25:36 -040019#include <functional>
Dominik Laskowski068173d2021-08-11 17:22:59 -070020#include <memory>
21#include <string>
22
Leon Scroggins III58af6ed2023-02-13 15:24:20 -050023#include <android-base/thread_annotations.h>
Leon Scroggins IIIc275df42023-02-07 16:40:21 -050024#include <ThreadContext.h>
25#include <ftl/enum.h>
26#include <ftl/optional.h>
Dominik Laskowskie85d7fa2023-05-15 10:50:22 -040027#include <ui/DisplayId.h>
Dominik Laskowskic183eed2023-01-21 10:02:15 -050028
Dominik Laskowskib418dd72023-06-13 17:31:04 -040029#include <scheduler/Features.h>
30#include <scheduler/IVsyncSource.h>
31#include <scheduler/Time.h>
32
33#include "ThreadContext.h"
ramindanid4354a92023-10-02 15:11:09 -070034#include "VSyncTracker.h"
Dominik Laskowskib418dd72023-06-13 17:31:04 -040035
Ady Abraham011f8ba2022-11-22 15:09:07 -080036namespace android {
37class EventThreadTest;
Leon Scroggins III58af6ed2023-02-13 15:24:20 -050038class VsyncScheduleTest;
Ady Abraham011f8ba2022-11-22 15:09:07 -080039}
40
41namespace android::fuzz {
42class SchedulerFuzzer;
43}
44
Dominik Laskowski068173d2021-08-11 17:22:59 -070045namespace android::scheduler {
46
47// TODO(b/185535769): Rename classes, and remove aliases.
48class VSyncDispatch;
49class VSyncTracker;
50
51class VsyncController;
52using VsyncDispatch = VSyncDispatch;
53using VsyncTracker = VSyncTracker;
54
55// Schedule that synchronizes to hardware VSYNC of a physical display.
Dominik Laskowskib418dd72023-06-13 17:31:04 -040056class VsyncSchedule final : public IVsyncSource {
Dominik Laskowski068173d2021-08-11 17:22:59 -070057public:
Dominik Laskowski66295432023-03-14 12:25:36 -040058 using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>;
59
Ady Abrahamc585dba2023-11-15 18:41:35 -080060 VsyncSchedule(ftl::NonNull<DisplayModePtr> modePtr, FeatureFlags, RequestHardwareVsync,
61 IVsyncTrackerCallback&);
Dominik Laskowski068173d2021-08-11 17:22:59 -070062 ~VsyncSchedule();
63
Dominik Laskowskib418dd72023-06-13 17:31:04 -040064 // IVsyncSource overrides:
65 Period period() const override;
66 TimePoint vsyncDeadlineAfter(TimePoint) const override;
Ady Abraham3db8a3c2023-11-20 17:53:47 -080067 Period minFramePeriod() const override;
Dominik Laskowski5d164f22022-07-07 07:56:07 -070068
Ady Abrahamc585dba2023-11-15 18:41:35 -080069 // Inform the schedule that the display mode changed the schedule needs to recalibrate
70 // itself to the new vsync period. The schedule will end the period transition internally.
71 // This will enable hardware VSYNCs in order to calibrate.
Leon Scroggins IIIc275df42023-02-07 16:40:21 -050072 //
Ady Abrahamc585dba2023-11-15 18:41:35 -080073 // \param [in] DisplayModePtr The mode that the display is changing to.
Leon Scroggins III67388622023-02-06 20:36:20 -050074 // \param [in] force True to force a transition even if it is not a
75 // change.
Ady Abrahamc585dba2023-11-15 18:41:35 -080076 void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force);
Leon Scroggins IIIc275df42023-02-07 16:40:21 -050077
78 // Pass a VSYNC sample to VsyncController. Return true if
79 // VsyncController detected that the VSYNC period changed. Enable or disable
80 // hardware VSYNCs depending on whether more samples are needed.
Dominik Laskowski66295432023-03-14 12:25:36 -040081 bool addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod);
Leon Scroggins IIIc275df42023-02-07 16:40:21 -050082
Dominik Laskowski068173d2021-08-11 17:22:59 -070083 // TODO(b/185535769): Hide behind API.
84 const VsyncTracker& getTracker() const { return *mTracker; }
85 VsyncTracker& getTracker() { return *mTracker; }
86 VsyncController& getController() { return *mController; }
87
Leon Scroggins III67388622023-02-06 20:36:20 -050088 // TODO(b/185535769): Once these are hidden behind the API, they may no
89 // longer need to be shared_ptrs.
90 using DispatchPtr = std::shared_ptr<VsyncDispatch>;
91 using TrackerPtr = std::shared_ptr<VsyncTracker>;
92
Dominik Laskowski068173d2021-08-11 17:22:59 -070093 // TODO(b/185535769): Remove once VsyncSchedule owns all registrations.
Leon Scroggins III67388622023-02-06 20:36:20 -050094 DispatchPtr getDispatch() { return mDispatch; }
Dominik Laskowski068173d2021-08-11 17:22:59 -070095
96 void dump(std::string&) const;
97
Leon Scroggins IIIc275df42023-02-07 16:40:21 -050098 // Turn on hardware VSYNCs, unless mHwVsyncState is Disallowed, in which
99 // case this call is ignored.
Dominik Laskowski66295432023-03-14 12:25:36 -0400100 void enableHardwareVsync() EXCLUDES(mHwVsyncLock);
Leon Scroggins IIIc275df42023-02-07 16:40:21 -0500101
102 // Disable hardware VSYNCs. If `disallow` is true, future calls to
Leon Scroggins III67388622023-02-06 20:36:20 -0500103 // enableHardwareVsync are ineffective until isHardwareVsyncAllowed is
104 // called with `makeAllowed` set to true.
Dominik Laskowski66295432023-03-14 12:25:36 -0400105 void disableHardwareVsync(bool disallow) EXCLUDES(mHwVsyncLock);
Leon Scroggins IIIc275df42023-02-07 16:40:21 -0500106
107 // If true, enableHardwareVsync can enable hardware VSYNC (if not already
108 // enabled). If false, enableHardwareVsync does nothing.
109 bool isHardwareVsyncAllowed(bool makeAllowed) EXCLUDES(mHwVsyncLock);
110
111 void setPendingHardwareVsyncState(bool enabled) REQUIRES(kMainThreadContext);
112
113 bool getPendingHardwareVsyncState() const REQUIRES(kMainThreadContext);
114
Leon Scroggins III67388622023-02-06 20:36:20 -0500115protected:
116 using ControllerPtr = std::unique_ptr<VsyncController>;
117
Dominik Laskowski66295432023-03-14 12:25:36 -0400118 static void NoOpRequestHardwareVsync(PhysicalDisplayId, bool) {}
119
Leon Scroggins III67388622023-02-06 20:36:20 -0500120 // For tests.
Dominik Laskowski66295432023-03-14 12:25:36 -0400121 VsyncSchedule(PhysicalDisplayId, TrackerPtr, DispatchPtr, ControllerPtr,
122 RequestHardwareVsync = NoOpRequestHardwareVsync);
Leon Scroggins III67388622023-02-06 20:36:20 -0500123
Dominik Laskowski068173d2021-08-11 17:22:59 -0700124private:
125 friend class TestableScheduler;
Ady Abraham011f8ba2022-11-22 15:09:07 -0800126 friend class android::EventThreadTest;
Leon Scroggins III58af6ed2023-02-13 15:24:20 -0500127 friend class android::VsyncScheduleTest;
Ady Abraham011f8ba2022-11-22 15:09:07 -0800128 friend class android::fuzz::SchedulerFuzzer;
Dominik Laskowski068173d2021-08-11 17:22:59 -0700129
Ady Abrahamc585dba2023-11-15 18:41:35 -0800130 static TrackerPtr createTracker(ftl::NonNull<DisplayModePtr> modePtr, IVsyncTrackerCallback&);
Leon Scroggins III67388622023-02-06 20:36:20 -0500131 static DispatchPtr createDispatch(TrackerPtr);
132 static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700133
Dominik Laskowski66295432023-03-14 12:25:36 -0400134 void enableHardwareVsyncLocked() REQUIRES(mHwVsyncLock);
Leon Scroggins IIIc275df42023-02-07 16:40:21 -0500135
136 mutable std::mutex mHwVsyncLock;
137 enum class HwVsyncState {
138 // Hardware VSYNCs are currently enabled.
139 Enabled,
140
141 // Hardware VSYNCs are currently disabled. They can be enabled by a call
142 // to `enableHardwareVsync`.
143 Disabled,
144
145 // Hardware VSYNCs are not currently allowed (e.g. because the display
146 // is off).
147 Disallowed,
148
149 ftl_last = Disallowed,
150 };
151 HwVsyncState mHwVsyncState GUARDED_BY(mHwVsyncLock) = HwVsyncState::Disallowed;
152
153 // Pending state, in case an attempt is made to set the state while the
154 // device is off.
155 HwVsyncState mPendingHwVsyncState GUARDED_BY(kMainThreadContext) = HwVsyncState::Disabled;
156
Dominik Laskowski068173d2021-08-11 17:22:59 -0700157 class PredictedVsyncTracer;
158 using TracerPtr = std::unique_ptr<PredictedVsyncTracer>;
159
Leon Scroggins III67388622023-02-06 20:36:20 -0500160 const PhysicalDisplayId mId;
Dominik Laskowski66295432023-03-14 12:25:36 -0400161 const RequestHardwareVsync mRequestHardwareVsync;
Leon Scroggins IIIc275df42023-02-07 16:40:21 -0500162 const TrackerPtr mTracker;
163 const DispatchPtr mDispatch;
164 const ControllerPtr mController;
165 const TracerPtr mTracer;
Dominik Laskowski068173d2021-08-11 17:22:59 -0700166};
167
168} // namespace android::scheduler