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