diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp index 94f90b3107..d9a11c4923 100644 --- a/src/gpu/ops/GrFillRectOp.cpp +++ b/src/gpu/ops/GrFillRectOp.cpp @@ -79,7 +79,7 @@ public: const GrPerspQuad& localQuad, GrQuadType localQuadType) : INHERITED(ClassID()) , fHelper(args, aaType, stencil) - , fColorType(GrQuadPerEdgeAA::MinColorType(paintColor)) { + , fWideColor(!SkPMColor4fFitsInBytes(paintColor)) { // The color stored with the quad is the clear color if a scissor-clear is decided upon // when executing the op. fDeviceQuads.push_back(deviceQuad, deviceQuadType, { paintColor, edgeFlags }); @@ -178,9 +178,10 @@ private: using Domain = GrQuadPerEdgeAA::Domain; static constexpr SkRect kEmptyDomain = SkRect::MakeEmpty(); - VertexSpec vertexSpec(fDeviceQuads.quadType(), fColorType, fLocalQuads.quadType(), - fHelper.usesLocalCoords(), Domain::kNo, fHelper.aaType(), - fHelper.compatibleWithAlphaAsCoverage()); + VertexSpec vertexSpec(fDeviceQuads.quadType(), + fWideColor ? ColorType::kHalf : ColorType::kByte, + fLocalQuads.quadType(), fHelper.usesLocalCoords(), Domain::kNo, + fHelper.aaType(), fHelper.compatibleWithAlphaAsCoverage()); // Make sure that if the op thought it was a solid color, the vertex spec does not use // local coords. SkASSERT(!fHelper.isTrivial() || !fHelper.usesLocalCoords()); @@ -257,7 +258,7 @@ private: // If the processor sets are compatible, the two ops are always compatible; it just needs to // adjust the state of the op to be the more general quad and aa types of the two ops and // then concatenate the per-quad data. - fColorType = SkTMax(fColorType, that->fColorType); + fWideColor |= that->fWideColor; // The helper stores the aa type, but isCompatible(with true arg) allows the two ops' aa // types to be none and coverage, in which case this op's aa type must be lifted to coverage @@ -296,8 +297,8 @@ private: } // clear compatible won't need to be updated, since device quad type and paint is the same, - // but this quad has a new color, so maybe update color type - fColorType = SkTMax(fColorType, GrQuadPerEdgeAA::MinColorType(color)); + // but this quad has a new color, so maybe update wide color + fWideColor |= !SkPMColor4fFitsInBytes(color); // Update the bounds and add the quad to this op's storage SkRect newBounds = this->bounds(); @@ -327,7 +328,7 @@ private: // No metadata attached to the local quads; this list is empty when local coords are not needed. GrQuadList fLocalQuads; - ColorType fColorType; + unsigned fWideColor: 1; typedef GrMeshDrawOp INHERITED; }; diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp index cdc49b32ff..4845b55f07 100644 --- a/src/gpu/ops/GrQuadPerEdgeAA.cpp +++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp @@ -624,7 +624,9 @@ static CoverageMode get_mode_for_spec(const GrQuadPerEdgeAA::VertexSpec& spec) { // Writes four vertices in triangle strip order, including the additional data for local // coordinates, domain, color, and coverage as needed to satisfy the vertex spec. static void write_quad(GrVertexWriter* vb, const GrQuadPerEdgeAA::VertexSpec& spec, - CoverageMode mode, Sk4f coverage, SkPMColor4f color4f, const SkRect& domain, + CoverageMode mode, Sk4f coverage, + SkPMColor4f color4f, bool wideColor, + const SkRect& domain, const Vertices& quad) { static constexpr auto If = GrVertexWriter::If; @@ -637,9 +639,8 @@ static void write_quad(GrVertexWriter* vb, const GrQuadPerEdgeAA::VertexSpec& sp // save color if (spec.hasVertexColors()) { - bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kHalf; vb->write(GrVertexColor( - color4f * (mode == CoverageMode::kWithColor ? coverage[i] : 1.f), wide)); + color4f * (mode == CoverageMode::kWithColor ? coverage[i] : 1.f), wideColor)); } // save local position @@ -683,21 +684,12 @@ static sk_sp get_index_buffer(GrResourceProvider* resourcePro namespace GrQuadPerEdgeAA { -ColorType MinColorType(SkPMColor4f color) { - if (color == SK_PMColor4fWHITE) { - return ColorType::kNone; - } else if (color.fitsInBytes()) { - return ColorType::kByte; - } else { - return ColorType::kHalf; - } -} - ////////////////// Tessellate Implementation void* Tessellate(void* vertices, const VertexSpec& spec, const GrPerspQuad& deviceQuad, const SkPMColor4f& color4f, const GrPerspQuad& localQuad, const SkRect& domain, GrQuadAAFlags aaFlags) { + bool wideColor = GrQuadPerEdgeAA::ColorType::kHalf == spec.colorType(); CoverageMode mode = get_mode_for_spec(spec); // Load position data into Sk4fs (always x, y, and load w to avoid branching down the road) @@ -740,12 +732,12 @@ void* Tessellate(void* vertices, const VertexSpec& spec, const GrPerspQuad& devi // applied a mirror, etc. The current 2D case is already adequately fast. // Write two quads for inner and outer, inner will use the - write_quad(&vb, spec, mode, maxCoverage, color4f, domain, inner); - write_quad(&vb, spec, mode, 0.f, color4f, domain, outer); + write_quad(&vb, spec, mode, maxCoverage, color4f, wideColor, domain, inner); + write_quad(&vb, spec, mode, 0.f, color4f, wideColor, domain, outer); } else { // No outsetting needed, just write a single quad with full coverage SkASSERT(mode == CoverageMode::kNone); - write_quad(&vb, spec, mode, 1.f, color4f, domain, outer); + write_quad(&vb, spec, mode, 1.f, color4f, wideColor, domain, outer); } return vb.fPtr; diff --git a/src/gpu/ops/GrQuadPerEdgeAA.h b/src/gpu/ops/GrQuadPerEdgeAA.h index a491f2603b..232a10d2f0 100644 --- a/src/gpu/ops/GrQuadPerEdgeAA.h +++ b/src/gpu/ops/GrQuadPerEdgeAA.h @@ -26,9 +26,6 @@ namespace GrQuadPerEdgeAA { enum class ColorType { kNone, kByte, kHalf, kLast = kHalf }; static const int kColorTypeCount = static_cast(ColorType::kLast) + 1; - // Gets the minimum ColorType that can represent a color. - 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. // This order matches the constructor argument order of VertexSpec and is the order that diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp index 5b4232ca39..9db287a61b 100644 --- a/src/gpu/ops/GrTextureOp.cpp +++ b/src/gpu/ops/GrTextureOp.cpp @@ -291,7 +291,7 @@ private: auto bounds = dstQuad.bounds(dstQuadType); this->setBounds(bounds, HasAABloat(aaType == GrAAType::kCoverage), IsZeroArea::kNo); fDomain = static_cast(domain); - fColorType = static_cast(GrQuadPerEdgeAA::MinColorType(color)); + fWideColor = !SkPMColor4fFitsInBytes(color); fCanSkipAllocatorGather = static_cast(fProxies[0].fProxy->canSkipResourceAllocator()); } @@ -311,7 +311,7 @@ private: // identical, unless an entry provides a dstClip or additional transform that changes it. // The quad list will automatically adapt to that. fQuads.reserve(cnt, GrQuadTypeForTransformedRect(viewMatrix)); - bool allOpaque = true; + for (unsigned p = 0; p < fProxyCnt; ++p) { fProxies[p].fProxy = SkRef(set[p].fProxy.get()); fProxies[p].fQuadCnt = 1; @@ -351,7 +351,6 @@ private: set[p].fDstRect); } float alpha = SkTPin(set[p].fAlpha, 0.f, 1.f); - allOpaque &= (1.f == alpha); SkPMColor4f color{alpha, alpha, alpha, alpha}; int srcQuadIndex = -1; if (set[p].fDstClipQuad) { @@ -372,7 +371,7 @@ private: } this->setBounds(bounds, HasAABloat(this->aaType() == GrAAType::kCoverage), IsZeroArea::kNo); fDomain = static_cast(false); - fColorType = static_cast(allOpaque ? ColorType::kNone : ColorType::kByte); + fWideColor = static_cast(false); } void tess(void* v, const VertexSpec& spec, const GrTextureProxy* proxy, int start, @@ -409,7 +408,7 @@ private: GrQuadType quadType = GrQuadType::kRect; GrQuadType srcQuadType = GrQuadType::kRect; Domain domain = Domain::kNo; - ColorType colorType = ColorType::kNone; + bool wideColor = false; int numProxies = 0; int numTotalQuads = 0; auto textureType = fProxies[0].fProxy->textureType(); @@ -427,7 +426,7 @@ private: if (op.fDomain) { domain = Domain::kYes; } - colorType = SkTMax(colorType, static_cast(op.fColorType)); + wideColor |= op.fWideColor; numProxies += op.fProxyCnt; for (unsigned p = 0; p < op.fProxyCnt; ++p) { numTotalQuads += op.fProxies[p].fQuadCnt; @@ -444,7 +443,8 @@ private: } } - VertexSpec vertexSpec(quadType, colorType, srcQuadType, /* hasLocal */ true, domain, aaType, + VertexSpec vertexSpec(quadType, wideColor ? ColorType::kHalf : ColorType::kByte, + srcQuadType, /* hasLocal */ true, domain, aaType, /* alpha as coverage */ true); GrSamplerState samplerState = GrSamplerState(GrSamplerState::WrapMode::kClamp, @@ -562,7 +562,7 @@ private: } fDomain |= that->fDomain; - fColorType = SkTMax(fColorType, that->fColorType); + fWideColor |= that->fWideColor; if (upgradeToCoverageAAOnMerge) { fAAType = static_cast(GrAAType::kCoverage); } @@ -644,12 +644,11 @@ private: unsigned fFilter : 2; unsigned fAAType : 2; unsigned fDomain : 1; - unsigned fColorType : 2; - GR_STATIC_ASSERT(GrQuadPerEdgeAA::kColorTypeCount <= 4); + unsigned fWideColor : 1; // Used to track whether fProxy is ref'ed or has a pending IO after finalize() is called. unsigned fFinalized : 1; unsigned fCanSkipAllocatorGather : 1; - unsigned fProxyCnt : 32 - 9; + unsigned fProxyCnt : 32 - 8; Proxy fProxies[1]; static_assert(kGrQuadTypeCount <= 4, "GrQuadType does not fit in 2 bits");