1 /*
2  * Copyright 2018 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 <atomic>
20 #include <functional>
21 #include <memory>
22 #include <mutex>
23 #include <optional>
24 #include <unordered_map>
25 
26 // TODO(b/129481165): remove the #pragma below and fix conversion issues
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Wconversion"
29 #pragma clang diagnostic ignored "-Wextra"
30 #include <ui/GraphicTypes.h>
31 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
32 
33 #include "EventThread.h"
34 #include "LayerHistory.h"
35 #include "OneShotTimer.h"
36 #include "RefreshRateConfigs.h"
37 #include "SchedulerUtils.h"
38 
39 namespace android {
40 
41 using namespace std::chrono_literals;
42 using scheduler::LayerHistory;
43 
44 class FenceTime;
45 class InjectVSyncSource;
46 class PredictedVsyncTracer;
47 
48 namespace scheduler {
49 class VsyncController;
50 class VSyncDispatch;
51 class VSyncTracker;
52 } // namespace scheduler
53 
54 namespace frametimeline {
55 class TokenManager;
56 } // namespace frametimeline
57 
58 struct ISchedulerCallback {
59     virtual void setVsyncEnabled(bool) = 0;
60     virtual void changeRefreshRate(const scheduler::RefreshRateConfigs::RefreshRate&,
61                                    scheduler::RefreshRateConfigEvent) = 0;
62     virtual void repaintEverythingForHWC() = 0;
63     virtual void kernelTimerChanged(bool expired) = 0;
64     virtual void triggerOnFrameRateOverridesChanged() = 0;
65 
66 protected:
67     ~ISchedulerCallback() = default;
68 };
69 
70 class Scheduler {
71 public:
72     using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate;
73     using ModeEvent = scheduler::RefreshRateConfigEvent;
74 
75     Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&);
76     ~Scheduler();
77 
78     using ConnectionHandle = scheduler::ConnectionHandle;
79     ConnectionHandle createConnection(const char* connectionName, frametimeline::TokenManager*,
80                                       std::chrono::nanoseconds workDuration,
81                                       std::chrono::nanoseconds readyDuration,
82                                       impl::EventThread::InterceptVSyncsCallback);
83 
84     sp<IDisplayEventConnection> createDisplayEventConnection(
85             ConnectionHandle, ISurfaceComposer::EventRegistrationFlags eventRegistration = {});
86 
87     sp<EventThreadConnection> getEventConnection(ConnectionHandle);
88 
89     void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
90     void onPrimaryDisplayModeChanged(ConnectionHandle, DisplayModePtr) EXCLUDES(mFeatureStateLock);
91     void onNonPrimaryDisplayModeChanged(ConnectionHandle, DisplayModePtr);
92     void onScreenAcquired(ConnectionHandle);
93     void onScreenReleased(ConnectionHandle);
94 
95     void onFrameRateOverridesChanged(ConnectionHandle, PhysicalDisplayId)
96             EXCLUDES(mFrameRateOverridesLock) EXCLUDES(mConnectionsLock);
97 
98     // Modifies work duration in the event thread.
99     void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
100                      std::chrono::nanoseconds readyDuration);
101 
102     DisplayStatInfo getDisplayStatInfo(nsecs_t now);
103 
104     // Returns injector handle if injection has toggled, or an invalid handle otherwise.
105     ConnectionHandle enableVSyncInjection(bool enable);
106     // Returns false if injection is disabled.
107     bool injectVSync(nsecs_t when, nsecs_t expectedVSyncTime, nsecs_t deadlineTimestamp);
108     void enableHardwareVsync();
109     void disableHardwareVsync(bool makeUnavailable);
110 
111     // Resyncs the scheduler to hardware vsync.
112     // If makeAvailable is true, then hardware vsync will be turned on.
113     // Otherwise, if hardware vsync is not already enabled then this method will
114     // no-op.
115     // The period is the vsync period from the current display configuration.
116     void resyncToHardwareVsync(bool makeAvailable, nsecs_t period);
117     void resync() EXCLUDES(mRefreshRateConfigsLock);
118 
119     // Passes a vsync sample to VsyncController. periodFlushed will be true if
120     // VsyncController detected that the vsync period changed, and false otherwise.
121     void addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
122                          bool* periodFlushed);
123     void addPresentFence(const std::shared_ptr<FenceTime>&);
124     void setIgnorePresentFences(bool ignore);
125 
126     // Layers are registered on creation, and unregistered when the weak reference expires.
127     void registerLayer(Layer*);
128     void recordLayerHistory(Layer*, nsecs_t presentTime, LayerHistory::LayerUpdateType updateType)
129             EXCLUDES(mRefreshRateConfigsLock);
130     void setModeChangePending(bool pending);
131     void deregisterLayer(Layer*);
132 
133     // Detects content using layer history, and selects a matching refresh rate.
134     void chooseRefreshRateForContent() EXCLUDES(mRefreshRateConfigsLock);
135 
136     void resetIdleTimer();
137 
138     // Function that resets the touch timer.
139     void notifyTouchEvent();
140 
141     void setDisplayPowerState(bool normal);
142 
getVsyncDispatch()143     scheduler::VSyncDispatch& getVsyncDispatch() { return *mVsyncSchedule.dispatch; }
144 
145     // Returns true if a given vsync timestamp is considered valid vsync
146     // for a given uid
147     bool isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const
148             EXCLUDES(mFrameRateOverridesLock);
149 
150     std::chrono::steady_clock::time_point getPreviousVsyncFrom(nsecs_t expectedPresentTime) const;
151 
152     void dump(std::string&) const;
153     void dump(ConnectionHandle, std::string&) const;
154     void dumpVsync(std::string&) const;
155 
156     // Get the appropriate refresh for current conditions.
157     DisplayModePtr getPreferredDisplayMode();
158 
159     // Notifies the scheduler about a refresh rate timeline change.
160     void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline);
161 
162     // Notifies the scheduler when the display was refreshed
163     void onDisplayRefreshed(nsecs_t timestamp);
164 
165     // Notifies the scheduler when the display size has changed. Called from SF's main thread
166     void onActiveDisplayAreaChanged(uint32_t displayArea);
167 
168     size_t getEventThreadConnectionCount(ConnectionHandle handle);
169 
170     std::unique_ptr<VSyncSource> makePrimaryDispSyncSource(const char* name,
171                                                            std::chrono::nanoseconds workDuration,
172                                                            std::chrono::nanoseconds readyDuration,
173                                                            bool traceVsync = true);
174 
175     // Stores the preferred refresh rate that an app should run at.
176     // FrameRateOverride.refreshRateHz == 0 means no preference.
177     void setPreferredRefreshRateForUid(FrameRateOverride) EXCLUDES(mFrameRateOverridesLock);
178     // Retrieves the overridden refresh rate for a given uid.
179     std::optional<Fps> getFrameRateOverride(uid_t uid) const
180             EXCLUDES(mRefreshRateConfigsLock, mFrameRateOverridesLock);
181 
setRefreshRateConfigs(std::shared_ptr<scheduler::RefreshRateConfigs> refreshRateConfigs)182     void setRefreshRateConfigs(std::shared_ptr<scheduler::RefreshRateConfigs> refreshRateConfigs)
183             EXCLUDES(mRefreshRateConfigsLock) {
184         // We need to stop the idle timer on the previous RefreshRateConfigs instance
185         // and cleanup the scheduler's state before we switch to the other RefreshRateConfigs.
186         {
187             std::scoped_lock lock(mRefreshRateConfigsLock);
188             if (mRefreshRateConfigs) mRefreshRateConfigs->stopIdleTimer();
189         }
190         {
191             std::scoped_lock lock(mFeatureStateLock);
192             mFeatures = {};
193         }
194         {
195             std::scoped_lock lock(mRefreshRateConfigsLock);
196             mRefreshRateConfigs = std::move(refreshRateConfigs);
197             mRefreshRateConfigs->setIdleTimerCallbacks(
198                     [this] { std::invoke(&Scheduler::idleTimerCallback, this, TimerState::Reset); },
199                     [this] {
200                         std::invoke(&Scheduler::idleTimerCallback, this, TimerState::Expired);
201                     },
202                     [this] {
203                         std::invoke(&Scheduler::kernelIdleTimerCallback, this, TimerState::Reset);
204                     },
205                     [this] {
206                         std::invoke(&Scheduler::kernelIdleTimerCallback, this, TimerState::Expired);
207                     });
208             mRefreshRateConfigs->startIdleTimer();
209         }
210     }
211 
getVsyncPeriodFromRefreshRateConfigs()212     nsecs_t getVsyncPeriodFromRefreshRateConfigs() const EXCLUDES(mRefreshRateConfigsLock) {
213         std::scoped_lock lock(mRefreshRateConfigsLock);
214         return mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
215     }
216 
217 private:
218     friend class TestableScheduler;
219 
220     // In order to make sure that the features don't override themselves, we need a state machine
221     // to keep track which feature requested the config change.
222     enum class ContentDetectionState { Off, On };
223     enum class TimerState { Reset, Expired };
224     enum class TouchState { Inactive, Active };
225 
226     struct Options {
227         // Whether to use content detection at all.
228         bool useContentDetection;
229     };
230 
231     struct VsyncSchedule {
232         std::unique_ptr<scheduler::VsyncController> controller;
233         std::unique_ptr<scheduler::VSyncTracker> tracker;
234         std::unique_ptr<scheduler::VSyncDispatch> dispatch;
235     };
236 
237     // Unlike the testing constructor, this creates the VsyncSchedule, LayerHistory, and timers.
238     Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&, Options);
239 
240     // Used by tests to inject mocks.
241     Scheduler(VsyncSchedule, const std::shared_ptr<scheduler::RefreshRateConfigs>&,
242               ISchedulerCallback&, std::unique_ptr<LayerHistory>, Options);
243 
244     static VsyncSchedule createVsyncSchedule(bool supportKernelIdleTimer);
245     static std::unique_ptr<LayerHistory> createLayerHistory();
246 
247     // Create a connection on the given EventThread.
248     ConnectionHandle createConnection(std::unique_ptr<EventThread>);
249     sp<EventThreadConnection> createConnectionInternal(
250             EventThread*, ISurfaceComposer::EventRegistrationFlags eventRegistration = {});
251 
252     // Update feature state machine to given state when corresponding timer resets or expires.
253     void kernelIdleTimerCallback(TimerState) EXCLUDES(mRefreshRateConfigsLock);
254     void idleTimerCallback(TimerState);
255     void touchTimerCallback(TimerState);
256     void displayPowerTimerCallback(TimerState);
257 
258     // handles various timer features to change the refresh rate.
259     template <class T>
260     bool handleTimerStateChanged(T* currentState, T newState);
261 
262     void setVsyncPeriod(nsecs_t period);
263 
264     // This function checks whether individual features that are affecting the refresh rate
265     // selection were initialized, prioritizes them, and calculates the DisplayModeId
266     // for the suggested refresh rate.
267     DisplayModePtr calculateRefreshRateModeId(
268             scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals = nullptr)
269             REQUIRES(mFeatureStateLock);
270 
271     void dispatchCachedReportedMode() REQUIRES(mFeatureStateLock) EXCLUDES(mRefreshRateConfigsLock);
272     bool updateFrameRateOverrides(scheduler::RefreshRateConfigs::GlobalSignals consideredSignals,
273                                   Fps displayRefreshRate) REQUIRES(mFeatureStateLock)
274             EXCLUDES(mFrameRateOverridesLock);
275 
276     impl::EventThread::ThrottleVsyncCallback makeThrottleVsyncCallback() const
277             EXCLUDES(mRefreshRateConfigsLock);
278     impl::EventThread::GetVsyncPeriodFunction makeGetVsyncPeriodFunction() const;
279 
holdRefreshRateConfigs()280     std::shared_ptr<scheduler::RefreshRateConfigs> holdRefreshRateConfigs() const
281             EXCLUDES(mRefreshRateConfigsLock) {
282         std::scoped_lock lock(mRefreshRateConfigsLock);
283         return mRefreshRateConfigs;
284     }
285 
286     // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
287     struct Connection {
288         sp<EventThreadConnection> connection;
289         std::unique_ptr<EventThread> thread;
290     };
291 
292     ConnectionHandle::Id mNextConnectionHandleId = 0;
293     mutable std::mutex mConnectionsLock;
294     std::unordered_map<ConnectionHandle, Connection> mConnections GUARDED_BY(mConnectionsLock);
295 
296     bool mInjectVSyncs = false;
297     InjectVSyncSource* mVSyncInjector = nullptr;
298     ConnectionHandle mInjectorConnectionHandle;
299 
300     mutable std::mutex mHWVsyncLock;
301     bool mPrimaryHWVsyncEnabled GUARDED_BY(mHWVsyncLock) = false;
302     bool mHWVsyncAvailable GUARDED_BY(mHWVsyncLock) = false;
303 
304     std::atomic<nsecs_t> mLastResyncTime = 0;
305 
306     const Options mOptions;
307     VsyncSchedule mVsyncSchedule;
308 
309     // Used to choose refresh rate if content detection is enabled.
310     std::unique_ptr<LayerHistory> mLayerHistory;
311 
312     // Timer used to monitor touch events.
313     std::optional<scheduler::OneShotTimer> mTouchTimer;
314     // Timer used to monitor display power mode.
315     std::optional<scheduler::OneShotTimer> mDisplayPowerTimer;
316 
317     ISchedulerCallback& mSchedulerCallback;
318 
319     // In order to make sure that the features don't override themselves, we need a state machine
320     // to keep track which feature requested the config change.
321     mutable std::mutex mFeatureStateLock;
322 
323     struct {
324         TimerState idleTimer = TimerState::Reset;
325         TouchState touch = TouchState::Inactive;
326         TimerState displayPowerTimer = TimerState::Expired;
327 
328         DisplayModePtr mode;
329         LayerHistory::Summary contentRequirements;
330 
331         bool isDisplayPowerStateNormal = true;
332 
333         // Used to cache the last parameters of onPrimaryDisplayModeChanged
334         struct ModeChangedParams {
335             ConnectionHandle handle;
336             DisplayModePtr mode;
337         };
338 
339         std::optional<ModeChangedParams> cachedModeChangedParams;
340     } mFeatures GUARDED_BY(mFeatureStateLock);
341 
342     mutable std::mutex mRefreshRateConfigsLock;
343     std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs
344             GUARDED_BY(mRefreshRateConfigsLock);
345 
346     std::mutex mVsyncTimelineLock;
347     std::optional<hal::VsyncPeriodChangeTimeline> mLastVsyncPeriodChangeTimeline
348             GUARDED_BY(mVsyncTimelineLock);
349     static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms;
350 
351     const std::unique_ptr<PredictedVsyncTracer> mPredictedVsyncTracer;
352 
353     // The frame rate override lists need their own mutex as they are being read
354     // by SurfaceFlinger, Scheduler and EventThread (as a callback) to prevent deadlocks
355     mutable std::mutex mFrameRateOverridesLock;
356 
357     // mappings between a UID and a preferred refresh rate that this app would
358     // run at.
359     scheduler::RefreshRateConfigs::UidToFrameRateOverride mFrameRateOverridesByContent
360             GUARDED_BY(mFrameRateOverridesLock);
361     scheduler::RefreshRateConfigs::UidToFrameRateOverride mFrameRateOverridesFromBackdoor
362             GUARDED_BY(mFrameRateOverridesLock);
363 
364     // Keeps track of whether the screen is acquired for debug
365     std::atomic<bool> mScreenAcquired = false;
366 };
367 
368 } // namespace android
369