Loading services/surfaceflinger/DisplayHardware/HWComposer.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -205,6 +205,9 @@ status_t HWComposer::commit() const { status_t HWComposer::release() const { status_t HWComposer::release() const { if (mHwc) { if (mHwc) { if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); } int err = mHwc->set(mHwc, NULL, NULL, NULL); int err = mHwc->set(mHwc, NULL, NULL, NULL); return (status_t)err; return (status_t)err; } } Loading services/surfaceflinger/EventThread.cpp +39 −17 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ EventThread::EventThread(const sp<SurfaceFlinger>& flinger) mHw(flinger->graphicPlane(0).editDisplayHardware()), mHw(flinger->graphicPlane(0).editDisplayHardware()), mLastVSyncTimestamp(0), mLastVSyncTimestamp(0), mVSyncTimestamp(0), mVSyncTimestamp(0), mUseSoftwareVSync(false), mDeliveredEvents(0), mDeliveredEvents(0), mDebugVsyncEnabled(false) mDebugVsyncEnabled(false) { { Loading @@ -55,16 +56,6 @@ sp<EventThread::Connection> EventThread::createEventConnection() const { return new Connection(const_cast<EventThread*>(this)); return new Connection(const_cast<EventThread*>(this)); } } nsecs_t EventThread::getLastVSyncTimestamp() const { Mutex::Autolock _l(mLock); return mLastVSyncTimestamp; } nsecs_t EventThread::getVSyncPeriod() const { return mHw.getRefreshPeriod(); } status_t EventThread::registerDisplayEventConnection( status_t EventThread::registerDisplayEventConnection( const sp<EventThread::Connection>& connection) { const sp<EventThread::Connection>& connection) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); Loading Loading @@ -108,6 +99,24 @@ void EventThread::requestNextVsync( } } } } void EventThread::onScreenReleased() { Mutex::Autolock _l(mLock); // wait for an eventual pending vsync to be serviced if (!mUseSoftwareVSync) { while (mVSyncTimestamp) { mCondition.wait(mLock); } } // disable reliance on h/w vsync mUseSoftwareVSync = true; } void EventThread::onScreenAcquired() { Mutex::Autolock _l(mLock); mUseSoftwareVSync = false; } void EventThread::onVSyncReceived(int, nsecs_t timestamp) { void EventThread::onVSyncReceived(int, nsecs_t timestamp) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); mVSyncTimestamp = timestamp; mVSyncTimestamp = timestamp; Loading @@ -121,7 +130,6 @@ bool EventThread::threadLoop() { Vector< wp<EventThread::Connection> > displayEventConnections; Vector< wp<EventThread::Connection> > displayEventConnections; do { do { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); do { do { // latch VSYNC event if any // latch VSYNC event if any Loading @@ -145,7 +153,7 @@ bool EventThread::threadLoop() { if (!waitForNextVsync) { if (!waitForNextVsync) { // we received a VSYNC but we have no clients // we received a VSYNC but we have no clients // don't report it, and disable VSYNC events // don't report it, and disable VSYNC events disableVSync(); disableVSyncLocked(); } else { } else { // report VSYNC event // report VSYNC event break; break; Loading @@ -157,12 +165,21 @@ bool EventThread::threadLoop() { // disable VSYNC events then. // disable VSYNC events then. if (waitForNextVsync) { if (waitForNextVsync) { // enable // enable enableVSync(); enableVSyncLocked(); } } } } // wait for something to happen // wait for something to happen if (mUseSoftwareVSync == true) { // 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) { mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); } } else { mCondition.wait(mLock); mCondition.wait(mLock); } } while(true); } while(true); // process vsync event // process vsync event Loading Loading @@ -233,12 +250,15 @@ bool EventThread::threadLoop() { return true; return true; } } void EventThread::enableVSync() { void EventThread::enableVSyncLocked() { if (!mUseSoftwareVSync) { // never enable h/w VSYNC when screen is off mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true); mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true); } mDebugVsyncEnabled = true; mDebugVsyncEnabled = true; } } void EventThread::disableVSync() { void EventThread::disableVSyncLocked() { mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false); mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false); mDebugVsyncEnabled = false; mDebugVsyncEnabled = false; } } Loading @@ -252,6 +272,8 @@ void EventThread::dump(String8& result, char* buffer, size_t SIZE) const { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); result.appendFormat("VSYNC state: %s\n", result.appendFormat("VSYNC state: %s\n", mDebugVsyncEnabled?"enabled":"disabled"); mDebugVsyncEnabled?"enabled":"disabled"); result.appendFormat(" soft-vsync: %s\n", mUseSoftwareVSync?"enabled":"disabled"); result.appendFormat(" numListeners=%u,\n events-delivered: %u\n", result.appendFormat(" numListeners=%u,\n events-delivered: %u\n", mDisplayEventConnections.size(), mDeliveredEvents); mDisplayEventConnections.size(), mDeliveredEvents); for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) { for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) { Loading services/surfaceflinger/EventThread.h +8 −4 Original line number Original line Diff line number Diff line Loading @@ -72,8 +72,11 @@ public: void setVsyncRate(uint32_t count, const sp<Connection>& connection); void setVsyncRate(uint32_t count, const sp<Connection>& connection); void requestNextVsync(const sp<Connection>& connection); void requestNextVsync(const sp<Connection>& connection); nsecs_t getLastVSyncTimestamp() const; // called before the screen is turned off from main thread nsecs_t getVSyncPeriod() const; void onScreenReleased(); // called after the screen is turned on from main thread void onScreenAcquired(); void dump(String8& result, char* buffer, size_t SIZE) const; void dump(String8& result, char* buffer, size_t SIZE) const; Loading @@ -84,8 +87,8 @@ private: virtual void onVSyncReceived(int, nsecs_t timestamp); virtual void onVSyncReceived(int, nsecs_t timestamp); void removeDisplayEventConnection(const wp<Connection>& connection); void removeDisplayEventConnection(const wp<Connection>& connection); void enableVSync(); void enableVSyncLocked(); void disableVSync(); void disableVSyncLocked(); // constants // constants sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger; Loading @@ -98,6 +101,7 @@ private: SortedVector< wp<Connection> > mDisplayEventConnections; SortedVector< wp<Connection> > mDisplayEventConnections; nsecs_t mLastVSyncTimestamp; nsecs_t mLastVSyncTimestamp; nsecs_t mVSyncTimestamp; nsecs_t mVSyncTimestamp; bool mUseSoftwareVSync; // main thread only // main thread only size_t mDeliveredEvents; size_t mDeliveredEvents; Loading services/surfaceflinger/SurfaceFlinger.cpp +7 −1 Original line number Original line Diff line number Diff line Loading @@ -1467,16 +1467,18 @@ uint32_t SurfaceFlinger::setClientStateLocked( void SurfaceFlinger::onScreenAcquired() { void SurfaceFlinger::onScreenAcquired() { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware()); hw.acquireScreen(); hw.acquireScreen(); mEventThread->onScreenAcquired(); // this is a temporary work-around, eventually this should be called // this is a temporary work-around, eventually this should be called // by the power-manager // by the power-manager SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); mDirtyRegion.set(hw.bounds()); mDirtyRegion.set(hw.bounds()); // from this point on, SF will priocess updates again // from this point on, SF will process updates again } } void SurfaceFlinger::onScreenReleased() { void SurfaceFlinger::onScreenReleased() { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware()); if (hw.isScreenAcquired()) { if (hw.isScreenAcquired()) { mEventThread->onScreenReleased(); mDirtyRegion.set(hw.bounds()); mDirtyRegion.set(hw.bounds()); hw.releaseScreen(); hw.releaseScreen(); // from this point on, SF will stop drawing // from this point on, SF will stop drawing Loading Loading @@ -1883,6 +1885,8 @@ status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, GLuint* textureName, GLfloat* uOut, GLfloat* vOut) GLuint* textureName, GLfloat* uOut, GLfloat* vOut) { { ATRACE_CALL(); if (!GLExtensions::getInstance().haveFramebufferObject()) if (!GLExtensions::getInstance().haveFramebufferObject()) return INVALID_OPERATION; return INVALID_OPERATION; Loading Loading @@ -2263,6 +2267,8 @@ status_t SurfaceFlinger::electronBeamOnAnimationImplLocked() status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) { { ATRACE_CALL(); DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); if (!hw.canDraw()) { if (!hw.canDraw()) { // we're already off // we're already off Loading Loading
services/surfaceflinger/DisplayHardware/HWComposer.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -205,6 +205,9 @@ status_t HWComposer::commit() const { status_t HWComposer::release() const { status_t HWComposer::release() const { if (mHwc) { if (mHwc) { if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); } int err = mHwc->set(mHwc, NULL, NULL, NULL); int err = mHwc->set(mHwc, NULL, NULL, NULL); return (status_t)err; return (status_t)err; } } Loading
services/surfaceflinger/EventThread.cpp +39 −17 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ EventThread::EventThread(const sp<SurfaceFlinger>& flinger) mHw(flinger->graphicPlane(0).editDisplayHardware()), mHw(flinger->graphicPlane(0).editDisplayHardware()), mLastVSyncTimestamp(0), mLastVSyncTimestamp(0), mVSyncTimestamp(0), mVSyncTimestamp(0), mUseSoftwareVSync(false), mDeliveredEvents(0), mDeliveredEvents(0), mDebugVsyncEnabled(false) mDebugVsyncEnabled(false) { { Loading @@ -55,16 +56,6 @@ sp<EventThread::Connection> EventThread::createEventConnection() const { return new Connection(const_cast<EventThread*>(this)); return new Connection(const_cast<EventThread*>(this)); } } nsecs_t EventThread::getLastVSyncTimestamp() const { Mutex::Autolock _l(mLock); return mLastVSyncTimestamp; } nsecs_t EventThread::getVSyncPeriod() const { return mHw.getRefreshPeriod(); } status_t EventThread::registerDisplayEventConnection( status_t EventThread::registerDisplayEventConnection( const sp<EventThread::Connection>& connection) { const sp<EventThread::Connection>& connection) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); Loading Loading @@ -108,6 +99,24 @@ void EventThread::requestNextVsync( } } } } void EventThread::onScreenReleased() { Mutex::Autolock _l(mLock); // wait for an eventual pending vsync to be serviced if (!mUseSoftwareVSync) { while (mVSyncTimestamp) { mCondition.wait(mLock); } } // disable reliance on h/w vsync mUseSoftwareVSync = true; } void EventThread::onScreenAcquired() { Mutex::Autolock _l(mLock); mUseSoftwareVSync = false; } void EventThread::onVSyncReceived(int, nsecs_t timestamp) { void EventThread::onVSyncReceived(int, nsecs_t timestamp) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); mVSyncTimestamp = timestamp; mVSyncTimestamp = timestamp; Loading @@ -121,7 +130,6 @@ bool EventThread::threadLoop() { Vector< wp<EventThread::Connection> > displayEventConnections; Vector< wp<EventThread::Connection> > displayEventConnections; do { do { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); do { do { // latch VSYNC event if any // latch VSYNC event if any Loading @@ -145,7 +153,7 @@ bool EventThread::threadLoop() { if (!waitForNextVsync) { if (!waitForNextVsync) { // we received a VSYNC but we have no clients // we received a VSYNC but we have no clients // don't report it, and disable VSYNC events // don't report it, and disable VSYNC events disableVSync(); disableVSyncLocked(); } else { } else { // report VSYNC event // report VSYNC event break; break; Loading @@ -157,12 +165,21 @@ bool EventThread::threadLoop() { // disable VSYNC events then. // disable VSYNC events then. if (waitForNextVsync) { if (waitForNextVsync) { // enable // enable enableVSync(); enableVSyncLocked(); } } } } // wait for something to happen // wait for something to happen if (mUseSoftwareVSync == true) { // 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) { mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); } } else { mCondition.wait(mLock); mCondition.wait(mLock); } } while(true); } while(true); // process vsync event // process vsync event Loading Loading @@ -233,12 +250,15 @@ bool EventThread::threadLoop() { return true; return true; } } void EventThread::enableVSync() { void EventThread::enableVSyncLocked() { if (!mUseSoftwareVSync) { // never enable h/w VSYNC when screen is off mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true); mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true); } mDebugVsyncEnabled = true; mDebugVsyncEnabled = true; } } void EventThread::disableVSync() { void EventThread::disableVSyncLocked() { mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false); mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false); mDebugVsyncEnabled = false; mDebugVsyncEnabled = false; } } Loading @@ -252,6 +272,8 @@ void EventThread::dump(String8& result, char* buffer, size_t SIZE) const { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); result.appendFormat("VSYNC state: %s\n", result.appendFormat("VSYNC state: %s\n", mDebugVsyncEnabled?"enabled":"disabled"); mDebugVsyncEnabled?"enabled":"disabled"); result.appendFormat(" soft-vsync: %s\n", mUseSoftwareVSync?"enabled":"disabled"); result.appendFormat(" numListeners=%u,\n events-delivered: %u\n", result.appendFormat(" numListeners=%u,\n events-delivered: %u\n", mDisplayEventConnections.size(), mDeliveredEvents); mDisplayEventConnections.size(), mDeliveredEvents); for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) { for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) { Loading
services/surfaceflinger/EventThread.h +8 −4 Original line number Original line Diff line number Diff line Loading @@ -72,8 +72,11 @@ public: void setVsyncRate(uint32_t count, const sp<Connection>& connection); void setVsyncRate(uint32_t count, const sp<Connection>& connection); void requestNextVsync(const sp<Connection>& connection); void requestNextVsync(const sp<Connection>& connection); nsecs_t getLastVSyncTimestamp() const; // called before the screen is turned off from main thread nsecs_t getVSyncPeriod() const; void onScreenReleased(); // called after the screen is turned on from main thread void onScreenAcquired(); void dump(String8& result, char* buffer, size_t SIZE) const; void dump(String8& result, char* buffer, size_t SIZE) const; Loading @@ -84,8 +87,8 @@ private: virtual void onVSyncReceived(int, nsecs_t timestamp); virtual void onVSyncReceived(int, nsecs_t timestamp); void removeDisplayEventConnection(const wp<Connection>& connection); void removeDisplayEventConnection(const wp<Connection>& connection); void enableVSync(); void enableVSyncLocked(); void disableVSync(); void disableVSyncLocked(); // constants // constants sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger; Loading @@ -98,6 +101,7 @@ private: SortedVector< wp<Connection> > mDisplayEventConnections; SortedVector< wp<Connection> > mDisplayEventConnections; nsecs_t mLastVSyncTimestamp; nsecs_t mLastVSyncTimestamp; nsecs_t mVSyncTimestamp; nsecs_t mVSyncTimestamp; bool mUseSoftwareVSync; // main thread only // main thread only size_t mDeliveredEvents; size_t mDeliveredEvents; Loading
services/surfaceflinger/SurfaceFlinger.cpp +7 −1 Original line number Original line Diff line number Diff line Loading @@ -1467,16 +1467,18 @@ uint32_t SurfaceFlinger::setClientStateLocked( void SurfaceFlinger::onScreenAcquired() { void SurfaceFlinger::onScreenAcquired() { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware()); hw.acquireScreen(); hw.acquireScreen(); mEventThread->onScreenAcquired(); // this is a temporary work-around, eventually this should be called // this is a temporary work-around, eventually this should be called // by the power-manager // by the power-manager SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); mDirtyRegion.set(hw.bounds()); mDirtyRegion.set(hw.bounds()); // from this point on, SF will priocess updates again // from this point on, SF will process updates again } } void SurfaceFlinger::onScreenReleased() { void SurfaceFlinger::onScreenReleased() { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware()); if (hw.isScreenAcquired()) { if (hw.isScreenAcquired()) { mEventThread->onScreenReleased(); mDirtyRegion.set(hw.bounds()); mDirtyRegion.set(hw.bounds()); hw.releaseScreen(); hw.releaseScreen(); // from this point on, SF will stop drawing // from this point on, SF will stop drawing Loading Loading @@ -1883,6 +1885,8 @@ status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, GLuint* textureName, GLfloat* uOut, GLfloat* vOut) GLuint* textureName, GLfloat* uOut, GLfloat* vOut) { { ATRACE_CALL(); if (!GLExtensions::getInstance().haveFramebufferObject()) if (!GLExtensions::getInstance().haveFramebufferObject()) return INVALID_OPERATION; return INVALID_OPERATION; Loading Loading @@ -2263,6 +2267,8 @@ status_t SurfaceFlinger::electronBeamOnAnimationImplLocked() status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) { { ATRACE_CALL(); DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); if (!hw.canDraw()) { if (!hw.canDraw()) { // we're already off // we're already off Loading