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