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