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