Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
skgpu::graphite::TessellateStrokesRenderStep Class Referencefinal

#include <TessellateStrokesRenderStep.h>

Inheritance diagram for skgpu::graphite::TessellateStrokesRenderStep:
skgpu::graphite::RenderStep

Public Member Functions

 TessellateStrokesRenderStep (bool infinitySupport)
 
 ~TessellateStrokesRenderStep () override
 
std::string vertexSkSL () const override
 
void writeVertices (DrawWriter *, const DrawParams &, skvx::ushort2 ssboIndices) const override
 
void writeUniformsAndTextures (const DrawParams &, PipelineDataGatherer *) const override
 
- Public Member Functions inherited from skgpu::graphite::RenderStep
virtual ~RenderStep ()=default
 
virtual void writeVertices (DrawWriter *, const DrawParams &, skvx::ushort2 ssboIndices) const =0
 
virtual void writeUniformsAndTextures (const DrawParams &, PipelineDataGatherer *) const =0
 
virtual std::string vertexSkSL () const =0
 
virtual std::string texturesAndSamplersSkSL (const ResourceBindingRequirements &, int *nextBindingIndex) const
 
virtual const char * fragmentCoverageSkSL () const
 
virtual const char * fragmentColorSkSL () const
 
uint32_t uniqueID () const
 
const char * name () const
 
bool requiresMSAA () const
 
bool performsShading () const
 
bool hasTextures () const
 
bool emitsPrimitiveColor () const
 
bool outsetBoundsForAA () const
 
Coverage coverage () const
 
PrimitiveType primitiveType () const
 
size_t vertexStride () const
 
size_t instanceStride () const
 
size_t numUniforms () const
 
size_t numVertexAttributes () const
 
size_t numInstanceAttributes () const
 
SkSpan< const Uniformuniforms () const
 
SkSpan< const AttributevertexAttributes () const
 
SkSpan< const AttributeinstanceAttributes () const
 
SkSpan< const Varyingvaryings () const
 
const DepthStencilSettingsdepthStencilSettings () const
 
SkEnumBitMask< DepthStencilFlagsdepthStencilFlags () const
 

Additional Inherited Members

- Static Public Member Functions inherited from skgpu::graphite::RenderStep
static const char * ssboIndicesAttribute ()
 
static const char * ssboIndicesVarying ()
 
- Protected Types inherited from skgpu::graphite::RenderStep
enum class  Flags : unsigned {
  kNone = 0b0000000 , kRequiresMSAA = 0b0000001 , kPerformsShading = 0b0000010 , kHasTextures = 0b0000100 ,
  kEmitsCoverage = 0b0001000 , kLCDCoverage = 0b0010000 , kEmitsPrimitiveColor = 0b0100000 , kOutsetBoundsForAA = 0b1000000
}
 
- Protected Member Functions inherited from skgpu::graphite::RenderStep
 RenderStep (std::string_view className, std::string_view variantName, SkEnumBitMask< Flags > flags, std::initializer_list< Uniform > uniforms, PrimitiveType primitiveType, DepthStencilSettings depthStencilSettings, SkSpan< const Attribute > vertexAttrs, SkSpan< const Attribute > instanceAttrs, SkSpan< const Varying > varyings={})
 

Detailed Description

Definition at line 15 of file TessellateStrokesRenderStep.h.

Constructor & Destructor Documentation

◆ TessellateStrokesRenderStep()

skgpu::graphite::TessellateStrokesRenderStep::TessellateStrokesRenderStep ( bool  infinitySupport)
explicit

Definition at line 78 of file TessellateStrokesRenderStep.cpp.

79 : RenderStep("TessellateStrokeRenderStep",
80 "",
82 /*uniforms=*/{{"affineMatrix", SkSLType::kFloat4},
83 {"translate", SkSLType::kFloat2},
84 {"maxScale", SkSLType::kFloat}},
87 /*vertexAttrs=*/ {},
88 /*instanceAttrs=*/kAttributes[infinitySupport])
89 , fInfinitySupport(infinitySupport) {}
RenderStep(std::string_view className, std::string_view variantName, SkEnumBitMask< Flags > flags, std::initializer_list< Uniform > uniforms, PrimitiveType primitiveType, DepthStencilSettings depthStencilSettings, SkSpan< const Attribute > vertexAttrs, SkSpan< const Attribute > instanceAttrs, SkSpan< const Varying > varyings={})
Definition: Renderer.cpp:19
static const std::map< std::string, VerticesBuilder::AttributeType > kAttributes
static constexpr DepthStencilSettings kDirectDepthGreaterPass

◆ ~TessellateStrokesRenderStep()

skgpu::graphite::TessellateStrokesRenderStep::~TessellateStrokesRenderStep ( )
override

Definition at line 91 of file TessellateStrokesRenderStep.cpp.

91{}

Member Function Documentation

◆ vertexSkSL()

std::string skgpu::graphite::TessellateStrokesRenderStep::vertexSkSL ( ) const
overridevirtual

Implements skgpu::graphite::RenderStep.

Definition at line 93 of file TessellateStrokesRenderStep.cpp.

93 {
94 // TODO: Assumes vertex ID support for now, max edges must equal
95 // skgpu::tess::FixedCountStrokes::kMaxEdges -> (2^14 - 1) -> 16383
97 R"(
98 float edgeID = float(sk_VertexID >> 1);
99 if ((sk_VertexID & 1) != 0) {
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: SkSLString.cpp:83

◆ writeUniformsAndTextures()

void skgpu::graphite::TessellateStrokesRenderStep::writeUniformsAndTextures ( const DrawParams params,
PipelineDataGatherer gatherer 
) const
overridevirtual

Implements skgpu::graphite::RenderStep.

Definition at line 230 of file TessellateStrokesRenderStep.cpp.

230 {
231 writer.writeCubic(chops);
232 writer.writeCubic(chops + 3);
233 writer.writeCubic(chops + 6);
234 }
235 }
236 break;
237 }
238 }
239}
240
242 PipelineDataGatherer* gatherer) const {
243 // TODO: Implement perspective
244 SkASSERT(params.transform().type() < Transform::Type::kPerspective);
245
246 SkDEBUGCODE(UniformExpectationsValidator uev(gatherer, this->uniforms());)
247
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
SkSpan< const Uniform > uniforms() const
Definition: Renderer.h:143
void writeUniformsAndTextures(const DrawParams &, PipelineDataGatherer *) const override
const EmbeddedViewParams * params

◆ writeVertices()

void skgpu::graphite::TessellateStrokesRenderStep::writeVertices ( DrawWriter dw,
const DrawParams params,
skvx::ushort2  ssboIndices 
) const
overridevirtual

Implements skgpu::graphite::RenderStep.

Definition at line 101 of file TessellateStrokesRenderStep.cpp.

109 : "curveType");
110}
111
113 const DrawParams& params,
114 skvx::ushort2 ssboIndices) const {
115 SkPath path = params.geometry().shape().asPath(); // TODO: Iterate the Shape directly
116
117 int patchReserveCount = FixedCountStrokes::PreallocCount(path.countVerbs());
118 // Stroke tessellation does not use fixed indices or vertex data, and only needs the vertex ID
119 static const BindBufferInfo kNullBinding = {};
120 // TODO: All HW that Graphite will run on should support instancing ith sk_VertexID, but when
121 // we support Vulkan+Swiftshader, we will need the vertex buffer ID fallback unless Swiftshader
122 // has figured out how to support vertex IDs before then.
123 Writer writer{fInfinitySupport ? kAttribs : kAttribsWithCurveType,
124 *dw,
125 kNullBinding,
126 kNullBinding,
127 patchReserveCount};
128 writer.updatePaintDepthAttrib(params.order().depthAsFloat());
129 writer.updateSsboIndexAttrib(ssboIndices);
130
131 // The vector xform approximates how the control points are transformed by the shader to
132 // more accurately compute how many *parametric* segments are needed.
133 // getMaxScale() returns -1 if it can't compute a scale factor (e.g. perspective), taking the
134 // absolute value automatically converts that to an identity scale factor for our purposes.
135 writer.setShaderTransform(wangs_formula::VectorXform{params.transform().matrix()},
136 params.transform().maxScaleFactor());
137
138 SkASSERT(params.isStroke());
139 writer.updateStrokeParamsAttrib({params.strokeStyle().halfWidth(),
140 params.strokeStyle().joinLimit()});
141
142 // TODO: If PatchWriter can handle adding caps to its deferred patches, and we can convert
143 // hairlines to use round caps instead of square, then StrokeIterator can be deleted entirely.
144 // Besides being simpler, PatchWriter already has what it needs from the shader matrix and
145 // stroke params, so we don't have to re-extract them here.
146 SkMatrix shaderMatrix = params.transform();
148 stroke.setStrokeStyle(params.strokeStyle().width());
149 stroke.setStrokeParams(params.strokeStyle().cap(),
150 params.strokeStyle().join(),
151 params.strokeStyle().miterLimit());
152 StrokeIterator strokeIter(path, &stroke, &shaderMatrix);
153 while (strokeIter.next()) {
154 using Verb = StrokeIterator::Verb;
155 const SkPoint* p = strokeIter.pts();
156 int numChops;
157
158 // TODO: The cusp detection logic should be moved into PatchWriter and shared between
159 // this and StrokeTessellator.cpp, but that will require updating a lot of SkGeometry to
160 // operate on float2 (skvx) instead of the legacy SkNx or SkPoint.
161 switch (strokeIter.verb()) {
162 case Verb::kContourFinished:
163 writer.writeDeferredStrokePatch();
164 break;
165 case Verb::kCircle:
166 // Round cap or else an empty stroke that is specified to be drawn as a circle.
167 writer.writeCircle(p[0]);
168 [[fallthrough]];
169 case Verb::kMoveWithinContour:
170 // A regular kMove invalidates the previous control point; the stroke iterator
171 // tells us a new value to use.
172 writer.updateJoinControlPointAttrib(p[0]);
173 break;
174 case Verb::kLine:
175 writer.writeLine(p[0], p[1]);
176 break;
177 case Verb::kQuad:
178 if (ConicHasCusp(p)) {
179 // The cusp is always at the midtandent.
181 writer.writeCircle(cusp);
182 // A quad can only have a cusp if it's flat with a 180-degree turnaround.
183 writer.writeLine(p[0], cusp);
184 writer.writeLine(cusp, p[2]);
185 } else {
186 writer.writeQuadratic(p);
187 }
188 break;
189 case Verb::kConic:
190 if (ConicHasCusp(p)) {
191 // The cusp is always at the midtandent.
192 SkConic conic(p, strokeIter.w());
193 SkPoint cusp = conic.evalAt(conic.findMidTangent());
194 writer.writeCircle(cusp);
195 // A conic can only have a cusp if it's flat with a 180-degree turnaround.
196 writer.writeLine(p[0], cusp);
197 writer.writeLine(cusp, p[2]);
198 } else {
199 writer.writeConic(p, strokeIter.w());
200 }
201 break;
202 case Verb::kCubic:
203 SkPoint chops[10];
204 float T[2];
205 bool areCusps;
206 numChops = FindCubicConvex180Chops(p, T, &areCusps);
207 if (numChops == 0) {
208 writer.writeCubic(p);
209 } else if (numChops == 1) {
210 SkChopCubicAt(p, chops, T[0]);
211 if (areCusps) {
212 writer.writeCircle(chops[3]);
213 // In a perfect world, these 3 points would be be equal after chopping
214 // on a cusp.
215 chops[2] = chops[4] = chops[3];
216 }
217 writer.writeCubic(chops);
218 writer.writeCubic(chops + 3);
219 } else {
220 SkASSERT(numChops == 2);
221 SkChopCubicAt(p, chops, T[0], T[1]);
222 if (areCusps) {
223 writer.writeCircle(chops[3]);
224 writer.writeCircle(chops[6]);
225 // Two cusps are only possible if it's a flat line with two 180-degree
226 // turnarounds.
227 writer.writeLine(chops[0], chops[3]);
228 writer.writeLine(chops[3], chops[6]);
float SkFindQuadMidTangent(const SkPoint src[3])
Definition: SkGeometry.cpp:231
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t)
Definition: SkGeometry.cpp:473
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint *pt, SkVector *tangent)
Definition: SkGeometry.cpp:132
Definition: SkPath.h:59
@ kHairline_InitStyle
Definition: SkStrokeRec.h:25
void writeVertices(DrawWriter *, const DrawParams &, skvx::ushort2 ssboIndices) const override
static constexpr int PreallocCount(int totalCombinedPathVerbCnt)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
const SkPoint kQuad[4]
bool ConicHasCusp(const SkPoint p[3])
Definition: Tessellation.h:131
int FindCubicConvex180Chops(const SkPoint pts[], float T[2], bool *areCusps)
AI float conic(float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:287
#define T
Definition: precompiler.cc:65
Definition: SkVx.h:83

The documentation for this class was generated from the following files: