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