diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp index f982794f3..067a54f6d 100644 --- a/services/surfaceflinger/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware.cpp @@ -106,7 +106,6 @@ DisplayHardware::DisplayHardware( : DisplayHardwareBase(display), mFlinger(flinger), mDisplayId(display), - mHwc(0), mNativeWindow(surface), mFlags(0), mSecureLayerVisible(false) @@ -227,12 +226,6 @@ void DisplayHardware::init(EGLConfig config) mFormat = format; mPageFlipCount = 0; - // initialize the H/W composer - mHwc = new HWComposer(mFlinger, *this, mRefreshPeriod); - if (mHwc->initCheck() == NO_ERROR) { - mHwc->setFrameBuffer(mDisplay, mSurface); - } - // initialize the shared control block surface_flinger_cblk_t* const scblk = mFlinger->getControlBlock(); scblk->connected |= 1 << mDisplayId; @@ -248,53 +241,6 @@ void DisplayHardware::init(EGLConfig config) DisplayHardware::setOrientation(ISurfaceComposer::eOrientationDefault); } -void DisplayHardware::setVSyncHandler(const sp& handler) { - Mutex::Autolock _l(mLock); - mVSyncHandler = handler; -} - -void DisplayHardware::eventControl(int event, int enabled) { - if (event == EVENT_VSYNC) { - mPowerHAL.vsyncHint(enabled); - } - mHwc->eventControl(event, enabled); -} - -void DisplayHardware::onVSyncReceived(int dpy, nsecs_t timestamp) { - sp handler; - { // scope for the lock - Mutex::Autolock _l(mLock); - mLastHwVSync = timestamp; - if (mVSyncHandler != NULL) { - handler = mVSyncHandler.promote(); - } - } - - if (handler != NULL) { - handler->onVSyncReceived(dpy, timestamp); - } -} - -HWComposer& DisplayHardware::getHwComposer() const { - return *mHwc; -} - -void DisplayHardware::releaseScreen() const -{ - DisplayHardwareBase::releaseScreen(); - if (mHwc->initCheck() == NO_ERROR) { - mHwc->release(); - } -} - -void DisplayHardware::acquireScreen() const -{ - if (mHwc->initCheck() == NO_ERROR) { - mHwc->acquire(); - } - DisplayHardwareBase::acquireScreen(); -} - uint32_t DisplayHardware::getPageFlipCount() const { return mPageFlipCount; } @@ -319,6 +265,11 @@ status_t DisplayHardware::compositionComplete() const { return mFramebufferSurface->compositionComplete(); } +void DisplayHardware::onVSyncReceived(nsecs_t timestamp) { + Mutex::Autolock _l(mLock); + mLastHwVSync = timestamp; +} + void DisplayHardware::flip(const Region& dirty) const { checkGLErrors(); @@ -342,13 +293,6 @@ void DisplayHardware::flip(const Region& dirty) const } mPageFlipCount++; - - if (mHwc->initCheck() == NO_ERROR) { - mHwc->commit(); - } else { - eglSwapBuffers(dpy, surface); - } - checkEGLErrors("eglSwapBuffers"); } uint32_t DisplayHardware::getFlags() const diff --git a/services/surfaceflinger/DisplayHardware.h b/services/surfaceflinger/DisplayHardware.h index a1a4764fc..88a8c0d07 100644 --- a/services/surfaceflinger/DisplayHardware.h +++ b/services/surfaceflinger/DisplayHardware.h @@ -27,30 +27,24 @@ #include #include +#include +#include + #include "Transform.h" #include "DisplayHardware/DisplayHardwareBase.h" -#include "DisplayHardware/HWComposer.h" -#include "DisplayHardware/PowerHAL.h" namespace android { class FramebufferSurface; +class LayerBase; +class SurfaceFlinger; class SurfaceTextureClient; -class DisplayHardware : - public DisplayHardwareBase, - public HWComposer::EventHandler +class DisplayHardware : public DisplayHardwareBase { public: - class VSyncHandler : virtual public RefBase { - friend class DisplayHardware; - virtual void onVSyncReceived(int dpy, nsecs_t timestamp) = 0; - protected: - virtual ~VSyncHandler() {} - }; - enum { PARTIAL_UPDATES = 0x00020000, // video driver feature SWAP_RECTANGLE = 0x00080000, @@ -64,13 +58,12 @@ public: virtual ~DisplayHardware(); - void releaseScreen() const; - void acquireScreen() const; - // Flip the front and back buffers if the back buffer is "dirty". Might // be instantaneous, might involve copying the frame buffer around. void flip(const Region& dirty) const; + void onVSyncReceived(nsecs_t timestamp); + float getDpiX() const; float getDpiY() const; float getRefreshRate() const; @@ -92,23 +85,11 @@ public: int getOrientation() const { return mOrientation; } const Transform& getTransform() const { return mGlobalTransform; } - void setVSyncHandler(const sp& handler); - - enum { - EVENT_VSYNC = HWC_EVENT_VSYNC - }; - - void eventControl(int event, int enabled); - - uint32_t getPageFlipCount() const; EGLDisplay getEGLDisplay() const { return mDisplay; } void dump(String8& res) const; - // Hardware Composer - HWComposer& getHwComposer() const; - status_t compositionComplete() const; Rect getBounds() const { @@ -119,15 +100,11 @@ public: private: void init(EGLConfig config); - virtual void onVSyncReceived(int dpy, nsecs_t timestamp); - /* * Constants, set during initialization */ sp mFlinger; int mDisplayId; - HWComposer* mHwc; - PowerHAL mPowerHAL; // ANativeWindow this display is rendering into sp mNativeWindow; // set if mNativeWindow is a FramebufferSurface @@ -148,8 +125,6 @@ private: mutable uint32_t mPageFlipCount; nsecs_t mRefreshPeriod; - mutable nsecs_t mLastHwVSync; - /* * Can only accessed from the main thread, these members @@ -171,7 +146,7 @@ private: * protected by mLock */ mutable Mutex mLock; - wp mVSyncHandler; + mutable nsecs_t mLastHwVSync; }; }; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 6d0631d8d..1742f1b2d 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -276,9 +276,14 @@ size_t HWComposer::getLayerCount(int type) const { } status_t HWComposer::commit() const { - int err = mHwc->set(mHwc, mDpy, mSur, mList); - if (mList) { - mList->flags &= ~HWC_GEOMETRY_CHANGED; + int err = NO_ERROR; + if (mHwc) { + err = mHwc->set(mHwc, mDpy, mSur, mList); + if (mList) { + mList->flags &= ~HWC_GEOMETRY_CHANGED; + } + } else { + eglSwapBuffers(mDpy, mSur); } return (status_t)err; } diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index fe9efa6d9..3d7957794 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -36,7 +36,7 @@ namespace android { // --------------------------------------------------------------------------- EventThread::EventThread(const sp& flinger) - : mHw(const_cast(flinger->getDefaultDisplayHardware())), // XXX: eventthread will need rework + : mFlinger(flinger), mLastVSyncTimestamp(0), mVSyncTimestamp(0), mUseSoftwareVSync(false), @@ -45,7 +45,6 @@ EventThread::EventThread(const sp& flinger) } void EventThread::onFirstRef() { - mHw.setVSyncHandler(this); run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); } @@ -251,13 +250,15 @@ bool EventThread::threadLoop() { void EventThread::enableVSyncLocked() { if (!mUseSoftwareVSync) { // never enable h/w VSYNC when screen is off - mHw.eventControl(DisplayHardware::EVENT_VSYNC, true); + mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, true); + mPowerHAL.vsyncHint(true); } mDebugVsyncEnabled = true; } void EventThread::disableVSyncLocked() { - mHw.eventControl(DisplayHardware::EVENT_VSYNC, false); + mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, false); + mPowerHAL.vsyncHint(false); mDebugVsyncEnabled = false; } diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h index 92c92ded8..2f10cdb16 100644 --- a/services/surfaceflinger/EventThread.h +++ b/services/surfaceflinger/EventThread.h @@ -28,6 +28,7 @@ #include #include "DisplayHardware.h" +#include "DisplayHardware/PowerHAL.h" // --------------------------------------------------------------------------- namespace android { @@ -38,7 +39,7 @@ class String8; // --------------------------------------------------------------------------- -class EventThread : public Thread, public DisplayHardware::VSyncHandler { +class EventThread : public Thread { class Connection : public BnDisplayEventConnection { public: Connection(const sp& eventThread); @@ -77,20 +78,23 @@ public: // called after the screen is turned on from main thread void onScreenAcquired(); + // called when receiving a vsync event + void onVSyncReceived(int display, nsecs_t timestamp); + void dump(String8& result, char* buffer, size_t SIZE) const; private: virtual bool threadLoop(); virtual status_t readyToRun(); virtual void onFirstRef(); - virtual void onVSyncReceived(int, nsecs_t timestamp); void removeDisplayEventConnection(const wp& connection); void enableVSyncLocked(); void disableVSyncLocked(); // constants - DisplayHardware& mHw; + sp mFlinger; + PowerHAL mPowerHAL; mutable Mutex mLock; mutable Condition mCondition; diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index aeafe4f34..7bf634e6a 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -35,6 +35,7 @@ #include "DisplayHardware.h" #include "Transform.h" +#include "DisplayHardware/HWComposer.h" namespace android { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 8f9432534..2ecdeb8e2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -406,6 +406,14 @@ status_t SurfaceFlinger::readyToRun() EGLSurface surface = hw->getEGLSurface(); initializeGL(display, surface); + // initialize the H/W composer + mHwc = new HWComposer(this, + *static_cast(this), + hw->getRefreshPeriod()); + if (mHwc->initCheck() == NO_ERROR) { + mHwc->setFrameBuffer(display, surface); + } + // start the EventThread mEventThread = new EventThread(this); mEventQueue.setEventThread(mEventThread); @@ -555,6 +563,16 @@ bool SurfaceFlinger::threadLoop() { return true; } +void SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) { + DisplayHardware& hw(const_cast(getDisplayHardware(dpy))); + hw.onVSyncReceived(timestamp); + mEventThread->onVSyncReceived(dpy, timestamp); +} + +void SurfaceFlinger::eventControl(int event, int enabled) { + getHwComposer().eventControl(event, enabled); +} + void SurfaceFlinger::onMessageReceived(int32_t what) { ATRACE_CALL(); switch (what) { @@ -705,7 +723,7 @@ void SurfaceFlinger::postFramebuffer() // h/w composer. const DisplayHardware& hw(getDefaultDisplayHardware()); - HWComposer& hwc(hw.getHwComposer()); + HWComposer& hwc(getHwComposer()); const Vector< sp >& layers(hw.getVisibleLayersSortedByZ()); size_t numLayers = layers.size(); const nsecs_t now = systemTime(); @@ -724,6 +742,7 @@ void SurfaceFlinger::postFramebuffer() } hw.flip(mSwapRegion); + hwc.commit(); if (hwc.initCheck() == NO_ERROR) { HWComposer::LayerListIterator cur = hwc.begin(); @@ -1027,7 +1046,7 @@ void SurfaceFlinger::handleRefresh() void SurfaceFlinger::handleWorkList(const DisplayHardware& hw) { mHwWorkListDirty = false; - HWComposer& hwc(hw.getHwComposer()); + HWComposer& hwc(getHwComposer()); if (hwc.initCheck() == NO_ERROR) { const Vector< sp >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); @@ -1089,7 +1108,7 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw) void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) { - HWComposer& hwc(hw.getHwComposer()); + HWComposer& hwc(getHwComposer()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); if (cur == end) { @@ -1122,7 +1141,7 @@ void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) { - HWComposer& hwc(hw.getHwComposer()); + HWComposer& hwc(getHwComposer()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); @@ -1578,6 +1597,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( void SurfaceFlinger::onScreenAcquired() { ALOGD("Screen about to return, flinger = %p", this); const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware + getHwComposer().acquire(); hw.acquireScreen(); mEventThread->onScreenAcquired(); // this is a temporary work-around, eventually this should be called @@ -1593,6 +1613,7 @@ void SurfaceFlinger::onScreenReleased() { if (hw.isScreenAcquired()) { mEventThread->onScreenReleased(); hw.releaseScreen(); + getHwComposer().release(); // from this point on, SF will stop drawing } } @@ -1842,7 +1863,7 @@ void SurfaceFlinger::dumpAllLocked( /* * Dump HWComposer state */ - HWComposer& hwc(hw.getHwComposer()); + HWComposer& hwc(getHwComposer()); snprintf(buffer, SIZE, "h/w composer state:\n"); result.append(buffer); snprintf(buffer, SIZE, " h/w composer %s and %s\n", @@ -2430,7 +2451,7 @@ status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) } // turn off hwc while we're doing the animation - hw.getHwComposer().disable(); + getHwComposer().disable(); // and make sure to turn it back on (if needed) next time we compose invalidateHwcGeometry(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 3ecaa7f95..64181222c 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -41,11 +41,15 @@ #include #include +#include + #include #include "Barrier.h" #include "MessageQueue.h" +#include "DisplayHardware/HWComposer.h" + namespace android { // --------------------------------------------------------------------------- @@ -81,7 +85,8 @@ enum { class SurfaceFlinger : public BinderService, public BnSurfaceComposer, private IBinder::DeathRecipient, - private Thread + private Thread, + private HWComposer::EventHandler { public: static char const* getServiceName() { @@ -90,6 +95,10 @@ public: SurfaceFlinger(); + enum { + EVENT_VSYNC = HWC_EVENT_VSYNC + }; + // post an asynchronous message to the main thread status_t postMessageAsync(const sp& msg, nsecs_t reltime = 0, uint32_t flags = 0); @@ -114,14 +123,19 @@ public: return getDisplayHardware(0); } + // utility function to delete a texture on the main thread + void deleteTextureAsync(GLuint texture); + + + // enable/disable h/w composer event + // TODO: this should be made accessible only to EventThread + void eventControl(int event, int enabled); + // called on the main thread by MessageQueue when an internal message // is received // TODO: this should be made accessible only to MessageQueue void onMessageReceived(int32_t what); - // utility function to delete a texture on the main thread - void deleteTextureAsync(GLuint texture); - private: friend class Client; friend class DisplayEventConnection; @@ -193,6 +207,11 @@ private: virtual status_t readyToRun(); virtual void onFirstRef(); + /* ------------------------------------------------------------------------ + * HWComposer::EventHandler interface + */ + virtual void onVSyncReceived(int dpy, nsecs_t timestamp); + /* ------------------------------------------------------------------------ * Message handling */ @@ -308,6 +327,12 @@ private: } /* ------------------------------------------------------------------------ + * H/W composer + */ + + HWComposer& getHwComposer() const { return *mHwc; } + + /* ------------------------------------------------------------------------ * Compositing */ void invalidateHwcGeometry(); @@ -359,6 +384,7 @@ private: // constant members (no synchronization needed for access) sp mServerHeap; surface_flinger_cblk_t* mServerCblk; + HWComposer* mHwc; GLuint mWormholeTexName; GLuint mProtectedTexName; nsecs_t mBootTime;