SurfaceFlinger: SW-based vsync events
This change adds the DispSync class, which models the hardware vsync event
times to allow vsync event callbacks to be done at an arbitrary phase offset
from the hardware vsync. This can be used to reduce the minimum latency from
Choreographer wake-up to on-screen image presentation.
Bug: 10624956
Change-Id: I8c7a54ceacaa4d709726ed97b0dcae4093a7bdcf
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index a61ad72..3528b62 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -36,9 +36,10 @@
namespace android {
// ---------------------------------------------------------------------------
-EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
- : mFlinger(flinger),
+EventThread::EventThread(const sp<VSyncSource>& src)
+ : mVSyncSource(src),
mUseSoftwareVSync(false),
+ mVsyncEnabled(false),
mDebugVsyncEnabled(false) {
for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
@@ -110,19 +111,13 @@
}
}
-
-void EventThread::onVSyncReceived(int type, nsecs_t timestamp) {
- ALOGE_IF(type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
- "received vsync event for an invalid display (id=%d)", type);
-
+void EventThread::onVSyncEvent(nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
- if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
- mVSyncEvent[type].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
- mVSyncEvent[type].header.id = type;
- mVSyncEvent[type].header.timestamp = timestamp;
- mVSyncEvent[type].vsync.count++;
- mCondition.broadcast();
- }
+ mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
+ mVSyncEvent[0].header.id = 0;
+ mVSyncEvent[0].header.timestamp = timestamp;
+ mVSyncEvent[0].vsync.count++;
+ mCondition.broadcast();
}
void EventThread::onHotplugReceived(int type, bool connected) {
@@ -308,18 +303,23 @@
void EventThread::enableVSyncLocked() {
if (!mUseSoftwareVSync) {
// never enable h/w VSYNC when screen is off
- mFlinger->eventControl(DisplayDevice::DISPLAY_PRIMARY,
- SurfaceFlinger::EVENT_VSYNC, true);
- mPowerHAL.vsyncHint(true);
+ if (!mVsyncEnabled) {
+ mVsyncEnabled = true;
+ mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
+ mVSyncSource->setVSyncEnabled(true);
+ mPowerHAL.vsyncHint(true);
+ }
}
mDebugVsyncEnabled = true;
}
void EventThread::disableVSyncLocked() {
- mFlinger->eventControl(DisplayDevice::DISPLAY_PRIMARY,
- SurfaceFlinger::EVENT_VSYNC, false);
- mPowerHAL.vsyncHint(false);
- mDebugVsyncEnabled = false;
+ if (mVsyncEnabled) {
+ mVsyncEnabled = false;
+ mVSyncSource->setVSyncEnabled(false);
+ mPowerHAL.vsyncHint(false);
+ mDebugVsyncEnabled = false;
+ }
}
void EventThread::dump(String8& result) const {