Fix "Battery/Status/Clock status bar area flickers when dragging down"

The crop is now handled like a resize, it's latched only when we
receive a new buffer in the case we have a resize in the same
transaction.

Bug: 6498869
Change-Id: I9f3cbbe08fb19443899461ec441c714748a4fd1a
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5988ed2..6ec4f49 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -435,25 +435,37 @@
         // the size changed, we need to ask our client to request a new buffer
         ALOGD_IF(DEBUG_RESIZE,
                 "doTransaction: "
-                "resize (layer=%p), requested (%dx%d), drawing (%d,%d), "
+                "geometry (layer=%p), size: current (%dx%d), drawing (%dx%d), "
+                "crop: current (%d,%d,%d,%d [%dx%d]), drawing (%d,%d,%d,%d [%dx%d]), "
                 "scalingMode=%d",
                 this,
                 int(temp.requested.w), int(temp.requested.h),
                 int(front.requested.w), int(front.requested.h),
+                temp.requested.crop.left,
+                temp.requested.crop.top,
+                temp.requested.crop.right,
+                temp.requested.crop.bottom,
+                temp.requested.crop.getWidth(),
+                temp.requested.crop.getHeight(),
+                front.requested.crop.left,
+                front.requested.crop.top,
+                front.requested.crop.right,
+                front.requested.crop.bottom,
+                front.requested.crop.getWidth(),
+                front.requested.crop.getHeight(),
                 mCurrentScalingMode);
 
         if (!isFixedSize()) {
             // this will make sure LayerBase::doTransaction doesn't update
-            // the drawing state's size
+            // the drawing state's geometry
             Layer::State& editDraw(mDrawingState);
-            editDraw.requested.w = temp.requested.w;
-            editDraw.requested.h = temp.requested.h;
+            editDraw.requested = temp.requested;
         }
 
         // record the new size, form this point on, when the client request
         // a buffer, it'll get the new size.
-        mSurfaceTexture->setDefaultBufferSize(temp.requested.w,
-                temp.requested.h);
+        mSurfaceTexture->setDefaultBufferSize(
+                temp.requested.w, temp.requested.h);
     }
 
     return LayerBase::doTransaction(flags);
@@ -554,9 +566,7 @@
         // FIXME: mPostedDirtyRegion = dirty & bounds
         mPostedDirtyRegion.set(front.active.w, front.active.h);
 
-        if ((front.active.w != front.requested.w) ||
-            (front.active.h != front.requested.h))
-        {
+        if (front.active != front.requested) {
             // check that we received a buffer of the right size
             // (Take the buffer's orientation into account)
             if (mCurrentTransform & Transform::ROT_90) {
@@ -571,8 +581,7 @@
                 // current and drawing states. Drawing state is only accessed
                 // in this thread, no need to have it locked
                 Layer::State& editDraw(mDrawingState);
-                editDraw.active.w = editDraw.requested.w;
-                editDraw.active.h = editDraw.requested.h;
+                editDraw.active = editDraw.requested;
 
                 // We also need to update the current state so that we don't
                 // end-up doing too much work during the next transaction.
@@ -580,8 +589,7 @@
                 // because State::w and State::h are only accessed from
                 // this thread
                 Layer::State& editTemp(currentState());
-                editTemp.active.w = editDraw.active.w;
-                editTemp.active.h = editDraw.active.h;
+                editTemp.active = editDraw.active;
 
                 // recompute visible region
                 recomputeVisibleRegions = true;
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index c52b49c..7c6a28a 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -173,10 +173,10 @@
     return true;
 }
 bool LayerBase::setCrop(const Rect& crop) {
-    if (mCurrentState.active.crop == crop)
+    if (mCurrentState.requested.crop == crop)
         return false;
     mCurrentState.sequence++;
-    mCurrentState.active.crop = crop;
+    mCurrentState.requested.crop = crop;
     requestTransaction();
     return true;
 }
@@ -201,15 +201,13 @@
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
-    if ((front.requested.w != temp.requested.w) ||
-        (front.requested.h != temp.requested.h))  {
-        // resize the layer, set the physical size to the requested size
+    if (front.requested != temp.requested)  {
+        // geometry of the layer has changed, set the active geometry
+        // to the requested geometry.
         Layer::State& editTemp(currentState());
-        editTemp.active.w = temp.requested.w;
-        editTemp.active.h = temp.requested.h;
+        editTemp.active = temp.requested;
     }
-
-    if ((front.active.w != temp.active.w) || (front.active.h != temp.active.h)) {
+    if (front.active != temp.active) {
         // invalidate and recompute the visible regions if needed
         flags |= Layer::eVisibleRegion;
     }
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index d0b2a74..9542424 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -66,9 +66,15 @@
             int32_t     sequence;
             
             struct Geometry {
-                uint32_t        w;
-                uint32_t        h;
-                Rect            crop;
+                uint32_t w;
+                uint32_t h;
+                Rect crop;
+                inline bool operator == (const Geometry& rhs) const {
+                    return (w==rhs.w && h==rhs.h && crop==rhs.crop);
+                }
+                inline bool operator != (const Geometry& rhs) const {
+                    return !operator == (rhs);
+                }
             };
 
             struct State {