am ce9ee16d: Merge "Conservatively estimate geometry bounds" into klp-dev

* commit 'ce9ee16d654a42f31d211c60708d7b23f17c1d8e':
  Conservatively estimate geometry bounds
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2066f69..89a82fd 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1628,14 +1628,7 @@
 
     Rect r(left, top, right, bottom);
     currentTransform().mapRect(r);
-
-    if (snapOut) {
-        // snapOut is generally used to account for 1 pixel ramp (in window coordinates)
-        // outside of the provided rect boundaries in tessellated AA geometry
-        r.snapOutToPixelBoundaries();
-    } else {
-        r.snapToPixelBoundaries();
-    }
+    r.snapGeometryToPixelBoundaries(snapOut);
 
     Rect clipRect(*mSnapshot->clipRect);
     clipRect.snapToPixelBoundaries();
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 9e4670e..7814a01 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -20,6 +20,7 @@
 #include <utils/Trace.h>
 
 #include "Program.h"
+#include "Vertex.h"
 
 namespace android {
 namespace uirenderer {
@@ -172,7 +173,7 @@
             // up and to the left.
             // This offset value is based on an assumption that some hardware may use as
             // little as 12.4 precision, so we offset by slightly more than 1/16.
-            p.translate(.065, .065);
+            p.translate(Vertex::gGeometryFudgeFactor, Vertex::gGeometryFudgeFactor);
             glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]);
         }
         mProjection = projectionMatrix;
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 7605307..dabd8d4 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -21,6 +21,8 @@
 
 #include <utils/Log.h>
 
+#include "Vertex.h"
+
 namespace android {
 namespace uirenderer {
 
@@ -171,17 +173,37 @@
     }
 
     /**
-     * Similar to snapToPixelBoundaries, but used for AA geometry with a ramp perimeter.
+     * Similar to snapToPixelBoundaries, but estimates bounds conservatively to handle GL rounding
+     * errors.
      *
-     * We inset the data by a fudge factor of slightly over 1/16 (similar to when drawing non-AA
-     * lines) before rounding out so that insignificant amounts of ramp geometry (esp. from rounding
-     * errors) are ignored.
+     * This function should be used whenever estimating the damage rect of geometry already mapped
+     * into layer space.
      */
-    void snapOutToPixelBoundaries() {
-        left = floorf(left + 0.065f);
-        top = floorf(top + 0.065f);
-        right = ceilf(right - 0.065f);
-        bottom = ceilf(bottom - 0.065f);
+    void snapGeometryToPixelBoundaries(bool snapOut) {
+        if (snapOut) {
+            /* For AA geometry with a ramp perimeter, don't snap by rounding - AA geometry will have
+             * a 0.5 pixel perimeter not accounted for in its bounds. Instead, snap by
+             * conservatively rounding out the bounds with floor/ceil.
+             *
+             * In order to avoid changing integer bounds with floor/ceil due to rounding errors
+             * inset the bounds first by the fudge factor. Very small fraction-of-a-pixel errors
+             * from this inset will only incur similarly small errors in output, due to transparency
+             * in extreme outside of the geometry.
+             */
+            left = floorf(left + Vertex::gGeometryFudgeFactor);
+            top = floorf(top + Vertex::gGeometryFudgeFactor);
+            right = ceilf(right - Vertex::gGeometryFudgeFactor);
+            bottom = ceilf(bottom - Vertex::gGeometryFudgeFactor);
+        } else {
+            /* For other geometry, we do the regular rounding in order to snap, but also outset the
+             * bounds by a fudge factor. This ensures that ambiguous geometry (e.g. a non-AA Rect
+             * with top left at (0.5, 0.5)) will err on the side of a larger damage rect.
+             */
+            left = floorf(left + 0.5f - Vertex::gGeometryFudgeFactor);
+            top = floorf(top + 0.5f - Vertex::gGeometryFudgeFactor);
+            right = floorf(right + 0.5f + Vertex::gGeometryFudgeFactor);
+            bottom = floorf(bottom + 0.5f + Vertex::gGeometryFudgeFactor);
+        }
     }
 
     void snapToPixelBoundaries() {
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index c06762f..790d4fc 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -26,6 +26,15 @@
  * Simple structure to describe a vertex with a position and a texture.
  */
 struct Vertex {
+    /**
+     * Fudge-factor used to disambiguate geometry pixel positioning.
+     *
+     * Used to offset lines and points to avoid ambiguous intersection with pixel centers (see
+     * Program::set()), and used to make geometry damage rect calculation conservative (see
+     * Rect::snapGeometryToPixelBoundaries())
+     */
+    static const float gGeometryFudgeFactor = 0.0656f;
+
     float position[2];
 
     static inline void set(Vertex* vertex, float x, float y) {