diff options
| -rw-r--r-- | services/surfaceflinger/Scheduler/EventThread.cpp | 86 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/EventThread.h | 17 |
2 files changed, 51 insertions, 52 deletions
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 01aedf45d7..281f6b7069 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -79,6 +79,20 @@ std::string toString(const DisplayEventReceiver::Event& event) { } } +DisplayEventReceiver::Event makeHotplug(uint32_t displayId, nsecs_t timestamp, bool connected) { + DisplayEventReceiver::Event event; + event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, displayId, timestamp}; + event.hotplug.connected = connected; + return event; +} + +DisplayEventReceiver::Event makeVSync(uint32_t displayId, nsecs_t timestamp, uint32_t count) { + DisplayEventReceiver::Event event; + event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp}; + event.vsync.count = count; + return event; +} + } // namespace EventThreadConnection::EventThreadConnection(EventThread* eventThread, @@ -149,12 +163,6 @@ EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSr if (src == nullptr) { mVSyncSource = mVSyncSourceUnique.get(); } - for (auto& event : mVSyncEvent) { - event.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; - event.header.id = 0; - event.header.timestamp = 0; - event.vsync.count = 0; - } mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS { std::unique_lock<std::mutex> lock(mMutex); @@ -253,41 +261,32 @@ void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection, void EventThread::onScreenReleased() { std::lock_guard<std::mutex> lock(mMutex); - if (!mUseSoftwareVSync) { - // disable reliance on h/w vsync - mUseSoftwareVSync = true; + if (!mVSyncState.synthetic) { + mVSyncState.synthetic = true; mCondition.notify_all(); } } void EventThread::onScreenAcquired() { std::lock_guard<std::mutex> lock(mMutex); - if (mUseSoftwareVSync) { - // resume use of h/w vsync - mUseSoftwareVSync = false; + if (mVSyncState.synthetic) { + mVSyncState.synthetic = false; mCondition.notify_all(); } } void EventThread::onVSyncEvent(nsecs_t timestamp) { std::lock_guard<std::mutex> lock(mMutex); - mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; - mVSyncEvent[0].header.id = 0; - mVSyncEvent[0].header.timestamp = timestamp; - mVSyncEvent[0].vsync.count++; + + mPendingEvents.push_back(makeVSync(mVSyncState.displayId, timestamp, ++mVSyncState.count)); mCondition.notify_all(); } void EventThread::onHotplugReceived(DisplayType displayType, bool connected) { std::lock_guard<std::mutex> lock(mMutex); - DisplayEventReceiver::Event event; - event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG; - event.header.id = displayType == DisplayType::Primary ? 0 : 1; - event.header.timestamp = systemTime(); - event.hotplug.connected = connected; - - mPendingEvents.push_back(event); + const uint32_t displayId = displayType == DisplayType::Primary ? 0 : 1; + mPendingEvents.push_back(makeHotplug(displayId, systemTime(), connected)); mCondition.notify_all(); } @@ -301,18 +300,13 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { if (!mPendingEvents.empty()) { event = mPendingEvents.front(); mPendingEvents.pop_front(); - } else { - for (auto& vsyncEvent : mVSyncEvent) { - if (vsyncEvent.header.timestamp) { - event = vsyncEvent; - vsyncEvent.header.timestamp = 0; - - if (mInterceptVSyncsCallback) { - mInterceptVSyncsCallback(event->header.timestamp); - } - break; - } - } + } + + const bool vsyncPending = + event && event->header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC; + + if (mInterceptVSyncsCallback && vsyncPending) { + mInterceptVSyncsCallback(event->header.timestamp); } bool vsyncRequested = false; @@ -338,9 +332,6 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { consumers.clear(); } - const bool vsyncPending = - event && event->header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC; - // Here we figure out if we need to enable or disable vsyncs if (vsyncPending && !vsyncRequested) { // we received a VSYNC but we have no clients @@ -364,15 +355,13 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { if (vsyncRequested) { // Generate a fake VSYNC after a long timeout in case the driver stalls. When the // display is off, keep feeding clients at 60 Hz. - const bool softwareSync = mUseSoftwareVSync; - const auto timeout = softwareSync ? 16ms : 1000ms; + const auto timeout = mVSyncState.synthetic ? 16ms : 1000ms; if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) { - ALOGW_IF(!softwareSync, "Faking VSYNC due to driver stall"); + ALOGW_IF(!mVSyncState.synthetic, "Faking VSYNC due to driver stall"); - mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; - mVSyncEvent[0].header.id = 0; - mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC); - mVSyncEvent[0].vsync.count++; + mPendingEvents.push_back(makeVSync(mVSyncState.displayId, + systemTime(SYSTEM_TIME_MONOTONIC), + ++mVSyncState.count)); } } else { mCondition.wait(lock); @@ -425,8 +414,7 @@ void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event, } void EventThread::enableVSyncLocked() { - if (!mUseSoftwareVSync) { - // never enable h/w VSYNC when screen is off + if (!mVSyncState.synthetic) { if (!mVsyncEnabled) { mVsyncEnabled = true; mVSyncSource->setCallback(this); @@ -448,8 +436,8 @@ void EventThread::dump(std::string& result) const { std::lock_guard<std::mutex> lock(mMutex); StringAppendF(&result, "%s: VSYNC %s\n", mThreadName, mDebugVsyncEnabled ? "on" : "off"); - StringAppendF(&result, " software VSYNC: %s\n", mUseSoftwareVSync ? "on" : "off"); - StringAppendF(&result, " VSYNC count: %u\n", mVSyncEvent[0].vsync.count); + StringAppendF(&result, " VSyncState{displayId=%u, count=%u%s}\n", mVSyncState.displayId, + mVSyncState.count, mVSyncState.synthetic ? ", synthetic" : ""); StringAppendF(&result, " pending events (count=%zu):\n", mPendingEvents.size()); for (const auto& event : mPendingEvents) { diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index b622e7abc5..1a8ebb7903 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -18,7 +18,6 @@ #include <sys/types.h> -#include <array> #include <condition_variable> #include <cstdint> #include <deque> @@ -199,8 +198,20 @@ private: std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex); std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex); - std::array<DisplayEventReceiver::Event, 2> mVSyncEvent GUARDED_BY(mMutex); - bool mUseSoftwareVSync GUARDED_BY(mMutex) = false; + + // VSYNC state of connected display. + struct VSyncState { + uint32_t displayId = 0; + + // Number of VSYNC events since display was connected. + uint32_t count = 0; + + // True if VSYNC should be faked, e.g. when display is off. + bool synthetic = false; + }; + + VSyncState mVSyncState GUARDED_BY(mMutex); + bool mVsyncEnabled GUARDED_BY(mMutex) = false; bool mKeepRunning GUARDED_BY(mMutex) = true; |