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 <functional> 21 #include <memory> 22 #include <mutex> 23 #include <optional> 24 #include <unordered_map> 25 26 // TODO(b/129481165): remove the #pragma below and fix conversion issues 27 #pragma clang diagnostic push 28 #pragma clang diagnostic ignored "-Wconversion" 29 #pragma clang diagnostic ignored "-Wextra" 30 #include <ui/GraphicTypes.h> 31 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" 32 33 #include "EventThread.h" 34 #include "LayerHistory.h" 35 #include "OneShotTimer.h" 36 #include "RefreshRateConfigs.h" 37 #include "SchedulerUtils.h" 38 39 namespace android { 40 41 using namespace std::chrono_literals; 42 using scheduler::LayerHistory; 43 44 class FenceTime; 45 class InjectVSyncSource; 46 class PredictedVsyncTracer; 47 48 namespace scheduler { 49 class VsyncController; 50 class VSyncDispatch; 51 class VSyncTracker; 52 } // namespace scheduler 53 54 namespace frametimeline { 55 class TokenManager; 56 } // namespace frametimeline 57 58 struct ISchedulerCallback { 59 virtual void setVsyncEnabled(bool) = 0; 60 virtual void changeRefreshRate(const scheduler::RefreshRateConfigs::RefreshRate&, 61 scheduler::RefreshRateConfigEvent) = 0; 62 virtual void repaintEverythingForHWC() = 0; 63 virtual void kernelTimerChanged(bool expired) = 0; 64 virtual void triggerOnFrameRateOverridesChanged() = 0; 65 66 protected: 67 ~ISchedulerCallback() = default; 68 }; 69 70 class Scheduler { 71 public: 72 using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate; 73 using ModeEvent = scheduler::RefreshRateConfigEvent; 74 75 Scheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&); 76 ~Scheduler(); 77 78 using ConnectionHandle = scheduler::ConnectionHandle; 79 ConnectionHandle createConnection(const char* connectionName, frametimeline::TokenManager*, 80 std::chrono::nanoseconds workDuration, 81 std::chrono::nanoseconds readyDuration, 82 impl::EventThread::InterceptVSyncsCallback); 83 84 sp<IDisplayEventConnection> createDisplayEventConnection( 85 ConnectionHandle, ISurfaceComposer::EventRegistrationFlags eventRegistration = {}); 86 87 sp<EventThreadConnection> getEventConnection(ConnectionHandle); 88 89 void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected); 90 void onPrimaryDisplayModeChanged(ConnectionHandle, PhysicalDisplayId, DisplayModeId, 91 nsecs_t vsyncPeriod) EXCLUDES(mFeatureStateLock); 92 void onNonPrimaryDisplayModeChanged(ConnectionHandle, PhysicalDisplayId, DisplayModeId, 93 nsecs_t vsyncPeriod); 94 void onScreenAcquired(ConnectionHandle); 95 void onScreenReleased(ConnectionHandle); 96 97 void onFrameRateOverridesChanged(ConnectionHandle, PhysicalDisplayId) 98 EXCLUDES(mFrameRateOverridesMutex) EXCLUDES(mConnectionsLock); 99 100 // Modifies work duration in the event thread. 101 void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration, 102 std::chrono::nanoseconds readyDuration); 103 104 DisplayStatInfo getDisplayStatInfo(nsecs_t now); 105 106 // Returns injector handle if injection has toggled, or an invalid handle otherwise. 107 ConnectionHandle enableVSyncInjection(bool enable); 108 // Returns false if injection is disabled. 109 bool injectVSync(nsecs_t when, nsecs_t expectedVSyncTime, nsecs_t deadlineTimestamp); 110 void enableHardwareVsync(); 111 void disableHardwareVsync(bool makeUnavailable); 112 113 // Resyncs the scheduler to hardware vsync. 114 // If makeAvailable is true, then hardware vsync will be turned on. 115 // Otherwise, if hardware vsync is not already enabled then this method will 116 // no-op. 117 // The period is the vsync period from the current display configuration. 118 void resyncToHardwareVsync(bool makeAvailable, nsecs_t period); 119 void resync(); 120 121 // Passes a vsync sample to VsyncController. periodFlushed will be true if 122 // VsyncController detected that the vsync period changed, and false otherwise. 123 void addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod, 124 bool* periodFlushed); 125 void addPresentFence(const std::shared_ptr<FenceTime>&); 126 void setIgnorePresentFences(bool ignore); 127 128 // Layers are registered on creation, and unregistered when the weak reference expires. 129 void registerLayer(Layer*); 130 void recordLayerHistory(Layer*, nsecs_t presentTime, LayerHistory::LayerUpdateType updateType); 131 void setModeChangePending(bool pending); 132 void deregisterLayer(Layer*); 133 134 // Detects content using layer history, and selects a matching refresh rate. 135 void chooseRefreshRateForContent(); 136 isIdleTimerEnabled()137 bool isIdleTimerEnabled() const { return mIdleTimer.has_value(); } 138 void resetIdleTimer(); 139 140 // Function that resets the touch timer. 141 void notifyTouchEvent(); 142 143 void setDisplayPowerState(bool normal); 144 getVsyncDispatch()145 scheduler::VSyncDispatch& getVsyncDispatch() { return *mVsyncSchedule.dispatch; } 146 147 // Returns true if a given vsync timestamp is considered valid vsync 148 // for a given uid 149 bool isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const 150 EXCLUDES(mFrameRateOverridesMutex); 151 152 std::chrono::steady_clock::time_point getPreviousVsyncFrom(nsecs_t expectedPresentTime) const; 153 154 void dump(std::string&) const; 155 void dump(ConnectionHandle, std::string&) const; 156 void dumpVsync(std::string&) const; 157 158 // Get the appropriate refresh for current conditions. 159 std::optional<DisplayModeId> getPreferredModeId(); 160 161 // Notifies the scheduler about a refresh rate timeline change. 162 void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline); 163 164 // Notifies the scheduler when the display was refreshed 165 void onDisplayRefreshed(nsecs_t timestamp); 166 167 // Notifies the scheduler when the display size has changed. Called from SF's main thread 168 void onPrimaryDisplayAreaChanged(uint32_t displayArea); 169 170 size_t getEventThreadConnectionCount(ConnectionHandle handle); 171 172 std::unique_ptr<VSyncSource> makePrimaryDispSyncSource(const char* name, 173 std::chrono::nanoseconds workDuration, 174 std::chrono::nanoseconds readyDuration, 175 bool traceVsync = true); 176 177 // Stores the preferred refresh rate that an app should run at. 178 // FrameRateOverride.refreshRateHz == 0 means no preference. 179 void setPreferredRefreshRateForUid(FrameRateOverride) EXCLUDES(mFrameRateOverridesMutex); 180 // Retrieves the overridden refresh rate for a given uid. 181 std::optional<Fps> getFrameRateOverride(uid_t uid) const EXCLUDES(mFrameRateOverridesMutex); 182 183 private: 184 friend class TestableScheduler; 185 186 // In order to make sure that the features don't override themselves, we need a state machine 187 // to keep track which feature requested the config change. 188 enum class ContentDetectionState { Off, On }; 189 enum class TimerState { Reset, Expired }; 190 enum class TouchState { Inactive, Active }; 191 192 struct Options { 193 // Whether to use idle timer callbacks that support the kernel timer. 194 bool supportKernelTimer; 195 // Whether to use content detection at all. 196 bool useContentDetection; 197 }; 198 199 struct VsyncSchedule { 200 std::unique_ptr<scheduler::VsyncController> controller; 201 std::unique_ptr<scheduler::VSyncTracker> tracker; 202 std::unique_ptr<scheduler::VSyncDispatch> dispatch; 203 }; 204 205 // Unlike the testing constructor, this creates the VsyncSchedule, LayerHistory, and timers. 206 Scheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&, Options); 207 208 // Used by tests to inject mocks. 209 Scheduler(VsyncSchedule, const scheduler::RefreshRateConfigs&, ISchedulerCallback&, 210 std::unique_ptr<LayerHistory>, Options); 211 212 static VsyncSchedule createVsyncSchedule(bool supportKernelIdleTimer); 213 static std::unique_ptr<LayerHistory> createLayerHistory(const scheduler::RefreshRateConfigs&); 214 215 // Create a connection on the given EventThread. 216 ConnectionHandle createConnection(std::unique_ptr<EventThread>); 217 sp<EventThreadConnection> createConnectionInternal( 218 EventThread*, ISurfaceComposer::EventRegistrationFlags eventRegistration = {}); 219 220 // Update feature state machine to given state when corresponding timer resets or expires. 221 void kernelIdleTimerCallback(TimerState); 222 void idleTimerCallback(TimerState); 223 void touchTimerCallback(TimerState); 224 void displayPowerTimerCallback(TimerState); 225 226 // handles various timer features to change the refresh rate. 227 template <class T> 228 bool handleTimerStateChanged(T* currentState, T newState); 229 230 void setVsyncPeriod(nsecs_t period); 231 232 // This function checks whether individual features that are affecting the refresh rate 233 // selection were initialized, prioritizes them, and calculates the DisplayModeId 234 // for the suggested refresh rate. 235 DisplayModeId calculateRefreshRateModeId( 236 scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals = nullptr) 237 REQUIRES(mFeatureStateLock); 238 239 void dispatchCachedReportedMode() REQUIRES(mFeatureStateLock); 240 bool updateFrameRateOverrides(scheduler::RefreshRateConfigs::GlobalSignals consideredSignals, 241 Fps displayRefreshRate) REQUIRES(mFeatureStateLock) 242 EXCLUDES(mFrameRateOverridesMutex); 243 244 impl::EventThread::ThrottleVsyncCallback makeThrottleVsyncCallback() const; 245 impl::EventThread::GetVsyncPeriodFunction makeGetVsyncPeriodFunction() const; 246 247 // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection. 248 struct Connection { 249 sp<EventThreadConnection> connection; 250 std::unique_ptr<EventThread> thread; 251 }; 252 253 ConnectionHandle::Id mNextConnectionHandleId = 0; 254 mutable std::mutex mConnectionsLock; 255 std::unordered_map<ConnectionHandle, Connection> mConnections GUARDED_BY(mConnectionsLock); 256 257 bool mInjectVSyncs = false; 258 InjectVSyncSource* mVSyncInjector = nullptr; 259 ConnectionHandle mInjectorConnectionHandle; 260 261 std::mutex mHWVsyncLock; 262 bool mPrimaryHWVsyncEnabled GUARDED_BY(mHWVsyncLock) = false; 263 bool mHWVsyncAvailable GUARDED_BY(mHWVsyncLock) = false; 264 265 std::atomic<nsecs_t> mLastResyncTime = 0; 266 267 const Options mOptions; 268 VsyncSchedule mVsyncSchedule; 269 270 // Used to choose refresh rate if content detection is enabled. 271 std::unique_ptr<LayerHistory> mLayerHistory; 272 273 // Timer that records time between requests for next vsync. 274 std::optional<scheduler::OneShotTimer> mIdleTimer; 275 // Timer used to monitor touch events. 276 std::optional<scheduler::OneShotTimer> mTouchTimer; 277 // Timer used to monitor display power mode. 278 std::optional<scheduler::OneShotTimer> mDisplayPowerTimer; 279 280 ISchedulerCallback& mSchedulerCallback; 281 282 // In order to make sure that the features don't override themselves, we need a state machine 283 // to keep track which feature requested the config change. 284 mutable std::mutex mFeatureStateLock; 285 286 struct { 287 TimerState idleTimer = TimerState::Reset; 288 TouchState touch = TouchState::Inactive; 289 TimerState displayPowerTimer = TimerState::Expired; 290 291 std::optional<DisplayModeId> modeId; 292 LayerHistory::Summary contentRequirements; 293 294 bool isDisplayPowerStateNormal = true; 295 296 // Used to cache the last parameters of onPrimaryDisplayModeChanged 297 struct ModeChangedParams { 298 ConnectionHandle handle; 299 PhysicalDisplayId displayId; 300 DisplayModeId modeId; 301 nsecs_t vsyncPeriod; 302 }; 303 304 std::optional<ModeChangedParams> cachedModeChangedParams; 305 } mFeatures GUARDED_BY(mFeatureStateLock); 306 307 const scheduler::RefreshRateConfigs& mRefreshRateConfigs; 308 309 std::mutex mVsyncTimelineLock; 310 std::optional<hal::VsyncPeriodChangeTimeline> mLastVsyncPeriodChangeTimeline 311 GUARDED_BY(mVsyncTimelineLock); 312 static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms; 313 314 const std::unique_ptr<PredictedVsyncTracer> mPredictedVsyncTracer; 315 316 // The frame rate override lists need their own mutex as they are being read 317 // by SurfaceFlinger, Scheduler and EventThread (as a callback) to prevent deadlocks 318 mutable std::mutex mFrameRateOverridesMutex; 319 320 // mappings between a UID and a preferred refresh rate that this app would 321 // run at. 322 scheduler::RefreshRateConfigs::UidToFrameRateOverride mFrameRateOverridesByContent 323 GUARDED_BY(mFrameRateOverridesMutex); 324 scheduler::RefreshRateConfigs::UidToFrameRateOverride mFrameRateOverridesFromBackdoor 325 GUARDED_BY(mFrameRateOverridesMutex); 326 }; 327 328 } // namespace android 329