diff options
| author | 2012-04-03 22:09:52 -0700 | |
|---|---|---|
| committer | 2012-04-04 19:01:20 -0700 | |
| commit | 3eb38cb33e41ce40dd1094bdec850f0fca9f8a53 (patch) | |
| tree | 3f8cc9dc54f314fc53e50b579ab2d903cdb09d5c /services/surfaceflinger/EventThread.cpp | |
| parent | 9d61b955db7ccd00d1e5b33e75f37dfd5ac2a456 (diff) | |
SurfaceFlinger now uses the new VSYNC HAL API.
If h/w composer doesn't support vsync (version < 0.3) we
"fake" it with a timer.
Change-Id: I1e3be79f43c9631d1293ad7d6cf52f9bfc42d65b
Diffstat (limited to 'services/surfaceflinger/EventThread.cpp')
| -rw-r--r-- | services/surfaceflinger/EventThread.cpp | 125 |
1 files changed, 70 insertions, 55 deletions
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index 97afb5fa37..b05b7c281b 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -38,13 +38,15 @@ namespace android { EventThread::EventThread(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger), - mHw(flinger->graphicPlane(0).displayHardware()), + mHw(flinger->graphicPlane(0).editDisplayHardware()), mLastVSyncTimestamp(0), + mVSyncTimestamp(0), mDeliveredEvents(0) { } void EventThread::onFirstRef() { + mHw.setVSyncHandler(this); run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); } @@ -105,76 +107,89 @@ void EventThread::requestNextVsync( } } +void EventThread::onVSyncReceived(int, nsecs_t timestamp) { + Mutex::Autolock _l(mLock); + mVSyncTimestamp = timestamp; + mCondition.signal(); +} + bool EventThread::threadLoop() { nsecs_t timestamp; DisplayEventReceiver::Event vsync; Vector< wp<EventThread::Connection> > displayEventConnections; - { // scope for the lock + do { + Mutex::Autolock _l(mLock); do { - // see if we need to wait for the VSYNC at all - do { - bool waitForNextVsync = false; - size_t count = mDisplayEventConnections.size(); - for (size_t i=0 ; i<count ; i++) { - sp<Connection> connection = - mDisplayEventConnections.itemAt(i).promote(); - if (connection!=0 && connection->count >= 0) { - // at least one continuous mode or active one-shot event - waitForNextVsync = true; - break; - } - } - - if (waitForNextVsync) - break; - - mCondition.wait(mLock); - } while(true); - - // at least one listener requested VSYNC - mLock.unlock(); - timestamp = mHw.waitForRefresh(); - ATRACE_INT("VSYNC", mDeliveredEvents&1); - mLock.lock(); - mDeliveredEvents++; - mLastVSyncTimestamp = timestamp; + // check if we have received a VSYNC event + if (mVSyncTimestamp) { + // we have a VSYNC event pending + timestamp = mVSyncTimestamp; + mVSyncTimestamp = 0; + break; + } - // now see if we still need to report this VSYNC event - const size_t count = mDisplayEventConnections.size(); + // check if we should be waiting for VSYNC events + bool waitForNextVsync = false; + size_t count = mDisplayEventConnections.size(); for (size_t i=0 ; i<count ; i++) { - bool reportVsync = false; sp<Connection> connection = mDisplayEventConnections.itemAt(i).promote(); - if (connection == 0) - continue; - - const int32_t count = connection->count; - if (count >= 1) { - if (count==1 || (mDeliveredEvents % count) == 0) { - // continuous event, and time to report it - reportVsync = true; - } - } else if (count >= -1) { - if (count == 0) { - // fired this time around - reportVsync = true; - } - connection->count--; + if (connection!=0 && connection->count >= 0) { + // at least one continuous mode or active one-shot event + waitForNextVsync = true; + break; } - if (reportVsync) { - displayEventConnections.add(connection); + } + + // enable or disable VSYNC events + mHw.getHwComposer().eventControl( + HWComposer::EVENT_VSYNC, waitForNextVsync); + + // wait for something to happen + mCondition.wait(mLock); + } while(true); + + // process vsync event + + ATRACE_INT("VSYNC", mDeliveredEvents&1); + mDeliveredEvents++; + mLastVSyncTimestamp = timestamp; + + // now see if we still need to report this VSYNC event + const size_t count = mDisplayEventConnections.size(); + for (size_t i=0 ; i<count ; i++) { + bool reportVsync = false; + sp<Connection> connection = + mDisplayEventConnections.itemAt(i).promote(); + if (connection == 0) + continue; + + const int32_t count = connection->count; + if (count >= 1) { + if (count==1 || (mDeliveredEvents % count) == 0) { + // continuous event, and time to report it + reportVsync = true; } + } else if (count >= -1) { + if (count == 0) { + // fired this time around + reportVsync = true; + } + connection->count--; + } + if (reportVsync) { + displayEventConnections.add(connection); } - } while (!displayEventConnections.size()); + } + } while (!displayEventConnections.size()); - // dispatch vsync events to listeners... - vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; - vsync.header.timestamp = timestamp; - vsync.vsync.count = mDeliveredEvents; - } + // dispatch vsync events to listeners... + vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; + vsync.header.timestamp = timestamp; + vsync.vsync.count = mDeliveredEvents; const size_t count = displayEventConnections.size(); for (size_t i=0 ; i<count ; i++) { |