split HWComposer out of DisplayHardware

we will only ever have a single instance of HWComposer, so
it's now an attribute of SurfaceFlinger, instead of being part
of DisplayHardware.

DisplayHardware now just represents a "display" (it should be renamed).

Change-Id: Iec191e57686868e1df6daa8b880a286c9fefde56
diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp
index f982794..067a54f 100644
--- a/services/surfaceflinger/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware.cpp
@@ -106,7 +106,6 @@
     : DisplayHardwareBase(display),
       mFlinger(flinger),
       mDisplayId(display),
-      mHwc(0),
       mNativeWindow(surface),
       mFlags(0),
       mSecureLayerVisible(false)
@@ -227,12 +226,6 @@
     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 @@
     DisplayHardware::setOrientation(ISurfaceComposer::eOrientationDefault);
 }
 
-void DisplayHardware::setVSyncHandler(const sp<VSyncHandler>& 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<VSyncHandler> 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 @@
     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 @@
     }
     
     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 a1a4764..88a8c0d 100644
--- a/services/surfaceflinger/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware.h
@@ -27,30 +27,24 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
+#include <utils/Mutex.h>
+#include <utils/Timers.h>
+
 #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 @@
 
     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 @@
     int                     getOrientation() const { return mOrientation; }
     const Transform&        getTransform() const { return mGlobalTransform; }
 
-    void setVSyncHandler(const sp<VSyncHandler>& 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 @@
 private:
     void init(EGLConfig config);
 
-    virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
-
     /*
      *  Constants, set during initialization
      */
     sp<SurfaceFlinger> mFlinger;
     int mDisplayId;
-    HWComposer* mHwc;
-    PowerHAL mPowerHAL;
     // ANativeWindow this display is rendering into
     sp<SurfaceTextureClient> mNativeWindow;
     // set if mNativeWindow is a FramebufferSurface
@@ -148,8 +125,6 @@
     mutable uint32_t mPageFlipCount;
 
     nsecs_t         mRefreshPeriod;
-    mutable nsecs_t mLastHwVSync;
-
 
     /*
      * Can only accessed from the main thread, these members
@@ -171,7 +146,7 @@
      *  protected by mLock
      */
     mutable Mutex mLock;
-    wp<VSyncHandler>    mVSyncHandler;
+    mutable nsecs_t mLastHwVSync;
 };
 
 }; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6d0631d..1742f1b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -276,9 +276,14 @@
 }
 
 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 fe9efa6..3d79577 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -36,7 +36,7 @@
 // ---------------------------------------------------------------------------
 
 EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
-    : mHw(const_cast<DisplayHardware&>(flinger->getDefaultDisplayHardware())), // XXX: eventthread will need rework
+    : mFlinger(flinger),
       mLastVSyncTimestamp(0),
       mVSyncTimestamp(0),
       mUseSoftwareVSync(false),
@@ -45,7 +45,6 @@
 }
 
 void EventThread::onFirstRef() {
-    mHw.setVSyncHandler(this);
     run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
 }
 
@@ -251,13 +250,15 @@
 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 92c92de..2f10cdb 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -28,6 +28,7 @@
 #include <utils/SortedVector.h>
 
 #include "DisplayHardware.h"
+#include "DisplayHardware/PowerHAL.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -38,7 +39,7 @@
 
 // ---------------------------------------------------------------------------
 
-class EventThread : public Thread, public DisplayHardware::VSyncHandler {
+class EventThread : public Thread {
     class Connection : public BnDisplayEventConnection {
     public:
         Connection(const sp<EventThread>& eventThread);
@@ -77,20 +78,23 @@
     // 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>& connection);
     void enableVSyncLocked();
     void disableVSyncLocked();
 
     // constants
-    DisplayHardware& mHw;
+    sp<SurfaceFlinger> mFlinger;
+    PowerHAL mPowerHAL;
 
     mutable Mutex mLock;
     mutable Condition mCondition;
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index aeafe4f..7bf634e 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 8f94325..2ecdeb8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -406,6 +406,14 @@
     EGLSurface surface = hw->getEGLSurface();
     initializeGL(display, surface);
 
+    // initialize the H/W composer
+    mHwc = new HWComposer(this,
+            *static_cast<HWComposer::EventHandler *>(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 @@
     return true;
 }
 
+void SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
+    DisplayHardware& hw(const_cast<DisplayHardware&>(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 @@
     // h/w composer.
 
     const DisplayHardware& hw(getDefaultDisplayHardware());
-    HWComposer& hwc(hw.getHwComposer());
+    HWComposer& hwc(getHwComposer());
     const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
     size_t numLayers = layers.size();
     const nsecs_t now = systemTime();
@@ -724,6 +742,7 @@
     }
 
     hw.flip(mSwapRegion);
+    hwc.commit();
 
     if (hwc.initCheck() == NO_ERROR) {
         HWComposer::LayerListIterator cur = hwc.begin();
@@ -1027,7 +1046,7 @@
 void SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
 {
     mHwWorkListDirty = false;
-    HWComposer& hwc(hw.getHwComposer());
+    HWComposer& hwc(getHwComposer());
     if (hwc.initCheck() == NO_ERROR) {
         const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
         const size_t count = currentLayers.size();
@@ -1089,7 +1108,7 @@
 
 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::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 @@
 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 @@
     if (hw.isScreenAcquired()) {
         mEventThread->onScreenReleased();
         hw.releaseScreen();
+        getHwComposer().release();
         // from this point on, SF will stop drawing
     }
 }
@@ -1842,7 +1863,7 @@
     /*
      * 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 @@
     }
 
     // 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 3ecaa7f..6418122 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -41,11 +41,15 @@
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
 
+#include <hardware/hwcomposer_defs.h>
+
 #include <private/gui/LayerState.h>
 
 #include "Barrier.h"
 #include "MessageQueue.h"
 
+#include "DisplayHardware/HWComposer.h"
+
 namespace android {
 
 // ---------------------------------------------------------------------------
@@ -81,7 +85,8 @@
 class SurfaceFlinger : public BinderService<SurfaceFlinger>,
                        public BnSurfaceComposer,
                        private IBinder::DeathRecipient,
-                       private Thread
+                       private Thread,
+                       private HWComposer::EventHandler
 {
 public:
     static char const* getServiceName() {
@@ -90,6 +95,10 @@
 
     SurfaceFlinger();
 
+    enum {
+        EVENT_VSYNC = HWC_EVENT_VSYNC
+    };
+
     // post an asynchronous message to the main thread
     status_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0,
         uint32_t flags = 0);
@@ -114,14 +123,19 @@
         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;
@@ -194,6 +208,11 @@
     virtual void onFirstRef();
 
     /* ------------------------------------------------------------------------
+     * HWComposer::EventHandler interface
+     */
+    virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
+
+    /* ------------------------------------------------------------------------
      * Message handling
      */
     void waitForEvent();
@@ -308,6 +327,12 @@
     }
 
     /* ------------------------------------------------------------------------
+     * H/W composer
+     */
+
+    HWComposer& getHwComposer() const { return *mHwc; }
+
+        /* ------------------------------------------------------------------------
      * Compositing
      */
     void invalidateHwcGeometry();
@@ -359,6 +384,7 @@
     // constant members (no synchronization needed for access)
     sp<IMemoryHeap> mServerHeap;
     surface_flinger_cblk_t* mServerCblk;
+    HWComposer* mHwc;
     GLuint mWormholeTexName;
     GLuint mProtectedTexName;
     nsecs_t mBootTime;