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