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 <android-base/stringprintf.h> 20 21 #include <algorithm> 22 #include <numeric> 23 #include <optional> 24 #include <type_traits> 25 26 #include "DisplayHardware/HWComposer.h" 27 #include "HwcStrongTypes.h" 28 #include "Scheduler/SchedulerUtils.h" 29 #include "Scheduler/StrongTyping.h" 30 31 namespace android::scheduler { 32 33 using namespace std::chrono_literals; 34 35 enum class RefreshRateConfigEvent : unsigned { None = 0b0, Changed = 0b1 }; 36 37 inline RefreshRateConfigEvent operator|(RefreshRateConfigEvent lhs, RefreshRateConfigEvent rhs) { 38 using T = std::underlying_type_t<RefreshRateConfigEvent>; 39 return static_cast<RefreshRateConfigEvent>(static_cast<T>(lhs) | static_cast<T>(rhs)); 40 } 41 42 /** 43 * This class is used to encapsulate configuration for refresh rates. It holds information 44 * about available refresh rates on the device, and the mapping between the numbers and human 45 * readable names. 46 */ 47 class RefreshRateConfigs { 48 public: 49 // Margin used when matching refresh rates to the content desired ones. 50 static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION = 51 std::chrono::nanoseconds(800us).count(); 52 53 class RefreshRate { 54 private: 55 // Effectively making the constructor private while allowing 56 // std::make_unique to create the object 57 struct ConstructorTag { ConstructorTagConstructorTag58 explicit ConstructorTag(int) {} 59 }; 60 61 public: RefreshRate(HwcConfigIndexType configId,std::shared_ptr<const HWC2::Display::Config> config,std::string name,float fps,ConstructorTag)62 RefreshRate(HwcConfigIndexType configId, 63 std::shared_ptr<const HWC2::Display::Config> config, std::string name, 64 float fps, ConstructorTag) 65 : configId(configId), hwcConfig(config), name(std::move(name)), fps(fps) {} 66 67 RefreshRate(const RefreshRate&) = delete; 68 getConfigId()69 HwcConfigIndexType getConfigId() const { return configId; } getVsyncPeriod()70 nsecs_t getVsyncPeriod() const { return hwcConfig->getVsyncPeriod(); } getConfigGroup()71 int32_t getConfigGroup() const { return hwcConfig->getConfigGroup(); } getName()72 const std::string& getName() const { return name; } getFps()73 float getFps() const { return fps; } 74 75 // Checks whether the fps of this RefreshRate struct is within a given min and max refresh 76 // rate passed in. FPS_EPSILON is applied to the boundaries for approximation. inPolicy(float minRefreshRate,float maxRefreshRate)77 bool inPolicy(float minRefreshRate, float maxRefreshRate) const { 78 return (fps >= (minRefreshRate - FPS_EPSILON) && fps <= (maxRefreshRate + FPS_EPSILON)); 79 } 80 81 bool operator!=(const RefreshRate& other) const { 82 return configId != other.configId || hwcConfig != other.hwcConfig; 83 } 84 85 bool operator<(const RefreshRate& other) const { return getFps() < other.getFps(); } 86 87 bool operator==(const RefreshRate& other) const { return !(*this != other); } 88 89 private: 90 friend RefreshRateConfigs; 91 friend class RefreshRateConfigsTest; 92 93 // The tolerance within which we consider FPS approximately equals. 94 static constexpr float FPS_EPSILON = 0.001f; 95 96 // This config ID corresponds to the position of the config in the vector that is stored 97 // on the device. 98 const HwcConfigIndexType configId; 99 // The config itself 100 std::shared_ptr<const HWC2::Display::Config> hwcConfig; 101 // Human readable name of the refresh rate. 102 const std::string name; 103 // Refresh rate in frames per second 104 const float fps = 0; 105 }; 106 107 using AllRefreshRatesMapType = 108 std::unordered_map<HwcConfigIndexType, std::unique_ptr<const RefreshRate>>; 109 110 struct Policy { 111 struct Range { 112 float min = 0; 113 float max = std::numeric_limits<float>::max(); 114 115 bool operator==(const Range& other) const { 116 return min == other.min && max == other.max; 117 } 118 119 bool operator!=(const Range& other) const { return !(*this == other); } 120 }; 121 122 // The default config, used to ensure we only initiate display config switches within the 123 // same config group as defaultConfigId's group. 124 HwcConfigIndexType defaultConfig; 125 // The primary refresh rate range represents display manager's general guidance on the 126 // display configs we'll consider when switching refresh rates. Unless we get an explicit 127 // signal from an app, we should stay within this range. 128 Range primaryRange; 129 // The app request refresh rate range allows us to consider more display configs when 130 // switching refresh rates. Although we should generally stay within the primary range, 131 // specific considerations, such as layer frame rate settings specified via the 132 // setFrameRate() api, may cause us to go outside the primary range. We never go outside the 133 // app request range. The app request range will be greater than or equal to the primary 134 // refresh rate range, never smaller. 135 Range appRequestRange; 136 // Whether or not we switch config groups to get the best frame rate. Only used by tests. 137 bool allowGroupSwitching = false; 138 139 Policy() = default; PolicyPolicy140 Policy(HwcConfigIndexType defaultConfig, const Range& range) 141 : Policy(defaultConfig, range, range) {} PolicyPolicy142 Policy(HwcConfigIndexType defaultConfig, const Range& primaryRange, 143 const Range& appRequestRange) 144 : defaultConfig(defaultConfig), 145 primaryRange(primaryRange), 146 appRequestRange(appRequestRange) {} 147 148 bool operator==(const Policy& other) const { 149 return defaultConfig == other.defaultConfig && primaryRange == other.primaryRange && 150 appRequestRange == other.appRequestRange && 151 allowGroupSwitching == other.allowGroupSwitching; 152 } 153 154 bool operator!=(const Policy& other) const { return !(*this == other); } 155 }; 156 157 // Return code set*Policy() to indicate the current policy is unchanged. 158 static constexpr int CURRENT_POLICY_UNCHANGED = 1; 159 160 // We maintain the display manager policy and the override policy separately. The override 161 // policy is used by CTS tests to get a consistent device state for testing. While the override 162 // policy is set, it takes precedence over the display manager policy. Once the override policy 163 // is cleared, we revert to using the display manager policy. 164 165 // Sets the display manager policy to choose refresh rates. The return value will be: 166 // - A negative value if the policy is invalid or another error occurred. 167 // - NO_ERROR if the policy was successfully updated, and the current policy is different from 168 // what it was before the call. 169 // - CURRENT_POLICY_UNCHANGED if the policy was successfully updated, but the current policy 170 // is the same as it was before the call. 171 status_t setDisplayManagerPolicy(const Policy& policy) EXCLUDES(mLock); 172 // Sets the override policy. See setDisplayManagerPolicy() for the meaning of the return value. 173 status_t setOverridePolicy(const std::optional<Policy>& policy) EXCLUDES(mLock); 174 // Gets the current policy, which will be the override policy if active, and the display manager 175 // policy otherwise. 176 Policy getCurrentPolicy() const EXCLUDES(mLock); 177 // Gets the display manager policy, regardless of whether an override policy is active. 178 Policy getDisplayManagerPolicy() const EXCLUDES(mLock); 179 180 // Returns true if config is allowed by the current policy. 181 bool isConfigAllowed(HwcConfigIndexType config) const EXCLUDES(mLock); 182 183 // Describes the different options the layer voted for refresh rate 184 enum class LayerVoteType { 185 NoVote, // Doesn't care about the refresh rate 186 Min, // Minimal refresh rate available 187 Max, // Maximal refresh rate available 188 Heuristic, // Specific refresh rate that was calculated by platform using a heuristic 189 ExplicitDefault, // Specific refresh rate that was provided by the app with Default 190 // compatibility 191 ExplicitExactOrMultiple // Specific refresh rate that was provided by the app with 192 // ExactOrMultiple compatibility 193 }; 194 195 // Captures the layer requirements for a refresh rate. This will be used to determine the 196 // display refresh rate. 197 struct LayerRequirement { 198 // Layer's name. Used for debugging purposes. 199 std::string name; 200 // Layer vote type. 201 LayerVoteType vote = LayerVoteType::NoVote; 202 // Layer's desired refresh rate, if applicable. 203 float desiredRefreshRate = 0.0f; 204 // Layer's weight in the range of [0, 1]. The higher the weight the more impact this layer 205 // would have on choosing the refresh rate. 206 float weight = 0.0f; 207 // Whether layer is in focus or not based on WindowManager's state 208 bool focused = false; 209 210 bool operator==(const LayerRequirement& other) const { 211 return name == other.name && vote == other.vote && 212 desiredRefreshRate == other.desiredRefreshRate && weight == other.weight && 213 focused == other.focused; 214 } 215 216 bool operator!=(const LayerRequirement& other) const { return !(*this == other); } 217 }; 218 219 // Returns the refresh rate that fits best to the given layers. 220 const RefreshRate& getRefreshRateForContent(const std::vector<LayerRequirement>& layers) const 221 EXCLUDES(mLock); 222 223 // Global state describing signals that affect refresh rate choice. 224 struct GlobalSignals { 225 // Whether the user touched the screen recently. Used to apply touch boost. 226 bool touch = false; 227 // True if the system hasn't seen any buffers posted to layers recently. 228 bool idle = false; 229 }; 230 231 // Returns the refresh rate that fits best to the given layers. 232 // layers - The layer requirements to consider. 233 // globalSignals - global state of touch and idle 234 // outSignalsConsidered - An output param that tells the caller whether the refresh rate was 235 // chosen based on touch boost and/or idle timer. 236 const RefreshRate& getBestRefreshRate(const std::vector<LayerRequirement>& layers, 237 const GlobalSignals& globalSignals, 238 GlobalSignals* outSignalsConsidered = nullptr) const 239 EXCLUDES(mLock); 240 241 // Returns all the refresh rates supported by the device. This won't change at runtime. 242 const AllRefreshRatesMapType& getAllRefreshRates() const EXCLUDES(mLock); 243 244 // Returns the lowest refresh rate supported by the device. This won't change at runtime. getMinRefreshRate()245 const RefreshRate& getMinRefreshRate() const { return *mMinSupportedRefreshRate; } 246 247 // Returns the lowest refresh rate according to the current policy. May change at runtime. Only 248 // uses the primary range, not the app request range. 249 const RefreshRate& getMinRefreshRateByPolicy() const EXCLUDES(mLock); 250 251 // Returns the highest refresh rate supported by the device. This won't change at runtime. getMaxRefreshRate()252 const RefreshRate& getMaxRefreshRate() const { return *mMaxSupportedRefreshRate; } 253 254 // Returns the highest refresh rate according to the current policy. May change at runtime. Only 255 // uses the primary range, not the app request range. 256 const RefreshRate& getMaxRefreshRateByPolicy() const EXCLUDES(mLock); 257 258 // Returns the current refresh rate 259 const RefreshRate& getCurrentRefreshRate() const EXCLUDES(mLock); 260 261 // Returns the current refresh rate, if allowed. Otherwise the default that is allowed by 262 // the policy. 263 const RefreshRate& getCurrentRefreshRateByPolicy() const; 264 265 // Returns the refresh rate that corresponds to a HwcConfigIndexType. This won't change at 266 // runtime. getRefreshRateFromConfigId(HwcConfigIndexType configId)267 const RefreshRate& getRefreshRateFromConfigId(HwcConfigIndexType configId) const { 268 return *mRefreshRates.at(configId); 269 }; 270 271 // Stores the current configId the device operates at 272 void setCurrentConfigId(HwcConfigIndexType configId) EXCLUDES(mLock); 273 274 // Returns a string that represents the layer vote type 275 static std::string layerVoteTypeString(LayerVoteType vote); 276 277 // Returns a known frame rate that is the closest to frameRate 278 float findClosestKnownFrameRate(float frameRate) const; 279 280 RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, 281 HwcConfigIndexType currentConfigId); 282 283 // Class to enumerate options around toggling the kernel timer on and off. We have an option 284 // for no change to avoid extra calls to kernel. 285 enum class KernelIdleTimerAction { 286 NoChange, // Do not change the idle timer. 287 TurnOff, // Turn off the idle timer. 288 TurnOn // Turn on the idle timer. 289 }; 290 // Checks whether kernel idle timer should be active depending the policy decisions around 291 // refresh rates. 292 KernelIdleTimerAction getIdleTimerAction() const; 293 294 private: 295 friend class RefreshRateConfigsTest; 296 297 void constructAvailableRefreshRates() REQUIRES(mLock); 298 static std::vector<float> constructKnownFrameRates( 299 const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs); 300 301 void getSortedRefreshRateList( 302 const std::function<bool(const RefreshRate&)>& shouldAddRefreshRate, 303 std::vector<const RefreshRate*>* outRefreshRates); 304 305 // Returns the refresh rate with the highest score in the collection specified from begin 306 // to end. If there are more than one with the same highest refresh rate, the first one is 307 // returned. 308 template <typename Iter> 309 const RefreshRate* getBestRefreshRate(Iter begin, Iter end) const; 310 311 // Returns number of display frames and remainder when dividing the layer refresh period by 312 // display refresh period. 313 std::pair<nsecs_t, nsecs_t> getDisplayFrames(nsecs_t layerPeriod, nsecs_t displayPeriod) const; 314 315 // Returns the lowest refresh rate according to the current policy. May change at runtime. Only 316 // uses the primary range, not the app request range. 317 const RefreshRate& getMinRefreshRateByPolicyLocked() const REQUIRES(mLock); 318 319 // Returns the highest refresh rate according to the current policy. May change at runtime. Only 320 // uses the primary range, not the app request range. 321 const RefreshRate& getMaxRefreshRateByPolicyLocked() const REQUIRES(mLock); 322 323 // Returns the current refresh rate, if allowed. Otherwise the default that is allowed by 324 // the policy. 325 const RefreshRate& getCurrentRefreshRateByPolicyLocked() const REQUIRES(mLock); 326 327 const Policy* getCurrentPolicyLocked() const REQUIRES(mLock); 328 bool isPolicyValid(const Policy& policy); 329 330 // The list of refresh rates, indexed by display config ID. This must not change after this 331 // object is initialized. 332 AllRefreshRatesMapType mRefreshRates; 333 334 // The list of refresh rates in the primary range of the current policy, ordered by vsyncPeriod 335 // (the first element is the lowest refresh rate). 336 std::vector<const RefreshRate*> mPrimaryRefreshRates GUARDED_BY(mLock); 337 338 // The list of refresh rates in the app request range of the current policy, ordered by 339 // vsyncPeriod (the first element is the lowest refresh rate). 340 std::vector<const RefreshRate*> mAppRequestRefreshRates GUARDED_BY(mLock); 341 342 // The current config. This will change at runtime. This is set by SurfaceFlinger on 343 // the main thread, and read by the Scheduler (and other objects) on other threads. 344 const RefreshRate* mCurrentRefreshRate GUARDED_BY(mLock); 345 346 // The policy values will change at runtime. They're set by SurfaceFlinger on the main thread, 347 // and read by the Scheduler (and other objects) on other threads. 348 Policy mDisplayManagerPolicy GUARDED_BY(mLock); 349 std::optional<Policy> mOverridePolicy GUARDED_BY(mLock); 350 351 // The min and max refresh rates supported by the device. 352 // This will not change at runtime. 353 const RefreshRate* mMinSupportedRefreshRate; 354 const RefreshRate* mMaxSupportedRefreshRate; 355 356 mutable std::mutex mLock; 357 358 // A sorted list of known frame rates that a Heuristic layer will choose 359 // from based on the closest value. 360 const std::vector<float> mKnownFrameRates; 361 }; 362 363 } // namespace android::scheduler 364