summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dominik Laskowski <domlaskowski@google.com> 2019-01-22 12:44:53 -0800
committer Dominik Laskowski <domlaskowski@google.com> 2019-01-23 16:49:15 -0800
commit23b867a444d80222638922daff372f2e67d77dcc (patch)
tree7da0dd0c757e8b94eeb64e602d45d26042623572
parentd9e4de637603b6d534d7e331d3bc7f090802cde6 (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.cpp86
-rw-r--r--services/surfaceflinger/Scheduler/EventThread.h17
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;