detect (and preserve) if patch colors are opaque
authorMike Reed <reed@google.com>
Fri, 19 May 2017 02:23:34 +0000 (22:23 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 19 May 2017 15:47:39 +0000 (15:47 +0000)
Bug: skia:
Change-Id: Ida3a1ff3f78db2498a6dfc655d8be4de8ad912c7
Reviewed-on: https://skia-review.googlesource.com/17380
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Mike Reed <reed@google.com>

src/utils/SkPatchUtils.cpp

index 9a789ea80f86ec8c09cfe9e408df165cddd172ae..119f734a24315c9e48a3c64d146fafd3c5da06fd 100644 (file)
@@ -242,15 +242,19 @@ sk_sp<SkVertices> SkPatchUtils::MakeVertices(const SkPoint cubics[12], const SkC
     SkPoint* texs = builder.texCoords();
     SkColor* colors = builder.colors();
     uint16_t* indices = builder.indices();
+    bool is_opaque = false;
 
     // if colors is not null then create array for colors
     SkPMColor colorsPM[kNumCorners];
     if (srcColors) {
+        SkColor c = ~0;
         // premultiply colors to avoid color bleeding.
         for (int i = 0; i < kNumCorners; i++) {
             colorsPM[i] = SkPreMultiplyColor(srcColors[i]);
+            c &= srcColors[i];
         }
         srcColors = colorsPM;
+        is_opaque = (SkColorGetA(c) == 0xFF);
     }
 
     SkPoint pts[kNumPtsCubic];
@@ -294,11 +298,16 @@ sk_sp<SkVertices> SkPatchUtils::MakeVertices(const SkPoint cubics[12], const SkC
             pos[dataIndex] = s0 + s1 - s2;
 
             if (colors) {
-                uint8_t a = uint8_t(bilerp(u, v,
-                                           SkScalar(SkColorGetA(colorsPM[kTopLeft_Corner])),
-                                           SkScalar(SkColorGetA(colorsPM[kTopRight_Corner])),
-                                           SkScalar(SkColorGetA(colorsPM[kBottomLeft_Corner])),
-                                           SkScalar(SkColorGetA(colorsPM[kBottomRight_Corner]))));
+                uint8_t a = 0xFF;
+                // We do the opaque check for speed, and to ensure that opaque stays opaque,
+                // in case we lose precision in the bilerp.
+                if (!is_opaque) {
+                    a = uint8_t(bilerp(u, v,
+                                       SkScalar(SkColorGetA(colorsPM[kTopLeft_Corner])),
+                                       SkScalar(SkColorGetA(colorsPM[kTopRight_Corner])),
+                                       SkScalar(SkColorGetA(colorsPM[kBottomLeft_Corner])),
+                                       SkScalar(SkColorGetA(colorsPM[kBottomRight_Corner]))));
+                }
                 uint8_t r = uint8_t(bilerp(u, v,
                                            SkScalar(SkColorGetR(colorsPM[kTopLeft_Corner])),
                                            SkScalar(SkColorGetR(colorsPM[kTopRight_Corner])),