OSDN Git Service

HWComposer now has its own concept of display IDs
authorMathias Agopian <mathias@google.com>
Wed, 22 Aug 2012 06:34:09 +0000 (23:34 -0700)
committerMathias Agopian <mathias@google.com>
Thu, 23 Aug 2012 23:03:37 +0000 (16:03 -0700)
HWComposer can now create IDs representing a display
it can deal with. IDs MAIN and HDMI are reserved.
SurfaceFlinger associate HWComposer IDs with a
DisplayDevice and uses that when it talks to HWComposer.

A DisplayDevice doesn't have to have a HWComposer ID,
in that case it just can't use h/w composer composition.

Change-Id: Iec3d7ac92e0c22bf975052ae2847402f58bade71

services/surfaceflinger/DisplayDevice.cpp
services/surfaceflinger/DisplayDevice.h
services/surfaceflinger/DisplayHardware/HWComposer.cpp
services/surfaceflinger/DisplayHardware/HWComposer.h
services/surfaceflinger/SurfaceFlinger.cpp

index 2289444..821a329 100644 (file)
@@ -68,12 +68,12 @@ void checkGLErrors()
 
 DisplayDevice::DisplayDevice(
         const sp<SurfaceFlinger>& flinger,
-        int display,
+        int32_t display, int32_t hwcDisplayId,
         const sp<ANativeWindow>& nativeWindow,
         const sp<FramebufferSurface>& framebufferSurface,
         EGLConfig config)
     : mFlinger(flinger),
-      mId(display),
+      mId(display), mHwcDisplayId(hwcDisplayId),
       mNativeWindow(nativeWindow),
       mFramebufferSurface(framebufferSurface),
       mDisplay(EGL_NO_DISPLAY),
index 9790699..14b194f 100644 (file)
@@ -62,7 +62,7 @@ public:
 
     DisplayDevice(
             const sp<SurfaceFlinger>& flinger,
-            int dpy,
+            int32_t dpy, int32_t hwcDisplayId,
             const sp<ANativeWindow>& nativeWindow,
             const sp<FramebufferSurface>& framebufferSurface,
             EGLConfig config);
@@ -96,6 +96,7 @@ public:
     const Transform&        getTransform() const { return mGlobalTransform; }
     uint32_t                getLayerStack() const { return mLayerStack; }
     int32_t                 getDisplayId() const { return mId; }
+    int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
 
     status_t compositionComplete() const;
     
@@ -132,6 +133,7 @@ private:
      */
     sp<SurfaceFlinger> mFlinger;
     int32_t mId;
+    int32_t mHwcDisplayId;
 
     // ANativeWindow this display is rendering into
     sp<ANativeWindow> mNativeWindow;
index 403b979..dd70232 100644 (file)
@@ -194,13 +194,13 @@ HWComposer::HWComposer(
         framebuffer_device_t const* fbDev)
     : mFlinger(flinger),
       mModule(0), mHwc(0), mNumDisplays(1), mCapacity(0),
-      mNumOVLayers(0), mNumFBLayers(0),
       mCBContext(new cb_context),
-      mEventHandler(handler), mRefreshPeriod(0),
+      mEventHandler(handler),
       mVSyncCount(0), mDebugForceFakeVSync(false)
 {
-    for (size_t i = 0; i < MAX_DISPLAYS; i++)
-        mLists[i] = NULL;
+    for (size_t i =0 ; i<MAX_DISPLAYS ; i++) {
+        mLists[i] = 0;
+    }
 
     char value[PROPERTY_VALUE_MAX];
     property_get("debug.sf.no_hw_vsync", value, "0");
@@ -232,6 +232,10 @@ HWComposer::HWComposer(
                 mHwc->registerProcs(mHwc, &mCBContext->procs);
             }
 
+            // these IDs are always reserved
+            mTokens.markBit(HWC_DISPLAY_PRIMARY);
+            mTokens.markBit(HWC_DISPLAY_EXTERNAL);
+
             // always turn vsync off when we start
             needVSyncThread = false;
             if (hwcHasVsyncEvent(mHwc)) {
@@ -239,7 +243,7 @@ HWComposer::HWComposer(
 
                 int period;
                 if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
-                    mRefreshPeriod = nsecs_t(period);
+                    mDisplayData[0].refresh = nsecs_t(period);
                 }
             } else {
                 needVSyncThread = true;
@@ -255,17 +259,17 @@ HWComposer::HWComposer(
 
 
     if (fbDev) {
-        if (mRefreshPeriod == 0) {
-            mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
-            ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
+        if (mDisplayData[HWC_DISPLAY_PRIMARY].refresh == 0) {
+            mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(1e9 / fbDev->fps);
+            ALOGW("getting VSYNC period from fb HAL: %lld", mDisplayData[0].refresh);
         }
-        mDpiX = fbDev->xdpi;
-        mDpiY = fbDev->ydpi;
+        mDisplayData[HWC_DISPLAY_PRIMARY].xdpi = fbDev->xdpi;
+        mDisplayData[HWC_DISPLAY_PRIMARY].ydpi = fbDev->ydpi;
     }
 
-    if (mRefreshPeriod == 0) {
-        mRefreshPeriod = nsecs_t(1e9 / 60.0);
-        ALOGW("getting VSYNC period thin air: %lld", mRefreshPeriod);
+    if (mDisplayData[HWC_DISPLAY_PRIMARY].refresh == 0) {
+        mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(1e9 / 60.0);
+        ALOGW("getting VSYNC period thin air: %lld", mDisplayData[0].refresh);
     }
 
     if (needVSyncThread) {
@@ -276,8 +280,9 @@ HWComposer::HWComposer(
 
 HWComposer::~HWComposer() {
     hwcEventControl(mHwc, 0, EVENT_VSYNC, 0);
-    for (size_t i = 0; i < MAX_DISPLAYS; i++)
+    for (size_t i = 0; i < MAX_DISPLAYS; i++) {
         free(mLists[i]);
+    }
     if (mVSyncThread != NULL) {
         mVSyncThread->requestExitAndWait();
     }
@@ -315,8 +320,32 @@ void HWComposer::vsync(int dpy, int64_t timestamp) {
     mLastHwVSync = timestamp;
 }
 
+int32_t HWComposer::allocateDisplayId() {
+    if (mTokens.isFull()) {
+        return NO_MEMORY;
+    }
+
+    // FIXME: for now we don't support h/w composition wifi displays
+    return -1;
+
+    int32_t id = mTokens.firstUnmarkedBit();
+    mTokens.markBit(id);
+    return id;
+}
+
+status_t HWComposer::freeDisplayId(int32_t id) {
+    if (id < MAX_DISPLAYS) {
+        return BAD_VALUE;
+    }
+    if (!mTokens.hasBit(id)) {
+        return BAD_INDEX;
+    }
+    mTokens.clearBit(id);
+    return NO_ERROR;
+}
+
 nsecs_t HWComposer::getRefreshPeriod() const {
-    return mRefreshPeriod;
+    return mDisplayData[0].refresh;
 }
 
 nsecs_t HWComposer::getRefreshTimestamp() const {
@@ -325,15 +354,15 @@ nsecs_t HWComposer::getRefreshTimestamp() const {
     // the refresh period and whatever closest timestamp we have.
     Mutex::Autolock _l(mLock);
     nsecs_t now = systemTime(CLOCK_MONOTONIC);
-    return now - ((now - mLastHwVSync) %  mRefreshPeriod);
+    return now - ((now - mLastHwVSync) %  mDisplayData[0].refresh);
 }
 
 float HWComposer::getDpiX() const {
-    return mDpiX;
+    return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi;
 }
 
 float HWComposer::getDpiY() const {
-    return mDpiY;
+    return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi;
 }
 
 void HWComposer::eventControl(int event, int enabled) {
@@ -354,10 +383,11 @@ void HWComposer::eventControl(int event, int enabled) {
 }
 
 status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
-    // FIXME: handle multiple displays
-    if (uint32_t(id) >= MAX_DISPLAYS)
+    if (!mTokens.hasBit(id)) {
         return BAD_INDEX;
+    }
 
+    // FIXME: handle multiple displays
     if (mHwc) {
         // TODO: must handle multiple displays here
         // mLists[0] is NULL only when this is called from the constructor
@@ -376,9 +406,10 @@ status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
     return NO_ERROR;
 }
 
-status_t HWComposer::prepare() const {
+status_t HWComposer::prepare() {
     int err = hwcPrepare(mHwc, mNumDisplays,
             const_cast<hwc_display_contents_1_t**>(mLists));
+
     if (err == NO_ERROR) {
 
         // here we're just making sure that "skip" layers are set
@@ -388,65 +419,58 @@ status_t HWComposer::prepare() const {
         // think is almost possible.
 
         // TODO: must handle multiple displays here
-
-        size_t numOVLayers = 0;
-        size_t numFBLayers = 0;
-        size_t count = getNumLayers(0);
-
-        for (size_t i=0 ; i<count ; i++) {
-            int compositionType;
-            if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
-                hwc_layer_1_t* l = &mLists[0]->hwLayers[i];
+        if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+            size_t count = getNumLayers(0);
+            struct hwc_display_contents_1* disp = mLists[0];
+            mDisplayData[0].hasFbComp = false;
+            mDisplayData[0].hasOvComp = false;
+            for (size_t i=0 ; i<count ; i++) {
+                hwc_layer_1_t* l = &disp->hwLayers[i];
                 if (l->flags & HWC_SKIP_LAYER) {
                     l->compositionType = HWC_FRAMEBUFFER;
                 }
-                compositionType = l->compositionType;
-            } else {
-                // mList really has hwc_layer_list_t memory layout
-                hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
-                hwc_layer_t* l = &list0->hwLayers[i];
+                if (l->compositionType == HWC_FRAMEBUFFER)
+                    mDisplayData[HWC_DISPLAY_PRIMARY].hasFbComp = true;
+                if (l->compositionType == HWC_OVERLAY)
+                    mDisplayData[HWC_DISPLAY_PRIMARY].hasOvComp = true;
+            }
+        } else {
+            size_t count = getNumLayers(0);
+            hwc_layer_list_t* disp = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
+            mDisplayData[0].hasFbComp = false;
+            mDisplayData[0].hasOvComp = false;
+            for (size_t i=0 ; i<count ; i++) {
+                hwc_layer_t* l = &disp->hwLayers[i];
                 if (l->flags & HWC_SKIP_LAYER) {
                     l->compositionType = HWC_FRAMEBUFFER;
                 }
-                compositionType = l->compositionType;
-            }
-
-            switch (compositionType) {
-                case HWC_OVERLAY:
-                    numOVLayers++;
-                    break;
-                case HWC_FRAMEBUFFER:
-                    numFBLayers++;
-                    break;
+                if (l->compositionType == HWC_FRAMEBUFFER)
+                    mDisplayData[HWC_DISPLAY_PRIMARY].hasFbComp = true;
+                if (l->compositionType == HWC_OVERLAY)
+                    mDisplayData[HWC_DISPLAY_PRIMARY].hasOvComp = true;
             }
         }
-        mNumOVLayers = numOVLayers;
-        mNumFBLayers = numFBLayers;
     }
     return (status_t)err;
 }
 
-size_t HWComposer::getLayerCount(int32_t id, int type) const {
-    // FIXME: handle multiple displays
-    if (uint32_t(id) >= MAX_DISPLAYS) {
-        // FIXME: in practice this is only use to know
-        // if we have at least one layer of type.
-        return (type == HWC_FRAMEBUFFER) ? 1 : 0;
-    }
-
+bool HWComposer::hasHwcComposition(int32_t id) const {
+    if (!mTokens.hasBit(id))
+        return false;
+    return mDisplayData[id].hasOvComp;
+}
 
-    switch (type) {
-        case HWC_OVERLAY:
-            return mNumOVLayers;
-        case HWC_FRAMEBUFFER:
-            return mNumFBLayers;
-    }
-    return 0;
+bool HWComposer::hasGlesComposition(int32_t id) const {
+    if (!mTokens.hasBit(id))
+        return false;
+    return mDisplayData[id].hasFbComp;
 }
 
-status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const {
+status_t HWComposer::commit() const {
     int err = NO_ERROR;
     if (mHwc) {
+        void* fbDisplay = eglGetCurrentDisplay();
+        void* fbSurface = eglGetCurrentSurface(EGL_DRAW);
         err = hwcSet(mHwc, fbDisplay, fbSurface, mNumDisplays,
                 const_cast<hwc_display_contents_1_t**>(mLists));
         if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
@@ -661,10 +685,10 @@ public:
  * returns an iterator initialized at a given index in the layer list
  */
 HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) {
-    // FIXME: handle multiple displays
-    if (uint32_t(id) >= MAX_DISPLAYS)
+    if (!mTokens.hasBit(id))
         return LayerListIterator();
 
+    // FIXME: handle multiple displays
     if (!mHwc || index > hwcNumHwLayers(mHwc, mLists[0]))
         return LayerListIterator();
     if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
@@ -741,7 +765,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
 HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
     : mHwc(hwc), mEnabled(false),
       mNextFakeVSync(0),
-      mRefreshPeriod(hwc.mRefreshPeriod)
+      mRefreshPeriod(hwc.getRefreshPeriod())
 {
 }
 
index d15c6f4..7bb3f81 100644 (file)
@@ -28,6 +28,7 @@
 #include <utils/Thread.h>
 #include <utils/Timers.h>
 #include <utils/Vector.h>
+#include <utils/BitSet.h>
 
 extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
                            const struct timespec *request,
@@ -70,14 +71,26 @@ public:
 
     status_t initCheck() const;
 
+    // returns a display ID starting at MAX_DISPLAYS, this ID
+    // is to be used with createWorkList (and all other
+    // methods requiring an ID below).
+    // IDs below MAX_DISPLAY are pre-defined and therefore are always valid.
+    // returns a negative error code if an ID cannot be allocated
+    int32_t allocateDisplayId();
+
+    // recycles the given ID and frees the associated worklist.
+    // IDs below MAX_DISPLAYS are not recycled
+    status_t freeDisplayId(int32_t id);
+
+
     // Asks the HAL what it can do
-    status_t prepare() const;
+    status_t prepare();
 
     // disable hwc until next createWorkList
     status_t disable();
 
     // commits the list
-    status_t commit(void* fbDisplay, void* fbSurface) const;
+    status_t commit() const;
 
     // release hardware resources and blank screen
     status_t release() const;
@@ -88,9 +101,11 @@ public:
     // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
     status_t createWorkList(int32_t id, size_t numLayers);
 
-    // get number of layers of the given type as updated in prepare().
-    // type is HWC_OVERLAY or HWC_FRAMEBUFFER
-    size_t getLayerCount(int32_t id, int type) const;
+    // does this display have layers handled by HWC
+    bool hasHwcComposition(int32_t id) const;
+
+    // does this display have layers handled by GLES
+    bool hasGlesComposition(int32_t id) const;
 
     // needed forward declarations
     class LayerListIterator;
@@ -237,26 +252,32 @@ private:
     inline void vsync(int dpy, int64_t timestamp);
 
 
+    struct DisplayData {
+        DisplayData() : xdpi(0), ydpi(0), refresh(0),
+            hasFbComp(false), hasOvComp(false) { }
+        float xdpi;
+        float ydpi;
+        nsecs_t refresh;
+        bool hasFbComp;
+        bool hasOvComp;
+    };
+
     sp<SurfaceFlinger>              mFlinger;
     hw_module_t const*              mModule;
     struct hwc_composer_device_1*   mHwc;
     // invariant: mLists[0] != NULL iff mHwc != NULL
-    // TODO: decide whether mLists[i>0] should be non-NULL when display i is
-    //       not attached/enabled.
+    // mLists[i>0] can be NULL. that display is to be ignored
     struct hwc_display_contents_1*  mLists[MAX_DISPLAYS];
+    DisplayData                     mDisplayData[MAX_DISPLAYS];
     size_t                          mNumDisplays;
 
     size_t                          mCapacity;
-    mutable size_t                  mNumOVLayers;
-    mutable size_t                  mNumFBLayers;
     cb_context*                     mCBContext;
     EventHandler&                   mEventHandler;
-    nsecs_t                         mRefreshPeriod;
-    float                           mDpiX;
-    float                           mDpiY;
     size_t                          mVSyncCount;
     sp<VSyncThread>                 mVSyncThread;
     bool                            mDebugForceFakeVSync;
+    BitSet32                        mTokens;
 
     // protected by mLock
     mutable Mutex mLock;
index c63d0cf..e6e258f 100644 (file)
@@ -409,7 +409,8 @@ status_t SurfaceFlinger::readyToRun()
         mCurrentState.displays.add(mDefaultDisplays[i], DisplayDeviceState(i));
     }
     sp<DisplayDevice> hw = new DisplayDevice(this,
-            DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig);
+            DisplayDevice::DISPLAY_ID_MAIN, HWC_DISPLAY_PRIMARY,
+            anw, fbs, mEGLConfig);
     mDisplays.add(hw->getDisplayId(), hw);
 
     //  initialize OpenGL ES
@@ -779,29 +780,30 @@ void SurfaceFlinger::setUpHWComposer() {
         mHwWorkListDirty = false;
         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
             sp<const DisplayDevice> hw(mDisplays[dpy]);
-            const Vector< sp<LayerBase> >& currentLayers(
+            const int32_t id = hw->getHwcDisplayId();
+            if (id >= 0) {
+                const Vector< sp<LayerBase> >& currentLayers(
                     hw->getVisibleLayersSortedByZ());
-            const size_t count = currentLayers.size();
-
-            const int32_t id = hw->getDisplayId();
-            if (hwc.createWorkList(id, count) >= 0) {
-                HWComposer::LayerListIterator cur = hwc.begin(id);
-                const HWComposer::LayerListIterator end = hwc.end(id);
-                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-                    const sp<LayerBase>& layer(currentLayers[i]);
-
-                    if (CC_UNLIKELY(workListsDirty)) {
-                        layer->setGeometry(hw, *cur);
-                        if (mDebugDisableHWC || mDebugRegion) {
-                            cur->setSkip(true);
+                const size_t count = currentLayers.size();
+                if (hwc.createWorkList(id, count) >= 0) {
+                    HWComposer::LayerListIterator cur = hwc.begin(id);
+                    const HWComposer::LayerListIterator end = hwc.end(id);
+                    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+                        const sp<LayerBase>& layer(currentLayers[i]);
+
+                        if (CC_UNLIKELY(workListsDirty)) {
+                            layer->setGeometry(hw, *cur);
+                            if (mDebugDisableHWC || mDebugRegion) {
+                                cur->setSkip(true);
+                            }
                         }
-                    }
 
-                    /*
-                     * update the per-frame h/w composer data for each layer
-                     * and build the transparent region of the FB
-                     */
-                    layer->setPerFrameData(hw, *cur);
+                        /*
+                         * update the per-frame h/w composer data for each layer
+                         * and build the transparent region of the FB
+                         */
+                        layer->setPerFrameData(hw, *cur);
+                    }
                 }
             }
         }
@@ -841,21 +843,20 @@ void SurfaceFlinger::postFramebuffer()
 
     HWComposer& hwc(getHwComposer());
     if (hwc.initCheck() == NO_ERROR) {
-        // FIXME: eventually commit() won't take arguments
         // FIXME: EGL spec says:
         //   "surface must be bound to the calling thread's current context,
         //    for the current rendering API."
         DisplayDevice::makeCurrent(
                 getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext);
-        hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
+        hwc.commit();
     }
 
     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
         sp<const DisplayDevice> hw(mDisplays[dpy]);
         const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
         const size_t count = currentLayers.size();
-        if (hwc.initCheck() == NO_ERROR) {
-            int32_t id = hw->getDisplayId();
+        int32_t id = hw->getHwcDisplayId();
+        if (id >=0 && hwc.initCheck() == NO_ERROR) {
             HWComposer::LayerListIterator cur = hwc.begin(id);
             const HWComposer::LayerListIterator end = hwc.end(id);
             for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
@@ -951,12 +952,15 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                     if (state.surface->asBinder() != draw[i].surface->asBinder()) {
                         // changing the surface is like destroying and
                         // recreating the DisplayDevice
+                        const int32_t hwcDisplayId =
+                            (uint32_t(state.id) < DisplayDevice::DISPLAY_ID_COUNT) ?
+                                state.id : getHwComposer().allocateDisplayId();
 
                         sp<SurfaceTextureClient> stc(
                                 new SurfaceTextureClient(state.surface));
 
                         sp<DisplayDevice> disp = new DisplayDevice(this,
-                                state.id, stc, 0, mEGLConfig);
+                            state.id, hwcDisplayId, stc, 0, mEGLConfig);
 
                         disp->setLayerStack(state.layerStack);
                         disp->setOrientation(state.orientation);
@@ -982,10 +986,14 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
             for (size_t i=0 ; i<cc ; i++) {
                 if (draw.indexOfKey(curr.keyAt(i)) < 0) {
                     const DisplayDeviceState& state(curr[i]);
+                    const int32_t hwcDisplayId =
+                        (uint32_t(state.id) < DisplayDevice::DISPLAY_ID_COUNT) ?
+                            state.id : getHwComposer().allocateDisplayId();
+
                     sp<SurfaceTextureClient> stc(
                             new SurfaceTextureClient(state.surface));
-                    sp<DisplayDevice> disp = new DisplayDevice(this, state.id,
-                            stc, 0, mEGLConfig);
+                    sp<DisplayDevice> disp = new DisplayDevice(this,
+                        state.id, hwcDisplayId, stc, 0, mEGLConfig);
                     mDisplays.add(state.id, disp);
                 }
             }
@@ -1251,12 +1259,13 @@ void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
 void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
 {
     HWComposer& hwc(getHwComposer());
-    int32_t id = hw->getDisplayId();
+    int32_t id = hw->getHwcDisplayId();
     HWComposer::LayerListIterator cur = hwc.begin(id);
     const HWComposer::LayerListIterator end = hwc.end(id);
 
-    const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER);
-    if (cur==end || fbLayerCount) {
+    const bool hasGlesComposition = hwc.hasGlesComposition(id);
+    const bool hasHwcComposition = hwc.hasHwcComposition(id);
+    if (cur==end || hasGlesComposition) {
 
         DisplayDevice::makeCurrent(hw, mEGLContext);
 
@@ -1265,7 +1274,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
         glLoadIdentity();
 
         // Never touch the framebuffer if we don't have any framebuffer layers
-        if (hwc.getLayerCount(id, HWC_OVERLAY)) {
+        if (hasHwcComposition) {
             // when using overlays, we assume a fully transparent framebuffer
             // NOTE: we could reduce how much we need to clear, for instance
             // remove where there are opaque FB layers. however, on some