Loading services/surfaceflinger/DisplayHardware/HWComposer.cpp +33 −15 Original line number Original line Diff line number Diff line Loading @@ -147,7 +147,7 @@ HWComposer::HWComposer( // don't need a vsync thread if we have a hardware composer // don't need a vsync thread if we have a hardware composer needVSyncThread = false; needVSyncThread = false; // always turn vsync off when we start // always turn vsync off when we start mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); // these IDs are always reserved // these IDs are always reserved for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) { for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) { Loading Loading @@ -202,7 +202,7 @@ HWComposer::HWComposer( HWComposer::~HWComposer() { HWComposer::~HWComposer() { if (mHwc) { if (mHwc) { mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); } } if (mVSyncThread != NULL) { if (mVSyncThread != NULL) { mVSyncThread->requestExitAndWait(); mVSyncThread->requestExitAndWait(); Loading Loading @@ -443,17 +443,33 @@ bool HWComposer::isConnected(int disp) const { return mDisplayData[disp].connected; return mDisplayData[disp].connected; } } void HWComposer::eventControl(int event, int enabled) { void HWComposer::eventControl(int disp, int event, int enabled) { if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) { return; } status_t err = NO_ERROR; status_t err = NO_ERROR; if (mHwc) { if (mHwc && !mDebugForceFakeVSync) { if (!mDebugForceFakeVSync) { // NOTE: we use our own internal lock here because we have to call err = mHwc->eventControl(mHwc, 0, event, enabled); // into the HWC with the lock held, and we want to make sure // that even if HWC blocks (which it shouldn't), it won't // affect other threads. Mutex::Autolock _l(mEventControlLock); const int32_t eventBit = 1UL << event; const int32_t newValue = enabled ? eventBit : 0; const int32_t oldValue = mDisplayData[disp].events & eventBit; if (newValue != oldValue) { ATRACE_CALL(); err = mHwc->eventControl(mHwc, disp, event, enabled); if (!err) { int32_t& events(mDisplayData[disp].events); events = (events & ~eventBit) | newValue; } } // error here should not happen -- not sure what we should // error here should not happen -- not sure what we should // do if it does. // do if it does. ALOGE_IF(err, "eventControl(%d, %d) failed %s", ALOGE_IF(err, "eventControl(%d, %d) failed %s", event, enabled, strerror(-err)); event, enabled, strerror(-err)); } } } if (err == NO_ERROR && mVSyncThread != NULL) { if (err == NO_ERROR && mVSyncThread != NULL) { mVSyncThread->setEnabled(enabled); mVSyncThread->setEnabled(enabled); Loading Loading @@ -652,16 +668,16 @@ status_t HWComposer::commit() { return (status_t)err; return (status_t)err; } } status_t HWComposer::release(int disp) const { status_t HWComposer::release(int disp) { LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); if (mHwc) { if (mHwc) { mHwc->eventControl(mHwc, disp, HWC_EVENT_VSYNC, 0); eventControl(disp, HWC_EVENT_VSYNC, 0); return (status_t)mHwc->blank(mHwc, disp, 1); return (status_t)mHwc->blank(mHwc, disp, 1); } } return NO_ERROR; return NO_ERROR; } } status_t HWComposer::acquire(int disp) const { status_t HWComposer::acquire(int disp) { LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); if (mHwc) { if (mHwc) { return (status_t)mHwc->blank(mHwc, disp, 0); return (status_t)mHwc->blank(mHwc, disp, 0); Loading Loading @@ -965,9 +981,11 @@ HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) void HWComposer::VSyncThread::setEnabled(bool enabled) { void HWComposer::VSyncThread::setEnabled(bool enabled) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); if (mEnabled != enabled) { mEnabled = enabled; mEnabled = enabled; mCondition.signal(); mCondition.signal(); } } } void HWComposer::VSyncThread::onFirstRef() { void HWComposer::VSyncThread::onFirstRef() { run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); Loading services/surfaceflinger/DisplayHardware/HWComposer.h +9 −4 Original line number Original line Diff line number Diff line Loading @@ -92,10 +92,10 @@ public: status_t commit(); status_t commit(); // release hardware resources and blank screen // release hardware resources and blank screen status_t release(int disp) const; status_t release(int disp); // acquire hardware resources and unblank screen // acquire hardware resources and unblank screen status_t acquire(int disp) const; status_t acquire(int disp); // reset state when an external, non-virtual display is disconnected // reset state when an external, non-virtual display is disconnected void disconnectDisplay(int disp); void disconnectDisplay(int disp); Loading Loading @@ -226,7 +226,7 @@ public: EVENT_VSYNC = HWC_EVENT_VSYNC EVENT_VSYNC = HWC_EVENT_VSYNC }; }; void eventControl(int event, int enabled); void eventControl(int disp, int event, int enabled); // Query display parameters. Pass in a display index (e.g. // Query display parameters. Pass in a display index (e.g. // HWC_DISPLAY_PRIMARY). // HWC_DISPLAY_PRIMARY). Loading Loading @@ -289,7 +289,7 @@ private: DisplayData() : xdpi(0), ydpi(0), refresh(0), DisplayData() : xdpi(0), ydpi(0), refresh(0), connected(false), hasFbComp(false), hasOvComp(false), connected(false), hasFbComp(false), hasOvComp(false), capacity(0), list(NULL), capacity(0), list(NULL), framebufferTarget(NULL), fbTargetHandle(NULL) { } framebufferTarget(NULL), fbTargetHandle(NULL), events(0) { } ~DisplayData() { ~DisplayData() { free(list); free(list); } } Loading @@ -306,6 +306,8 @@ private: hwc_display_contents_1* list; hwc_display_contents_1* list; hwc_layer_1* framebufferTarget; hwc_layer_1* framebufferTarget; buffer_handle_t fbTargetHandle; buffer_handle_t fbTargetHandle; // protected by mEventControlLock int32_t events; }; }; sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger; Loading @@ -327,6 +329,9 @@ private: // protected by mLock // protected by mLock mutable Mutex mLock; mutable Mutex mLock; mutable nsecs_t mLastHwVSync; mutable nsecs_t mLastHwVSync; // thread-safe mutable Mutex mEventControlLock; }; }; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading services/surfaceflinger/EventThread.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -308,14 +308,14 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent( void EventThread::enableVSyncLocked() { void EventThread::enableVSyncLocked() { if (!mUseSoftwareVSync) { if (!mUseSoftwareVSync) { // never enable h/w VSYNC when screen is off // never enable h/w VSYNC when screen is off mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, true); mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); mPowerHAL.vsyncHint(true); mPowerHAL.vsyncHint(true); } } mDebugVsyncEnabled = true; mDebugVsyncEnabled = true; } } void EventThread::disableVSyncLocked() { void EventThread::disableVSyncLocked() { mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, false); mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); mPowerHAL.vsyncHint(false); mPowerHAL.vsyncHint(false); mDebugVsyncEnabled = false; mDebugVsyncEnabled = false; } } Loading services/surfaceflinger/SurfaceFlinger.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -777,8 +777,8 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) { } } } } void SurfaceFlinger::eventControl(int event, int enabled) { void SurfaceFlinger::eventControl(int disp, int event, int enabled) { getHwComposer().eventControl(event, enabled); getHwComposer().eventControl(disp, event, enabled); } } void SurfaceFlinger::onMessageReceived(int32_t what) { void SurfaceFlinger::onMessageReceived(int32_t what) { Loading services/surfaceflinger/SurfaceFlinger.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -123,7 +123,7 @@ public: // enable/disable h/w composer event // enable/disable h/w composer event // TODO: this should be made accessible only to EventThread // TODO: this should be made accessible only to EventThread void eventControl(int event, int enabled); void eventControl(int disp, int event, int enabled); // called on the main thread by MessageQueue when an internal message // called on the main thread by MessageQueue when an internal message // is received // is received Loading Loading
services/surfaceflinger/DisplayHardware/HWComposer.cpp +33 −15 Original line number Original line Diff line number Diff line Loading @@ -147,7 +147,7 @@ HWComposer::HWComposer( // don't need a vsync thread if we have a hardware composer // don't need a vsync thread if we have a hardware composer needVSyncThread = false; needVSyncThread = false; // always turn vsync off when we start // always turn vsync off when we start mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); // these IDs are always reserved // these IDs are always reserved for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) { for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) { Loading Loading @@ -202,7 +202,7 @@ HWComposer::HWComposer( HWComposer::~HWComposer() { HWComposer::~HWComposer() { if (mHwc) { if (mHwc) { mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); } } if (mVSyncThread != NULL) { if (mVSyncThread != NULL) { mVSyncThread->requestExitAndWait(); mVSyncThread->requestExitAndWait(); Loading Loading @@ -443,17 +443,33 @@ bool HWComposer::isConnected(int disp) const { return mDisplayData[disp].connected; return mDisplayData[disp].connected; } } void HWComposer::eventControl(int event, int enabled) { void HWComposer::eventControl(int disp, int event, int enabled) { if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) { return; } status_t err = NO_ERROR; status_t err = NO_ERROR; if (mHwc) { if (mHwc && !mDebugForceFakeVSync) { if (!mDebugForceFakeVSync) { // NOTE: we use our own internal lock here because we have to call err = mHwc->eventControl(mHwc, 0, event, enabled); // into the HWC with the lock held, and we want to make sure // that even if HWC blocks (which it shouldn't), it won't // affect other threads. Mutex::Autolock _l(mEventControlLock); const int32_t eventBit = 1UL << event; const int32_t newValue = enabled ? eventBit : 0; const int32_t oldValue = mDisplayData[disp].events & eventBit; if (newValue != oldValue) { ATRACE_CALL(); err = mHwc->eventControl(mHwc, disp, event, enabled); if (!err) { int32_t& events(mDisplayData[disp].events); events = (events & ~eventBit) | newValue; } } // error here should not happen -- not sure what we should // error here should not happen -- not sure what we should // do if it does. // do if it does. ALOGE_IF(err, "eventControl(%d, %d) failed %s", ALOGE_IF(err, "eventControl(%d, %d) failed %s", event, enabled, strerror(-err)); event, enabled, strerror(-err)); } } } if (err == NO_ERROR && mVSyncThread != NULL) { if (err == NO_ERROR && mVSyncThread != NULL) { mVSyncThread->setEnabled(enabled); mVSyncThread->setEnabled(enabled); Loading Loading @@ -652,16 +668,16 @@ status_t HWComposer::commit() { return (status_t)err; return (status_t)err; } } status_t HWComposer::release(int disp) const { status_t HWComposer::release(int disp) { LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); if (mHwc) { if (mHwc) { mHwc->eventControl(mHwc, disp, HWC_EVENT_VSYNC, 0); eventControl(disp, HWC_EVENT_VSYNC, 0); return (status_t)mHwc->blank(mHwc, disp, 1); return (status_t)mHwc->blank(mHwc, disp, 1); } } return NO_ERROR; return NO_ERROR; } } status_t HWComposer::acquire(int disp) const { status_t HWComposer::acquire(int disp) { LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES); if (mHwc) { if (mHwc) { return (status_t)mHwc->blank(mHwc, disp, 0); return (status_t)mHwc->blank(mHwc, disp, 0); Loading Loading @@ -965,9 +981,11 @@ HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) void HWComposer::VSyncThread::setEnabled(bool enabled) { void HWComposer::VSyncThread::setEnabled(bool enabled) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); if (mEnabled != enabled) { mEnabled = enabled; mEnabled = enabled; mCondition.signal(); mCondition.signal(); } } } void HWComposer::VSyncThread::onFirstRef() { void HWComposer::VSyncThread::onFirstRef() { run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); Loading
services/surfaceflinger/DisplayHardware/HWComposer.h +9 −4 Original line number Original line Diff line number Diff line Loading @@ -92,10 +92,10 @@ public: status_t commit(); status_t commit(); // release hardware resources and blank screen // release hardware resources and blank screen status_t release(int disp) const; status_t release(int disp); // acquire hardware resources and unblank screen // acquire hardware resources and unblank screen status_t acquire(int disp) const; status_t acquire(int disp); // reset state when an external, non-virtual display is disconnected // reset state when an external, non-virtual display is disconnected void disconnectDisplay(int disp); void disconnectDisplay(int disp); Loading Loading @@ -226,7 +226,7 @@ public: EVENT_VSYNC = HWC_EVENT_VSYNC EVENT_VSYNC = HWC_EVENT_VSYNC }; }; void eventControl(int event, int enabled); void eventControl(int disp, int event, int enabled); // Query display parameters. Pass in a display index (e.g. // Query display parameters. Pass in a display index (e.g. // HWC_DISPLAY_PRIMARY). // HWC_DISPLAY_PRIMARY). Loading Loading @@ -289,7 +289,7 @@ private: DisplayData() : xdpi(0), ydpi(0), refresh(0), DisplayData() : xdpi(0), ydpi(0), refresh(0), connected(false), hasFbComp(false), hasOvComp(false), connected(false), hasFbComp(false), hasOvComp(false), capacity(0), list(NULL), capacity(0), list(NULL), framebufferTarget(NULL), fbTargetHandle(NULL) { } framebufferTarget(NULL), fbTargetHandle(NULL), events(0) { } ~DisplayData() { ~DisplayData() { free(list); free(list); } } Loading @@ -306,6 +306,8 @@ private: hwc_display_contents_1* list; hwc_display_contents_1* list; hwc_layer_1* framebufferTarget; hwc_layer_1* framebufferTarget; buffer_handle_t fbTargetHandle; buffer_handle_t fbTargetHandle; // protected by mEventControlLock int32_t events; }; }; sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger; Loading @@ -327,6 +329,9 @@ private: // protected by mLock // protected by mLock mutable Mutex mLock; mutable Mutex mLock; mutable nsecs_t mLastHwVSync; mutable nsecs_t mLastHwVSync; // thread-safe mutable Mutex mEventControlLock; }; }; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading
services/surfaceflinger/EventThread.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -308,14 +308,14 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent( void EventThread::enableVSyncLocked() { void EventThread::enableVSyncLocked() { if (!mUseSoftwareVSync) { if (!mUseSoftwareVSync) { // never enable h/w VSYNC when screen is off // never enable h/w VSYNC when screen is off mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, true); mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); mPowerHAL.vsyncHint(true); mPowerHAL.vsyncHint(true); } } mDebugVsyncEnabled = true; mDebugVsyncEnabled = true; } } void EventThread::disableVSyncLocked() { void EventThread::disableVSyncLocked() { mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, false); mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); mPowerHAL.vsyncHint(false); mPowerHAL.vsyncHint(false); mDebugVsyncEnabled = false; mDebugVsyncEnabled = false; } } Loading
services/surfaceflinger/SurfaceFlinger.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -777,8 +777,8 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) { } } } } void SurfaceFlinger::eventControl(int event, int enabled) { void SurfaceFlinger::eventControl(int disp, int event, int enabled) { getHwComposer().eventControl(event, enabled); getHwComposer().eventControl(disp, event, enabled); } } void SurfaceFlinger::onMessageReceived(int32_t what) { void SurfaceFlinger::onMessageReceived(int32_t what) { Loading
services/surfaceflinger/SurfaceFlinger.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -123,7 +123,7 @@ public: // enable/disable h/w composer event // enable/disable h/w composer event // TODO: this should be made accessible only to EventThread // TODO: this should be made accessible only to EventThread void eventControl(int event, int enabled); void eventControl(int disp, int event, int enabled); // called on the main thread by MessageQueue when an internal message // called on the main thread by MessageQueue when an internal message // is received // is received Loading