Merge "Fix an issue with VSYNC"

This commit is contained in:
Mathias Agopian 2012-01-12 10:36:39 -08:00 committed by Android (Google) Code Review
commit fcf6cd0421

View File

@ -107,27 +107,17 @@ bool EventThread::threadLoop() {
{ // scope for the lock { // scope for the lock
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
do { do {
// wait for listeners // see if we need to wait for the VSYNC at all
do { do {
bool waitForNextVsync = false; bool waitForNextVsync = false;
size_t count = mDisplayEventConnections.size(); size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) { for (size_t i=0 ; i<count ; i++) {
const ConnectionInfo& info( const ConnectionInfo& info(
mDisplayEventConnections.valueAt(i)); mDisplayEventConnections.valueAt(i));
if (info.count >= 1) { if (info.count >= 0) {
// continuous mode // at least one continuous mode or active one-shot event
waitForNextVsync = true; waitForNextVsync = true;
} else { break;
// one-shot event
if (info.count >= -1) {
ConnectionInfo& info(
mDisplayEventConnections.editValueAt(i));
info.count--;
if (info.count == -1) {
// fired this time around
waitForNextVsync = true;
}
}
} }
} }
@ -137,14 +127,38 @@ bool EventThread::threadLoop() {
mCondition.wait(mLock); mCondition.wait(mLock);
} while(true); } while(true);
// wait for vsync // at least one listener requested VSYNC
mLock.unlock(); mLock.unlock();
timestamp = mHw.waitForVSync(); timestamp = mHw.waitForVSync();
mLock.lock(); mLock.lock();
mDeliveredEvents++; mDeliveredEvents++;
// make sure we still have some listeners // now see if we still need to report this VSYNC event
} while (!mDisplayEventConnections.size()); bool reportVsync = false;
size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
const ConnectionInfo& info(
mDisplayEventConnections.valueAt(i));
if (info.count >= 1) {
if (info.count==1 || (mDeliveredEvents % info.count) == 0) {
// continuous event, and time to report it
reportVsync = true;
}
} else if (info.count >= -1) {
ConnectionInfo& info(
mDisplayEventConnections.editValueAt(i));
if (info.count == 0) {
// fired this time around
reportVsync = true;
}
info.count--;
}
}
if (reportVsync) {
break;
}
} while (true);
// dispatch vsync events to listeners... // dispatch vsync events to listeners...
vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
@ -161,27 +175,6 @@ bool EventThread::threadLoop() {
sp<DisplayEventConnection> conn(displayEventConnections.keyAt(i).promote()); sp<DisplayEventConnection> conn(displayEventConnections.keyAt(i).promote());
// make sure the connection didn't die // make sure the connection didn't die
if (conn != NULL) { if (conn != NULL) {
const ConnectionInfo& info(
displayEventConnections.valueAt(i));
if ((info.count > 1) && (mDeliveredEvents % info.count)) {
// continuous event, but not time to send this event yet
continue;
} else if (info.count < -1) {
// disabled event
continue;
} else if (info.count == 0) {
// impossible by construction. but we prefer to be safe.
continue;
}
// here, either:
// count = -1 : one-shot scheduled this time around
// count = 1 : continuous not rate-limited
// count > 1 : continuous, rate-limited
// Note: count == 0 is not possible by construction
status_t err = conn->postEvent(vsync); status_t err = conn->postEvent(vsync);
if (err == -EAGAIN || err == -EWOULDBLOCK) { if (err == -EAGAIN || err == -EWOULDBLOCK) {
// The destination doesn't accept events anymore, it's probably // The destination doesn't accept events anymore, it's probably