1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2021 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 <functional> 20*38e8c45fSAndroid Build Coastguard Worker #include <memory> 21*38e8c45fSAndroid Build Coastguard Worker #include <string> 22*38e8c45fSAndroid Build Coastguard Worker 23*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h> 24*38e8c45fSAndroid Build Coastguard Worker #include <ThreadContext.h> 25*38e8c45fSAndroid Build Coastguard Worker #include <ftl/enum.h> 26*38e8c45fSAndroid Build Coastguard Worker #include <ftl/optional.h> 27*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayId.h> 28*38e8c45fSAndroid Build Coastguard Worker 29*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/Features.h> 30*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/IVsyncSource.h> 31*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/Time.h> 32*38e8c45fSAndroid Build Coastguard Worker 33*38e8c45fSAndroid Build Coastguard Worker #include "ThreadContext.h" 34*38e8c45fSAndroid Build Coastguard Worker #include "VSyncTracker.h" 35*38e8c45fSAndroid Build Coastguard Worker 36*38e8c45fSAndroid Build Coastguard Worker namespace android { 37*38e8c45fSAndroid Build Coastguard Worker class EventThreadTest; 38*38e8c45fSAndroid Build Coastguard Worker class VsyncScheduleTest; 39*38e8c45fSAndroid Build Coastguard Worker } 40*38e8c45fSAndroid Build Coastguard Worker 41*38e8c45fSAndroid Build Coastguard Worker namespace android::fuzz { 42*38e8c45fSAndroid Build Coastguard Worker class SchedulerFuzzer; 43*38e8c45fSAndroid Build Coastguard Worker } 44*38e8c45fSAndroid Build Coastguard Worker 45*38e8c45fSAndroid Build Coastguard Worker namespace android::scheduler { 46*38e8c45fSAndroid Build Coastguard Worker 47*38e8c45fSAndroid Build Coastguard Worker // TODO(b/185535769): Rename classes, and remove aliases. 48*38e8c45fSAndroid Build Coastguard Worker class VSyncDispatch; 49*38e8c45fSAndroid Build Coastguard Worker class VSyncTracker; 50*38e8c45fSAndroid Build Coastguard Worker 51*38e8c45fSAndroid Build Coastguard Worker class VsyncController; 52*38e8c45fSAndroid Build Coastguard Worker using VsyncDispatch = VSyncDispatch; 53*38e8c45fSAndroid Build Coastguard Worker using VsyncTracker = VSyncTracker; 54*38e8c45fSAndroid Build Coastguard Worker 55*38e8c45fSAndroid Build Coastguard Worker // Schedule that synchronizes to hardware VSYNC of a physical display. 56*38e8c45fSAndroid Build Coastguard Worker class VsyncSchedule final : public IVsyncSource { 57*38e8c45fSAndroid Build Coastguard Worker public: 58*38e8c45fSAndroid Build Coastguard Worker using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>; 59*38e8c45fSAndroid Build Coastguard Worker 60*38e8c45fSAndroid Build Coastguard Worker VsyncSchedule(ftl::NonNull<DisplayModePtr> modePtr, FeatureFlags, RequestHardwareVsync); 61*38e8c45fSAndroid Build Coastguard Worker ~VsyncSchedule(); 62*38e8c45fSAndroid Build Coastguard Worker 63*38e8c45fSAndroid Build Coastguard Worker // IVsyncSource overrides: 64*38e8c45fSAndroid Build Coastguard Worker Period period() const override; 65*38e8c45fSAndroid Build Coastguard Worker TimePoint vsyncDeadlineAfter(TimePoint, 66*38e8c45fSAndroid Build Coastguard Worker ftl::Optional<TimePoint> lastVsyncOpt = {}) const override; 67*38e8c45fSAndroid Build Coastguard Worker Period minFramePeriod() const override; 68*38e8c45fSAndroid Build Coastguard Worker 69*38e8c45fSAndroid Build Coastguard Worker // Inform the schedule that the display mode changed the schedule needs to recalibrate 70*38e8c45fSAndroid Build Coastguard Worker // itself to the new vsync period. The schedule will end the period transition internally. 71*38e8c45fSAndroid Build Coastguard Worker // This will enable hardware VSYNCs in order to calibrate. 72*38e8c45fSAndroid Build Coastguard Worker // 73*38e8c45fSAndroid Build Coastguard Worker // \param [in] DisplayModePtr The mode that the display is changing to. 74*38e8c45fSAndroid Build Coastguard Worker // \param [in] force True to force a transition even if it is not a 75*38e8c45fSAndroid Build Coastguard Worker // change. 76*38e8c45fSAndroid Build Coastguard Worker void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force); 77*38e8c45fSAndroid Build Coastguard Worker 78*38e8c45fSAndroid Build Coastguard Worker // Pass a VSYNC sample to VsyncController. Return true if 79*38e8c45fSAndroid Build Coastguard Worker // VsyncController detected that the VSYNC period changed. Enable or disable 80*38e8c45fSAndroid Build Coastguard Worker // hardware VSYNCs depending on whether more samples are needed. 81*38e8c45fSAndroid Build Coastguard Worker bool addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod); 82*38e8c45fSAndroid Build Coastguard Worker 83*38e8c45fSAndroid Build Coastguard Worker // TODO(b/185535769): Hide behind API. getTracker()84*38e8c45fSAndroid Build Coastguard Worker VsyncTracker& getTracker() const { return *mTracker; } getTracker()85*38e8c45fSAndroid Build Coastguard Worker VsyncTracker& getTracker() { return *mTracker; } getController()86*38e8c45fSAndroid Build Coastguard Worker VsyncController& getController() { return *mController; } 87*38e8c45fSAndroid Build Coastguard Worker 88*38e8c45fSAndroid Build Coastguard Worker // TODO(b/185535769): Once these are hidden behind the API, they may no 89*38e8c45fSAndroid Build Coastguard Worker // longer need to be shared_ptrs. 90*38e8c45fSAndroid Build Coastguard Worker using DispatchPtr = std::shared_ptr<VsyncDispatch>; 91*38e8c45fSAndroid Build Coastguard Worker using TrackerPtr = std::shared_ptr<VsyncTracker>; 92*38e8c45fSAndroid Build Coastguard Worker 93*38e8c45fSAndroid Build Coastguard Worker // TODO(b/185535769): Remove once VsyncSchedule owns all registrations. getDispatch()94*38e8c45fSAndroid Build Coastguard Worker DispatchPtr getDispatch() { return mDispatch; } 95*38e8c45fSAndroid Build Coastguard Worker 96*38e8c45fSAndroid Build Coastguard Worker void dump(std::string&) const; 97*38e8c45fSAndroid Build Coastguard Worker 98*38e8c45fSAndroid Build Coastguard Worker // Turn on hardware VSYNCs, unless mHwVsyncState is Disallowed, in which 99*38e8c45fSAndroid Build Coastguard Worker // case this call is ignored. 100*38e8c45fSAndroid Build Coastguard Worker void enableHardwareVsync() EXCLUDES(mHwVsyncLock); 101*38e8c45fSAndroid Build Coastguard Worker 102*38e8c45fSAndroid Build Coastguard Worker // Disable hardware VSYNCs. If `disallow` is true, future calls to 103*38e8c45fSAndroid Build Coastguard Worker // enableHardwareVsync are ineffective until isHardwareVsyncAllowed is 104*38e8c45fSAndroid Build Coastguard Worker // called with `makeAllowed` set to true. 105*38e8c45fSAndroid Build Coastguard Worker void disableHardwareVsync(bool disallow) EXCLUDES(mHwVsyncLock); 106*38e8c45fSAndroid Build Coastguard Worker 107*38e8c45fSAndroid Build Coastguard Worker // If true, enableHardwareVsync can enable hardware VSYNC (if not already 108*38e8c45fSAndroid Build Coastguard Worker // enabled). If false, enableHardwareVsync does nothing. 109*38e8c45fSAndroid Build Coastguard Worker bool isHardwareVsyncAllowed(bool makeAllowed) EXCLUDES(mHwVsyncLock); 110*38e8c45fSAndroid Build Coastguard Worker 111*38e8c45fSAndroid Build Coastguard Worker void setPendingHardwareVsyncState(bool enabled) REQUIRES(kMainThreadContext); 112*38e8c45fSAndroid Build Coastguard Worker 113*38e8c45fSAndroid Build Coastguard Worker bool getPendingHardwareVsyncState() const REQUIRES(kMainThreadContext); 114*38e8c45fSAndroid Build Coastguard Worker getPhysicalDisplayId()115*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId getPhysicalDisplayId() const { return mId; } 116*38e8c45fSAndroid Build Coastguard Worker 117*38e8c45fSAndroid Build Coastguard Worker protected: 118*38e8c45fSAndroid Build Coastguard Worker using ControllerPtr = std::unique_ptr<VsyncController>; 119*38e8c45fSAndroid Build Coastguard Worker NoOpRequestHardwareVsync(PhysicalDisplayId,bool)120*38e8c45fSAndroid Build Coastguard Worker static void NoOpRequestHardwareVsync(PhysicalDisplayId, bool) {} 121*38e8c45fSAndroid Build Coastguard Worker 122*38e8c45fSAndroid Build Coastguard Worker // For tests. 123*38e8c45fSAndroid Build Coastguard Worker VsyncSchedule(PhysicalDisplayId, TrackerPtr, DispatchPtr, ControllerPtr, 124*38e8c45fSAndroid Build Coastguard Worker RequestHardwareVsync = NoOpRequestHardwareVsync); 125*38e8c45fSAndroid Build Coastguard Worker 126*38e8c45fSAndroid Build Coastguard Worker private: 127*38e8c45fSAndroid Build Coastguard Worker friend class TestableScheduler; 128*38e8c45fSAndroid Build Coastguard Worker friend class android::EventThreadTest; 129*38e8c45fSAndroid Build Coastguard Worker friend class android::VsyncScheduleTest; 130*38e8c45fSAndroid Build Coastguard Worker friend class android::fuzz::SchedulerFuzzer; 131*38e8c45fSAndroid Build Coastguard Worker 132*38e8c45fSAndroid Build Coastguard Worker static TrackerPtr createTracker(ftl::NonNull<DisplayModePtr> modePtr); 133*38e8c45fSAndroid Build Coastguard Worker static DispatchPtr createDispatch(TrackerPtr); 134*38e8c45fSAndroid Build Coastguard Worker static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags); 135*38e8c45fSAndroid Build Coastguard Worker 136*38e8c45fSAndroid Build Coastguard Worker void enableHardwareVsyncLocked() REQUIRES(mHwVsyncLock); 137*38e8c45fSAndroid Build Coastguard Worker 138*38e8c45fSAndroid Build Coastguard Worker mutable std::mutex mHwVsyncLock; 139*38e8c45fSAndroid Build Coastguard Worker enum class HwVsyncState { 140*38e8c45fSAndroid Build Coastguard Worker // Hardware VSYNCs are currently enabled. 141*38e8c45fSAndroid Build Coastguard Worker Enabled, 142*38e8c45fSAndroid Build Coastguard Worker 143*38e8c45fSAndroid Build Coastguard Worker // Hardware VSYNCs are currently disabled. They can be enabled by a call 144*38e8c45fSAndroid Build Coastguard Worker // to `enableHardwareVsync`. 145*38e8c45fSAndroid Build Coastguard Worker Disabled, 146*38e8c45fSAndroid Build Coastguard Worker 147*38e8c45fSAndroid Build Coastguard Worker // Hardware VSYNCs are not currently allowed (e.g. because the display 148*38e8c45fSAndroid Build Coastguard Worker // is off). 149*38e8c45fSAndroid Build Coastguard Worker Disallowed, 150*38e8c45fSAndroid Build Coastguard Worker 151*38e8c45fSAndroid Build Coastguard Worker ftl_last = Disallowed, 152*38e8c45fSAndroid Build Coastguard Worker }; 153*38e8c45fSAndroid Build Coastguard Worker HwVsyncState mHwVsyncState GUARDED_BY(mHwVsyncLock) = HwVsyncState::Disallowed; 154*38e8c45fSAndroid Build Coastguard Worker 155*38e8c45fSAndroid Build Coastguard Worker // Pending state, in case an attempt is made to set the state while the 156*38e8c45fSAndroid Build Coastguard Worker // device is off. 157*38e8c45fSAndroid Build Coastguard Worker HwVsyncState mPendingHwVsyncState GUARDED_BY(kMainThreadContext) = HwVsyncState::Disabled; 158*38e8c45fSAndroid Build Coastguard Worker 159*38e8c45fSAndroid Build Coastguard Worker class PredictedVsyncTracer; 160*38e8c45fSAndroid Build Coastguard Worker using TracerPtr = std::unique_ptr<PredictedVsyncTracer>; 161*38e8c45fSAndroid Build Coastguard Worker 162*38e8c45fSAndroid Build Coastguard Worker const PhysicalDisplayId mId; 163*38e8c45fSAndroid Build Coastguard Worker const RequestHardwareVsync mRequestHardwareVsync; 164*38e8c45fSAndroid Build Coastguard Worker const TrackerPtr mTracker; 165*38e8c45fSAndroid Build Coastguard Worker const DispatchPtr mDispatch; 166*38e8c45fSAndroid Build Coastguard Worker const ControllerPtr mController; 167*38e8c45fSAndroid Build Coastguard Worker const TracerPtr mTracer; 168*38e8c45fSAndroid Build Coastguard Worker }; 169*38e8c45fSAndroid Build Coastguard Worker 170*38e8c45fSAndroid Build Coastguard Worker } // namespace android::scheduler 171