1 /* 2 * Copyright (C) 2011 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 <android-base/thread_annotations.h> 20 #include <android/gui/BnDisplayEventConnection.h> 21 #include <gui/DisplayEventReceiver.h> 22 #include <private/gui/BitTube.h> 23 #include <sys/types.h> 24 #include <ui/DisplayId.h> 25 #include <utils/Errors.h> 26 27 #include <scheduler/FrameRateMode.h> 28 #include <condition_variable> 29 #include <cstdint> 30 #include <deque> 31 #include <mutex> 32 #include <optional> 33 #include <thread> 34 #include <vector> 35 36 #include "DisplayHardware/DisplayMode.h" 37 #include "TracedOrdinal.h" 38 #include "VSyncDispatch.h" 39 #include "VsyncSchedule.h" 40 41 // --------------------------------------------------------------------------- 42 namespace android { 43 // --------------------------------------------------------------------------- 44 45 class EventThread; 46 class EventThreadTest; 47 class SurfaceFlinger; 48 49 namespace frametimeline { 50 class TokenManager; 51 } // namespace frametimeline 52 53 using gui::ParcelableVsyncEventData; 54 using gui::VsyncEventData; 55 56 // --------------------------------------------------------------------------- 57 58 using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride; 59 using BufferStuffingMap = ftl::SmallMap<uid_t, uint32_t, 10>; 60 61 enum class VSyncRequest { 62 None = -2, 63 // Single wakes up for the next two frames to avoid scheduler overhead 64 Single = -1, 65 // SingleSuppressCallback only wakes up for the next frame 66 SingleSuppressCallback = 0, 67 Periodic = 1, 68 // Subsequent values are periods. 69 }; 70 71 class EventThreadConnection : public gui::BnDisplayEventConnection { 72 public: 73 EventThreadConnection(EventThread*, uid_t callingUid, 74 EventRegistrationFlags eventRegistration = {}); 75 virtual ~EventThreadConnection(); 76 77 virtual status_t postEvent(const DisplayEventReceiver::Event& event); 78 79 binder::Status stealReceiveChannel(gui::BitTube* outChannel) override; 80 binder::Status setVsyncRate(int rate) override; 81 binder::Status requestNextVsync() override; // asynchronous 82 binder::Status getLatestVsyncEventData(ParcelableVsyncEventData* outVsyncEventData) override; 83 binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) override; 84 85 VSyncRequest vsyncRequest = VSyncRequest::None; 86 const uid_t mOwnerUid; 87 const EventRegistrationFlags mEventRegistration; 88 89 /** The frame rate set to the attached choreographer. */ 90 Fps frameRate; 91 92 private: 93 virtual void onFirstRef(); 94 EventThread* const mEventThread; 95 std::mutex mLock; 96 gui::BitTube mChannel GUARDED_BY(mLock); 97 98 std::vector<DisplayEventReceiver::Event> mPendingEvents; 99 }; 100 101 class EventThread { 102 public: 103 virtual ~EventThread(); 104 105 virtual sp<EventThreadConnection> createEventConnection( 106 EventRegistrationFlags eventRegistration = {}) const = 0; 107 108 // Feed clients with fake VSYNC, e.g. while the display is off. 109 virtual void enableSyntheticVsync(bool) = 0; 110 111 virtual void omitVsyncDispatching(bool) = 0; 112 113 virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0; 114 115 virtual void onHotplugConnectionError(int32_t connectionError) = 0; 116 117 // called when SF changes the active mode and apps needs to be notified about the change 118 virtual void onModeChanged(const scheduler::FrameRateMode&) = 0; 119 120 // called when SF rejects the mode change request 121 virtual void onModeRejected(PhysicalDisplayId displayId, DisplayModeId modeId) = 0; 122 123 // called when SF updates the Frame Rate Override list 124 virtual void onFrameRateOverridesChanged(PhysicalDisplayId displayId, 125 std::vector<FrameRateOverride> overrides) = 0; 126 127 virtual void dump(std::string& result) const = 0; 128 129 virtual void setDuration(std::chrono::nanoseconds workDuration, 130 std::chrono::nanoseconds readyDuration) = 0; 131 132 virtual status_t registerDisplayEventConnection( 133 const sp<EventThreadConnection>& connection) = 0; 134 virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0; 135 // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer. 136 virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0; 137 virtual VsyncEventData getLatestVsyncEventData(const sp<EventThreadConnection>& connection, 138 nsecs_t now) const = 0; 139 140 virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0; 141 142 virtual void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel, 143 int32_t maxLevel) = 0; 144 145 // An elevated number of queued buffers in the server is detected. This propagates a 146 // flag to Choreographer indicating that buffer stuffing recovery should begin. 147 virtual void addBufferStuffedUids(BufferStuffingMap bufferStuffedUids); 148 }; 149 150 struct IEventThreadCallback { 151 virtual ~IEventThreadCallback() = default; 152 153 virtual bool throttleVsync(TimePoint, uid_t) = 0; 154 virtual Period getVsyncPeriod(uid_t) = 0; 155 virtual void resync() = 0; 156 virtual void onExpectedPresentTimePosted(TimePoint) = 0; 157 }; 158 159 namespace impl { 160 161 class EventThread : public android::EventThread { 162 public: 163 EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule>, 164 frametimeline::TokenManager*, IEventThreadCallback& callback, 165 std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration); 166 ~EventThread(); 167 168 sp<EventThreadConnection> createEventConnection( 169 EventRegistrationFlags eventRegistration = {}) const override; 170 171 status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override; 172 void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override; 173 void requestNextVsync(const sp<EventThreadConnection>& connection) override; 174 VsyncEventData getLatestVsyncEventData(const sp<EventThreadConnection>& connection, 175 nsecs_t now) const override; 176 177 void enableSyntheticVsync(bool) override; 178 179 void omitVsyncDispatching(bool) override; 180 181 void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override; 182 183 void onHotplugConnectionError(int32_t connectionError) override; 184 185 void onModeChanged(const scheduler::FrameRateMode&) override; 186 187 void onModeRejected(PhysicalDisplayId displayId, DisplayModeId modeId) override; 188 189 void onFrameRateOverridesChanged(PhysicalDisplayId displayId, 190 std::vector<FrameRateOverride> overrides) override; 191 192 void dump(std::string& result) const override; 193 194 void setDuration(std::chrono::nanoseconds workDuration, 195 std::chrono::nanoseconds readyDuration) override; 196 197 void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override EXCLUDES(mMutex); 198 199 void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel, 200 int32_t maxLevel) override; 201 202 void addBufferStuffedUids(BufferStuffingMap bufferStuffedUids) override; 203 204 private: 205 friend EventThreadTest; 206 207 using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>; 208 209 void threadMain(std::unique_lock<std::mutex>& lock) REQUIRES(mMutex); 210 211 bool shouldConsumeEvent(const DisplayEventReceiver::Event& event, 212 const sp<EventThreadConnection>& connection) const REQUIRES(mMutex); 213 void dispatchEvent(const DisplayEventReceiver::Event& event, 214 const DisplayEventConsumers& consumers) REQUIRES(mMutex); 215 216 void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection) 217 REQUIRES(mMutex); 218 219 void onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime); 220 221 int64_t generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp, 222 nsecs_t expectedPresentationTime) const; 223 void generateFrameTimeline(VsyncEventData& outVsyncEventData, nsecs_t frameInterval, 224 nsecs_t timestamp, nsecs_t preferredExpectedPresentationTime, 225 nsecs_t preferredDeadlineTimestamp) const; 226 227 scheduler::VSyncDispatch::Callback createDispatchCallback(); 228 229 // Returns the old registration so it can be destructed outside the lock to 230 // avoid deadlock. 231 scheduler::VSyncCallbackRegistration onNewVsyncScheduleInternal( 232 std::shared_ptr<scheduler::VsyncSchedule>) EXCLUDES(mMutex); 233 234 const char* const mThreadName; 235 TracedOrdinal<int> mVsyncTracer; 236 TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex); 237 std::chrono::nanoseconds mReadyDuration GUARDED_BY(mMutex); 238 std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule GUARDED_BY(mMutex); 239 TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now(); 240 TimePoint mLastCommittedVsyncTime GUARDED_BY(mMutex) = TimePoint::now(); 241 scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex); 242 frametimeline::TokenManager* const mTokenManager; 243 244 // All consumers that need to recover from buffer stuffing and the number 245 // of their queued buffers. 246 BufferStuffingMap mBufferStuffedUids GUARDED_BY(mMutex); 247 248 IEventThreadCallback& mCallback; 249 250 std::thread mThread; 251 mutable std::mutex mMutex; 252 mutable std::condition_variable mCondition; 253 254 std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex); 255 std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex); 256 257 // VSYNC state of connected display. 258 struct VSyncState { 259 // Number of VSYNC events since display was connected. 260 uint32_t count = 0; 261 262 // True if VSYNC should be faked, e.g. when display is off. 263 bool synthetic = false; 264 265 // True if VSYNC should not be delivered to apps. Used when the display is off. 266 bool omitted = false; 267 }; 268 269 // TODO(b/74619554): Create per-display threads waiting on respective VSYNC signals, 270 // and support headless mode by injecting a fake display with synthetic VSYNC. 271 std::optional<VSyncState> mVSyncState GUARDED_BY(mMutex); 272 273 // State machine for event loop. 274 enum class State { 275 Idle, 276 Quit, 277 SyntheticVSync, 278 VSync, 279 }; 280 281 State mState GUARDED_BY(mMutex) = State::Idle; 282 283 static const char* toCString(State); 284 }; 285 286 // --------------------------------------------------------------------------- 287 288 } // namespace impl 289 } // namespace android 290