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