getting closer to final main composition loop

Change-Id: Icd63782366ffd11d9ea00c925ae5783ed7440cdb
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c344870..198beeb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -82,6 +82,7 @@
         mTransactionFlags(0),
         mTransationPending(false),
         mLayersRemoved(false),
+        mRepaintEverything(0),
         mBootTime(systemTime()),
         mVisibleRegionsDirty(false),
         mHwWorkListDirty(false),
@@ -577,7 +578,7 @@
 void SurfaceFlinger::handleMessageRefresh() {
     handleRefresh();
 
-    if (mVisibleRegionsDirty) {
+    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
         mVisibleRegionsDirty = false;
         invalidateHwcGeometry();
 
@@ -586,9 +587,8 @@
          */
 
         const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
-        // TODO: iterate through all displays
-        {
-            DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
+        for (int dpy=0 ; dpy<1 ; dpy++) {  // TODO: iterate through all displays
+            DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
 
             Region opaqueRegion;
             Region dirtyRegion;
@@ -612,45 +612,70 @@
         }
     }
 
-    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
+    HWComposer& hwc(getHwComposer());
+    if (hwc.initCheck() == NO_ERROR) {
+        // build the h/w work list
+        const bool workListsDirty = mHwWorkListDirty;
+        mHwWorkListDirty = false;
+        for (int dpy=0 ; dpy<1 ; dpy++) {  // TODO: iterate through all displays
+            DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
+            const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+            const size_t count = currentLayers.size();
 
-    // TODO: iterate through all displays
-    for (int dpy=0 ; dpy<1 ; dpy++) {
-        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
-        if (hw.dirtyRegion.isEmpty()) {
-            continue;
+            hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays
+
+            HWComposer::LayerListIterator cur = hwc.begin();
+            const HWComposer::LayerListIterator end = hwc.end();
+            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(*cur);
+            }
         }
+        status_t err = hwc.prepare();
+        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
+    }
+
+    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
+    for (int dpy=0 ; dpy<1 ; dpy++) {  // TODO: iterate through all displays
+        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
 
         // transform the dirty region into this screen's coordinate space
         const Transform& planeTransform(hw.getTransform());
         Region dirtyRegion;
         if (repaintEverything) {
+            dirtyRegion.set(hw.bounds());
+        } else {
             dirtyRegion = planeTransform.transform(hw.dirtyRegion);
             dirtyRegion.andSelf(hw.bounds());
-        } else {
-            dirtyRegion.set(hw.bounds());
         }
         hw.dirtyRegion.clear();
 
-        // build the h/w work list
-        if (CC_UNLIKELY(mHwWorkListDirty)) {
-            handleWorkList(hw);
+        if (!dirtyRegion.isEmpty()) {
+            if (hw.canDraw()) {
+                // repaint the framebuffer (if needed)
+                handleRepaint(hw, dirtyRegion);
+            }
         }
-
-        if (CC_LIKELY(hw.canDraw())) {
-            // repaint the framebuffer (if needed)
-            handleRepaint(hw, dirtyRegion);
-            // inform the h/w that we're done compositing
-            hw.compositionComplete();
-            postFramebuffer();
-        } else {
-            // pretend we did the post
-            hw.compositionComplete();
-        }
+        // inform the h/w that we're done compositing
+        hw.compositionComplete();
     }
 
+    postFramebuffer();
 
-#if 0
+
+#if 1
     // render to the external display if we have one
     EGLSurface externalDisplaySurface = getExternalDisplaySurface();
     if (externalDisplaySurface != EGL_NO_SURFACE) {
@@ -670,6 +695,7 @@
             glMatrixMode(GL_MODELVIEW);
             glLoadIdentity();
 
+            DisplayHardware& hw(const_cast<DisplayDevice&>(getDisplayHardware(0)));
             const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
             const size_t count = layers.size();
             for (size_t i=0 ; i<count ; ++i) {
@@ -695,45 +721,51 @@
 void SurfaceFlinger::postFramebuffer()
 {
     ATRACE_CALL();
-    // mSwapRegion can be empty here is some cases, for instance if a hidden
-    // or fully transparent window is updating.
-    // in that case, we need to flip anyways to not risk a deadlock with
-    // h/w composer.
 
-    const DisplayHardware& hw(getDefaultDisplayHardware());
-    HWComposer& hwc(getHwComposer());
-    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
-    size_t numLayers = layers.size();
     const nsecs_t now = systemTime();
     mDebugInSwapBuffers = now;
 
-    if (hwc.initCheck() == NO_ERROR) {
-        HWComposer::LayerListIterator cur = hwc.begin();
-        const HWComposer::LayerListIterator end = hwc.end();
-        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
-            if (cur->getCompositionType() == HWC_OVERLAY) {
-                layers[i]->setAcquireFence(*cur);
-            } else {
-                cur->setAcquireFenceFd(-1);
+    HWComposer& hwc(getHwComposer());
+
+    for (int dpy=0 ; dpy<1 ; dpy++) {  // TODO: iterate through all displays
+        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
+        if (hwc.initCheck() == NO_ERROR) {
+            const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+            const size_t count = currentLayers.size();
+            HWComposer::LayerListIterator cur = hwc.begin();
+            const HWComposer::LayerListIterator end = hwc.end();
+            for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+                const sp<LayerBase>& layer(currentLayers[i]);
+                layer->setAcquireFence(*cur);
             }
         }
+        hw.flip(hw.swapRegion);
+        hw.swapRegion.clear();
     }
 
-    hw.flip(hw.swapRegion);
-    hw.swapRegion.clear();
-
     if (hwc.initCheck() == NO_ERROR) {
-        hwc.commit(mEGLDisplay, hw.getEGLSurface());
-        HWComposer::LayerListIterator cur = hwc.begin();
-        const HWComposer::LayerListIterator end = hwc.end();
-        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
-            layers[i]->onLayerDisplayed(&*cur);
+        // FIXME: eventually commit() won't take arguments
+        hwc.commit(mEGLDisplay, getDefaultDisplayHardware().getEGLSurface());
+    }
+
+    for (int dpy=0 ; dpy<1 ; dpy++) {  // TODO: iterate through all displays
+        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
+        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+        const size_t count = currentLayers.size();
+        if (hwc.initCheck() == NO_ERROR) {
+            HWComposer::LayerListIterator cur = hwc.begin();
+            const HWComposer::LayerListIterator end = hwc.end();
+            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
+                currentLayers[i]->onLayerDisplayed(&*cur);
+            }
+        } else {
+            eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
+            for (size_t i = 0; i < count; i++) {
+                currentLayers[i]->onLayerDisplayed(NULL);
+            }
         }
-    } else {
-        eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
-        for (size_t i = 0; i < numLayers; i++) {
-            layers[i]->onLayerDisplayed(NULL);
-        }
+
+        // FIXME: we need to call eglSwapBuffers() on displays that have GL composition
     }
 
     mLastSwapBufferTime = systemTime() - now;
@@ -1028,27 +1060,6 @@
     }
 }
 
-
-void SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
-{
-    mHwWorkListDirty = false;
-    HWComposer& hwc(getHwComposer());
-    if (hwc.initCheck() == NO_ERROR) {
-        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
-        const size_t count = currentLayers.size();
-        hwc.createWorkList(count);
-
-        HWComposer::LayerListIterator cur = hwc.begin();
-        const HWComposer::LayerListIterator end = hwc.end();
-        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-            currentLayers[i]->setGeometry(hw, *cur);
-            if (mDebugDisableHWC || mDebugRegion) {
-                cur->setSkip(true);
-            }
-        }
-    }
-}
-
 void SurfaceFlinger::handleRepaint(const DisplayHardware& hw,
         const Region& inDirtyRegion)
 {
@@ -1063,10 +1074,6 @@
         debugFlashRegions(hw, dirtyRegion);
     }
 
-    // set the frame buffer
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-
     uint32_t flags = hw.getFlags();
     if (flags & DisplayHardware::SWAP_RECTANGLE) {
         // we can redraw only what's dirty, but since SWAP_RECTANGLE only
@@ -1087,57 +1094,29 @@
         }
     }
 
-    setupHardwareComposer(hw);
     composeSurfaces(hw, dirtyRegion);
 
     // update the swap region and clear the dirty region
     hw.swapRegion.orSelf(dirtyRegion);
 }
 
-void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
-{
-    HWComposer& hwc(getHwComposer());
-    HWComposer::LayerListIterator cur = hwc.begin();
-    const HWComposer::LayerListIterator end = hwc.end();
-    if (cur == end) {
-        return;
-    }
-
-    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
-    size_t count = layers.size();
-
-    ALOGE_IF(hwc.getNumLayers() != count,
-            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
-            hwc.getNumLayers(), count);
-
-    // just to be extra-safe, use the smallest count
-    if (hwc.initCheck() == NO_ERROR) {
-        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
-    }
-
-    /*
-     *  update the per-frame h/w composer data for each layer
-     *  and build the transparent region of the FB
-     */
-    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-        const sp<LayerBase>& layer(layers[i]);
-        layer->setPerFrameData(*cur);
-    }
-    status_t err = hwc.prepare();
-    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
-}
-
 void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
 {
     HWComposer& hwc(getHwComposer());
     HWComposer::LayerListIterator cur = hwc.begin();
     const HWComposer::LayerListIterator end = hwc.end();
 
-    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
+    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);  // FIXME: this should be per display
     if (cur==end || fbLayerCount) {
-        // Never touch the framebuffer if we don't have any framebuffer layers
 
-        if (hwc.getLayerCount(HWC_OVERLAY)) {
+        DisplayHardware::makeCurrent(hw, mEGLContext);
+
+        // set the frame buffer
+        glMatrixMode(GL_MODELVIEW);
+        glLoadIdentity();
+
+        // Never touch the framebuffer if we don't have any framebuffer layers
+        if (hwc.getLayerCount(HWC_OVERLAY)) { // FIXME: this should be per display
             // 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