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