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