Flutter Engine
The Flutter Engine
VerticesRenderStep.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
18
19namespace skgpu::graphite {
20
21namespace {
22
23static constexpr Attribute kPositionAttr =
25static constexpr Attribute kTexCoordAttr =
27static constexpr Attribute kColorAttr =
29static constexpr Attribute kSsboIndexAttr =
31
32static constexpr Attribute kAttributePositionOnly[] =
33 {kPositionAttr, kSsboIndexAttr};
34static constexpr Attribute kAttributeColor[] =
35 {kPositionAttr, kColorAttr, kSsboIndexAttr};
36static constexpr Attribute kAttributeTexCoords[] =
37 {kPositionAttr, kTexCoordAttr, kSsboIndexAttr};
38static constexpr Attribute kAttributeColorAndTexCoords[] =
39 {kPositionAttr, kColorAttr, kTexCoordAttr, kSsboIndexAttr};
40
41static constexpr SkSpan<const Attribute> kAttributes[4] = {
42 kAttributePositionOnly,
43 kAttributeColor,
44 kAttributeTexCoords,
45 kAttributeColorAndTexCoords,
46 };
47
48static constexpr Varying kVaryingColor[] =
49 {{"color", SkSLType::kHalf4}};
50
51static constexpr SkSpan<const Varying> kVaryings[2] = {
52 /*none*/ {},
53 /*color*/ kVaryingColor
54 };
55
56std::string variant_name(PrimitiveType type, bool hasColor, bool hasTexCoords) {
58 std::string name = (type == PrimitiveType::kTriangles ? "tris" : "tristrips");
59 if (hasColor) {
60 name += "-color";
61 }
62 if (hasTexCoords) {
63 name += "-texCoords";
64 }
65 return name;
66}
67
68} // namespace
69
71 : RenderStep("VerticesRenderStep",
72 variant_name(type, hasColor, hasTexCoords),
73 hasColor ? Flags::kEmitsPrimitiveColor | Flags::kPerformsShading
74 : Flags::kPerformsShading,
75 /*uniforms=*/{{"localToDevice", SkSLType::kFloat4x4},
76 {"depth", SkSLType::kFloat}},
77 type,
79 /*vertexAttrs=*/ kAttributes[2*hasTexCoords + hasColor],
80 /*instanceAttrs=*/{},
81 /*varyings=*/ kVaryings[hasColor])
82 , fHasColor(hasColor)
83 , fHasTexCoords(hasTexCoords) {}
84
86
87std::string VerticesRenderStep::vertexSkSL() const {
88 if (fHasColor && fHasTexCoords) {
89 return R"(
90 color = half4(vertColor.bgr * vertColor.a, vertColor.a);
91 float4 devPosition = localToDevice * float4(position, 0.0, 1.0);
92 devPosition.z = depth;
93 stepLocalCoords = texCoords;
94 )";
95 } else if (fHasTexCoords) {
96 return R"(
97 float4 devPosition = localToDevice * float4(position, 0.0, 1.0);
98 devPosition.z = depth;
99 stepLocalCoords = texCoords;
100 )";
101 } else if (fHasColor) {
102 return R"(
103 color = half4(vertColor.bgr * vertColor.a, vertColor.a);
104 float4 devPosition = localToDevice * float4(position, 0.0, 1.0);
105 devPosition.z = depth;
106 stepLocalCoords = position;
107 )";
108 } else {
109 return R"(
110 float4 devPosition = localToDevice * float4(position, 0.0, 1.0);
111 devPosition.z = depth;
112 stepLocalCoords = position;
113 )";
114 }
115}
116
118 if (fHasColor) {
119 return "primitiveColor = color;\n";
120 } else {
121 return "";
122 }
123}
124
126 const DrawParams& params,
127 skvx::ushort2 ssboIndices) const {
128 SkVerticesPriv info(params.geometry().vertices()->priv());
129 const int vertexCount = info.vertexCount();
130 const int indexCount = info.indexCount();
131 const SkPoint* positions = info.positions();
132 const uint16_t* indices = info.indices();
133 const SkColor* colors = info.colors();
134 const SkPoint* texCoords = info.texCoords();
135
136 // This should always be the case if the Renderer was chosen appropriately, but the vertex
137 // writing loop is set up in such a way that if the shader expects color or tex coords and they
138 // are missing, it will just read 0s, so release builds are safe.
139 SkASSERT(fHasColor == SkToBool(colors));
140 SkASSERT(fHasTexCoords == SkToBool(texCoords));
141
142 // TODO: We could access the writer's DrawBufferManager and upload the SkVertices index buffer
143 // but that would require we manually manage the VertexWriter for interleaving the position,
144 // color, and tex coord arrays together. This wouldn't be so bad if we let ::Vertices() take
145 // a CPU index buffer that indexes into the accumulated vertex data (and handles offsetting for
146 // merged drawIndexed calls), or if we could bind multiple attribute sources and copy the
147 // position/color/texCoord data separately in bulk w/o using an Appender.
148 DrawWriter::Vertices verts{*writer};
149 verts.reserve(indices ? indexCount : vertexCount);
150
151 VertState state(vertexCount, indices, indexCount);
152 VertState::Proc vertProc = state.chooseProc(info.mode());
153 while (vertProc(&state)) {
154 verts.append(3) << positions[state.f0]
155 << VertexWriter::If(fHasColor, colors ? colors[state.f0]
157 << VertexWriter::If(fHasTexCoords, texCoords ? texCoords[state.f0]
158 : SkPoint{0.f, 0.f})
159 << ssboIndices
160 << positions[state.f1]
161 << VertexWriter::If(fHasColor, colors ? colors[state.f1]
163 << VertexWriter::If(fHasTexCoords, texCoords ? texCoords[state.f1]
164 : SkPoint{0.f, 0.f})
165 << ssboIndices
166 << positions[state.f2]
167 << VertexWriter::If(fHasColor, colors ? colors[state.f2]
169 << VertexWriter::If(fHasTexCoords, texCoords ? texCoords[state.f2]
170 : SkPoint{0.f, 0.f})
171 << ssboIndices;
172 }
173}
174
176 PipelineDataGatherer* gatherer) const {
177 // Vertices are transformed on the GPU. Store PaintDepth as a uniform to avoid copying the
178 // same depth for each vertex.
179 SkDEBUGCODE(UniformExpectationsValidator uev(gatherer, this->uniforms());)
180 gatherer->write(params.transform().matrix());
181 gatherer->write(params.order().depthAsFloat());
182}
183
184} // namespace skgpu::graphite
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SkASSERT(cond)
Definition: SkAssert.h:116
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
GLenum type
SkSpan< const Uniform > uniforms() const
Definition: Renderer.h:143
void writeVertices(DrawWriter *writer, const DrawParams &params, skvx::ushort2 ssboIndices) const override
const char * fragmentColorSkSL() const override
std::string vertexSkSL() const override
VerticesRenderStep(PrimitiveType, bool hasColor, bool hasTexCoords)
void writeUniformsAndTextures(const DrawParams &, PipelineDataGatherer *) const override
const EmbeddedViewParams * params
AtkStateType state
PODArray< SkColor > colors
Definition: SkRecords.h:276
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
static const std::map< std::string, VerticesBuilder::AttributeType > kAttributes
static constexpr DepthStencilSettings kDirectDepthGEqualPass
bool(* Proc)(VertState *)
Definition: SkVertState.h:39
static Conditional< T > If(bool condition, const T &value)
Definition: BufferWriter.h:153
Definition: SkVx.h:83