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