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