• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 <algorithm>
20 #include <numeric>
21 #include <set>
22 #include <type_traits>
23 #include <utility>
24 #include <variant>
25 
26 #include <ftl/concat.h>
27 #include <ftl/optional.h>
28 #include <ftl/unit.h>
29 #include <gui/DisplayEventReceiver.h>
30 
31 #include <scheduler/Fps.h>
32 #include <scheduler/FrameRateMode.h>
33 #include <scheduler/Seamlessness.h>
34 
35 #include "DisplayHardware/DisplayMode.h"
36 #include "Scheduler/OneShotTimer.h"
37 #include "Scheduler/StrongTyping.h"
38 #include "ThreadContext.h"
39 #include "Utils/Dumper.h"
40 
41 namespace android::scheduler {
42 
43 using namespace std::chrono_literals;
44 
45 enum class DisplayModeEvent : unsigned { None = 0b0, Changed = 0b1 };
46 
47 inline DisplayModeEvent operator|(DisplayModeEvent lhs, DisplayModeEvent rhs) {
48     using T = std::underlying_type_t<DisplayModeEvent>;
49     return static_cast<DisplayModeEvent>(static_cast<T>(lhs) | static_cast<T>(rhs));
50 }
51 
52 using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
53 
54 // Selects the refresh rate of a display by ranking its `DisplayModes` in accordance with
55 // the DisplayManager (or override) `Policy`, the `LayerRequirement` of each active layer,
56 // and `GlobalSignals`.
57 class RefreshRateSelector {
58 public:
59     // Margin used when matching refresh rates to the content desired ones.
60     static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION =
61             std::chrono::nanoseconds(800us).count();
62 
63     // The lowest Render Frame Rate that will ever be selected
64     static constexpr Fps kMinSupportedFrameRate = 20_Hz;
65 
66     class Policy {
67         static constexpr int kAllowGroupSwitchingDefault = false;
68 
69     public:
70         // The default mode, used to ensure we only initiate display mode switches within the
71         // same mode group as defaultMode's group.
72         DisplayModeId defaultMode;
73         // Whether or not we switch mode groups to get the best frame rate.
74         bool allowGroupSwitching = kAllowGroupSwitchingDefault;
75         // The primary refresh rate ranges. @see DisplayModeSpecs.aidl for details.
76         // TODO(b/257072060): use the render range when selecting SF render rate
77         //  or the app override frame rate
78         FpsRanges primaryRanges;
79         // The app request refresh rate ranges. @see DisplayModeSpecs.aidl for details.
80         FpsRanges appRequestRanges;
81 
82         Policy() = default;
83 
84         Policy(DisplayModeId defaultMode, FpsRange range,
85                bool allowGroupSwitching = kAllowGroupSwitchingDefault)
Policy(defaultMode,FpsRanges{range, range},FpsRanges{range, range},allowGroupSwitching)86               : Policy(defaultMode, FpsRanges{range, range}, FpsRanges{range, range},
87                        allowGroupSwitching) {}
88 
89         Policy(DisplayModeId defaultMode, FpsRanges primaryRanges, FpsRanges appRequestRanges,
90                bool allowGroupSwitching = kAllowGroupSwitchingDefault)
defaultMode(defaultMode)91               : defaultMode(defaultMode),
92                 allowGroupSwitching(allowGroupSwitching),
93                 primaryRanges(primaryRanges),
94                 appRequestRanges(appRequestRanges) {}
95 
96         bool operator==(const Policy& other) const {
97             using namespace fps_approx_ops;
98             return defaultMode == other.defaultMode && primaryRanges == other.primaryRanges &&
99                     appRequestRanges == other.appRequestRanges &&
100                     allowGroupSwitching == other.allowGroupSwitching;
101         }
102 
103         bool operator!=(const Policy& other) const { return !(*this == other); }
104 
primaryRangeIsSingleRate()105         bool primaryRangeIsSingleRate() const {
106             return isApproxEqual(primaryRanges.physical.min, primaryRanges.physical.max);
107         }
108 
109         std::string toString() const;
110     };
111 
112     enum class SetPolicyResult { Invalid, Unchanged, Changed };
113 
114     // We maintain the display manager policy and the override policy separately. The override
115     // policy is used by CTS tests to get a consistent device state for testing. While the override
116     // policy is set, it takes precedence over the display manager policy. Once the override policy
117     // is cleared, we revert to using the display manager policy.
118     struct DisplayManagerPolicy : Policy {
119         using Policy::Policy;
120     };
121 
122     struct OverridePolicy : Policy {
123         using Policy::Policy;
124     };
125 
126     struct NoOverridePolicy {};
127 
128     using PolicyVariant = std::variant<DisplayManagerPolicy, OverridePolicy, NoOverridePolicy>;
129 
130     SetPolicyResult setPolicy(const PolicyVariant&) EXCLUDES(mLock) REQUIRES(kMainThreadContext);
131 
onModeChangeInitiated()132     void onModeChangeInitiated() REQUIRES(kMainThreadContext) { mNumModeSwitchesInPolicy++; }
133 
134     // Gets the current policy, which will be the override policy if active, and the display manager
135     // policy otherwise.
136     Policy getCurrentPolicy() const EXCLUDES(mLock);
137     // Gets the display manager policy, regardless of whether an override policy is active.
138     Policy getDisplayManagerPolicy() const EXCLUDES(mLock);
139 
140     // Returns true if mode is allowed by the current policy.
141     bool isModeAllowed(const FrameRateMode&) const EXCLUDES(mLock);
142 
143     // Describes the different options the layer voted for refresh rate
144     enum class LayerVoteType {
145         NoVote,          // Doesn't care about the refresh rate
146         Min,             // Minimal refresh rate available
147         Max,             // Maximal refresh rate available
148         Heuristic,       // Specific refresh rate that was calculated by platform using a heuristic
149         ExplicitDefault, // Specific refresh rate that was provided by the app with Default
150                          // compatibility
151         ExplicitExactOrMultiple, // Specific refresh rate that was provided by the app with
152                                  // ExactOrMultiple compatibility
153         ExplicitExact,           // Specific refresh rate that was provided by the app with
154                                  // Exact compatibility
155 
156         ftl_last = ExplicitExact
157     };
158 
159     // Captures the layer requirements for a refresh rate. This will be used to determine the
160     // display refresh rate.
161     struct LayerRequirement {
162         // Layer's name. Used for debugging purposes.
163         std::string name;
164         // Layer's owner uid
165         uid_t ownerUid = static_cast<uid_t>(-1);
166         // Layer vote type.
167         LayerVoteType vote = LayerVoteType::NoVote;
168         // Layer's desired refresh rate, if applicable.
169         Fps desiredRefreshRate;
170         // If a seamless mode switch is required.
171         Seamlessness seamlessness = Seamlessness::Default;
172         // Layer's weight in the range of [0, 1]. The higher the weight the more impact this layer
173         // would have on choosing the refresh rate.
174         float weight = 0.0f;
175         // Whether layer is in focus or not based on WindowManager's state
176         bool focused = false;
177 
178         bool operator==(const LayerRequirement& other) const {
179             return name == other.name && vote == other.vote &&
180                     isApproxEqual(desiredRefreshRate, other.desiredRefreshRate) &&
181                     seamlessness == other.seamlessness && weight == other.weight &&
182                     focused == other.focused;
183         }
184 
185         bool operator!=(const LayerRequirement& other) const { return !(*this == other); }
186     };
187 
188     // Global state describing signals that affect refresh rate choice.
189     struct GlobalSignals {
190         // Whether the user touched the screen recently. Used to apply touch boost.
191         bool touch = false;
192         // True if the system hasn't seen any buffers posted to layers recently.
193         bool idle = false;
194         // Whether the display is about to be powered on, or has been in PowerMode::ON
195         // within the timeout of DisplayPowerTimer.
196         bool powerOnImminent = false;
197 
198         bool operator==(GlobalSignals other) const {
199             return touch == other.touch && idle == other.idle &&
200                     powerOnImminent == other.powerOnImminent;
201         }
202 
toStringGlobalSignals203         auto toString() const {
204             return ftl::Concat("{touch=", touch, ", idle=", idle,
205                                ", powerOnImminent=", powerOnImminent, '}');
206         }
207     };
208 
209     struct ScoredFrameRate {
210         FrameRateMode frameRateMode;
211         float score = 0.0f;
212 
213         bool operator==(const ScoredFrameRate& other) const {
214             return frameRateMode == other.frameRateMode && score == other.score;
215         }
216 
scoresEqualScoredFrameRate217         static bool scoresEqual(float lhs, float rhs) {
218             constexpr float kEpsilon = 0.0001f;
219             return std::abs(lhs - rhs) <= kEpsilon;
220         }
221 
222         struct DescendingScore {
operatorScoredFrameRate::DescendingScore223             bool operator()(const ScoredFrameRate& lhs, const ScoredFrameRate& rhs) const {
224                 return lhs.score > rhs.score && !scoresEqual(lhs.score, rhs.score);
225             }
226         };
227     };
228 
229     using FrameRateRanking = std::vector<ScoredFrameRate>;
230 
231     struct RankedFrameRates {
232         FrameRateRanking ranking; // Ordered by descending score.
233         GlobalSignals consideredSignals;
234 
235         bool operator==(const RankedFrameRates& other) const {
236             return ranking == other.ranking && consideredSignals == other.consideredSignals;
237         }
238     };
239 
240     RankedFrameRates getRankedFrameRates(const std::vector<LayerRequirement>&, GlobalSignals) const
241             EXCLUDES(mLock);
242 
getSupportedRefreshRateRange()243     FpsRange getSupportedRefreshRateRange() const EXCLUDES(mLock) {
244         std::lock_guard lock(mLock);
245         return {mMinRefreshRateModeIt->second->getFps(), mMaxRefreshRateModeIt->second->getFps()};
246     }
247 
248     ftl::Optional<FrameRateMode> onKernelTimerChanged(
249             std::optional<DisplayModeId> desiredActiveModeId, bool timerExpired) const
250             EXCLUDES(mLock);
251 
252     void setActiveMode(DisplayModeId, Fps renderFrameRate) EXCLUDES(mLock);
253 
254     // See mActiveModeOpt for thread safety.
255     FrameRateMode getActiveMode() const EXCLUDES(mLock);
256 
257     // Returns a known frame rate that is the closest to frameRate
258     Fps findClosestKnownFrameRate(Fps frameRate) const;
259 
260     enum class KernelIdleTimerController { Sysprop, HwcApi, ftl_last = HwcApi };
261 
262     // Configuration flags.
263     struct Config {
264         enum class FrameRateOverride {
265             // Do not override the frame rate for an app
266             Disabled,
267 
268             // Override the frame rate for an app to a value which is also
269             // a display refresh rate
270             AppOverrideNativeRefreshRates,
271 
272             // Override the frame rate for an app to any value
273             AppOverride,
274 
275             // Override the frame rate for all apps and all values.
276             Enabled,
277 
278             ftl_last = Enabled
279         };
280         FrameRateOverride enableFrameRateOverride = FrameRateOverride::Disabled;
281 
282         // Specifies the upper refresh rate threshold (inclusive) for layer vote types of multiple
283         // or heuristic, such that refresh rates higher than this value will not be voted for. 0 if
284         // no threshold is set.
285         int frameRateMultipleThreshold = 0;
286 
287         // The Idle Timer timeout. 0 timeout means no idle timer.
288         std::chrono::milliseconds idleTimerTimeout = 0ms;
289 
290         // The controller representing how the kernel idle timer will be configured
291         // either on the HWC api or sysprop.
292         ftl::Optional<KernelIdleTimerController> kernelIdleTimerController;
293     };
294 
295     RefreshRateSelector(
296             DisplayModes, DisplayModeId activeModeId,
297             Config config = {.enableFrameRateOverride = Config::FrameRateOverride::Disabled,
298                              .frameRateMultipleThreshold = 0,
299                              .idleTimerTimeout = 0ms,
300                              .kernelIdleTimerController = {}});
301 
302     RefreshRateSelector(const RefreshRateSelector&) = delete;
303     RefreshRateSelector& operator=(const RefreshRateSelector&) = delete;
304 
displayModes()305     const DisplayModes& displayModes() const { return mDisplayModes; }
306 
307     // Returns whether switching modes (refresh rate or resolution) is possible.
308     // TODO(b/158780872): Consider HAL support, and skip frame rate detection if the modes only
309     //  differ in resolution. Once Config::FrameRateOverride::Enabled becomes the default,
310     //  we can probably remove canSwitch altogether since all devices will be able
311     //  to switch to a frame rate divisor.
canSwitch()312     bool canSwitch() const EXCLUDES(mLock) {
313         std::lock_guard lock(mLock);
314         return mDisplayModes.size() > 1 ||
315                 mFrameRateOverrideConfig == Config::FrameRateOverride::Enabled;
316     }
317 
318     // Class to enumerate options around toggling the kernel timer on and off.
319     enum class KernelIdleTimerAction {
320         TurnOff, // Turn off the idle timer.
321         TurnOn   // Turn on the idle timer.
322     };
323 
324     // Checks whether kernel idle timer should be active depending the policy decisions around
325     // refresh rates.
326     KernelIdleTimerAction getIdleTimerAction() const;
327 
supportsAppFrameRateOverrideByContent()328     bool supportsAppFrameRateOverrideByContent() const {
329         return mFrameRateOverrideConfig != Config::FrameRateOverride::Disabled;
330     }
331 
supportsFrameRateOverride()332     bool supportsFrameRateOverride() const {
333         return mFrameRateOverrideConfig == Config::FrameRateOverride::Enabled;
334     }
335 
336     // Return the display refresh rate divisor to match the layer
337     // frame rate, or 0 if the display refresh rate is not a multiple of the
338     // layer refresh rate.
339     static int getFrameRateDivisor(Fps displayRefreshRate, Fps layerFrameRate);
340 
341     // Returns if the provided frame rates have a ratio t*1000/1001 or t*1001/1000
342     // for an integer t.
343     static bool isFractionalPairOrMultiple(Fps, Fps);
344 
345     using UidToFrameRateOverride = std::map<uid_t, Fps>;
346 
347     // Returns the frame rate override for each uid.
348     UidToFrameRateOverride getFrameRateOverrides(const std::vector<LayerRequirement>&,
349                                                  Fps displayFrameRate, GlobalSignals) const
350             EXCLUDES(mLock);
351 
kernelIdleTimerController()352     std::optional<KernelIdleTimerController> kernelIdleTimerController() {
353         return mConfig.kernelIdleTimerController;
354     }
355 
356     struct IdleTimerCallbacks {
357         struct Callbacks {
358             std::function<void()> onReset;
359             std::function<void()> onExpired;
360         };
361 
362         Callbacks platform;
363         Callbacks kernel;
364     };
365 
setIdleTimerCallbacks(IdleTimerCallbacks callbacks)366     void setIdleTimerCallbacks(IdleTimerCallbacks callbacks) EXCLUDES(mIdleTimerCallbacksMutex) {
367         std::scoped_lock lock(mIdleTimerCallbacksMutex);
368         mIdleTimerCallbacks = std::move(callbacks);
369     }
370 
clearIdleTimerCallbacks()371     void clearIdleTimerCallbacks() EXCLUDES(mIdleTimerCallbacksMutex) {
372         std::scoped_lock lock(mIdleTimerCallbacksMutex);
373         mIdleTimerCallbacks.reset();
374     }
375 
startIdleTimer()376     void startIdleTimer() {
377         if (mIdleTimer) {
378             mIdleTimer->start();
379         }
380     }
381 
stopIdleTimer()382     void stopIdleTimer() {
383         if (mIdleTimer) {
384             mIdleTimer->stop();
385         }
386     }
387 
resetKernelIdleTimer()388     void resetKernelIdleTimer() {
389         if (mIdleTimer && mConfig.kernelIdleTimerController) {
390             mIdleTimer->reset();
391         }
392     }
393 
resetIdleTimer()394     void resetIdleTimer() {
395         if (mIdleTimer) {
396             mIdleTimer->reset();
397         }
398     }
399 
400     void dump(utils::Dumper&) const EXCLUDES(mLock);
401 
402     std::chrono::milliseconds getIdleTimerTimeout();
403 
404 private:
405     friend struct TestableRefreshRateSelector;
406 
407     void constructAvailableRefreshRates() REQUIRES(mLock);
408 
409     // See mActiveModeOpt for thread safety.
410     const FrameRateMode& getActiveModeLocked() const REQUIRES(mLock);
411 
412     RankedFrameRates getRankedFrameRatesLocked(const std::vector<LayerRequirement>& layers,
413                                                GlobalSignals signals) const REQUIRES(mLock);
414 
415     // Returns number of display frames and remainder when dividing the layer refresh period by
416     // display refresh period.
417     std::pair<nsecs_t, nsecs_t> getDisplayFrames(nsecs_t layerPeriod, nsecs_t displayPeriod) const;
418 
419     // Returns the lowest refresh rate according to the current policy. May change at runtime. Only
420     // uses the primary range, not the app request range.
421     const DisplayModePtr& getMinRefreshRateByPolicyLocked() const REQUIRES(mLock);
422 
423     // Returns the highest refresh rate according to the current policy. May change at runtime. Only
424     // uses the primary range, not the app request range.
425     const DisplayModePtr& getMaxRefreshRateByPolicyLocked(int anchorGroup) const REQUIRES(mLock);
426 
427     struct RefreshRateScoreComparator;
428 
429     enum class RefreshRateOrder {
430         Ascending,
431         Descending,
432 
433         ftl_last = Descending
434     };
435 
436     // Only uses the primary range, not the app request range.
437     FrameRateRanking rankFrameRates(
438             std::optional<int> anchorGroupOpt, RefreshRateOrder refreshRateOrder,
439             std::optional<DisplayModeId> preferredDisplayModeOpt = std::nullopt) const
440             REQUIRES(mLock);
441 
442     const Policy* getCurrentPolicyLocked() const REQUIRES(mLock);
443     bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock);
444 
445     // Returns the refresh rate score as a ratio to max refresh rate, which has a score of 1.
446     float calculateDistanceScoreFromMax(Fps refreshRate) const REQUIRES(mLock);
447     // calculates a score for a layer. Used to determine the display refresh rate
448     // and the frame rate override for certains applications.
449     float calculateLayerScoreLocked(const LayerRequirement&, Fps refreshRate,
450                                     bool isSeamlessSwitch) const REQUIRES(mLock);
451 
452     float calculateNonExactMatchingLayerScoreLocked(const LayerRequirement&, Fps refreshRate) const
453             REQUIRES(mLock);
454 
455     void updateDisplayModes(DisplayModes, DisplayModeId activeModeId) EXCLUDES(mLock)
456             REQUIRES(kMainThreadContext);
457 
458     void initializeIdleTimer();
459 
getIdleTimerCallbacks()460     std::optional<IdleTimerCallbacks::Callbacks> getIdleTimerCallbacks() const
461             REQUIRES(mIdleTimerCallbacksMutex) {
462         if (!mIdleTimerCallbacks) return {};
463         return mConfig.kernelIdleTimerController.has_value() ? mIdleTimerCallbacks->kernel
464                                                              : mIdleTimerCallbacks->platform;
465     }
466 
isNativeRefreshRate(Fps fps)467     bool isNativeRefreshRate(Fps fps) const REQUIRES(mLock) {
468         LOG_ALWAYS_FATAL_IF(mConfig.enableFrameRateOverride !=
469                                     Config::FrameRateOverride::AppOverrideNativeRefreshRates,
470                             "should only be called when "
471                             "Config::FrameRateOverride::AppOverrideNativeRefreshRates is used");
472         return mAppOverrideNativeRefreshRates.contains(fps);
473     }
474 
475     std::vector<FrameRateMode> createFrameRateModes(
476             const Policy&, std::function<bool(const DisplayMode&)>&& filterModes,
477             const FpsRange&) const REQUIRES(mLock);
478 
479     // The display modes of the active display. The DisplayModeIterators below are pointers into
480     // this container, so must be invalidated whenever the DisplayModes change. The Policy below
481     // is also dependent, so must be reset as well.
482     DisplayModes mDisplayModes GUARDED_BY(mLock);
483 
484     // Set of supported display refresh rates for easy lookup
485     // when FrameRateOverride::AppOverrideNativeRefreshRates is in use.
486     ftl::SmallMap<Fps, ftl::Unit, 8, FpsApproxEqual> mAppOverrideNativeRefreshRates;
487 
488     ftl::Optional<FrameRateMode> mActiveModeOpt GUARDED_BY(mLock);
489 
490     DisplayModeIterator mMinRefreshRateModeIt GUARDED_BY(mLock);
491     DisplayModeIterator mMaxRefreshRateModeIt GUARDED_BY(mLock);
492 
493     // Display modes that satisfy the Policy's ranges, filtered and sorted by refresh rate.
494     std::vector<FrameRateMode> mPrimaryFrameRates GUARDED_BY(mLock);
495     std::vector<FrameRateMode> mAppRequestFrameRates GUARDED_BY(mLock);
496 
497     Policy mDisplayManagerPolicy GUARDED_BY(mLock);
498     std::optional<Policy> mOverridePolicy GUARDED_BY(mLock);
499 
500     unsigned mNumModeSwitchesInPolicy GUARDED_BY(kMainThreadContext) = 0;
501 
502     mutable std::mutex mLock;
503 
504     // A sorted list of known frame rates that a Heuristic layer will choose
505     // from based on the closest value.
506     const std::vector<Fps> mKnownFrameRates;
507 
508     const Config mConfig;
509 
510     // A list of known frame rates that favors at least 60Hz if there is no exact match display
511     // refresh rate
512     const std::vector<Fps> mFrameRatesThatFavorsAtLeast60 = {23.976_Hz, 25_Hz, 29.97_Hz, 50_Hz,
513                                                              59.94_Hz};
514 
515     Config::FrameRateOverride mFrameRateOverrideConfig;
516 
517     struct GetRankedFrameRatesCache {
518         std::pair<std::vector<LayerRequirement>, GlobalSignals> arguments;
519         RankedFrameRates result;
520     };
521     mutable std::optional<GetRankedFrameRatesCache> mGetRankedFrameRatesCache GUARDED_BY(mLock);
522 
523     // Declare mIdleTimer last to ensure its thread joins before the mutex/callbacks are destroyed.
524     std::mutex mIdleTimerCallbacksMutex;
525     std::optional<IdleTimerCallbacks> mIdleTimerCallbacks GUARDED_BY(mIdleTimerCallbacksMutex);
526     // Used to detect (lack of) frame activity.
527     ftl::Optional<scheduler::OneShotTimer> mIdleTimer;
528 };
529 
530 } // namespace android::scheduler
531