Merge "Cleanup RS logs Reduce the startup/shutdown info and format the logs in a consistent manner."
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index 4e65a2d..9e98bc5 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -27,7 +27,7 @@
 class Rect : public ARect
 {
 public:
-    typedef int32_t value_type;
+    typedef ARect::value_type value_type;
 
     // we don't provide copy-ctor and operator= on purpose
     // because we want the compiler generated versions
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index a060a5f..8dab291 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -479,6 +479,11 @@
         const Region& lhs,
         const Rect& rhs, int dx, int dy)
 {
+    if (!rhs.isValid()) {
+        LOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}",
+                op, rhs.left, rhs.top, rhs.right, rhs.bottom);
+    }
+
 #if VALIDATE_WITH_CORECG || VALIDATE_REGIONS
     boolean_operation(op, dst, lhs, Region(rhs), dx, dy);
 #else
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 40a6f1e..f02c954 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -84,9 +84,10 @@
     
     status_t compositionComplete() const;
     
-    Rect bounds() const {
+    Rect getBounds() const {
         return Rect(mWidth, mHeight);
     }
+    inline Rect bounds() const { return getBounds(); }
 
     // only for debugging
     int getCurrentBufferIndex() const;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index c9567d5..e707bdc 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -40,6 +40,7 @@
 HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
     : mFlinger(flinger),
       mModule(0), mHwc(0), mList(0), mCapacity(0),
+      mNumOVLayers(0), mNumFBLayers(0),
       mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
 {
     int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
@@ -98,9 +99,40 @@
 
 status_t HWComposer::prepare() const {
     int err = mHwc->prepare(mHwc, mList);
+    if (err == NO_ERROR) {
+        size_t numOVLayers = 0;
+        size_t numFBLayers = 0;
+        size_t count = mList->numHwLayers;
+        for (size_t i=0 ; i<count ; i++) {
+            hwc_layer& l(mList->hwLayers[i]);
+            if (l.flags & HWC_SKIP_LAYER) {
+                l.compositionType = HWC_FRAMEBUFFER;
+            }
+            switch (l.compositionType) {
+                case HWC_OVERLAY:
+                    numOVLayers++;
+                    break;
+                case HWC_FRAMEBUFFER:
+                    numFBLayers++;
+                    break;
+            }
+        }
+        mNumOVLayers = numOVLayers;
+        mNumFBLayers = numFBLayers;
+    }
     return (status_t)err;
 }
 
+size_t HWComposer::getLayerCount(int type) const {
+    switch (type) {
+        case HWC_OVERLAY:
+            return mNumOVLayers;
+        case HWC_FRAMEBUFFER:
+            return mNumFBLayers;
+    }
+    return 0;
+}
+
 status_t HWComposer::commit() const {
     int err = mHwc->set(mHwc, mDpy, mSur, mList);
     if (mList) {
@@ -143,18 +175,29 @@
         snprintf(buffer, SIZE, "  numHwLayers=%u, flags=%08x\n",
                 mList->numHwLayers, mList->flags);
         result.append(buffer);
-
+        result.append(
+                "    type   |   hints  |   flags  | tr | blend |  format  |     source rectangle      |      crop rectangle       name \n"
+                "-----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
+        //      "  ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
         for (size_t i=0 ; i<mList->numHwLayers ; i++) {
             const hwc_layer_t& l(mList->hwLayers[i]);
-            snprintf(buffer, SIZE, "  %8s | %08x | %08x | %02x | %04x | [%5d,%5d,%5d,%5d] |  [%5d,%5d,%5d,%5d] %s\n",
+            const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
+            int32_t format = -1;
+            if (layer->getLayer() != NULL) {
+                const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
+                if (buffer != NULL) {
+                    format = buffer->getPixelFormat();
+                }
+            }
+            snprintf(buffer, SIZE,
+                    "  %8s | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
                     l.compositionType ? "OVERLAY" : "FB",
-                    l.hints, l.flags, l.transform, l.blending,
+                    l.hints, l.flags, l.transform, l.blending, format,
                     l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
                     l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
-                    visibleLayersSortedByZ[i]->getName().string());
+                    layer->getName().string());
             result.append(buffer);
         }
-
     }
     if (mHwc && mHwc->common.version >= 1 && mHwc->dump) {
         mHwc->dump(mHwc, buffer, SIZE);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 8758a80..aa8ebe1 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -64,6 +64,9 @@
     size_t getNumLayers() const;
     hwc_layer_t* getLayers() const;
 
+    // updated in preapre()
+    size_t getLayerCount(int type) const;
+
     // for debugging
     void dump(String8& out, char* scratch, size_t SIZE,
             const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
@@ -81,6 +84,8 @@
     hwc_composer_device_t*  mHwc;
     hwc_layer_list_t*       mList;
     size_t                  mCapacity;
+    mutable size_t          mNumOVLayers;
+    mutable size_t          mNumFBLayers;
     hwc_display_t           mDpy;
     hwc_surface_t           mSur;
     cb_context              mCBContext;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d06a35f..ff389ae 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -73,12 +73,14 @@
     virtual bool isSecure() const           { return mSecure; }
     virtual bool isProtected() const;
     virtual void onRemoved();
+    virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
 
     // LayerBaseClient interface
     virtual wp<IBinder> getSurfaceTextureBinder() const;
 
     // only for debugging
     inline const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
+    inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
 
 protected:
     virtual void onFirstRef();
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index ee50428..a14b397 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -46,6 +46,7 @@
 class DisplayHardware;
 class GraphicBuffer;
 class GraphicPlane;
+class Layer;
 class LayerBaseClient;
 class SurfaceFlinger;
 
@@ -105,6 +106,7 @@
             void invalidate();
 
     virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
+    virtual sp<Layer> getLayer() const { return 0; }
 
     virtual const char* getTypeId() const { return "LayerBase"; }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index df13640..0ef03bb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -469,14 +469,14 @@
 
 void SurfaceFlinger::postFramebuffer()
 {
-    if (!mInvalidRegion.isEmpty()) {
+    if (!mSwapRegion.isEmpty()) {
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         const nsecs_t now = systemTime();
         mDebugInSwapBuffers = now;
-        hw.flip(mInvalidRegion);
+        hw.flip(mSwapRegion);
         mLastSwapBufferTime = systemTime() - now;
         mDebugInSwapBuffers = 0;
-        mInvalidRegion.clear();
+        mSwapRegion.clear();
     }
 }
 
@@ -834,7 +834,7 @@
 void SurfaceFlinger::handleRepaint()
 {
     // compute the invalid region
-    mInvalidRegion.orSelf(mDirtyRegion);
+    mSwapRegion.orSelf(mDirtyRegion);
 
     if (UNLIKELY(mDebugRegion)) {
         debugFlashRegions();
@@ -855,7 +855,7 @@
         if (flags & DisplayHardware::SWAP_RECTANGLE) {
             // TODO: we really should be able to pass a region to
             // SWAP_RECTANGLE so that we don't have to redraw all this.
-            mDirtyRegion.set(mInvalidRegion.bounds());
+            mDirtyRegion.set(mSwapRegion.bounds());
         } else {
             // in the BUFFER_PRESERVED case, obviously, we can update only
             // what's needed and nothing more.
@@ -868,32 +868,29 @@
             // (pushed to the framebuffer).
             // This is needed because PARTIAL_UPDATES only takes one
             // rectangle instead of a region (see DisplayHardware::flip())
-            mDirtyRegion.set(mInvalidRegion.bounds());
+            mDirtyRegion.set(mSwapRegion.bounds());
         } else {
             // we need to redraw everything (the whole screen)
             mDirtyRegion.set(hw.bounds());
-            mInvalidRegion = mDirtyRegion;
+            mSwapRegion = mDirtyRegion;
         }
     }
 
-    Region expandDirty = setupHardwareComposer(mDirtyRegion);
-    mDirtyRegion.orSelf(expandDirty);
-    mInvalidRegion.orSelf(mDirtyRegion);
+    setupHardwareComposer(mDirtyRegion);
     composeSurfaces(mDirtyRegion);
 
-    // clear the dirty regions
+    // update the swap region and clear the dirty region
+    mSwapRegion.orSelf(mDirtyRegion);
     mDirtyRegion.clear();
 }
 
-Region SurfaceFlinger::setupHardwareComposer(const Region& dirty)
+void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
 {
-    Region dirtyOut(dirty);
-
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     HWComposer& hwc(hw.getHwComposer());
     hwc_layer_t* const cur(hwc.getLayers());
     if (!cur) {
-        return dirtyOut;
+        return;
     }
 
     const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
@@ -916,53 +913,62 @@
         const sp<LayerBase>& layer(layers[i]);
         layer->setPerFrameData(&cur[i]);
     }
+    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
     status_t err = hwc.prepare();
     LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
 
     if (err == NO_ERROR) {
+        // what's happening here is tricky.
+        // we want to clear all the layers with the CLEAR_FB flags
+        // that are opaque.
+        // however, since some GPU are efficient at preserving
+        // the backbuffer, we want to take advantage of that so we do the
+        // clear only in the dirty region (other areas will be preserved
+        // on those GPUs).
+        //   NOTE: on non backbuffer preserving GPU, the dirty region
+        //   has already been expanded as needed, so the code is correct
+        //   there too.
+        //
+        // However, the content of the framebuffer cannot be trusted when
+        // we switch to/from FB/OVERLAY, in which case we need to
+        // expand the dirty region to those areas too.
+        //
+        // Note also that there is a special case when switching from
+        // "no layers in FB" to "some layers in FB", where we need to redraw
+        // the entire FB, since some areas might contain uninitialized
+        // data.
+        //
+        // Also we want to make sure to not clear areas that belong to
+        // layers above that won't redraw (we would just erasing them),
+        // that is, we can't erase anything outside the dirty region.
+
         Region transparent;
-        for (size_t i=0 ; i<count ; i++) {
-            // what's happening here is tricky.
-            // we want to clear all the layers with the CLEAR_FB flags
-            // that are opaque.
-            // however, since some GPU have are efficient at preserving
-            // the backbuffer, we want to take advantage of that so we do the
-            // clear only in the dirty region (other areas will be preserved
-            // on those GPUs).
-            //   NOTE: on non backbuffer preserving GPU, the dirty region
-            //   has already been expanded as needed, so the code is correct
-            //   there too.
-            // However, the content of the framebuffer cannot be trusted when
-            // we switch to/from FB/OVERLAY, in which case we need to
-            // expand the dirty region to those areas too.
-            //
-            // Also we want to make sure to not clear areas that belong to
-            // layers above that won't redraw (we would just erasing them),
-            // that is, we can't erase anything outside the dirty region.
 
-            const sp<LayerBase>& layer(layers[i]);
-            if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
-                transparent.orSelf(layer->visibleRegionScreen);
+        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
+            transparent.set(hw.getBounds());
+            dirtyInOut = transparent;
+        } else {
+            for (size_t i=0 ; i<count ; i++) {
+                const sp<LayerBase>& layer(layers[i]);
+                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
+                    transparent.orSelf(layer->visibleRegionScreen);
+                }
+                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
+                if (isOverlay != layer->isOverlay()) {
+                    // we transitioned to/from overlay, so add this layer
+                    // to the dirty region so the framebuffer can be either
+                    // cleared or redrawn.
+                    dirtyInOut.orSelf(layer->visibleRegionScreen);
+                }
+                layer->setOverlay(isOverlay);
             }
-
-            bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER) &&
-                !(cur[i].flags & HWC_SKIP_LAYER);
-
-            if (isOverlay != layer->isOverlay()) {
-                // we transitioned to/from overlay, so add this layer
-                // to the dirty region so the framebuffer can be either
-                // cleared or redrawn.
-                dirtyOut.orSelf(layer->visibleRegionScreen);
-            }
-            layer->setOverlay(isOverlay);
+            // don't erase stuff outside the dirty region
+            transparent.andSelf(dirtyInOut);
         }
 
-
         /*
          *  clear the area of the FB that need to be transparent
          */
-        // don't erase stuff outside the dirty region
-        transparent.andSelf(dirtyOut);
         if (!transparent.isEmpty()) {
             glClearColor(0,0,0,0);
             Region::const_iterator it = transparent.begin();
@@ -976,7 +982,6 @@
             }
         }
     }
-    return dirtyOut;
 }
 
 void SurfaceFlinger::composeSurfaces(const Region& dirty)
@@ -997,8 +1002,7 @@
     const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
     size_t count = layers.size();
     for (size_t i=0 ; i<count ; i++) {
-        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) &&
-                !(cur[i].flags & HWC_SKIP_LAYER)) {
+        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
             continue;
         }
         const sp<LayerBase>& layer(layers[i]);
@@ -1014,7 +1018,7 @@
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t flags = hw.getFlags();
     const int32_t height = hw.getHeight();
-    if (mInvalidRegion.isEmpty()) {
+    if (mSwapRegion.isEmpty()) {
         return;
     }
 
@@ -1051,7 +1055,7 @@
         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-    hw.flip(mInvalidRegion);
+    hw.flip(mSwapRegion);
 
     if (mDebugRegion > 1)
         usleep(mDebugRegion * 1000);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 126ca39..d7f005f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -277,7 +277,7 @@
             void        handleWorkList();
             void        handleRepaint();
             void        postFramebuffer();
-            Region      setupHardwareComposer(const Region& dirty);
+            void        setupHardwareComposer(Region& dirtyInOut);
             void        composeSurfaces(const Region& dirty);
             void        repaintEverything();
 
@@ -358,7 +358,7 @@
                 State                       mDrawingState;
                 Region                      mDirtyRegion;
                 Region                      mDirtyRegionRemovedLayer;
-                Region                      mInvalidRegion;
+                Region                      mSwapRegion;
                 Region                      mWormholeRegion;
                 bool                        mVisibleRegionsDirty;
                 bool                        mHwWorkListDirty;