SF: Change rounding behavior in setGeometry

- Add an option for a transform to round outwards instead of to the
  nearest pixel.
- Use this new rounding behavior when converting the crop rectangle
  from display-space to layer-space. Otherwise a pixel that will
  partially be on the screen might be marked as transparent.

Bug 30510632

Change-Id: I1aece177cc29c54ee0d4a2c919e47442eb455f30
diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
index c2be91d..6be9ae2 100644
--- a/services/surfaceflinger/Transform.cpp
+++ b/services/surfaceflinger/Transform.cpp
@@ -196,7 +196,7 @@
     return transform( Rect(w, h) );
 }
 
-Rect Transform::transform(const Rect& bounds) const
+Rect Transform::transform(const Rect& bounds, bool roundOutwards) const
 {
     Rect r;
     vec2 lt( bounds.left,  bounds.top    );
@@ -209,10 +209,17 @@
     lb = transform(lb);
     rb = transform(rb);
 
-    r.left   = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
-    r.top    = floorf(min(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
-    r.right  = floorf(max(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
-    r.bottom = floorf(max(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+    if (roundOutwards) {
+        r.left   = floorf(min(lt[0], rt[0], lb[0], rb[0]));
+        r.top    = floorf(min(lt[1], rt[1], lb[1], rb[1]));
+        r.right  = ceilf(max(lt[0], rt[0], lb[0], rb[0]));
+        r.bottom = ceilf(max(lt[1], rt[1], lb[1], rb[1]));
+    } else {
+        r.left   = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
+        r.top    = floorf(min(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+        r.right  = floorf(max(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
+        r.bottom = floorf(max(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+    }
 
     return r;
 }