diff --git a/src/gpu/ganesh/ops/PathTessellator.cpp b/src/gpu/ganesh/ops/PathTessellator.cpp index 4871cc1abd..22985ee3a0 100644 --- a/src/gpu/ganesh/ops/PathTessellator.cpp +++ b/src/gpu/ganesh/ops/PathTessellator.cpp @@ -163,8 +163,7 @@ void PathCurveTessellator::prepareWithTriangles( int patchPreallocCount = FixedCountCurves::PreallocCount(totalCombinedPathVerbCnt) + (extraTriangles ? extraTriangles->count() : 0); if (patchPreallocCount) { - CurveWriter writer{fAttribs, skgpu::kMaxParametricSegments, - target, &fVertexChunkArray, patchPreallocCount}; + CurveWriter writer{fAttribs, target, &fVertexChunkArray, patchPreallocCount}; // Write out extra space-filling triangles to connect the curve patches with any external // source of geometry (e.g. inner triangulation that handles winding explicitly). @@ -237,8 +236,7 @@ void PathWedgeTessellator::prepare(GrMeshDrawTarget* target, const PathDrawList& pathDrawList, int totalCombinedPathVerbCnt) { if (int patchPreallocCount = FixedCountWedges::PreallocCount(totalCombinedPathVerbCnt)) { - WedgeWriter writer{fAttribs, skgpu::kMaxParametricSegments, - target, &fVertexChunkArray, patchPreallocCount}; + WedgeWriter writer{fAttribs, target, &fVertexChunkArray, patchPreallocCount}; int resolveLevel = write_wedge_patches(std::move(writer), shaderMatrix, pathDrawList); this->updateResolveLevel(resolveLevel); } diff --git a/src/gpu/ganesh/ops/StrokeTessellateOp.cpp b/src/gpu/ganesh/ops/StrokeTessellateOp.cpp index b9d8ab3a3e..5e55385b82 100644 --- a/src/gpu/ganesh/ops/StrokeTessellateOp.cpp +++ b/src/gpu/ganesh/ops/StrokeTessellateOp.cpp @@ -172,8 +172,7 @@ void StrokeTessellateOp::prePrepareTessellator(GrTessellationShader::ProgramArgs fPatchAttribs, fViewMatrix, this->headStroke(), - this->headColor(), - StrokeTessellator::kMaxParametricSegments_log2); + this->headColor()); auto fillStencil = &GrUserStencilSettings::kUnused; if (fNeedsStencil) { diff --git a/src/gpu/ganesh/ops/StrokeTessellator.cpp b/src/gpu/ganesh/ops/StrokeTessellator.cpp index ce346b43a4..b0a3cfa422 100644 --- a/src/gpu/ganesh/ops/StrokeTessellator.cpp +++ b/src/gpu/ganesh/ops/StrokeTessellator.cpp @@ -236,8 +236,7 @@ void StrokeTessellator::prepare(GrMeshDrawTarget* target, PathStrokeList* pathStrokeList, int totalCombinedStrokeVerbCnt) { int preallocCount = FixedCountStrokes::PreallocCount(totalCombinedStrokeVerbCnt); - FixedCountStrokeWriter patchWriter{fAttribs, kMaxParametricSegments, - target, &fVertexChunkArray, preallocCount}; + FixedCountStrokeWriter patchWriter{fAttribs, target, &fVertexChunkArray, preallocCount}; fFixedEdgeCount = write_fixed_count_patches(std::move(patchWriter), shaderMatrix, diff --git a/src/gpu/ganesh/ops/StrokeTessellator.h b/src/gpu/ganesh/ops/StrokeTessellator.h index 20b3f9223c..9d6edd7fda 100644 --- a/src/gpu/ganesh/ops/StrokeTessellator.h +++ b/src/gpu/ganesh/ops/StrokeTessellator.h @@ -27,8 +27,6 @@ namespace skgpu::v1 { // as degenerate triangles. class StrokeTessellator { public: - constexpr static int8_t kMaxParametricSegments_log2 = - SkNextLog2_portable(kMaxParametricSegments); struct PathStrokeList { PathStrokeList(const SkPath& path, const SkStrokeRec& stroke, const SkPMColor4f& color) diff --git a/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.cpp b/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.cpp index a424fc39b3..e3a4ffa0f1 100644 --- a/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.cpp +++ b/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.cpp @@ -86,13 +86,11 @@ GrStrokeTessellationShader::GrStrokeTessellationShader(const GrShaderCaps& shade PatchAttribs attribs, const SkMatrix& viewMatrix, const SkStrokeRec& stroke, - SkPMColor4f color, - int8_t maxParametricSegments_log2) + SkPMColor4f color) : GrTessellationShader(kTessellate_GrStrokeTessellationShader_ClassID, GrPrimitiveType::kTriangleStrip, viewMatrix, color) , fPatchAttribs(attribs | PatchAttribs::kJoinControlPoint) - , fStroke(stroke) - , fMaxParametricSegments_log2(maxParametricSegments_log2) { + , fStroke(stroke) { // We should use explicit curve type when, and only when, there isn't infinity support. // Otherwise the GPU can infer curve type based on infinity. SkASSERT(shaderCaps.infinitySupport() != (attribs & PatchAttribs::kExplicitCurveType)); @@ -606,7 +604,7 @@ void GrStrokeTessellationShader::Impl::emitTessellationCode( // ensures crack-free seaming between instances. tangent = (combinedEdgeID == 0) ? tan0 : tan1; strokeCoord = (combinedEdgeID == 0) ? p0 : p3; - })", shader.maxParametricSegments_log2() /* Parametric/radial sort loop count. */); + })", skgpu::kMaxFixedResolveLevel /* Parametric/radial sort loop count. */); code->append(R"( // At this point 'tangent' is normalized, so the orthogonal vector is also normalized. @@ -690,7 +688,6 @@ void GrStrokeTessellationShader::addToKey(const GrShaderCaps&, skgpu::KeyBuilder uint32_t key = (uint32_t)(fPatchAttribs & ~PatchAttribs::kColor); key = (key << 2) | ((keyNeedsJoin) ? fStroke.getJoin() : 0); key = (key << 1) | (uint32_t)fStroke.isHairlineStyle(); - key = (key << 8) | fMaxParametricSegments_log2; b->add32(key); } diff --git a/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.h b/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.h index 576707b7dc..a171f6192b 100644 --- a/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.h +++ b/src/gpu/ganesh/tessellate/shaders/GrStrokeTessellationShader.h @@ -29,14 +29,13 @@ public: // 'viewMatrix' is applied to the geometry post tessellation. It cannot have perspective. GrStrokeTessellationShader(const GrShaderCaps&, PatchAttribs, const SkMatrix& viewMatrix, - const SkStrokeRec&, SkPMColor4f, int8_t maxParametricSegments_log2); + const SkStrokeRec&, SkPMColor4f); PatchAttribs attribs() const { return fPatchAttribs; } bool hasDynamicStroke() const { return fPatchAttribs & PatchAttribs::kStrokeParams; } bool hasDynamicColor() const { return fPatchAttribs & PatchAttribs::kColor; } bool hasExplicitCurveType() const { return fPatchAttribs & PatchAttribs::kExplicitCurveType; } const SkStrokeRec& stroke() const { return fStroke;} - int8_t maxParametricSegments_log2() const { return fMaxParametricSegments_log2; } private: const char* name() const override { return "GrStrokeTessellationShader"; } @@ -45,7 +44,6 @@ private: const PatchAttribs fPatchAttribs; const SkStrokeRec fStroke; - const int8_t fMaxParametricSegments_log2; constexpr static int kMaxAttribCount = 6; SkSTArray fAttribs; diff --git a/src/gpu/graphite/render/TessellateCurvesRenderStep.cpp b/src/gpu/graphite/render/TessellateCurvesRenderStep.cpp index 513f1bd37e..bdf505e955 100644 --- a/src/gpu/graphite/render/TessellateCurvesRenderStep.cpp +++ b/src/gpu/graphite/render/TessellateCurvesRenderStep.cpp @@ -95,8 +95,7 @@ void TessellateCurvesRenderStep::writeVertices(DrawWriter* dw, const DrawGeometr FixedCountCurves::IndexBufferSize); int patchReserveCount = FixedCountCurves::PreallocCount(path.countVerbs()); - Writer writer{kAttribs, kMaxParametricSegments, - *dw, fixedVertexBuffer, fixedIndexBuffer, patchReserveCount}; + Writer writer{kAttribs, *dw, fixedVertexBuffer, fixedIndexBuffer, patchReserveCount}; writer.updatePaintDepthAttrib(geom.order().depthAsFloat()); diff --git a/src/gpu/graphite/render/TessellateWedgesRenderStep.cpp b/src/gpu/graphite/render/TessellateWedgesRenderStep.cpp index b3aa9d245f..e40cc4d057 100644 --- a/src/gpu/graphite/render/TessellateWedgesRenderStep.cpp +++ b/src/gpu/graphite/render/TessellateWedgesRenderStep.cpp @@ -99,8 +99,7 @@ void TessellateWedgesRenderStep::writeVertices(DrawWriter* dw, const DrawGeometr FixedCountWedges::IndexBufferSize); int patchReserveCount = FixedCountWedges::PreallocCount(path.countVerbs()); - Writer writer{kAttribs, kMaxParametricSegments, - *dw, fixedVertexBuffer, fixedIndexBuffer, patchReserveCount}; + Writer writer{kAttribs, *dw, fixedVertexBuffer, fixedIndexBuffer, patchReserveCount}; writer.updatePaintDepthAttrib(geom.order().depthAsFloat()); // TODO: Is it better to pre-transform on the CPU and only have a matrix uniform to compute diff --git a/src/gpu/tessellate/PatchWriter.h b/src/gpu/tessellate/PatchWriter.h index a2d1073358..2c41b9d966 100644 --- a/src/gpu/tessellate/PatchWriter.h +++ b/src/gpu/tessellate/PatchWriter.h @@ -238,11 +238,8 @@ class PatchWriter { public: template // forwarded to PatchAllocator PatchWriter(PatchAttribs attribs, - int maxTessellationSegments, Args&&... allocArgs) : fAttribs(attribs) - , fMaxSegments_pow2(pow2(maxTessellationSegments)) - , fMaxSegments_pow4(pow2(fMaxSegments_pow2)) , fCurrMinSegments_pow4(1.f) , fPatchAllocator(PatchStride(attribs), std::forward(allocArgs)...) , fJoin(attribs) @@ -350,9 +347,8 @@ public: // Write a cubic curve with its four control points. AI void writeCubic(float2 p0, float2 p1, float2 p2, float2 p3, - const VectorXform& shaderXform, - float precision = kTessellationPrecision) { - float n4 = wangs_formula::cubic_pow4(precision, p0, p1, p2, p3, shaderXform); + const VectorXform& shaderXform) { + float n4 = wangs_formula::cubic_pow4(kTessellationPrecision, p0, p1, p2, p3, shaderXform); if constexpr (kDiscardFlatCurves) { if (n4 <= 1.f) { // This cubic only needs one segment (e.g. a line) but we're not filling space with @@ -364,24 +360,23 @@ public: this->writeCubicPatch(p0, p1, p2, p3); } else { int numPatches = SkScalarCeilToInt(wangs_formula::root4( - std::min(n4, pow4(kMaxTessellationSegmentsPerCurve)) / fMaxSegments_pow4)); + std::min(n4, pow4(kMaxTessellationSegmentsPerCurve)) / + pow4(kMaxParametricSegments))); this->chopAndWriteCubics(p0, p1, p2, p3, numPatches); } } AI void writeCubic(const SkPoint pts[4], - const VectorXform& shaderXform, - float precision = kTessellationPrecision) { + const VectorXform& shaderXform) { float4 p0p1 = float4::Load(pts); float4 p2p3 = float4::Load(pts + 2); - this->writeCubic(p0p1.lo, p0p1.hi, p2p3.lo, p2p3.hi, shaderXform, precision); + this->writeCubic(p0p1.lo, p0p1.hi, p2p3.lo, p2p3.hi, shaderXform); } // Write a conic curve with three control points and 'w', with the last coord of the last // control point signaling a conic by being set to infinity. AI void writeConic(float2 p0, float2 p1, float2 p2, float w, - const VectorXform& shaderXform, - float precision = kTessellationPrecision) { - float n2 = wangs_formula::conic_pow2(precision, p0, p1, p2, w, shaderXform); + const VectorXform& shaderXform) { + float n2 = wangs_formula::conic_pow2(kTessellationPrecision, p0, p1, p2, w, shaderXform); if constexpr (kDiscardFlatCurves) { if (n2 <= 1.f) { // This conic only needs one segment (e.g. a line) but we're not filling space with @@ -393,25 +388,24 @@ public: this->writeConicPatch(p0, p1, p2, w); } else { int numPatches = SkScalarCeilToInt(sqrtf( - std::min(n2, pow2(kMaxTessellationSegmentsPerCurve)) / fMaxSegments_pow2)); + std::min(n2, pow2(kMaxTessellationSegmentsPerCurve)) / + pow2(kMaxParametricSegments))); this->chopAndWriteConics(p0, p1, p2, w, numPatches); } } AI void writeConic(const SkPoint pts[3], float w, - const VectorXform& shaderXform, - float precision = kTessellationPrecision) { + const VectorXform& shaderXform) { this->writeConic(skvx::bit_pun(pts[0]), skvx::bit_pun(pts[1]), skvx::bit_pun(pts[2]), - w, shaderXform, precision); + w, shaderXform); } // Write a quadratic curve that automatically converts its three control points into an // equivalent cubic. AI void writeQuadratic(float2 p0, float2 p1, float2 p2, - const VectorXform& shaderXform, - float precision = kTessellationPrecision) { - float n4 = wangs_formula::quadratic_pow4(precision, p0, p1, p2, shaderXform); + const VectorXform& shaderXform) { + float n4 = wangs_formula::quadratic_pow4(kTessellationPrecision, p0, p1, p2, shaderXform); if constexpr (kDiscardFlatCurves) { if (n4 <= 1.f) { // This quad only needs one segment (e.g. a line) but we're not filling space with @@ -423,17 +417,17 @@ public: this->writeQuadPatch(p0, p1, p2); } else { int numPatches = SkScalarCeilToInt(wangs_formula::root4( - std::min(n4, pow4(kMaxTessellationSegmentsPerCurve)) / fMaxSegments_pow4)); + std::min(n4, pow4(kMaxTessellationSegmentsPerCurve)) / + pow4(kMaxParametricSegments))); this->chopAndWriteQuads(p0, p1, p2, numPatches); } } AI void writeQuadratic(const SkPoint pts[3], - const VectorXform& shaderXform, - float precision = kTessellationPrecision) { + const VectorXform& shaderXform) { this->writeQuadratic(skvx::bit_pun(pts[0]), skvx::bit_pun(pts[1]), skvx::bit_pun(pts[2]), - shaderXform, precision); + shaderXform); } // Write a line that is automatically converted into an equivalent cubic. @@ -547,11 +541,11 @@ private: // Returns true if curve can be written w/o needing to chop (e.g. represented by one instance) bool curveFitsInMaxSegments(float n4) { - if (n4 <= fMaxSegments_pow4) { + if (n4 <= pow4(kMaxParametricSegments)) { fCurrMinSegments_pow4 = std::max(n4, fCurrMinSegments_pow4); return true; } else { - fCurrMinSegments_pow4 = fMaxSegments_pow4; + fCurrMinSegments_pow4 = pow4(kMaxParametricSegments); return false; } } @@ -695,8 +689,6 @@ private: // attribs enabled (e.g. depending on caps or batching). const PatchAttribs fAttribs; - const float fMaxSegments_pow2; - const float fMaxSegments_pow4; float fCurrMinSegments_pow4; PatchAllocator fPatchAllocator;