SurfaceFlinger: Add EventControlThread
This change adds a new thread for calling HWComposer's eventControl
asynchronously. The DispSync-based vsync approach ends up enabling and
disabling HWComposer's vsync callbacks at arbitrary times, and some HWComposer
implementations do not have these calls optimized.
Bug: 11175503
Change-Id: I719be82bd200b391c61d40863b991c7b59acdfd6
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bc8cfb8..8ef4d6f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -60,6 +60,7 @@
#include "DdmConnection.h"
#include "DisplayDevice.h"
#include "DispSync.h"
+#include "EventControlThread.h"
#include "EventThread.h"
#include "Layer.h"
#include "LayerDim.h"
@@ -592,6 +593,9 @@
mEventThread = new EventThread(vsyncSrc);
mEventQueue.setEventThread(mEventThread);
+ mEventControlThread = new EventControlThread(this);
+ mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
+
// set a fake vsync period if there is no HWComposer
if (mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
@@ -755,7 +759,8 @@
Mutex::Autolock _l(mHWVsyncLock);
if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
mPrimaryDispSync.beginResync();
- eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
+ //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
+ mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
}
@@ -778,7 +783,8 @@
if (!mPrimaryHWVsyncEnabled) {
mPrimaryDispSync.beginResync();
- eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
+ //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
+ mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
}
@@ -786,7 +792,8 @@
void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
Mutex::Autolock _l(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
- eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
+ //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
+ mEventControlThread->setVsyncEnabled(false);
mPrimaryDispSync.endResync();
mPrimaryHWVsyncEnabled = false;
}
@@ -796,15 +803,20 @@
}
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
- if (type == 0) {
- bool needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
+ bool needsHwVsync = false;
- if (needsHwVsync) {
- enableHardwareVsync();
- } else {
- disableHardwareVsync(false);
+ { // Scope for the lock
+ Mutex::Autolock _l(mHWVsyncLock);
+ if (type == 0 && mPrimaryHWVsyncEnabled) {
+ needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}
+
+ if (needsHwVsync) {
+ enableHardwareVsync();
+ } else {
+ disableHardwareVsync(false);
+ }
}
void SurfaceFlinger::onHotplugReceived(int type, bool connected) {