• 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 <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 ResyncCallback = std::function<void()>;
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, ResyncCallback,
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 
83     // Called in response to requestNextVsync.
84     const ResyncCallback resyncCallback;
85 
86     VSyncRequest vsyncRequest = VSyncRequest::None;
87     const uid_t mOwnerUid;
88     const EventRegistrationFlags mEventRegistration;
89 
90     /** The frame rate set to the attached choreographer. */
91     Fps frameRate;
92 
93 private:
94     virtual void onFirstRef();
95     EventThread* const mEventThread;
96     std::mutex mLock;
97     gui::BitTube mChannel GUARDED_BY(mLock);
98 
99     std::vector<DisplayEventReceiver::Event> mPendingEvents;
100 };
101 
102 class EventThread {
103 public:
104     virtual ~EventThread();
105 
106     virtual sp<EventThreadConnection> createEventConnection(
107             ResyncCallback, EventRegistrationFlags eventRegistration = {}) const = 0;
108 
109     // Feed clients with fake VSYNC, e.g. while the display is off.
110     virtual void enableSyntheticVsync(bool) = 0;
111 
112     virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0;
113 
114     // called when SF changes the active mode and apps needs to be notified about the change
115     virtual void onModeChanged(const scheduler::FrameRateMode&) = 0;
116 
117     // called when SF updates the Frame Rate Override list
118     virtual void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
119                                              std::vector<FrameRateOverride> overrides) = 0;
120 
121     virtual void dump(std::string& result) const = 0;
122 
123     virtual void setDuration(std::chrono::nanoseconds workDuration,
124                              std::chrono::nanoseconds readyDuration) = 0;
125 
126     virtual status_t registerDisplayEventConnection(
127             const sp<EventThreadConnection>& connection) = 0;
128     virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0;
129     // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
130     virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
131     virtual VsyncEventData getLatestVsyncEventData(
132             const sp<EventThreadConnection>& connection) const = 0;
133 
134     // Retrieves the number of event connections tracked by this EventThread.
135     virtual size_t getEventThreadConnectionCount() = 0;
136 
137     virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0;
138 };
139 
140 namespace impl {
141 
142 class EventThread : public android::EventThread {
143 public:
144     using ThrottleVsyncCallback = std::function<bool(nsecs_t, uid_t)>;
145     using GetVsyncPeriodFunction = std::function<nsecs_t(uid_t)>;
146 
147     EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule>,
148                 frametimeline::TokenManager*, ThrottleVsyncCallback, GetVsyncPeriodFunction,
149                 std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration);
150     ~EventThread();
151 
152     sp<EventThreadConnection> createEventConnection(
153             ResyncCallback, EventRegistrationFlags eventRegistration = {}) const override;
154 
155     status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
156     void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
157     void requestNextVsync(const sp<EventThreadConnection>& connection) override;
158     VsyncEventData getLatestVsyncEventData(
159             const sp<EventThreadConnection>& connection) const override;
160 
161     void enableSyntheticVsync(bool) override;
162 
163     void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override;
164 
165     void onModeChanged(const scheduler::FrameRateMode&) override;
166 
167     void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
168                                      std::vector<FrameRateOverride> overrides) override;
169 
170     void dump(std::string& result) const override;
171 
172     void setDuration(std::chrono::nanoseconds workDuration,
173                      std::chrono::nanoseconds readyDuration) override;
174 
175     size_t getEventThreadConnectionCount() override;
176 
177     void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override EXCLUDES(mMutex);
178 
179 private:
180     friend EventThreadTest;
181 
182     using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>;
183 
184     void threadMain(std::unique_lock<std::mutex>& lock) REQUIRES(mMutex);
185 
186     bool shouldConsumeEvent(const DisplayEventReceiver::Event& event,
187                             const sp<EventThreadConnection>& connection) const REQUIRES(mMutex);
188     void dispatchEvent(const DisplayEventReceiver::Event& event,
189                        const DisplayEventConsumers& consumers) REQUIRES(mMutex);
190 
191     void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection)
192             REQUIRES(mMutex);
193 
194     void onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime);
195 
196     int64_t generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp,
197                           nsecs_t expectedPresentationTime) const;
198     void generateFrameTimeline(VsyncEventData& outVsyncEventData, nsecs_t frameInterval,
199                                nsecs_t timestamp, nsecs_t preferredExpectedPresentationTime,
200                                nsecs_t preferredDeadlineTimestamp) const;
201 
202     scheduler::VSyncDispatch::Callback createDispatchCallback();
203 
204     // Returns the old registration so it can be destructed outside the lock to
205     // avoid deadlock.
206     scheduler::VSyncCallbackRegistration onNewVsyncScheduleInternal(
207             std::shared_ptr<scheduler::VsyncSchedule>) EXCLUDES(mMutex);
208 
209     const char* const mThreadName;
210     TracedOrdinal<int> mVsyncTracer;
211     TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex);
212     std::chrono::nanoseconds mReadyDuration GUARDED_BY(mMutex);
213     std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule GUARDED_BY(mMutex);
214     TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now();
215     scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex);
216     frametimeline::TokenManager* const mTokenManager;
217 
218     const ThrottleVsyncCallback mThrottleVsyncCallback;
219     const GetVsyncPeriodFunction mGetVsyncPeriodFunction;
220 
221     std::thread mThread;
222     mutable std::mutex mMutex;
223     mutable std::condition_variable mCondition;
224 
225     std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
226     std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
227 
228     // VSYNC state of connected display.
229     struct VSyncState {
VSyncStateVSyncState230         explicit VSyncState(PhysicalDisplayId displayId) : displayId(displayId) {}
231 
232         const PhysicalDisplayId displayId;
233 
234         // Number of VSYNC events since display was connected.
235         uint32_t count = 0;
236 
237         // True if VSYNC should be faked, e.g. when display is off.
238         bool synthetic = false;
239     };
240 
241     // TODO(b/74619554): Create per-display threads waiting on respective VSYNC signals,
242     // and support headless mode by injecting a fake display with synthetic VSYNC.
243     std::optional<VSyncState> mVSyncState GUARDED_BY(mMutex);
244 
245     // State machine for event loop.
246     enum class State {
247         Idle,
248         Quit,
249         SyntheticVSync,
250         VSync,
251     };
252 
253     State mState GUARDED_BY(mMutex) = State::Idle;
254 
255     static const char* toCString(State);
256 };
257 
258 // ---------------------------------------------------------------------------
259 
260 } // namespace impl
261 } // namespace android
262