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();