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 <cstdint> 21 #include <functional> 22 #include <future> 23 #include <memory> 24 #include <mutex> 25 #include <unordered_map> 26 #include <utility> 27 28 // TODO(b/129481165): remove the #pragma below and fix conversion issues 29 #pragma clang diagnostic push 30 #pragma clang diagnostic ignored "-Wconversion" 31 #pragma clang diagnostic ignored "-Wextra" 32 #include <ui/GraphicTypes.h> 33 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" 34 35 #include <ftl/fake_guard.h> 36 #include <ftl/non_null.h> 37 #include <ftl/optional.h> 38 #include <scheduler/Features.h> 39 #include <scheduler/FrameRateMode.h> 40 #include <scheduler/FrameTargeter.h> 41 #include <scheduler/Time.h> 42 #include <scheduler/VsyncConfig.h> 43 #include <ui/DisplayId.h> 44 #include <ui/DisplayMap.h> 45 46 #include "DisplayHardware/DisplayMode.h" 47 #include "EventThread.h" 48 #include "FrameRateOverrideMappings.h" 49 #include "ISchedulerCallback.h" 50 #include "LayerHistory.h" 51 #include "MessageQueue.h" 52 #include "OneShotTimer.h" 53 #include "RefreshRateSelector.h" 54 #include "SmallAreaDetectionAllowMappings.h" 55 #include "Utils/Dumper.h" 56 #include "VsyncConfiguration.h" 57 #include "VsyncModulator.h" 58 59 #include <FrontEnd/LayerHierarchy.h> 60 61 namespace android { 62 63 class FenceTime; 64 class TimeStats; 65 66 namespace frametimeline { 67 class TokenManager; 68 } // namespace frametimeline 69 70 namespace surfaceflinger { 71 class Factory; 72 } // namespace surfaceflinger 73 74 namespace scheduler { 75 76 using GlobalSignals = RefreshRateSelector::GlobalSignals; 77 78 class RefreshRateStats; 79 class VsyncConfiguration; 80 class VsyncSchedule; 81 82 enum class Cycle { 83 Render, // Surface rendering. 84 LastComposite // Ahead of display compositing by one refresh period. 85 }; 86 87 class Scheduler : public IEventThreadCallback, android::impl::MessageQueue { 88 using Impl = android::impl::MessageQueue; 89 90 public: 91 Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags, surfaceflinger::Factory&, 92 Fps activeRefreshRate, TimeStats&); 93 virtual ~Scheduler(); 94 95 void startTimers(); 96 97 // TODO: b/241285191 - Remove this API by promoting pacesetter in onScreen{Acquired,Released}. 98 void setPacesetterDisplay(PhysicalDisplayId) REQUIRES(kMainThreadContext) 99 EXCLUDES(mDisplayLock, mVsyncConfigLock); 100 101 using RefreshRateSelectorPtr = std::shared_ptr<RefreshRateSelector>; 102 103 using ConstVsyncSchedulePtr = std::shared_ptr<const VsyncSchedule>; 104 using VsyncSchedulePtr = std::shared_ptr<VsyncSchedule>; 105 106 // After registration/unregistration, `activeDisplayId` is promoted to pacesetter. Note that the 107 // active display is never unregistered, since hotplug disconnect never happens for activatable 108 // displays, i.e. a foldable's internal displays or otherwise the (internal or external) primary 109 // display. 110 // TODO: b/255635821 - Remove active display parameters. 111 void registerDisplay(PhysicalDisplayId, RefreshRateSelectorPtr, 112 PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext) 113 EXCLUDES(mDisplayLock); 114 void unregisterDisplay(PhysicalDisplayId, PhysicalDisplayId activeDisplayId) 115 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock); 116 117 void run(); 118 119 void initVsync(frametimeline::TokenManager&, std::chrono::nanoseconds workDuration); 120 121 using Impl::setDuration; 122 123 using Impl::getScheduledFrameResult; 124 using Impl::scheduleConfigure; 125 using Impl::scheduleFrame; 126 127 // Schedule an asynchronous or synchronous task on the main thread. 128 template <typename F, typename T = std::invoke_result_t<F>> schedule(F && f)129 [[nodiscard]] std::future<T> schedule(F&& f) { 130 auto [task, future] = makeTask(std::move(f)); 131 postMessage(std::move(task)); 132 return std::move(future); 133 } 134 135 template <typename F, typename T = std::invoke_result_t<F>> scheduleDelayed(F && f,nsecs_t uptimeDelay)136 [[nodiscard]] std::future<T> scheduleDelayed(F&& f, nsecs_t uptimeDelay) { 137 auto [task, future] = makeTask(std::move(f)); 138 postMessageDelayed(std::move(task), uptimeDelay); 139 return std::move(future); 140 } 141 142 void createEventThread(Cycle, frametimeline::TokenManager*, 143 std::chrono::nanoseconds workDuration, 144 std::chrono::nanoseconds readyDuration); 145 146 sp<IDisplayEventConnection> createDisplayEventConnection( 147 Cycle, EventRegistrationFlags eventRegistration = {}, 148 const sp<IBinder>& layerHandle = nullptr) EXCLUDES(mChoreographerLock); 149 150 enum class Hotplug { Connected, Disconnected }; 151 void dispatchHotplug(PhysicalDisplayId, Hotplug); 152 153 void dispatchHotplugError(int32_t errorCode); 154 155 // Returns true if the PhysicalDisplayId is the pacesetter. 156 bool onDisplayModeChanged(PhysicalDisplayId, const FrameRateMode&, 157 bool clearContentRequirements) EXCLUDES(mPolicyLock); 158 159 void onDisplayModeRejected(PhysicalDisplayId, DisplayModeId); 160 161 void enableSyntheticVsync(bool = true) REQUIRES(kMainThreadContext); 162 void omitVsyncDispatching(bool) REQUIRES(kMainThreadContext); 163 164 void onHdcpLevelsChanged(Cycle, PhysicalDisplayId, int32_t, int32_t); 165 166 // Modifies work duration in the event thread. 167 void setDuration(Cycle, std::chrono::nanoseconds workDuration, 168 std::chrono::nanoseconds readyDuration); 169 vsyncModulator()170 VsyncModulator& vsyncModulator() { return *mVsyncModulator; } 171 172 // In some cases, we should only modulate for the pacesetter display. In those 173 // cases, the caller should pass in the relevant display, and the method 174 // will no-op if it's not the pacesetter. Other cases are not specific to a 175 // display. 176 template <typename... Args, 177 typename Handler = std::optional<VsyncConfig> (VsyncModulator::*)(Args...)> modulateVsync(std::optional<PhysicalDisplayId> id,Handler handler,Args...args)178 void modulateVsync(std::optional<PhysicalDisplayId> id, Handler handler, Args... args) { 179 if (id) { 180 std::scoped_lock lock(mDisplayLock); 181 ftl::FakeGuard guard(kMainThreadContext); 182 if (id != mPacesetterDisplayId) { 183 return; 184 } 185 } 186 187 if (const auto config = (*mVsyncModulator.*handler)(args...)) { 188 setVsyncConfig(*config, getPacesetterVsyncPeriod()); 189 } 190 } 191 192 void updatePhaseConfiguration(PhysicalDisplayId, Fps) EXCLUDES(mVsyncConfigLock); 193 void reloadPhaseConfiguration(Fps, Duration minSfDuration, Duration maxSfDuration, 194 Duration appDuration) EXCLUDES(mVsyncConfigLock); 195 getCurrentVsyncConfigs()196 VsyncConfigSet getCurrentVsyncConfigs() const EXCLUDES(mVsyncConfigLock) { 197 std::scoped_lock lock{mVsyncConfigLock}; 198 return mVsyncConfiguration->getCurrentConfigs(); 199 } 200 getVsyncConfigsForRefreshRate(Fps refreshRate)201 VsyncConfigSet getVsyncConfigsForRefreshRate(Fps refreshRate) const EXCLUDES(mVsyncConfigLock) { 202 std::scoped_lock lock{mVsyncConfigLock}; 203 return mVsyncConfiguration->getConfigsForRefreshRate(refreshRate); 204 } 205 206 // Sets the render rate for the scheduler to run at. 207 void setRenderRate(PhysicalDisplayId, Fps, bool applyImmediately); 208 209 void enableHardwareVsync(PhysicalDisplayId) REQUIRES(kMainThreadContext); 210 void disableHardwareVsync(PhysicalDisplayId, bool disallow) REQUIRES(kMainThreadContext); 211 212 // Resyncs the scheduler to hardware vsync. 213 // If allowToEnable is true, then hardware vsync will be turned on. 214 // Otherwise, if hardware vsync is not already enabled then this method will 215 // no-op. 216 // If modePtr is nullopt, use the active display mode. 217 void resyncToHardwareVsync(PhysicalDisplayId id, bool allowToEnable, EXCLUDES(mDisplayLock)218 DisplayModePtr modePtr = nullptr) EXCLUDES(mDisplayLock) { 219 std::scoped_lock lock(mDisplayLock); 220 ftl::FakeGuard guard(kMainThreadContext); 221 resyncToHardwareVsyncLocked(id, allowToEnable, modePtr); 222 } forceNextResync()223 void forceNextResync() { mLastResyncTime = 0; } 224 225 // Passes a vsync sample to VsyncController. Returns true if 226 // VsyncController detected that the vsync period changed and false 227 // otherwise. 228 bool addResyncSample(PhysicalDisplayId, nsecs_t timestamp, 229 std::optional<nsecs_t> hwcVsyncPeriod); 230 void addPresentFence(PhysicalDisplayId, std::shared_ptr<FenceTime>) 231 REQUIRES(kMainThreadContext); 232 233 // Layers are registered on creation, and unregistered when the weak reference expires. 234 void registerLayer(Layer*, FrameRateCompatibility); 235 void recordLayerHistory(int32_t id, const LayerProps& layerProps, nsecs_t presentTime, 236 nsecs_t now, LayerHistory::LayerUpdateType) EXCLUDES(mDisplayLock); 237 void setModeChangePending(bool pending); 238 void setDefaultFrameRateCompatibility(int32_t id, scheduler::FrameRateCompatibility); 239 void setLayerProperties(int32_t id, const LayerProps&); 240 void deregisterLayer(Layer*); 241 void onLayerDestroyed(Layer*) EXCLUDES(mChoreographerLock); 242 243 // Detects content using layer history, and selects a matching refresh rate. 244 void chooseRefreshRateForContent(const surfaceflinger::frontend::LayerHierarchy*, 245 bool updateAttachedChoreographer) EXCLUDES(mDisplayLock); 246 247 void resetIdleTimer(); 248 249 // Indicates that touch interaction is taking place. 250 void onTouchHint(); 251 252 void setDisplayPowerMode(PhysicalDisplayId, hal::PowerMode) REQUIRES(kMainThreadContext); 253 254 // TODO(b/255635821): Track this per display. 255 void setActiveDisplayPowerModeForRefreshRateStats(hal::PowerMode) REQUIRES(kMainThreadContext); 256 257 ConstVsyncSchedulePtr getVsyncSchedule(std::optional<PhysicalDisplayId> = std::nullopt) const 258 EXCLUDES(mDisplayLock); 259 260 VsyncSchedulePtr getVsyncSchedule(std::optional<PhysicalDisplayId> idOpt = std::nullopt) EXCLUDES(mDisplayLock)261 EXCLUDES(mDisplayLock) { 262 return std::const_pointer_cast<VsyncSchedule>(std::as_const(*this).getVsyncSchedule(idOpt)); 263 } 264 expectedPresentTimeForPacesetter()265 TimePoint expectedPresentTimeForPacesetter() const EXCLUDES(mDisplayLock) { 266 std::scoped_lock lock(mDisplayLock); 267 return pacesetterDisplayLocked() 268 .transform([](const Display& display) { 269 return display.targeterPtr->target().expectedPresentTime(); 270 }) 271 .value_or(TimePoint()); 272 } 273 274 // Returns true if a given vsync timestamp is considered valid vsync 275 // for a given uid 276 bool isVsyncValid(TimePoint expectedVsyncTime, uid_t uid) const; 277 278 bool isVsyncInPhase(TimePoint expectedVsyncTime, Fps frameRate) const; 279 280 void dump(utils::Dumper&) const EXCLUDES(mVsyncConfigLock); 281 void dump(Cycle, std::string&) const; 282 void dumpVsync(std::string&) const EXCLUDES(mDisplayLock); 283 284 // Returns the preferred refresh rate and frame rate for the pacesetter display. 285 FrameRateMode getPreferredDisplayMode(); 286 287 // Notifies the scheduler about a refresh rate timeline change. 288 void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline); 289 290 // Notifies the scheduler once the composition is presented. Returns if recomposite is needed. 291 bool onCompositionPresented(nsecs_t presentTime); 292 293 // Notifies the scheduler when the display size has changed. Called from SF's main thread 294 void onActiveDisplayAreaChanged(uint32_t displayArea); 295 296 // Stores the preferred refresh rate that an app should run at. 297 // FrameRateOverride.refreshRateHz == 0 means no preference. 298 void setPreferredRefreshRateForUid(FrameRateOverride); 299 300 // Stores the frame rate override that a game should run at set by game interventions. 301 // FrameRateOverride.refreshRateHz == 0 means no preference. 302 void setGameModeFrameRateForUid(FrameRateOverride) EXCLUDES(mDisplayLock); 303 304 // Stores the frame rate override that a game should run rat set by default game frame rate. 305 // FrameRateOverride.refreshRateHz == 0 means no preference, game default game frame rate is not 306 // enabled. 307 // 308 // "ro.surface_flinger.game_default_frame_rate_override" sets the frame rate value, 309 // "persist.graphics.game_default_frame_rate.enabled" controls whether this feature is enabled. 310 void setGameDefaultFrameRateForUid(FrameRateOverride) EXCLUDES(mDisplayLock); 311 312 void updateSmallAreaDetection(std::vector<std::pair<int32_t, float>>& uidThresholdMappings); 313 314 void setSmallAreaDetectionThreshold(int32_t appId, float threshold); 315 316 // Returns true if the dirty area is less than threshold. 317 bool isSmallDirtyArea(int32_t appId, uint32_t dirtyArea); 318 319 // Retrieves the overridden refresh rate for a given uid. 320 std::optional<Fps> getFrameRateOverride(uid_t) const EXCLUDES(mDisplayLock); 321 getPacesetterVsyncPeriod()322 Period getPacesetterVsyncPeriod() const EXCLUDES(mDisplayLock) { 323 return pacesetterSelectorPtr()->getActiveMode().fps.getPeriod(); 324 } 325 getPacesetterRefreshRate()326 Fps getPacesetterRefreshRate() const EXCLUDES(mDisplayLock) { 327 return pacesetterSelectorPtr()->getActiveMode().fps; 328 } 329 330 Fps getNextFrameInterval(PhysicalDisplayId, TimePoint currentExpectedPresentTime) const 331 EXCLUDES(mDisplayLock); 332 333 // Returns the framerate of the layer with the given sequence ID getLayerFramerate(nsecs_t now,int32_t id)334 float getLayerFramerate(nsecs_t now, int32_t id) const { 335 return mLayerHistory.getLayerFramerate(now, id); 336 } 337 338 void updateFrameRateOverrides(GlobalSignals, Fps displayRefreshRate) EXCLUDES(mPolicyLock); 339 340 // Returns true if the small dirty detection is enabled for the appId. supportSmallDirtyDetection(int32_t appId)341 bool supportSmallDirtyDetection(int32_t appId) { 342 return mFeatures.test(Feature::kSmallDirtyContentDetection) && 343 mSmallAreaDetectionAllowMappings.getThresholdForAppId(appId).has_value(); 344 } 345 346 // Injects a delay that is a fraction of the predicted frame duration for the next frame. injectPacesetterDelay(float frameDurationFraction)347 void injectPacesetterDelay(float frameDurationFraction) REQUIRES(kMainThreadContext) { 348 mPacesetterFrameDurationFractionToSkip = frameDurationFraction; 349 } 350 setDebugPresentDelay(TimePoint delay)351 void setDebugPresentDelay(TimePoint delay) { mDebugPresentDelay = delay; } 352 353 private: 354 friend class TestableScheduler; 355 356 enum class ContentDetectionState { Off, On }; 357 enum class TimerState { Reset, Expired }; 358 enum class TouchState { Inactive, Active }; 359 360 // impl::MessageQueue overrides: 361 void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) override 362 REQUIRES(kMainThreadContext, mDisplayLock) EXCLUDES(mVsyncConfigLock); 363 364 // Used to skip event dispatch before EventThread creation during boot. 365 // TODO: b/241285191 - Reorder Scheduler initialization to avoid this. hasEventThreads()366 bool hasEventThreads() const { 367 return CC_LIKELY( 368 mRenderEventThread && 369 (FlagManager::getInstance().deprecate_vsync_sf() || mLastCompositeEventThread)); 370 } 371 eventThreadFor(Cycle cycle)372 EventThread& eventThreadFor(Cycle cycle) const { 373 return *(cycle == Cycle::Render ? mRenderEventThread : mLastCompositeEventThread); 374 } 375 376 // Update feature state machine to given state when corresponding timer resets or expires. 377 void kernelIdleTimerCallback(TimerState) EXCLUDES(mDisplayLock); 378 void idleTimerCallback(TimerState); 379 void touchTimerCallback(TimerState); 380 void displayPowerTimerCallback(TimerState); 381 382 // VsyncSchedule delegate. 383 void onHardwareVsyncRequest(PhysicalDisplayId, bool enable); 384 385 void resyncToHardwareVsyncLocked(PhysicalDisplayId, bool allowToEnable, 386 DisplayModePtr modePtr = nullptr) 387 REQUIRES(kMainThreadContext, mDisplayLock); 388 void resyncAllToHardwareVsync(bool allowToEnable) EXCLUDES(mDisplayLock); 389 void setVsyncConfig(const VsyncConfig&, Period vsyncPeriod); 390 391 // TODO: b/241286431 - Remove this option, which assumes that the pacesetter does not change 392 // when a (secondary) display is registered or unregistered. In the short term, this avoids 393 // a deadlock where the main thread joins with the timer thread as the timer thread waits to 394 // lock a mutex held by the main thread. 395 struct PromotionParams { 396 // Whether to stop and start the idle timer. 397 bool toggleIdleTimer; 398 }; 399 400 void promotePacesetterDisplay(PhysicalDisplayId pacesetterId, PromotionParams) 401 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock); 402 403 // Changes to the displays (e.g. registering and unregistering) must be made 404 // while mDisplayLock is locked, and the new pacesetter then must be promoted while 405 // mDisplayLock is still locked. However, a new pacesetter means that 406 // MessageQueue and EventThread need to use the new pacesetter's 407 // VsyncSchedule, and this must happen while mDisplayLock is *not* locked, 408 // or else we may deadlock with EventThread. 409 std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(PhysicalDisplayId pacesetterId, 410 PromotionParams) 411 REQUIRES(kMainThreadContext, mDisplayLock); 412 void applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule>) EXCLUDES(mDisplayLock); 413 414 // If toggleIdleTimer is true, the calling thread blocks until the pacesetter's idle timer 415 // thread exits, in which case mDisplayLock must not be locked by the caller to avoid deadlock, 416 // since the timer thread locks it before exit. 417 void demotePacesetterDisplay(PromotionParams) REQUIRES(kMainThreadContext) 418 EXCLUDES(mDisplayLock, mPolicyLock); 419 420 void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr, VsyncSchedulePtr, 421 PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext) 422 EXCLUDES(mDisplayLock); 423 424 struct Policy; 425 426 // Sets the S state of the policy to the T value under mPolicyLock, and chooses a display mode 427 // that fulfills the new policy if the state changed. Returns the signals that were considered. 428 template <typename S, typename T> 429 GlobalSignals applyPolicy(S Policy::*, T&&) EXCLUDES(mPolicyLock); 430 431 struct DisplayModeChoice { DisplayModeChoiceDisplayModeChoice432 DisplayModeChoice(FrameRateMode mode, GlobalSignals consideredSignals) 433 : mode(std::move(mode)), consideredSignals(consideredSignals) {} 434 fromDisplayModeChoice435 static DisplayModeChoice from(RefreshRateSelector::RankedFrameRates rankedFrameRates) { 436 return {rankedFrameRates.ranking.front().frameRateMode, 437 rankedFrameRates.consideredSignals}; 438 } 439 440 FrameRateMode mode; 441 GlobalSignals consideredSignals; 442 443 bool operator==(const DisplayModeChoice& other) const { 444 return mode == other.mode && consideredSignals == other.consideredSignals; 445 } 446 447 // For tests. 448 friend std::ostream& operator<<(std::ostream& stream, const DisplayModeChoice& choice) { 449 return stream << '{' << to_string(*choice.mode.modePtr) << " considering " 450 << choice.consideredSignals.toString().c_str() << '}'; 451 } 452 }; 453 454 using DisplayModeChoiceMap = ui::PhysicalDisplayMap<PhysicalDisplayId, DisplayModeChoice>; 455 456 // See mDisplayLock for thread safety. 457 DisplayModeChoiceMap chooseDisplayModes() const 458 REQUIRES(mPolicyLock, mDisplayLock, kMainThreadContext); 459 460 GlobalSignals makeGlobalSignals() const REQUIRES(mPolicyLock); 461 462 bool updateFrameRateOverridesLocked(GlobalSignals, Fps displayRefreshRate) 463 REQUIRES(mPolicyLock); 464 465 void onFrameRateOverridesChanged(); 466 467 void updateAttachedChoreographers(const surfaceflinger::frontend::LayerHierarchy&, 468 Fps displayRefreshRate); 469 int updateAttachedChoreographersInternal(const surfaceflinger::frontend::LayerHierarchy&, 470 Fps displayRefreshRate, int parentDivisor); 471 void updateAttachedChoreographersFrameRate(const surfaceflinger::frontend::RequestedLayerState&, 472 Fps fps) EXCLUDES(mChoreographerLock); 473 474 void emitModeChangeIfNeeded() REQUIRES(mPolicyLock) EXCLUDES(mDisplayLock); 475 476 // IEventThreadCallback overrides 477 bool throttleVsync(TimePoint, uid_t) override; 478 // Get frame interval 479 Period getVsyncPeriod(uid_t) override EXCLUDES(mDisplayLock); 480 void resync() override EXCLUDES(mDisplayLock); 481 void onExpectedPresentTimePosted(TimePoint expectedPresentTime) override EXCLUDES(mDisplayLock); 482 483 std::unique_ptr<EventThread> mRenderEventThread; 484 std::unique_ptr<EventThread> mLastCompositeEventThread; 485 486 std::atomic<nsecs_t> mLastResyncTime = 0; 487 488 const FeatureFlags mFeatures; 489 490 mutable std::mutex mVsyncConfigLock; 491 // Stores phase offsets configured per refresh rate. 492 std::unique_ptr<VsyncConfiguration> mVsyncConfiguration GUARDED_BY(mVsyncConfigLock); 493 494 // Shifts the VSYNC phase during certain transactions and refresh rate changes. 495 const sp<VsyncModulator> mVsyncModulator; 496 497 const std::unique_ptr<RefreshRateStats> mRefreshRateStats; 498 499 // Used to choose refresh rate if content detection is enabled. 500 LayerHistory mLayerHistory; 501 502 // Timer used to monitor touch events. 503 ftl::Optional<OneShotTimer> mTouchTimer; 504 // Timer used to monitor display power mode. 505 ftl::Optional<OneShotTimer> mDisplayPowerTimer; 506 507 // Injected delay prior to compositing, for simulating jank. 508 float mPacesetterFrameDurationFractionToSkip GUARDED_BY(kMainThreadContext) = 0.f; 509 510 ISchedulerCallback& mSchedulerCallback; 511 512 // mDisplayLock may be locked while under mPolicyLock. 513 mutable std::mutex mPolicyLock; 514 515 // Only required for reads outside kMainThreadContext. kMainThreadContext is the only writer, so 516 // must lock for writes but not reads. See also mPolicyLock for locking order. 517 mutable std::mutex mDisplayLock; 518 519 using FrameTargeterPtr = std::unique_ptr<FrameTargeter>; 520 521 struct Display { DisplayDisplay522 Display(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr, 523 VsyncSchedulePtr schedulePtr, FeatureFlags features) 524 : displayId(displayId), 525 selectorPtr(std::move(selectorPtr)), 526 schedulePtr(std::move(schedulePtr)), 527 targeterPtr(std::make_unique<FrameTargeter>(displayId, features)) {} 528 529 const PhysicalDisplayId displayId; 530 531 // Effectively const except in move constructor. 532 RefreshRateSelectorPtr selectorPtr; 533 VsyncSchedulePtr schedulePtr; 534 FrameTargeterPtr targeterPtr; 535 536 hal::PowerMode powerMode = hal::PowerMode::OFF; 537 }; 538 539 using DisplayRef = std::reference_wrapper<Display>; 540 using ConstDisplayRef = std::reference_wrapper<const Display>; 541 542 ui::PhysicalDisplayMap<PhysicalDisplayId, Display> mDisplays GUARDED_BY(mDisplayLock) 543 GUARDED_BY(kMainThreadContext); 544 545 ftl::Optional<PhysicalDisplayId> mPacesetterDisplayId GUARDED_BY(mDisplayLock) 546 GUARDED_BY(kMainThreadContext); 547 pacesetterDisplayLocked()548 ftl::Optional<DisplayRef> pacesetterDisplayLocked() REQUIRES(mDisplayLock) { 549 return static_cast<const Scheduler*>(this)->pacesetterDisplayLocked().transform( 550 [](const Display& display) { return std::ref(const_cast<Display&>(display)); }); 551 } 552 pacesetterDisplayLocked()553 ftl::Optional<ConstDisplayRef> pacesetterDisplayLocked() const REQUIRES(mDisplayLock) { 554 ftl::FakeGuard guard(kMainThreadContext); 555 return mPacesetterDisplayId.and_then([this](PhysicalDisplayId pacesetterId) 556 REQUIRES(mDisplayLock, kMainThreadContext) { 557 return mDisplays.get(pacesetterId); 558 }); 559 } 560 561 // The pacesetter must exist as a precondition. pacesetterPtrLocked()562 ftl::NonNull<const Display*> pacesetterPtrLocked() const REQUIRES(mDisplayLock) { 563 return ftl::as_non_null(&pacesetterDisplayLocked()->get()); 564 } 565 pacesetterSelectorPtr()566 RefreshRateSelectorPtr pacesetterSelectorPtr() const EXCLUDES(mDisplayLock) { 567 std::scoped_lock lock(mDisplayLock); 568 return pacesetterSelectorPtrLocked(); 569 } 570 pacesetterSelectorPtrLocked()571 RefreshRateSelectorPtr pacesetterSelectorPtrLocked() const REQUIRES(mDisplayLock) { 572 return pacesetterDisplayLocked() 573 .transform([](const Display& display) { return display.selectorPtr; }) 574 .or_else([] { return std::optional<RefreshRateSelectorPtr>(nullptr); }) 575 .value(); 576 } 577 578 ConstVsyncSchedulePtr getVsyncScheduleLocked( 579 std::optional<PhysicalDisplayId> = std::nullopt) const REQUIRES(mDisplayLock); 580 581 VsyncSchedulePtr getVsyncScheduleLocked(std::optional<PhysicalDisplayId> idOpt = std::nullopt) REQUIRES(mDisplayLock)582 REQUIRES(mDisplayLock) { 583 return std::const_pointer_cast<VsyncSchedule>( 584 static_cast<const Scheduler*>(this)->getVsyncScheduleLocked(idOpt)); 585 } 586 587 struct Policy { 588 // Policy for choosing the display mode. 589 LayerHistory::Summary contentRequirements; 590 TimerState idleTimer = TimerState::Reset; 591 TouchState touch = TouchState::Inactive; 592 TimerState displayPowerTimer = TimerState::Expired; 593 hal::PowerMode displayPowerMode = hal::PowerMode::ON; 594 595 // Chosen display mode. 596 ftl::Optional<FrameRateMode> modeOpt; 597 598 // Display mode of latest emitted event. 599 std::optional<FrameRateMode> emittedModeOpt; 600 } mPolicy GUARDED_BY(mPolicyLock); 601 602 std::mutex mChoreographerLock; 603 604 struct AttachedChoreographers { 605 Fps frameRate; 606 std::unordered_set<wp<EventThreadConnection>, WpHash> connections; 607 }; 608 // Map keyed by layer ID (sequence) to choreographer connections. 609 std::unordered_map<int32_t, AttachedChoreographers> mAttachedChoreographers 610 GUARDED_BY(mChoreographerLock); 611 612 std::mutex mVsyncTimelineLock; 613 std::optional<hal::VsyncPeriodChangeTimeline> mLastVsyncPeriodChangeTimeline 614 GUARDED_BY(mVsyncTimelineLock); 615 static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms; 616 617 FrameRateOverrideMappings mFrameRateOverrideMappings; 618 SmallAreaDetectionAllowMappings mSmallAreaDetectionAllowMappings; 619 620 std::atomic<std::optional<TimePoint>> mDebugPresentDelay; 621 }; 622 623 } // namespace scheduler 624 } // namespace android 625