Support wide color in GrLatticeOp

Like other image drawing, paint color is only used when drawing alpha
images, so I had to add a new GM to trigger the relevant code path.
That GM previously drew wrong (clipped color) in glenarrow, and now
draws correctly (matching enarrow).

Bug: skia:
Change-Id: I12c19c2afba29d5176b3ac60ef840d849107bb17
Reviewed-on: https://skia-review.googlesource.com/c/179987
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 0975025..68b15bc 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -30,8 +30,10 @@
     static sk_sp<GrGeometryProcessor> Make(GrGpu* gpu,
                                            const GrTextureProxy* proxy,
                                            sk_sp<GrColorSpaceXform> csxf,
-                                           GrSamplerState::Filter filter) {
-        return sk_sp<GrGeometryProcessor>(new LatticeGP(gpu, proxy, std::move(csxf), filter));
+                                           GrSamplerState::Filter filter,
+                                           bool wideColor) {
+        return sk_sp<GrGeometryProcessor>(
+                new LatticeGP(gpu, proxy, std::move(csxf), filter, wideColor));
     }
 
     const char* name() const override { return "LatticeGP"; }
@@ -90,7 +92,7 @@
 
 private:
     LatticeGP(GrGpu* gpu, const GrTextureProxy* proxy, sk_sp<GrColorSpaceXform> csxf,
-              GrSamplerState::Filter filter)
+              GrSamplerState::Filter filter, bool wideColor)
             : INHERITED(kLatticeGP_ClassID), fColorSpaceXform(std::move(csxf)) {
 
         GrSamplerState samplerState = GrSamplerState(GrSamplerState::WrapMode::kClamp,
@@ -104,7 +106,7 @@
         fInPosition = {"position", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
         fInTextureCoords = {"textureCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
         fInTextureDomain = {"textureDomain", kFloat4_GrVertexAttribType, kFloat4_GrSLType};
-        fInColor = {"color", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
+        fInColor = MakeColorAttribute("color", wideColor);
         this->setVertexAttributes(&fInPosition, 4);
     }
 
@@ -163,6 +165,7 @@
 
         // setup bounds
         this->setTransformedBounds(patch.fDst, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
+        fWideColor = !SkPMColor4fFitsInBytes(color);
     }
 
     const char* name() const override { return "NonAALatticeOp"; }
@@ -204,7 +207,7 @@
 private:
     void onPrepareDraws(Target* target) override {
         GrGpu* gpu = target->resourceProvider()->priv().gpu();
-        auto gp = LatticeGP::Make(gpu, fProxy.get(), fColorSpaceXform, fFilter);
+        auto gp = LatticeGP::Make(gpu, fProxy.get(), fColorSpaceXform, fFilter, fWideColor);
         if (!gp) {
             SkDebugf("Couldn't create GrGeometryProcessor\n");
             return;
@@ -233,8 +236,7 @@
         for (int i = 0; i < patchCnt; i++) {
             const Patch& patch = fPatches[i];
 
-            // TODO4F: Preserve float colors
-            GrColor patchColor = patch.fColor.toBytes_RGBA();
+            GrVertexColor patchColor(patch.fColor, fWideColor);
 
             // Apply the view matrix here if it is scale-translate.  Otherwise, we need to
             // wait until we've created the dst rects.
@@ -299,6 +301,7 @@
         }
 
         fPatches.move_back_n(that->fPatches.count(), that->fPatches.begin());
+        fWideColor |= that->fWideColor;
         return CombineResult::kMerged;
     }
 
@@ -314,6 +317,7 @@
     sk_sp<GrTextureProxy> fProxy;
     sk_sp<GrColorSpaceXform> fColorSpaceXform;
     GrSamplerState::Filter fFilter;
+    bool fWideColor;
 
     typedef GrMeshDrawOp INHERITED;
 };