Switch to float vertex colors for wide color vertex attribs

Bug: chromium:985500

Change-Id: Iab73405728dc64c816f736e95b00a23e11fd4888
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/258565
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrColor.h b/src/gpu/GrColor.h
index 39e7bfa..26f0937 100644
--- a/src/gpu/GrColor.h
+++ b/src/gpu/GrColor.h
@@ -95,18 +95,18 @@
     explicit GrVertexColor(const SkPMColor4f& color, bool wideColor)
             : fWideColor(wideColor) {
         if (wideColor) {
-            SkFloatToHalf_finite_ftz(Sk4f::Load(color.vec())).store(&fColor);
+            memcpy(fColor, color.vec(), sizeof(fColor));
         } else {
             fColor[0] = color.toBytes_RGBA();
         }
     }
 
-    size_t size() const { return fWideColor ? 8 : 4; }
+    size_t size() const { return fWideColor ? 16 : 4; }
 
 private:
     friend struct GrVertexWriter;
 
-    uint32_t fColor[2];
+    uint32_t fColor[4];
     bool     fWideColor;
 };
 
diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h
index 966437a..687fc70 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -35,11 +35,11 @@
 protected:
     void setWillUseGeoShader() { fWillUseGeoShader = true; }
 
-    // GPs that need to use either half-float or ubyte colors can just call this to get a correctly
+    // GPs that need to use either float or ubyte colors can just call this to get a correctly
     // configured Attribute struct
     static Attribute MakeColorAttribute(const char* name, bool wideColor) {
         return { name,
-                 wideColor ? kHalf4_GrVertexAttribType : kUByte4_norm_GrVertexAttribType,
+                 wideColor ? kFloat4_GrVertexAttribType : kUByte4_norm_GrVertexAttribType,
                  kHalf4_GrSLType };
     }
 
diff --git a/src/gpu/GrVertexWriter.h b/src/gpu/GrVertexWriter.h
index 7b1ddc1..74706ff 100644
--- a/src/gpu/GrVertexWriter.h
+++ b/src/gpu/GrVertexWriter.h
@@ -71,6 +71,8 @@
         this->write(color.fColor[0]);
         if (color.fWideColor) {
             this->write(color.fColor[1]);
+            this->write(color.fColor[2]);
+            this->write(color.fColor[3]);
         }
         this->write(remainder...);
     }
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 79a6882..05044af 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -65,15 +65,6 @@
 /** Converts an SkColor4f to the destination color space. */
 SkColor4f SkColor4fPrepForDst(SkColor4f, const GrColorInfo&);
 
-/** Returns true if half-floats are required to store the color in a vertex (and half-floats
-    are supported). */
-static inline bool SkPMColor4fNeedsWideColor(SkPMColor4f color, GrClampType clampType,
-                                             const GrCaps& caps) {
-    return GrClampType::kNone == clampType &&
-        caps.halfFloatVertexAttributeSupport() &&
-        !color.fitsInBytes();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Paint conversion
 
diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp
index a8cf7fb..099f4cf 100644
--- a/src/gpu/ops/GrFillRRectOp.cpp
+++ b/src/gpu/ops/GrFillRRectOp.cpp
@@ -143,9 +143,7 @@
     SkPMColor4f finalColor = analysis.inputColorIsOverridden() ? overrideColor : fOriginalColor;
     if (!SkPMColor4fFitsInBytes(finalColor)) {
         fFlags |= Flags::kWideColor;
-        uint32_t halfColor[2];
-        SkFloatToHalf_finite_ftz(Sk4f::Load(finalColor.vec())).store(&halfColor);
-        this->writeInstanceData(halfColor[0], halfColor[1]);
+        this->writeInstanceData(finalColor);
     } else {
         this->writeInstanceData(finalColor.toBytes_RGBA());
     }
diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp
index afd8ba2..e2e490b 100644
--- a/src/gpu/ops/GrFillRectOp.cpp
+++ b/src/gpu/ops/GrFillRectOp.cpp
@@ -146,7 +146,7 @@
         iter = fQuads.metadata();
         SkPMColor4f colorOverride;
         if (quadColors.isConstant(&colorOverride)) {
-            fColorType = GrQuadPerEdgeAA::MinColorType(colorOverride, clampType, caps);
+            fColorType = GrQuadPerEdgeAA::MinColorType(colorOverride);
             while(iter.next()) {
                 iter->fColor = colorOverride;
             }
@@ -154,8 +154,7 @@
             // Otherwise compute the color type needed as the max over all quads.
             fColorType = ColorType::kNone;
             while(iter.next()) {
-                fColorType = SkTMax(fColorType,
-                                    GrQuadPerEdgeAA::MinColorType(iter->fColor, clampType, caps));
+                fColorType = SkTMax(fColorType, GrQuadPerEdgeAA::MinColorType(iter->fColor));
             }
         }
         // Most SkShaders' FPs multiply their calculated color by the paint color or alpha. We want
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 9995b77..3e4733f 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -203,7 +203,7 @@
                 caps, clip, hasMixedSampledCoverage, clampType, GrProcessorAnalysisCoverage::kNone,
                 &analysisColor);
         analysisColor.isConstant(&fPatches[0].fColor);
-        fWideColor = SkPMColor4fNeedsWideColor(fPatches[0].fColor, clampType, caps);
+        fWideColor = !fPatches[0].fColor.fitsInBytes();
         return result;
     }
 
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index da70bf6..e1a3616 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -40,7 +40,7 @@
 
         // save color
         if (spec.hasVertexColors()) {
-            bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kHalf;
+            bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kFloat;
             vb->write(GrVertexColor(
                 color * (mode == GrQuadPerEdgeAA::CoverageMode::kWithColor ? coverage[i] : 1.f),
                 wide));
@@ -85,7 +85,7 @@
     // accumulate local coords conservatively (paint not trivial), and then after analysis realize
     // the processors don't need local coordinates.
 
-    bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kHalf;
+    bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kFloat;
     for (int i = 0; i < 4; ++i) {
         // If this is not coverage-with-alpha, make sure coverage == 1 so it doesn't do anything
         SkASSERT(spec.coverageMode() == GrQuadPerEdgeAA::CoverageMode::kWithColor ||
@@ -130,7 +130,7 @@
     SkASSERT(!spec.hasDomain());
     SkASSERT(localQuad);
 
-    bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kHalf;
+    bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kFloat;
     for (int i = 0; i < 4; ++i) {
         // If this is not coverage-with-alpha, make sure coverage == 1 so it doesn't do anything
         SkASSERT(spec.coverageMode() == GrQuadPerEdgeAA::CoverageMode::kWithColor ||
@@ -203,7 +203,7 @@
     SkASSERT(spec.hasDomain());
     SkASSERT(localQuad);
 
-    bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kHalf;
+    bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kFloat;
     for (int i = 0; i < 4; ++i) {
         // If this is not coverage-with-alpha, make sure coverage == 1 so it doesn't do anything
         SkASSERT(spec.coverageMode() == GrQuadPerEdgeAA::CoverageMode::kWithColor ||
@@ -248,13 +248,12 @@
     }
 }
 
-// This is a more elaborate version of SkPMColor4fNeedsWideColor that allows "no color" for white
-ColorType MinColorType(SkPMColor4f color, GrClampType clampType, const GrCaps& caps) {
+// This is a more elaborate version of fitsInBytes() that allows "no color" for white
+ColorType MinColorType(SkPMColor4f color) {
     if (color == SK_PMColor4fWHITE) {
         return ColorType::kNone;
     } else {
-        return SkPMColor4fNeedsWideColor(color, clampType, caps) ? ColorType::kHalf
-                                                                 : ColorType::kByte;
+        return color.fitsInBytes() ? ColorType::kByte : ColorType::kFloat;
     }
 }
 
@@ -509,8 +508,8 @@
 
     if (ColorType::kByte == this->colorType()) {
         count += GrVertexAttribTypeSize(kUByte4_norm_GrVertexAttribType);
-    } else if (ColorType::kHalf == this->colorType()) {
-        count += GrVertexAttribTypeSize(kHalf4_GrVertexAttribType);
+    } else if (ColorType::kFloat == this->colorType()) {
+        count += GrVertexAttribTypeSize(kFloat4_GrVertexAttribType);
     }
 
     if (this->hasDomain()) {
@@ -788,10 +787,8 @@
             fLocalCoord = {"localCoord", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
         } // else localDim == 0 and attribute remains uninitialized
 
-        if (ColorType::kByte == spec.colorType()) {
-            fColor = {"color", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
-        } else if (ColorType::kHalf == spec.colorType()) {
-            fColor = {"color", kHalf4_GrVertexAttribType, kHalf4_GrSLType};
+        if (spec.hasVertexColors()) {
+            fColor = MakeColorAttribute("color", ColorType::kFloat == spec.colorType());
         }
 
         if (spec.hasDomain()) {
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.h b/src/gpu/ops/GrQuadPerEdgeAA.h
index 35a18fd..acd565d 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.h
+++ b/src/gpu/ops/GrQuadPerEdgeAA.h
@@ -30,7 +30,7 @@
 
     enum class CoverageMode { kNone, kWithPosition, kWithColor };
     enum class Domain : bool { kNo = false, kYes = true };
-    enum class ColorType { kNone, kByte, kHalf, kLast = kHalf };
+    enum class ColorType { kNone, kByte, kFloat, kLast = kFloat };
     static const int kColorTypeCount = static_cast<int>(ColorType::kLast) + 1;
 
     enum class IndexBufferOption {
@@ -44,7 +44,7 @@
     IndexBufferOption CalcIndexBufferOption(GrAAType aa, int numQuads);
 
     // Gets the minimum ColorType that can represent a color.
-    ColorType MinColorType(SkPMColor4f, GrClampType, const GrCaps&);
+    ColorType MinColorType(SkPMColor4f);
 
     // Specifies the vertex configuration for an op that renders per-edge AA quads. The vertex
     // order (when enabled) is device position, color, local position, domain, aa edge equations.
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
index 9b6e945..b0c491e 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
@@ -74,7 +74,7 @@
             caps, clip, hasMixedSampledCoverage, clampType, geometryCoverage, &color);
     color.isConstant(geometryColor);
     if (wideColor) {
-        *wideColor = SkPMColor4fNeedsWideColor(*geometryColor, clampType, caps);
+        *wideColor = !geometryColor->fitsInBytes();
     }
     return result;
 }
@@ -181,7 +181,7 @@
             caps, clip, hasMixedSampledCoverage, clampType, geometryCoverage, &color);
     color.isConstant(geometryColor);
     if (wideColor) {
-        *wideColor = SkPMColor4fNeedsWideColor(*geometryColor, clampType, caps);
+        *wideColor = !geometryColor->fitsInBytes();
     }
     return result;
 }
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index c0ce6f7..039fe22 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -287,7 +287,7 @@
         SkASSERT(fMetadata.colorType() == ColorType::kNone);
         auto iter = fQuads.metadata();
         while(iter.next()) {
-            auto colorType = GrQuadPerEdgeAA::MinColorType(iter->fColor, clampType, caps);
+            auto colorType = GrQuadPerEdgeAA::MinColorType(iter->fColor);
             fMetadata.fColorType = SkTMax(fMetadata.fColorType, static_cast<uint16_t>(colorType));
         }
         return GrProcessorSet::EmptySetAnalysis();