diff options
| author | 2019-01-22 12:44:53 -0800 | |
|---|---|---|
| committer | 2019-01-23 16:49:15 -0800 | |
| commit | 23b867a444d80222638922daff372f2e67d77dcc (patch) | |
| tree | 7da0dd0c757e8b94eeb64e602d45d26042623572 | |
| parent | d9e4de637603b6d534d7e331d3bc7f090802cde6 (diff) | |
SF: Remove fixed-size array for VSYNC events
EventThread maintains two DisplayEventReceiver::Event instances to store
the latest VSYNC state for the internal and external displays, regardless
of their connection status. This CL removes the (unused) latter instance,
replaces the former with VSyncState, and generalizes event processing by
queuing up VSYNC events along with hotplug events.
The VSyncState lifetime will be tied to hotplug events in a future CL.
Bug: 74619554
Test: libsurfaceflinger_unittest
Test: dumpsys SurfaceFlinger --vsync
Change-Id: I5fbc1d08259145387dab73596a0cfe4624c35676
| -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; |