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