Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrGeometryProcessor.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 Google Inc.
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
11#include "src/gpu/KeyBuilder.h"
17
18#include <queue>
19
21
23 SkASSERT(i >= 0 && i < this->numTextureSamplers());
24 return this->onTextureSampler(i);
25}
26
28 // This is highly coupled with the code in ProgramImpl::collectTransforms().
29 uint32_t key = static_cast<uint32_t>(fp.sampleUsage().kind()) << 1;
30 // This needs to be updated if GP starts specializing varyings on additional matrix types.
31 if (fp.sampleUsage().hasPerspective()) {
32 key |= 0b1;
33 }
34 return key;
35}
36
38 b->appendComment("vertex attributes");
39 fVertexAttributes.addToKey(b);
40 b->appendComment("instance attributes");
41 fInstanceAttributes.addToKey(b);
42}
43
44///////////////////////////////////////////////////////////////////////////////////////////////////
45
47 GrSamplerState::Filter requestedFilter) {
49 return std::min(requestedFilter, GrSamplerState::Filter::kLinear);
50 }
51 return requestedFilter;
52}
53
55 const GrBackendFormat& backendFormat,
56 const skgpu::Swizzle& swizzle) {
57 this->reset(samplerState, backendFormat, swizzle);
58}
59
61 const GrBackendFormat& backendFormat,
62 const skgpu::Swizzle& swizzle) {
63 fSamplerState = samplerState;
64 fSamplerState = GrSamplerState(samplerState.wrapModeX(),
65 samplerState.wrapModeY(),
66 clamp_filter(backendFormat.textureType(), samplerState.filter()),
67 samplerState.mipmapMode());
68 fBackendFormat = backendFormat;
69 fSwizzle = swizzle;
70 fIsInitialized = true;
71}
72
73//////////////////////////////////////////////////////////////////////////////
74
76
77std::tuple<ProgramImpl::FPCoordsMap, GrShaderVar>
78ProgramImpl::emitCode(EmitArgs& args, const GrPipeline& pipeline) {
79 GrGPArgs gpArgs;
80 this->onEmitCode(args, &gpArgs);
81
82 FPCoordsMap transformMap = this->collectTransforms(args.fVertBuilder,
83 args.fVaryingHandler,
84 args.fUniformHandler,
85 gpArgs.fLocalCoordShader,
86 gpArgs.fLocalCoordVar,
87 gpArgs.fPositionVar,
88 pipeline);
89
90 GrGLSLVertexBuilder* vBuilder = args.fVertBuilder;
91 // Emit the vertex position to the hardware in the normalized window coordinates it expects.
92 SkASSERT(SkSLType::kFloat2 == gpArgs.fPositionVar.getType() ||
93 SkSLType::kFloat3 == gpArgs.fPositionVar.getType());
94 vBuilder->emitNormalizedSkPosition(gpArgs.fPositionVar.c_str(),
95 gpArgs.fPositionVar.getType());
96 if (SkSLType::kFloat2 == gpArgs.fPositionVar.getType()) {
97 args.fVaryingHandler->setNoPerspective();
98 }
99
100 return {transformMap, gpArgs.fLocalCoordVar};
101}
102
103ProgramImpl::FPCoordsMap ProgramImpl::collectTransforms(GrGLSLVertexBuilder* vb,
104 GrGLSLVaryingHandler* varyingHandler,
105 GrGLSLUniformHandler* uniformHandler,
106 GrShaderType localCoordsShader,
107 const GrShaderVar& localCoordsVar,
108 const GrShaderVar& positionVar,
109 const GrPipeline& pipeline) {
110 SkASSERT(localCoordsVar.getType() == SkSLType::kFloat2 ||
111 localCoordsVar.getType() == SkSLType::kFloat3 ||
112 localCoordsVar.getType() == SkSLType::kVoid);
113 SkASSERT(positionVar.getType() == SkSLType::kFloat2 ||
114 positionVar.getType() == SkSLType::kFloat3 ||
115 positionVar.getType() == SkSLType::kVoid);
116
117 enum class BaseCoord { kNone, kLocal, kPosition };
118
119 auto baseLocalCoordFSVar = [&, baseLocalCoordVarying = GrGLSLVarying()]() mutable {
120 if (localCoordsShader == kFragment_GrShaderType) {
121 return localCoordsVar;
122 }
123 SkASSERT(localCoordsShader == kVertex_GrShaderType);
124 SkASSERT(SkSLTypeIsFloatType(localCoordsVar.getType()));
125 if (baseLocalCoordVarying.type() == SkSLType::kVoid) {
126 // Initialize to the GP provided coordinate
127 baseLocalCoordVarying = GrGLSLVarying(localCoordsVar.getType());
128 varyingHandler->addVarying("LocalCoord", &baseLocalCoordVarying);
129 vb->codeAppendf("%s = %s;\n",
130 baseLocalCoordVarying.vsOut(),
131 localCoordsVar.getName().c_str());
132 }
133 return baseLocalCoordVarying.fsInVar();
134 };
135
136 bool canUsePosition = positionVar.getType() != SkSLType::kVoid;
137
139 // Performs a pre-order traversal of FP hierarchy rooted at fp and identifies FPs that are
140 // sampled with a series of matrices applied to local coords. For each such FP a varying is
141 // added to the varying handler and added to 'result'.
142 auto liftTransforms = [&, traversalIndex = 0](
143 auto& self,
144 const GrFragmentProcessor& fp,
145 bool hasPerspective,
146 const GrFragmentProcessor* lastMatrixFP = nullptr,
147 int lastMatrixTraversalIndex = -1,
148 BaseCoord baseCoord = BaseCoord::kLocal) mutable -> void {
149 ++traversalIndex;
150 if (localCoordsShader == kVertex_GrShaderType) {
151 switch (fp.sampleUsage().kind()) {
153 // This should only happen at the root. Otherwise how did this FP get added?
154 SkASSERT(!fp.parent());
155 break;
157 break;
159 // Update tracking of last matrix and matrix props.
160 hasPerspective |= fp.sampleUsage().hasPerspective();
161 lastMatrixFP = &fp;
162 lastMatrixTraversalIndex = traversalIndex;
163 break;
165 hasPerspective = positionVar.getType() == SkSLType::kFloat3;
166 lastMatrixFP = nullptr;
167 lastMatrixTraversalIndex = -1;
168 baseCoord = BaseCoord::kPosition;
169 break;
171 baseCoord = BaseCoord::kNone;
172 break;
173 }
174 } else {
175 // If the GP doesn't provide an interpolatable local coord then there is no hope to
176 // lift.
177 baseCoord = BaseCoord::kNone;
178 }
179
180 auto& [varyingFSVar, hasCoordsParam] = result[&fp];
181 hasCoordsParam = fp.usesSampleCoordsDirectly();
182
183 // We add a varying if we're in a chain of matrices multiplied by local or device coords.
184 // If the coord is the untransformed local coord we add a varying. We don't if it is
185 // untransformed device coords since it doesn't save us anything over "sk_FragCoord.xy". Of
186 // course, if the FP doesn't directly use its coords then we don't add a varying.
187 if (fp.usesSampleCoordsDirectly() &&
188 (baseCoord == BaseCoord::kLocal ||
189 (baseCoord == BaseCoord::kPosition && lastMatrixFP && canUsePosition))) {
190 // Associate the varying with the highest possible node in the FP tree that shares the
191 // same coordinates so that multiple FPs in a subtree can share. If there are no matrix
192 // sample nodes on the way up the tree then directly use the local coord.
193 if (!lastMatrixFP) {
194 varyingFSVar = baseLocalCoordFSVar();
195 } else {
196 // If there is an already a varying that incorporates all matrices from the root to
197 // lastMatrixFP just use it. Otherwise, we add it.
198 auto& [varying, inputCoords, varyingIdx] = fTransformVaryingsMap[lastMatrixFP];
199 if (varying.type() == SkSLType::kVoid) {
200 varying = GrGLSLVarying(hasPerspective ? SkSLType::kFloat3 : SkSLType::kFloat2);
201 SkString strVaryingName = SkStringPrintf("TransformedCoords_%d",
202 lastMatrixTraversalIndex);
203 varyingHandler->addVarying(strVaryingName.c_str(), &varying);
204 inputCoords = baseCoord == BaseCoord::kLocal ? localCoordsVar : positionVar;
205 varyingIdx = lastMatrixTraversalIndex;
206 }
207 SkASSERT(varyingIdx == lastMatrixTraversalIndex);
208 // The FP will use the varying in the fragment shader as its coords.
209 varyingFSVar = varying.fsInVar();
210 }
211 hasCoordsParam = false;
212 }
213
214 for (int c = 0; c < fp.numChildProcessors(); ++c) {
215 if (auto* child = fp.childProcessor(c)) {
216 self(self,
217 *child,
218 hasPerspective,
219 lastMatrixFP,
220 lastMatrixTraversalIndex,
221 baseCoord);
222 // If we have a varying then we never need a param. Otherwise, if one of our
223 // children takes a non-explicit coord then we'll need our coord.
224 hasCoordsParam |= varyingFSVar.getType() == SkSLType::kVoid &&
225 !child->sampleUsage().isExplicit() &&
226 !child->sampleUsage().isFragCoord() &&
227 result[child].hasCoordsParam;
228 }
229 }
230 };
231
232 bool hasPerspective = SkSLTypeVecLength(localCoordsVar.getType()) == 3;
233 for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
234 liftTransforms(liftTransforms, pipeline.getFragmentProcessor(i), hasPerspective);
235 }
236 return result;
237}
238
239void ProgramImpl::emitTransformCode(GrGLSLVertexBuilder* vb, GrGLSLUniformHandler* uniformHandler) {
240 // Because descendant varyings may be computed using the varyings of ancestor FPs we make
241 // sure to visit the varyings according to FP pre-order traversal by dumping them into a
242 // priority queue.
243 using FPAndInfo = std::tuple<const GrFragmentProcessor*, TransformInfo>;
244 auto compare = [](const FPAndInfo& a, const FPAndInfo& b) {
245 return std::get<1>(a).traversalOrder > std::get<1>(b).traversalOrder;
246 };
247 std::priority_queue<FPAndInfo, std::vector<FPAndInfo>, decltype(compare)> pq(compare);
248 std::for_each(fTransformVaryingsMap.begin(), fTransformVaryingsMap.end(), [&pq](auto entry) {
249 pq.push(entry);
250 });
251 for (; !pq.empty(); pq.pop()) {
252 const auto& [fp, info] = pq.top();
253 // If we recorded a transform info, its sample matrix must be uniform
254 SkASSERT(fp->sampleUsage().isUniformMatrix());
255 GrShaderVar uniform = uniformHandler->liftUniformToVertexShader(
257 // Start with this matrix and accumulate additional matrices as we walk up the FP tree
258 // to either the base coords or an ancestor FP that has an associated varying.
259 SkString transformExpression = uniform.getName();
260
261 // If we hit an ancestor with a varying on our walk up then save off the varying as the
262 // input to our accumulated transformExpression. Start off assuming we'll reach the root.
263 GrShaderVar inputCoords = info.inputCoords;
264
265 for (const auto* base = fp->parent(); base; base = base->parent()) {
266 if (auto iter = fTransformVaryingsMap.find(base); iter != fTransformVaryingsMap.end()) {
267 // Can stop here, as this varying already holds all transforms from higher FPs
268 // We'll apply the residual transformExpression we've accumulated up from our
269 // starting FP to this varying.
270 inputCoords = iter->second.varying.vsOutVar();
271 break;
272 } else if (base->sampleUsage().isUniformMatrix()) {
273 // Accumulate any matrices along the path to either the original local/device coords
274 // or a parent varying. Getting here means this FP was sampled with a uniform matrix
275 // but all uses of coords below here in the FP hierarchy are beneath additional
276 // matrix samples and thus this node wasn't assigned a varying.
277 GrShaderVar parentUniform = uniformHandler->liftUniformToVertexShader(
279 transformExpression.appendf(" * %s", parentUniform.getName().c_str());
280 } else if (base->sampleUsage().isFragCoord()) {
281 // Our chain of matrices starts here and is based on the device space position.
282 break;
283 } else {
284 // This intermediate FP is just a pass through and doesn't need to be built
285 // in to the expression, but we must visit its parents in case they add transforms.
286 SkASSERT(base->sampleUsage().isPassThrough() || !base->sampleUsage().isSampled());
287 }
288 }
289
290 SkString inputStr;
291 if (inputCoords.getType() == SkSLType::kFloat2) {
292 inputStr = SkStringPrintf("%s.xy1", inputCoords.getName().c_str());
293 } else {
294 SkASSERT(inputCoords.getType() == SkSLType::kFloat3);
295 inputStr = inputCoords.getName();
296 }
297
298 vb->codeAppend("{\n");
299 if (info.varying.type() == SkSLType::kFloat2) {
301 vb->codeAppendf("%s = float3x2(%s) * %s",
302 info.varying.vsOut(),
303 transformExpression.c_str(),
304 inputStr.c_str());
305 } else {
306 vb->codeAppendf("%s = (%s * %s).xy",
307 info.varying.vsOut(),
308 transformExpression.c_str(),
309 inputStr.c_str());
310 }
311 } else {
312 SkASSERT(info.varying.type() == SkSLType::kFloat3);
313 vb->codeAppendf("%s = %s * %s",
314 info.varying.vsOut(),
315 transformExpression.c_str(),
316 inputStr.c_str());
317 }
318 vb->codeAppend(";\n");
319 vb->codeAppend("}\n");
320 }
321 // We don't need this map anymore.
322 fTransformVaryingsMap.clear();
323}
324
325void ProgramImpl::setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
326 GrGLSLUniformHandler* uniformHandler,
327 const char* outputName,
328 UniformHandle* colorUniform) {
329 SkASSERT(colorUniform);
330 const char* stagedLocalVarName;
331 *colorUniform = uniformHandler->addUniform(nullptr,
334 "Color",
335 &stagedLocalVarName);
336 fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
338 fragBuilder->codeAppendf("%s = max(%s, half4(0));", outputName, outputName);
339 }
340}
341
342void ProgramImpl::SetTransform(const GrGLSLProgramDataManager& pdman,
343 const GrShaderCaps& shaderCaps,
344 const UniformHandle& uniform,
345 const SkMatrix& matrix,
346 SkMatrix* state) {
347 if (!uniform.isValid() || (state && SkMatrixPriv::CheapEqual(*state, matrix))) {
348 // No update needed
349 return;
350 }
351 if (state) {
352 *state = matrix;
353 }
354 if (matrix.isScaleTranslate() && !shaderCaps.fReducedShaderMode) {
355 // ComputeMatrixKey and writeX() assume the uniform is a float4 (can't assert since nothing
356 // is exposed on a handle, but should be caught lower down).
357 float values[4] = {matrix.getScaleX(), matrix.getTranslateX(),
358 matrix.getScaleY(), matrix.getTranslateY()};
359 pdman.set4fv(uniform, 1, values);
360 } else {
361 pdman.setSkMatrix(uniform, matrix);
362 }
363}
364
366 const GrShaderVar& inPos,
367 GrShaderVar* outPos) {
369 SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
370 outPos->set(inPos.getType(), outName.c_str());
371 vertBuilder->codeAppendf("float%d %s = %s;",
372 SkSLTypeVecLength(inPos.getType()),
373 outName.c_str(),
374 inPos.getName().c_str());
375}
376
378 GrGLSLUniformHandler* uniformHandler,
379 const GrShaderCaps& shaderCaps,
380 const GrShaderVar& inPos,
381 const SkMatrix& matrix,
382 const char* matrixName,
383 GrShaderVar* outPos,
384 ProgramImpl::UniformHandle* matrixUniform) {
386 SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
387
388 if (matrix.isIdentity() && !shaderCaps.fReducedShaderMode) {
389 write_passthrough_vertex_position(vertBuilder, inPos, outPos);
390 return;
391 }
392 SkASSERT(matrixUniform);
393
394 bool useCompactTransform = matrix.isScaleTranslate() && !shaderCaps.fReducedShaderMode;
395 const char* mangledMatrixName;
396 *matrixUniform = uniformHandler->addUniform(nullptr,
398 useCompactTransform ? SkSLType::kFloat4
400 matrixName,
401 &mangledMatrixName);
402
403 if (inPos.getType() == SkSLType::kFloat3) {
404 // A float3 stays a float3 whether or not the matrix adds perspective
405 if (useCompactTransform) {
406 vertBuilder->codeAppendf("float3 %s = %s.xz1 * %s + %s.yw0;\n",
407 outName.c_str(),
408 mangledMatrixName,
409 inPos.getName().c_str(),
410 mangledMatrixName);
411 } else {
412 vertBuilder->codeAppendf("float3 %s = %s * %s;\n",
413 outName.c_str(),
414 mangledMatrixName,
415 inPos.getName().c_str());
416 }
417 outPos->set(SkSLType::kFloat3, outName.c_str());
418 return;
419 }
420 if (matrix.hasPerspective()) {
421 // A float2 is promoted to a float3 if we add perspective via the matrix
422 SkASSERT(!useCompactTransform);
423 vertBuilder->codeAppendf("float3 %s = (%s * %s.xy1);",
424 outName.c_str(),
425 mangledMatrixName,
426 inPos.getName().c_str());
427 outPos->set(SkSLType::kFloat3, outName.c_str());
428 return;
429 }
430 if (useCompactTransform) {
431 vertBuilder->codeAppendf("float2 %s = %s.xz * %s + %s.yw;\n",
432 outName.c_str(),
433 mangledMatrixName,
434 inPos.getName().c_str(),
435 mangledMatrixName);
436 } else if (shaderCaps.fNonsquareMatrixSupport) {
437 vertBuilder->codeAppendf("float2 %s = float3x2(%s) * %s.xy1;\n",
438 outName.c_str(),
439 mangledMatrixName,
440 inPos.getName().c_str());
441 } else {
442 vertBuilder->codeAppendf("float2 %s = (%s * %s.xy1).xy;\n",
443 outName.c_str(),
444 mangledMatrixName,
445 inPos.getName().c_str());
446 }
447 outPos->set(SkSLType::kFloat2, outName.c_str());
448}
449
450void ProgramImpl::WriteOutputPosition(GrGLSLVertexBuilder* vertBuilder,
451 GrGPArgs* gpArgs,
452 const char* posName) {
453 // writeOutputPosition assumes the incoming pos name points to a float2 variable
454 GrShaderVar inPos(posName, SkSLType::kFloat2);
455 write_passthrough_vertex_position(vertBuilder, inPos, &gpArgs->fPositionVar);
456}
457
458void ProgramImpl::WriteOutputPosition(GrGLSLVertexBuilder* vertBuilder,
459 GrGLSLUniformHandler* uniformHandler,
460 const GrShaderCaps& shaderCaps,
461 GrGPArgs* gpArgs,
462 const char* posName,
463 const SkMatrix& mat,
464 UniformHandle* viewMatrixUniform) {
465 GrShaderVar inPos(posName, SkSLType::kFloat2);
466 write_vertex_position(vertBuilder,
467 uniformHandler,
468 shaderCaps,
469 inPos,
470 mat,
471 "viewMatrix",
472 &gpArgs->fPositionVar,
473 viewMatrixUniform);
474}
475
476void ProgramImpl::WriteLocalCoord(GrGLSLVertexBuilder* vertBuilder,
477 GrGLSLUniformHandler* uniformHandler,
478 const GrShaderCaps& shaderCaps,
479 GrGPArgs* gpArgs,
480 GrShaderVar localVar,
481 const SkMatrix& localMatrix,
482 UniformHandle* localMatrixUniform) {
483 write_vertex_position(vertBuilder,
484 uniformHandler,
485 shaderCaps,
486 localVar,
487 localMatrix,
488 "localMatrix",
489 &gpArgs->fLocalCoordVar,
490 localMatrixUniform);
491}
492
493//////////////////////////////////////////////////////////////////////////////
494
497
498GrGeometryProcessor::Attribute AttributeSet::Iter::operator*() const {
499 if (fCurr->offset().has_value()) {
500 return *fCurr;
501 }
502 return Attribute(fCurr->name(), fCurr->cpuType(), fCurr->gpuType(), fImplicitOffset);
503}
504
505void AttributeSet::Iter::operator++() {
506 if (fRemaining) {
507 fRemaining--;
508 fImplicitOffset += Attribute::AlignOffset(fCurr->size());
509 fCurr++;
510 this->skipUninitialized();
511 }
512}
513
514void AttributeSet::Iter::skipUninitialized() {
515 if (!fRemaining) {
516 fCurr = nullptr;
517 } else {
518 while (!fCurr->isInitialized()) {
519 ++fCurr;
520 }
521 }
522}
523
525 fAttributes = attrs;
526 fRawCount = count;
527 fCount = 0;
528 fStride = 0;
529 for (int i = 0; i < count; ++i) {
530 if (attrs[i].isInitialized()) {
531 fCount++;
532 fStride += Attribute::AlignOffset(attrs[i].size());
533 }
534 }
535}
536
537void AttributeSet::initExplicit(const Attribute* attrs, int count, size_t stride) {
538 fAttributes = attrs;
539 fRawCount = count;
540 fCount = count;
541 fStride = stride;
542 SkASSERT(Attribute::AlignOffset(fStride) == fStride);
543 for (int i = 0; i < count; ++i) {
544 SkASSERT(attrs[i].isInitialized());
545 SkASSERT(attrs[i].offset().has_value());
546 SkASSERT(Attribute::AlignOffset(*attrs[i].offset()) == *attrs[i].offset());
547 SkASSERT(*attrs[i].offset() + attrs[i].size() <= fStride);
548 }
549}
550
552 int rawCount = SkAbs32(fRawCount);
553 b->addBits(16, SkToU16(this->stride()), "stride");
554 b->addBits(16, rawCount, "attribute count");
555 size_t implicitOffset = 0;
556 for (int i = 0; i < rawCount; ++i) {
557 const Attribute& attr = fAttributes[i];
558 b->appendComment(attr.isInitialized() ? attr.name() : "unusedAttr");
559 static_assert(kGrVertexAttribTypeCount < (1 << 8), "");
560 static_assert(kSkSLTypeCount < (1 << 8), "");
561 b->addBits(8, attr.isInitialized() ? attr.cpuType() : 0xff, "attrType");
562 b->addBits(8 , attr.isInitialized() ? static_cast<int>(attr.gpuType()) : 0xff,
563 "attrGpuType");
564 int16_t offset = -1;
565 if (attr.isInitialized()) {
566 if (attr.offset().has_value()) {
567 offset = *attr.offset();
568 } else {
569 offset = implicitOffset;
570 implicitOffset += Attribute::AlignOffset(attr.size());
571 }
572 }
573 b->addBits(16, static_cast<uint16_t>(offset), "attrOffset");
574 }
575}
576
577AttributeSet::Iter AttributeSet::begin() const { return Iter(fAttributes, fCount); }
578AttributeSet::Iter AttributeSet::end() const { return Iter(); }
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
Definition BlurTest.cpp:100
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
m reset()
int count
static void write_passthrough_vertex_position(GrGLSLVertexBuilder *vertBuilder, const GrShaderVar &inPos, GrShaderVar *outPos)
static GrSamplerState::Filter clamp_filter(GrTextureType type, GrSamplerState::Filter requestedFilter)
static void write_vertex_position(GrGLSLVertexBuilder *vertBuilder, GrGLSLUniformHandler *uniformHandler, const GrShaderCaps &shaderCaps, const GrShaderVar &inPos, const SkMatrix &matrix, const char *matrixName, GrShaderVar *outPos, ProgramImpl::UniformHandle *matrixUniform)
@ kVertex_GrShaderFlag
@ kFragment_GrShaderFlag
GrShaderType
@ kFragment_GrShaderType
@ kVertex_GrShaderType
GrTextureType
static const int kGrVertexAttribTypeCount
static bool GrTextureTypeHasRestrictedSampling(GrTextureType type)
#define SkASSERT(cond)
Definition SkAssert.h:116
static const int kSkSLTypeCount
SkSLType
static constexpr bool SkSLTypeIsFloatType(SkSLType type)
static constexpr int SkSLTypeVecLength(SkSLType type)
static int32_t SkAbs32(int32_t value)
Definition SkSafe32.h:41
SkFilterMode
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
constexpr uint16_t SkToU16(S x)
Definition SkTo.h:24
GrTextureType textureType() const
GrGLSLUniformHandler::UniformHandle UniformHandle
virtual void emitCode(EmitArgs &)=0
const GrShaderCaps * shaderCaps() const
virtual void set4fv(UniformHandle, int arrayCount, const float v[]) const =0
void setSkMatrix(UniformHandle, const SkMatrix &) const
void codeAppend(const char *str)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
SkString newTmpVarName(const char *suffix)
GrGLSLProgramBuilder * getProgramBuilder()
GrShaderVar liftUniformToVertexShader(const GrProcessor &owner, SkString rawName)
UniformHandle addUniform(const GrProcessor *owner, uint32_t visibility, SkSLType type, const char *name, const char **outName=nullptr)
void addVarying(const char *name, GrGLSLVarying *varying, Interpolation=Interpolation::kInterpolated)
void emitNormalizedSkPosition(const char *devPos, SkSLType devPosType=SkSLType::kFloat2)
void initImplicit(const Attribute *attrs, int count)
void addToKey(skgpu::KeyBuilder *b) const
void initExplicit(const Attribute *attrs, int count, size_t stride)
std::optional< size_t > offset() const
constexpr GrVertexAttribType cpuType() const
constexpr bool isInitialized() const
constexpr const char * name() const
constexpr SkSLType gpuType() const
virtual void onEmitCode(EmitArgs &, GrGPArgs *)=0
GrGLSLProgramDataManager::UniformHandle UniformHandle
std::unordered_map< const GrFragmentProcessor *, FPCoords > FPCoordsMap
void reset(GrSamplerState, const GrBackendFormat &, const skgpu::Swizzle &)
const GrBackendFormat & backendFormat() const
const skgpu::Swizzle & swizzle() const
const TextureSampler & textureSampler(int index) const
virtual const TextureSampler & onTextureSampler(int) const
static uint32_t ComputeCoordTransformsKey(const GrFragmentProcessor &fp)
void getAttributeKey(skgpu::KeyBuilder *b) const
int numFragmentProcessors() const
Definition GrPipeline.h:99
const GrFragmentProcessor & getFragmentProcessor(int idx) const
Definition GrPipeline.h:157
constexpr WrapMode wrapModeX() const
constexpr Filter filter() const
constexpr MipmapMode mipmapMode() const
constexpr WrapMode wrapModeY() const
SkSLType getType() const
Definition GrShaderVar.h:97
void set(SkSLType type, const char *name)
Definition GrShaderVar.h:78
const SkString & getName() const
Definition GrShaderVar.h:91
static bool CheapEqual(const SkMatrix &a, const SkMatrix &b)
static const char * MatrixUniformName()
const char * c_str() const
Definition SkString.h:133
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:550
virtual void addBits(uint32_t numBits, uint32_t val, std::string_view label)
Definition KeyBuilder.h:29
static bool b
struct MyStruct a[10]
AtkStateType state
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
const uint32_t fp
Point offset
bool fMustObfuscateUniformColor
bool fReducedShaderMode
bool fNonsquareMatrixSupport
Definition SkSLUtil.h:90