xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Scheduler/EventThread.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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