• 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 <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 
85     // Called in response to requestNextVsync.
86     const ResyncCallback resyncCallback;
87 
88     VSyncRequest vsyncRequest = VSyncRequest::None;
89     const ISurfaceComposer::ConfigChanged mConfigChanged =
90             ISurfaceComposer::ConfigChanged::eConfigChangedSuppress;
91 
92 private:
93     virtual void onFirstRef();
94     EventThread* const mEventThread;
95     gui::BitTube mChannel;
96 };
97 
98 class EventThread {
99 public:
100     virtual ~EventThread();
101 
102     virtual sp<EventThreadConnection> createEventConnection(
103             ResyncCallback, ISurfaceComposer::ConfigChanged configChanged) const = 0;
104 
105     // called before the screen is turned off from main thread
106     virtual void onScreenReleased() = 0;
107 
108     // called after the screen is turned on from main thread
109     virtual void onScreenAcquired() = 0;
110 
111     virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0;
112 
113     // called when SF changes the active config and apps needs to be notified about the change
114     virtual void onConfigChanged(PhysicalDisplayId displayId, HwcConfigIndexType configId,
115                                  nsecs_t vsyncPeriod) = 0;
116 
117     virtual void dump(std::string& result) const = 0;
118 
119     virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
120 
121     virtual status_t registerDisplayEventConnection(
122             const sp<EventThreadConnection>& connection) = 0;
123     virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0;
124     // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
125     virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
126 
127     // Retrieves the number of event connections tracked by this EventThread.
128     virtual size_t getEventThreadConnectionCount() = 0;
129 };
130 
131 namespace impl {
132 
133 class EventThread : public android::EventThread, private VSyncSource::Callback {
134 public:
135     using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
136 
137     EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback);
138     ~EventThread();
139 
140     sp<EventThreadConnection> createEventConnection(
141             ResyncCallback, ISurfaceComposer::ConfigChanged configChanged) const override;
142 
143     status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
144     void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
145     void requestNextVsync(const sp<EventThreadConnection>& connection) override;
146 
147     // called before the screen is turned off from main thread
148     void onScreenReleased() override;
149 
150     // called after the screen is turned on from main thread
151     void onScreenAcquired() override;
152 
153     void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override;
154 
155     void onConfigChanged(PhysicalDisplayId displayId, HwcConfigIndexType configId,
156                          nsecs_t vsyncPeriod) override;
157 
158     void dump(std::string& result) const override;
159 
160     void setPhaseOffset(nsecs_t phaseOffset) override;
161 
162     size_t getEventThreadConnectionCount() override;
163 
164 private:
165     friend EventThreadTest;
166 
167     using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>;
168 
169     void threadMain(std::unique_lock<std::mutex>& lock) REQUIRES(mMutex);
170 
171     bool shouldConsumeEvent(const DisplayEventReceiver::Event& event,
172                             const sp<EventThreadConnection>& connection) const REQUIRES(mMutex);
173     void dispatchEvent(const DisplayEventReceiver::Event& event,
174                        const DisplayEventConsumers& consumers) REQUIRES(mMutex);
175 
176     void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection)
177             REQUIRES(mMutex);
178 
179     // Implements VSyncSource::Callback
180     void onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) override;
181 
182     const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
183 
184     const InterceptVSyncsCallback mInterceptVSyncsCallback;
185     const char* const mThreadName;
186 
187     std::thread mThread;
188     mutable std::mutex mMutex;
189     mutable std::condition_variable mCondition;
190 
191     std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
192     std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
193 
194     // VSYNC state of connected display.
195     struct VSyncState {
VSyncStateVSyncState196         explicit VSyncState(PhysicalDisplayId displayId) : displayId(displayId) {}
197 
198         const PhysicalDisplayId displayId;
199 
200         // Number of VSYNC events since display was connected.
201         uint32_t count = 0;
202 
203         // True if VSYNC should be faked, e.g. when display is off.
204         bool synthetic = false;
205     };
206 
207     // TODO(b/74619554): Create per-display threads waiting on respective VSYNC signals,
208     // and support headless mode by injecting a fake display with synthetic VSYNC.
209     std::optional<VSyncState> mVSyncState GUARDED_BY(mMutex);
210 
211     // State machine for event loop.
212     enum class State {
213         Idle,
214         Quit,
215         SyntheticVSync,
216         VSync,
217     };
218 
219     State mState GUARDED_BY(mMutex) = State::Idle;
220 
221     static const char* toCString(State);
222 };
223 
224 // ---------------------------------------------------------------------------
225 
226 } // namespace impl
227 } // namespace android
228