Loading services/surfaceflinger/EventThread.cpp +86 −98 Original line number Diff line number Diff line Loading @@ -36,10 +36,9 @@ namespace android { EventThread::EventThread(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger), mLastVSyncTimestamp(0), mVSyncTimestamp(0), mUseSoftwareVSync(false), mDeliveredEvents(0), mVSyncCount(0), mDebugVsyncEnabled(false) { } Loading Loading @@ -116,34 +115,40 @@ void EventThread::onScreenAcquired() { void EventThread::onVSyncReceived(int, nsecs_t timestamp) { Mutex::Autolock _l(mLock); mVSyncTimestamp = timestamp; mVSyncCount++; mCondition.broadcast(); } bool EventThread::threadLoop() { nsecs_t timestamp; size_t vsyncCount; size_t activeEvents; DisplayEventReceiver::Event vsync; Vector< wp<EventThread::Connection> > displayEventConnections; Vector< sp<EventThread::Connection> > activeConnections; do { Mutex::Autolock _l(mLock); do { // latch VSYNC event if any timestamp = mVSyncTimestamp; mVSyncTimestamp = 0; // check if we should be waiting for VSYNC events activeEvents = 0; 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) { sp<Connection> connection(mDisplayEventConnections[i].promote()); if (connection != NULL) { activeConnections.add(connection); if (connection->count >= 0) { // at least one continuous mode or active one-shot event waitForNextVsync = true; activeEvents++; break; } } } if (timestamp) { if (!waitForNextVsync) { Loading Loading @@ -172,54 +177,43 @@ bool EventThread::threadLoop() { // is, we just need to make sure to serve the clients if (mCondition.waitRelative(mLock, ms2ns(16)) == TIMED_OUT) { mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); mVSyncCount++; } } else { mCondition.wait(mLock); } } while(true); // process vsync event mDeliveredEvents++; mLastVSyncTimestamp = timestamp; vsyncCount = mVSyncCount; } while (!activeConnections.size()); // 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); } if (!activeEvents) { // no events to return. start over. // (here we make sure to exit the scope of this function // so that we release our Connection references) return true; } } while (!displayEventConnections.size()); // dispatch vsync events to listeners... vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; vsync.header.timestamp = timestamp; vsync.vsync.count = mDeliveredEvents; vsync.vsync.count = vsyncCount; const size_t count = displayEventConnections.size(); const size_t count = activeConnections.size(); for (size_t i=0 ; i<count ; i++) { sp<Connection> conn(displayEventConnections[i].promote()); // make sure the connection didn't die if (conn != NULL) { const sp<Connection>& conn(activeConnections[i]); // now see if we still need to report this VSYNC event const int32_t vcount = conn->count; if (vcount >= 0) { bool reportVsync = false; if (vcount == 0) { // fired this time around conn->count = -1; reportVsync = true; } else if (vcount == 1 || (vsyncCount % vcount) == 0) { // continuous event, and time to report it reportVsync = true; } if (reportVsync) { status_t err = conn->postEvent(vsync); if (err == -EAGAIN || err == -EWOULDBLOCK) { // The destination doesn't accept events anymore, it's probably Loading @@ -231,17 +225,11 @@ bool EventThread::threadLoop() { // handle any other error on the pipe as fatal. the only // reasonable thing to do is to clean-up this connection. // The most common error we'll get here is -EPIPE. removeDisplayEventConnection(displayEventConnections[i]); removeDisplayEventConnection(activeConnections[i]); } } } else { // somehow the connection is dead, but we still have it in our list // just clean the list. removeDisplayEventConnection(displayEventConnections[i]); } } // clear all our references without holding mLock displayEventConnections.clear(); return true; } Loading Loading @@ -273,7 +261,7 @@ void EventThread::dump(String8& result, char* buffer, size_t SIZE) const { result.appendFormat(" soft-vsync: %s\n", mUseSoftwareVSync?"enabled":"disabled"); result.appendFormat(" numListeners=%u,\n events-delivered: %u\n", mDisplayEventConnections.size(), mDeliveredEvents); mDisplayEventConnections.size(), mVSyncCount); for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) { sp<Connection> connection = mDisplayEventConnections.itemAt(i).promote(); Loading services/surfaceflinger/EventThread.h +1 −4 Original line number Diff line number Diff line Loading @@ -100,12 +100,9 @@ private: // protected by mLock SortedVector< wp<Connection> > mDisplayEventConnections; nsecs_t mLastVSyncTimestamp; nsecs_t mVSyncTimestamp; bool mUseSoftwareVSync; // main thread only size_t mDeliveredEvents; size_t mVSyncCount; // for debugging bool mDebugVsyncEnabled; Loading Loading
services/surfaceflinger/EventThread.cpp +86 −98 Original line number Diff line number Diff line Loading @@ -36,10 +36,9 @@ namespace android { EventThread::EventThread(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger), mLastVSyncTimestamp(0), mVSyncTimestamp(0), mUseSoftwareVSync(false), mDeliveredEvents(0), mVSyncCount(0), mDebugVsyncEnabled(false) { } Loading Loading @@ -116,34 +115,40 @@ void EventThread::onScreenAcquired() { void EventThread::onVSyncReceived(int, nsecs_t timestamp) { Mutex::Autolock _l(mLock); mVSyncTimestamp = timestamp; mVSyncCount++; mCondition.broadcast(); } bool EventThread::threadLoop() { nsecs_t timestamp; size_t vsyncCount; size_t activeEvents; DisplayEventReceiver::Event vsync; Vector< wp<EventThread::Connection> > displayEventConnections; Vector< sp<EventThread::Connection> > activeConnections; do { Mutex::Autolock _l(mLock); do { // latch VSYNC event if any timestamp = mVSyncTimestamp; mVSyncTimestamp = 0; // check if we should be waiting for VSYNC events activeEvents = 0; 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) { sp<Connection> connection(mDisplayEventConnections[i].promote()); if (connection != NULL) { activeConnections.add(connection); if (connection->count >= 0) { // at least one continuous mode or active one-shot event waitForNextVsync = true; activeEvents++; break; } } } if (timestamp) { if (!waitForNextVsync) { Loading Loading @@ -172,54 +177,43 @@ bool EventThread::threadLoop() { // is, we just need to make sure to serve the clients if (mCondition.waitRelative(mLock, ms2ns(16)) == TIMED_OUT) { mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); mVSyncCount++; } } else { mCondition.wait(mLock); } } while(true); // process vsync event mDeliveredEvents++; mLastVSyncTimestamp = timestamp; vsyncCount = mVSyncCount; } while (!activeConnections.size()); // 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); } if (!activeEvents) { // no events to return. start over. // (here we make sure to exit the scope of this function // so that we release our Connection references) return true; } } while (!displayEventConnections.size()); // dispatch vsync events to listeners... vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; vsync.header.timestamp = timestamp; vsync.vsync.count = mDeliveredEvents; vsync.vsync.count = vsyncCount; const size_t count = displayEventConnections.size(); const size_t count = activeConnections.size(); for (size_t i=0 ; i<count ; i++) { sp<Connection> conn(displayEventConnections[i].promote()); // make sure the connection didn't die if (conn != NULL) { const sp<Connection>& conn(activeConnections[i]); // now see if we still need to report this VSYNC event const int32_t vcount = conn->count; if (vcount >= 0) { bool reportVsync = false; if (vcount == 0) { // fired this time around conn->count = -1; reportVsync = true; } else if (vcount == 1 || (vsyncCount % vcount) == 0) { // continuous event, and time to report it reportVsync = true; } if (reportVsync) { status_t err = conn->postEvent(vsync); if (err == -EAGAIN || err == -EWOULDBLOCK) { // The destination doesn't accept events anymore, it's probably Loading @@ -231,17 +225,11 @@ bool EventThread::threadLoop() { // handle any other error on the pipe as fatal. the only // reasonable thing to do is to clean-up this connection. // The most common error we'll get here is -EPIPE. removeDisplayEventConnection(displayEventConnections[i]); removeDisplayEventConnection(activeConnections[i]); } } } else { // somehow the connection is dead, but we still have it in our list // just clean the list. removeDisplayEventConnection(displayEventConnections[i]); } } // clear all our references without holding mLock displayEventConnections.clear(); return true; } Loading Loading @@ -273,7 +261,7 @@ void EventThread::dump(String8& result, char* buffer, size_t SIZE) const { result.appendFormat(" soft-vsync: %s\n", mUseSoftwareVSync?"enabled":"disabled"); result.appendFormat(" numListeners=%u,\n events-delivered: %u\n", mDisplayEventConnections.size(), mDeliveredEvents); mDisplayEventConnections.size(), mVSyncCount); for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) { sp<Connection> connection = mDisplayEventConnections.itemAt(i).promote(); Loading
services/surfaceflinger/EventThread.h +1 −4 Original line number Diff line number Diff line Loading @@ -100,12 +100,9 @@ private: // protected by mLock SortedVector< wp<Connection> > mDisplayEventConnections; nsecs_t mLastVSyncTimestamp; nsecs_t mVSyncTimestamp; bool mUseSoftwareVSync; // main thread only size_t mDeliveredEvents; size_t mVSyncCount; // for debugging bool mDebugVsyncEnabled; Loading