diff options
author | Andy McFadden <fadden@android.com> | 2012-09-04 09:38:39 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-09-04 09:38:39 -0700 |
commit | 6b09f280e522da902ca41b96c3e4510d7a2879b7 (patch) | |
tree | e6df3334580f10a3d60765278774a6cee27ef594 /services/surfaceflinger | |
parent | 63f165fd6b86d04be94d4023e845e98560504a96 (diff) | |
parent | 6bf552ee02f8540a36cde7be90ffd840b2f6cd5c (diff) | |
download | frameworks_native-6b09f280e522da902ca41b96c3e4510d7a2879b7.zip frameworks_native-6b09f280e522da902ca41b96c3e4510d7a2879b7.tar.gz frameworks_native-6b09f280e522da902ca41b96c3e4510d7a2879b7.tar.bz2 |
Merge "Add timeout when waiting for HW vsync" into jb-mr1-dev
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r-- | services/surfaceflinger/EventThread.cpp | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index dcda67e..ade9f75 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -140,6 +140,8 @@ bool EventThread::threadLoop() { return true; } +// This will return when (1) a vsync event has been received, and (2) there was +// at least one connection interested in receiving it when we started waiting. Vector< sp<EventThread::Connection> > EventThread::waitForEvent( DisplayEventReceiver::Event* event) { @@ -193,31 +195,54 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent( // don't report it, and disable VSYNC events disableVSyncLocked(); } else if (!timestamp && waitForVSync) { + // we have at least one client, so we want vsync enabled + // (TODO: this function is called right after we finish + // notifying clients of a vsync, so this call will be made + // at the vsync rate, e.g. 60fps. If we can accurately + // track the current state we could avoid making this call + // so often.) enableVSyncLocked(); } - // note: !timestamp implies signalConnections.isEmpty() + // note: !timestamp implies signalConnections.isEmpty(), because we + // don't populate signalConnections if there's no vsync pending if (!timestamp) { // wait for something to happen - if (CC_UNLIKELY(mUseSoftwareVSync && waitForVSync)) { - // h/w vsync cannot be used (screen is off), so we use - // a timeout instead. it doesn't matter how imprecise this - // is, we just need to make sure to serve the clients - if (mCondition.waitRelative(mLock, ms2ns(16)) == TIMED_OUT) { + if (waitForVSync) { + // This is where we spend most of our time, waiting + // for vsync events and new client registrations. + // + // If the screen is off, we can't use h/w vsync, so we + // use a 16ms timeout instead. It doesn't need to be + // precise, we just need to keep feeding our clients. + // + // We don't want to stall if there's a driver bug, so we + // use a (long) timeout when waiting for h/w vsync, and + // generate fake events when necessary. + bool softwareSync = mUseSoftwareVSync; + nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000); + if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) { + if (!softwareSync) { + ALOGW("Timed out waiting for hw vsync; faking it"); + } mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); mVSyncCount++; } } else { - // This is where we spend most of our time, waiting - // for a vsync events and registered clients + // Nobody is interested in vsync, so we just want to sleep. + // h/w vsync should be disabled, so this will wait until we + // get a new connection, or an existing connection becomes + // interested in receiving vsync again. mCondition.wait(mLock); } } } while (signalConnections.isEmpty()); // here we're guaranteed to have a timestamp and some connections to signal + // (The connections might have dropped out of mDisplayEventConnections + // while we were asleep, but we'll still have strong references to them.) - // dispatch vsync events to listeners... + // fill in vsync event info event->header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; event->header.timestamp = timestamp; event->vsync.count = vsyncCount; |