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 <gui/DisplayEventReceiver.h>
21 #include <gui/IDisplayEventConnection.h>
22 #include <private/gui/BitTube.h>
23 #include <sys/types.h>
24 #include <utils/Errors.h>
25 
26 #include <condition_variable>
27 #include <cstdint>
28 #include <deque>
29 #include <mutex>
30 #include <optional>
31 #include <thread>
32 #include <vector>
33 
34 #include "HwcStrongTypes.h"
35 
36 // ---------------------------------------------------------------------------
37 namespace android {
38 // ---------------------------------------------------------------------------
39 
40 class EventThread;
41 class EventThreadTest;
42 class SurfaceFlinger;
43 
44 // ---------------------------------------------------------------------------
45 
46 using ResyncCallback = std::function<void()>;
47 
48 enum class VSyncRequest {
49     None = -1,
50     Single = 0,
51     Periodic = 1,
52     // Subsequent values are periods.
53 };
54 
55 class VSyncSource {
56 public:
57     class Callback {
58     public:
~Callback()59         virtual ~Callback() {}
60         virtual void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) = 0;
61     };
62 
~VSyncSource()63     virtual ~VSyncSource() {}
64 
65     virtual const char* getName() const = 0;
66     virtual void setVSyncEnabled(bool enable) = 0;
67     virtual void setCallback(Callback* callback) = 0;
68     virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
69 
70     virtual void dump(std::string& result) const = 0;
71 };
72 
73 class EventThreadConnection : public BnDisplayEventConnection {
74 public:
75     EventThreadConnection(EventThread*, ResyncCallback,
76                           ISurfaceComposer::ConfigChanged configChanged);
77     virtual ~EventThreadConnection();
78 
79     virtual status_t postEvent(const DisplayEventReceiver::Event& event);
80 
81     status_t stealReceiveChannel(gui::BitTube* outChannel) override;
82     status_t setVsyncRate(uint32_t rate) override;
83     void requestNextVsync() override; // asynchronous
84     void requestLatestConfig() override; // asynchronous
85 
86     // Called in response to requestNextVsync.
87     const ResyncCallback resyncCallback;
88 
89     VSyncRequest vsyncRequest = VSyncRequest::None;
90     ISurfaceComposer::ConfigChanged mConfigChanged =
91             ISurfaceComposer::ConfigChanged::eConfigChangedSuppress;
92     // Store whether we need to force dispatching a config change separately -
93     // if mConfigChanged ever changes before the config change is dispatched
94     // then we still need to propagate an initial config to the app if we
95     // haven't already.
96     bool mForcedConfigChangeDispatch = false;
97 
98 private:
99     virtual void onFirstRef();
100     EventThread* const mEventThread;
101     gui::BitTube mChannel;
102 };
103 
104 class EventThread {
105 public:
106     virtual ~EventThread();
107 
108     virtual sp<EventThreadConnection> createEventConnection(
109             ResyncCallback, ISurfaceComposer::ConfigChanged configChanged) const = 0;
110 
111     // called before the screen is turned off from main thread
112     virtual void onScreenReleased() = 0;
113 
114     // called after the screen is turned on from main thread
115     virtual void onScreenAcquired() = 0;
116 
117     virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0;
118 
119     // called when SF changes the active config and apps needs to be notified about the change
120     virtual void onConfigChanged(PhysicalDisplayId displayId, HwcConfigIndexType configId,
121                                  nsecs_t vsyncPeriod) = 0;
122 
123     virtual void dump(std::string& result) const = 0;
124 
125     virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
126 
127     virtual status_t registerDisplayEventConnection(
128             const sp<EventThreadConnection>& connection) = 0;
129     virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0;
130     // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
131     virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
132     // Dispatches the most recent configuration
133     // Usage of this method assumes that only the primary internal display
134     // supports multiple display configurations.
135     virtual void requestLatestConfig(const sp<EventThreadConnection>& connection) = 0;
136 
137     // Retrieves the number of event connections tracked by this EventThread.
138     virtual size_t getEventThreadConnectionCount() = 0;
139 };
140 
141 namespace impl {
142 
143 class EventThread : public android::EventThread, private VSyncSource::Callback {
144 public:
145     using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
146 
147     EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback);
148     ~EventThread();
149 
150     sp<EventThreadConnection> createEventConnection(
151             ResyncCallback, ISurfaceComposer::ConfigChanged configChanged) const override;
152 
153     status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
154     void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
155     void requestNextVsync(const sp<EventThreadConnection>& connection) override;
156     void requestLatestConfig(const sp<EventThreadConnection>& connection) override;
157 
158     // called before the screen is turned off from main thread
159     void onScreenReleased() override;
160 
161     // called after the screen is turned on from main thread
162     void onScreenAcquired() override;
163 
164     void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override;
165 
166     void onConfigChanged(PhysicalDisplayId displayId, HwcConfigIndexType configId,
167                          nsecs_t vsyncPeriod) override;
168 
169     void dump(std::string& result) const override;
170 
171     void setPhaseOffset(nsecs_t phaseOffset) override;
172 
173     size_t getEventThreadConnectionCount() override;
174 
175 private:
176     friend EventThreadTest;
177 
178     using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>;
179 
180     void threadMain(std::unique_lock<std::mutex>& lock) REQUIRES(mMutex);
181 
182     bool shouldConsumeEvent(const DisplayEventReceiver::Event& event,
183                             const sp<EventThreadConnection>& connection) const REQUIRES(mMutex);
184     void dispatchEvent(const DisplayEventReceiver::Event& event,
185                        const DisplayEventConsumers& consumers) REQUIRES(mMutex);
186 
187     void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection)
188             REQUIRES(mMutex);
189 
190     // Implements VSyncSource::Callback
191     void onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) override;
192 
193     const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
194 
195     const InterceptVSyncsCallback mInterceptVSyncsCallback;
196     const char* const mThreadName;
197 
198     std::thread mThread;
199     mutable std::mutex mMutex;
200     mutable std::condition_variable mCondition;
201 
202     std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
203     std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
204     DisplayEventReceiver::Event mLastConfigChangeEvent GUARDED_BY(mMutex);
205 
206     // VSYNC state of connected display.
207     struct VSyncState {
VSyncStateVSyncState208         explicit VSyncState(PhysicalDisplayId displayId) : displayId(displayId) {}
209 
210         const PhysicalDisplayId displayId;
211 
212         // Number of VSYNC events since display was connected.
213         uint32_t count = 0;
214 
215         // True if VSYNC should be faked, e.g. when display is off.
216         bool synthetic = false;
217     };
218 
219     // TODO(b/74619554): Create per-display threads waiting on respective VSYNC signals,
220     // and support headless mode by injecting a fake display with synthetic VSYNC.
221     std::optional<VSyncState> mVSyncState GUARDED_BY(mMutex);
222 
223     // State machine for event loop.
224     enum class State {
225         Idle,
226         Quit,
227         SyntheticVSync,
228         VSync,
229     };
230 
231     State mState GUARDED_BY(mMutex) = State::Idle;
232 
233     static const char* toCString(State);
234 };
235 
236 // ---------------------------------------------------------------------------
237 
238 } // namespace impl
239 } // namespace android
240