Clean up quick rejection, especially surrounding points + lines.

bug:4351353

quickReject and quickRejectNoScissor have been renamed and refactored:
- to make the scissor side effect clear and explicit
- dangerous methods no longer public
- to make the simple quick reject check logic const
- simple quick reject is now conservative

This CL also fixes several issues with line and point quickRejection -
sub-pixel and hairline lines are much less likely to be incorrectly
rejected, especially at small canvas scale.

Additionally, alpha modulation for AA points < 1px in size is now
correct, dumplicating SW behavior (similar to lines and stroked
shapes work).

Change-Id: Ibb0710c721b9fb415d05acf54dd3d2b4d602156a
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 03b2099..7e8a45b 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "PathTessellator"
+#define LOG_TAG "OpenGLRenderer"
 #define LOG_NDEBUG 1
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
@@ -57,9 +57,12 @@
 #define ROUND_CAP_THRESH 0.25f
 #define PI 3.1415926535897932f
 
-void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint,
-        bool forceExpand) {
-    if (forceExpand || paint->getStyle() != SkPaint::kFill_Style) {
+/**
+ * Note: this function doesn't account for the AA case with sub-pixel line thickness (not just 0 <
+ * width < 1.0, canvas scale factors in as well) so this can't be used for points/lines
+ */
+void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint) {
+    if (paint->getStyle() != SkPaint::kFill_Style) {
         float outset = paint->getStrokeWidth() * 0.5f;
         if (outset == 0) outset = 0.5f; // account for hairline
         bounds.outset(outset, outset);
@@ -159,6 +162,17 @@
         }
         return 0;
     }
+
+    /**
+     * Outset the bounds of point data (for line endpoints or points) to account for AA stroke
+     * geometry.
+     */
+    void expandBoundsForStrokeAA(SkRect& bounds) const {
+        float outset = halfStrokeWidth;
+        if (outset == 0) outset = 0.5f;
+        bounds.outset(outset * inverseScaleX + Vertex::gGeometryFudgeFactor,
+                outset * inverseScaleY + Vertex::gGeometryFudgeFactor);
+    }
 };
 
 void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) {
@@ -329,7 +343,7 @@
  * 3 - zig zag back and forth inside the shape to fill it (using perimeter.size() vertices)
  */
 void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter,
-        VertexBuffer& vertexBuffer) {
+        VertexBuffer& vertexBuffer, float maxAlpha = 1.0f) {
     AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2);
 
     // generate alpha points - fill Alpha vertex gaps in between each point with
@@ -357,7 +371,7 @@
         AlphaVertex::set(&buffer[currentIndex++],
                 current->x - totalOffset.x,
                 current->y - totalOffset.y,
-                1.0f);
+                maxAlpha);
 
         last = current;
         current = next;
@@ -829,11 +843,14 @@
         getFillVerticesFromPerimeter(outlineVertices, tempBuffer);
         instanceVertices<Vertex>(tempBuffer, vertexBuffer, points, count, bounds);
     } else {
-        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer);
+        // note: pass maxAlpha directly, since we want fill to be alpha modulated
+        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer, paintInfo.maxAlpha);
         instanceVertices<AlphaVertex>(tempBuffer, vertexBuffer, points, count, bounds);
     }
 
-    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
+    // expand bounds from vertex coords to pixel data
+    paintInfo.expandBoundsForStrokeAA(bounds);
+
 }
 
 void PathTessellator::tessellateLines(const float* points, int count, SkPaint* paint,
@@ -873,14 +890,15 @@
         expandRectToCoverVertex(bounds, tempVerticesData[1]);
     }
 
-    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
-
     // since multiple objects tessellated into buffer, separate them with degen tris
     if (paintInfo.isAA) {
         vertexBuffer.createDegenerateSeparators<AlphaVertex>(lineAllocSize);
     } else {
         vertexBuffer.createDegenerateSeparators<Vertex>(lineAllocSize);
     }
+
+    // expand bounds from vertex coords to pixel data
+    paintInfo.expandBoundsForStrokeAA(bounds);
 }
 
 ///////////////////////////////////////////////////////////////////////////////