Flutter Engine
The Flutter Engine
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 auto baseLocalCoordFSVar = [&, baseLocalCoordVarying = GrGLSLVarying()]() mutable {
118 if (localCoordsShader == kFragment_GrShaderType) {
119 return localCoordsVar;
120 }
121 SkASSERT(localCoordsShader == kVertex_GrShaderType);
122 SkASSERT(SkSLTypeIsFloatType(localCoordsVar.getType()));
123 if (baseLocalCoordVarying.type() == SkSLType::kVoid) {
124 // Initialize to the GP provided coordinate
125 baseLocalCoordVarying = GrGLSLVarying(localCoordsVar.getType());
126 varyingHandler->addVarying("LocalCoord", &baseLocalCoordVarying);
127 vb->codeAppendf("%s = %s;\n",
128 baseLocalCoordVarying.vsOut(),
129 localCoordsVar.getName().c_str());
130 }
131 return baseLocalCoordVarying.fsInVar();
132 };
133
134 bool canUsePosition = positionVar.getType() != SkSLType::kVoid;
135
137 // Performs a pre-order traversal of FP hierarchy rooted at fp and identifies FPs that are
138 // sampled with a series of matrices applied to local coords. For each such FP a varying is
139 // added to the varying handler and added to 'result'.
140 auto liftTransforms = [&, traversalIndex = 0](
141 auto& self,
142 const GrFragmentProcessor& fp,
143 bool hasPerspective,
144 const GrFragmentProcessor* lastMatrixFP = nullptr,
145 int lastMatrixTraversalIndex = -1,
146 BaseCoord baseCoord = BaseCoord::kLocal) mutable -> void {
147 ++traversalIndex;
148 if (localCoordsShader == kVertex_GrShaderType) {
149 switch (fp.sampleUsage().kind()) {
151 // This should only happen at the root. Otherwise how did this FP get added?
152 SkASSERT(!fp.parent());
153 break;
155 break;
157 // Update tracking of last matrix and matrix props.
158 hasPerspective |= fp.sampleUsage().hasPerspective();
159 lastMatrixFP = &fp;
160 lastMatrixTraversalIndex = traversalIndex;
161 break;
163 hasPerspective = positionVar.getType() == SkSLType::kFloat3;
164 lastMatrixFP = nullptr;
165 lastMatrixTraversalIndex = -1;
166 baseCoord = BaseCoord::kPosition;
167 break;
169 baseCoord = BaseCoord::kNone;
170 break;
171 }
172 } else {
173 // If the GP doesn't provide an interpolatable local coord then there is no hope to
174 // lift.
175 baseCoord = BaseCoord::kNone;
176 }
177
178 auto& [varyingFSVar, hasCoordsParam] = result[&fp];
179 hasCoordsParam = fp.usesSampleCoordsDirectly();
180
181 // We add a varying if we're in a chain of matrices multiplied by local or device coords.
182 // If the coord is the untransformed local coord we add a varying. We don't if it is
183 // untransformed device coords since it doesn't save us anything over "sk_FragCoord.xy". Of
184 // course, if the FP doesn't directly use its coords then we don't add a varying.
185 if (fp.usesSampleCoordsDirectly() &&
186 (baseCoord == BaseCoord::kLocal ||
187 (baseCoord == BaseCoord::kPosition && lastMatrixFP && canUsePosition))) {
188 // Associate the varying with the highest possible node in the FP tree that shares the
189 // same coordinates so that multiple FPs in a subtree can share. If there are no matrix
190 // sample nodes on the way up the tree then directly use the local coord.
191 if (!lastMatrixFP) {
192 varyingFSVar = baseLocalCoordFSVar();
193 } else {
194 // If there is an already a varying that incorporates all matrices from the root to
195 // lastMatrixFP just use it. Otherwise, we add it.
196 auto& [varying, inputCoords, varyingIdx] = fTransformVaryingsMap[lastMatrixFP];
197 if (varying.type() == SkSLType::kVoid) {
198 varying = GrGLSLVarying(hasPerspective ? SkSLType::kFloat3 : SkSLType::kFloat2);
199 SkString strVaryingName = SkStringPrintf("TransformedCoords_%d",
200 lastMatrixTraversalIndex);
201 varyingHandler->addVarying(strVaryingName.c_str(), &varying);
202 inputCoords = baseCoord == BaseCoord::kLocal ? localCoordsVar : positionVar;
203 varyingIdx = lastMatrixTraversalIndex;
204 }
205 SkASSERT(varyingIdx == lastMatrixTraversalIndex);
206 // The FP will use the varying in the fragment shader as its coords.
207 varyingFSVar = varying.fsInVar();
208 }
209 hasCoordsParam = false;
210 }
211
212 for (int c = 0; c < fp.numChildProcessors(); ++c) {
213 if (auto* child = fp.childProcessor(c)) {
214 self(self,
215 *child,
216 hasPerspective,
217 lastMatrixFP,
218 lastMatrixTraversalIndex,
219 baseCoord);
220 // If we have a varying then we never need a param. Otherwise, if one of our
221 // children takes a non-explicit coord then we'll need our coord.
222 hasCoordsParam |= varyingFSVar.getType() == SkSLType::kVoid &&
223 !child->sampleUsage().isExplicit() &&
224 !child->sampleUsage().isFragCoord() &&
225 result[child].hasCoordsParam;
226 }
227 }
228 };
229
230 bool hasPerspective = SkSLTypeVecLength(localCoordsVar.getType()) == 3;
231 for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
232 liftTransforms(liftTransforms, pipeline.getFragmentProcessor(i), hasPerspective);
233 }
234 return result;
235}
236
238 // Because descendant varyings may be computed using the varyings of ancestor FPs we make
239 // sure to visit the varyings according to FP pre-order traversal by dumping them into a
240 // priority queue.
241 using FPAndInfo = std::tuple<const GrFragmentProcessor*, TransformInfo>;
242 auto compare = [](const FPAndInfo& a, const FPAndInfo& b) {
243 return std::get<1>(a).traversalOrder > std::get<1>(b).traversalOrder;
244 };
245 std::priority_queue<FPAndInfo, std::vector<FPAndInfo>, decltype(compare)> pq(compare);
246 std::for_each(fTransformVaryingsMap.begin(), fTransformVaryingsMap.end(), [&pq](auto entry) {
247 pq.push(entry);
248 });
249 for (; !pq.empty(); pq.pop()) {
250 const auto& [fp, info] = pq.top();
251 // If we recorded a transform info, its sample matrix must be uniform
252 SkASSERT(fp->sampleUsage().isUniformMatrix());
253 GrShaderVar uniform = uniformHandler->liftUniformToVertexShader(
255 // Start with this matrix and accumulate additional matrices as we walk up the FP tree
256 // to either the base coords or an ancestor FP that has an associated varying.
257 SkString transformExpression = uniform.getName();
258
259 // If we hit an ancestor with a varying on our walk up then save off the varying as the
260 // input to our accumulated transformExpression. Start off assuming we'll reach the root.
261 GrShaderVar inputCoords = info.inputCoords;
262
263 for (const auto* base = fp->parent(); base; base = base->parent()) {
264 if (auto iter = fTransformVaryingsMap.find(base); iter != fTransformVaryingsMap.end()) {
265 // Can stop here, as this varying already holds all transforms from higher FPs
266 // We'll apply the residual transformExpression we've accumulated up from our
267 // starting FP to this varying.
268 inputCoords = iter->second.varying.vsOutVar();
269 break;
270 } else if (base->sampleUsage().isUniformMatrix()) {
271 // Accumulate any matrices along the path to either the original local/device coords
272 // or a parent varying. Getting here means this FP was sampled with a uniform matrix
273 // but all uses of coords below here in the FP hierarchy are beneath additional
274 // matrix samples and thus this node wasn't assigned a varying.
275 GrShaderVar parentUniform = uniformHandler->liftUniformToVertexShader(
277 transformExpression.appendf(" * %s", parentUniform.getName().c_str());
278 } else if (base->sampleUsage().isFragCoord()) {
279 // Our chain of matrices starts here and is based on the device space position.
280 break;
281 } else {
282 // This intermediate FP is just a pass through and doesn't need to be built
283 // in to the expression, but we must visit its parents in case they add transforms.
284 SkASSERT(base->sampleUsage().isPassThrough() || !base->sampleUsage().isSampled());
285 }
286 }
287
288 SkString inputStr;
289 if (inputCoords.getType() == SkSLType::kFloat2) {
290 inputStr = SkStringPrintf("%s.xy1", inputCoords.getName().c_str());
291 } else {
292 SkASSERT(inputCoords.getType() == SkSLType::kFloat3);
293 inputStr = inputCoords.getName();
294 }
295
296 vb->codeAppend("{\n");
297 if (info.varying.type() == SkSLType::kFloat2) {
299 vb->codeAppendf("%s = float3x2(%s) * %s",
300 info.varying.vsOut(),
301 transformExpression.c_str(),
302 inputStr.c_str());
303 } else {
304 vb->codeAppendf("%s = (%s * %s).xy",
305 info.varying.vsOut(),
306 transformExpression.c_str(),
307 inputStr.c_str());
308 }
309 } else {
310 SkASSERT(info.varying.type() == SkSLType::kFloat3);
311 vb->codeAppendf("%s = %s * %s",
312 info.varying.vsOut(),
313 transformExpression.c_str(),
314 inputStr.c_str());
315 }
316 vb->codeAppend(";\n");
317 vb->codeAppend("}\n");
318 }
319 // We don't need this map anymore.
320 fTransformVaryingsMap.clear();
321}
322
324 GrGLSLUniformHandler* uniformHandler,
325 const char* outputName,
326 UniformHandle* colorUniform) {
327 SkASSERT(colorUniform);
328 const char* stagedLocalVarName;
329 *colorUniform = uniformHandler->addUniform(nullptr,
332 "Color",
333 &stagedLocalVarName);
334 fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
336 fragBuilder->codeAppendf("%s = max(%s, half4(0));", outputName, outputName);
337 }
338}
339
341 const GrShaderCaps& shaderCaps,
342 const UniformHandle& uniform,
343 const SkMatrix& matrix,
344 SkMatrix* state) {
345 if (!uniform.isValid() || (state && SkMatrixPriv::CheapEqual(*state, matrix))) {
346 // No update needed
347 return;
348 }
349 if (state) {
350 *state = matrix;
351 }
352 if (matrix.isScaleTranslate() && !shaderCaps.fReducedShaderMode) {
353 // ComputeMatrixKey and writeX() assume the uniform is a float4 (can't assert since nothing
354 // is exposed on a handle, but should be caught lower down).
355 float values[4] = {matrix.getScaleX(), matrix.getTranslateX(),
356 matrix.getScaleY(), matrix.getTranslateY()};
357 pdman.set4fv(uniform, 1, values);
358 } else {
359 pdman.setSkMatrix(uniform, matrix);
360 }
361}
362
364 const GrShaderVar& inPos,
365 GrShaderVar* outPos) {
367 SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
368 outPos->set(inPos.getType(), outName.c_str());
369 vertBuilder->codeAppendf("float%d %s = %s;",
370 SkSLTypeVecLength(inPos.getType()),
371 outName.c_str(),
372 inPos.getName().c_str());
373}
374
376 GrGLSLUniformHandler* uniformHandler,
377 const GrShaderCaps& shaderCaps,
378 const GrShaderVar& inPos,
379 const SkMatrix& matrix,
380 const char* matrixName,
381 GrShaderVar* outPos,
382 ProgramImpl::UniformHandle* matrixUniform) {
384 SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
385
386 if (matrix.isIdentity() && !shaderCaps.fReducedShaderMode) {
387 write_passthrough_vertex_position(vertBuilder, inPos, outPos);
388 return;
389 }
390 SkASSERT(matrixUniform);
391
392 bool useCompactTransform = matrix.isScaleTranslate() && !shaderCaps.fReducedShaderMode;
393 const char* mangledMatrixName;
394 *matrixUniform = uniformHandler->addUniform(nullptr,
396 useCompactTransform ? SkSLType::kFloat4
398 matrixName,
399 &mangledMatrixName);
400
401 if (inPos.getType() == SkSLType::kFloat3) {
402 // A float3 stays a float3 whether or not the matrix adds perspective
403 if (useCompactTransform) {
404 vertBuilder->codeAppendf("float3 %s = %s.xz1 * %s + %s.yw0;\n",
405 outName.c_str(),
406 mangledMatrixName,
407 inPos.getName().c_str(),
408 mangledMatrixName);
409 } else {
410 vertBuilder->codeAppendf("float3 %s = %s * %s;\n",
411 outName.c_str(),
412 mangledMatrixName,
413 inPos.getName().c_str());
414 }
415 outPos->set(SkSLType::kFloat3, outName.c_str());
416 return;
417 }
418 if (matrix.hasPerspective()) {
419 // A float2 is promoted to a float3 if we add perspective via the matrix
420 SkASSERT(!useCompactTransform);
421 vertBuilder->codeAppendf("float3 %s = (%s * %s.xy1);",
422 outName.c_str(),
423 mangledMatrixName,
424 inPos.getName().c_str());
425 outPos->set(SkSLType::kFloat3, outName.c_str());
426 return;
427 }
428 if (useCompactTransform) {
429 vertBuilder->codeAppendf("float2 %s = %s.xz * %s + %s.yw;\n",
430 outName.c_str(),
431 mangledMatrixName,
432 inPos.getName().c_str(),
433 mangledMatrixName);
434 } else if (shaderCaps.fNonsquareMatrixSupport) {
435 vertBuilder->codeAppendf("float2 %s = float3x2(%s) * %s.xy1;\n",
436 outName.c_str(),
437 mangledMatrixName,
438 inPos.getName().c_str());
439 } else {
440 vertBuilder->codeAppendf("float2 %s = (%s * %s.xy1).xy;\n",
441 outName.c_str(),
442 mangledMatrixName,
443 inPos.getName().c_str());
444 }
445 outPos->set(SkSLType::kFloat2, outName.c_str());
446}
447
449 GrGPArgs* gpArgs,
450 const char* posName) {
451 // writeOutputPosition assumes the incoming pos name points to a float2 variable
452 GrShaderVar inPos(posName, SkSLType::kFloat2);
453 write_passthrough_vertex_position(vertBuilder, inPos, &gpArgs->fPositionVar);
454}
455
457 GrGLSLUniformHandler* uniformHandler,
458 const GrShaderCaps& shaderCaps,
459 GrGPArgs* gpArgs,
460 const char* posName,
461 const SkMatrix& mat,
462 UniformHandle* viewMatrixUniform) {
463 GrShaderVar inPos(posName, SkSLType::kFloat2);
464 write_vertex_position(vertBuilder,
465 uniformHandler,
466 shaderCaps,
467 inPos,
468 mat,
469 "viewMatrix",
470 &gpArgs->fPositionVar,
471 viewMatrixUniform);
472}
473
475 GrGLSLUniformHandler* uniformHandler,
476 const GrShaderCaps& shaderCaps,
477 GrGPArgs* gpArgs,
478 GrShaderVar localVar,
479 const SkMatrix& localMatrix,
480 UniformHandle* localMatrixUniform) {
481 write_vertex_position(vertBuilder,
482 uniformHandler,
483 shaderCaps,
484 localVar,
485 localMatrix,
486 "localMatrix",
487 &gpArgs->fLocalCoordVar,
488 localMatrixUniform);
489}
490
491//////////////////////////////////////////////////////////////////////////////
492
495
497 if (fCurr->offset().has_value()) {
498 return *fCurr;
499 }
500 return Attribute(fCurr->name(), fCurr->cpuType(), fCurr->gpuType(), fImplicitOffset);
501}
502
503void AttributeSet::Iter::operator++() {
504 if (fRemaining) {
505 fRemaining--;
506 fImplicitOffset += Attribute::AlignOffset(fCurr->size());
507 fCurr++;
508 this->skipUninitialized();
509 }
510}
511
512void AttributeSet::Iter::skipUninitialized() {
513 if (!fRemaining) {
514 fCurr = nullptr;
515 } else {
516 while (!fCurr->isInitialized()) {
517 ++fCurr;
518 }
519 }
520}
521
523 fAttributes = attrs;
524 fRawCount = count;
525 fCount = 0;
526 fStride = 0;
527 for (int i = 0; i < count; ++i) {
528 if (attrs[i].isInitialized()) {
529 fCount++;
530 fStride += Attribute::AlignOffset(attrs[i].size());
531 }
532 }
533}
534
535void AttributeSet::initExplicit(const Attribute* attrs, int count, size_t stride) {
536 fAttributes = attrs;
537 fRawCount = count;
538 fCount = count;
539 fStride = stride;
540 SkASSERT(Attribute::AlignOffset(fStride) == fStride);
541 for (int i = 0; i < count; ++i) {
542 SkASSERT(attrs[i].isInitialized());
543 SkASSERT(attrs[i].offset().has_value());
544 SkASSERT(Attribute::AlignOffset(*attrs[i].offset()) == *attrs[i].offset());
545 SkASSERT(*attrs[i].offset() + attrs[i].size() <= fStride);
546 }
547}
548
550 int rawCount = SkAbs32(fRawCount);
551 b->addBits(16, SkToU16(this->stride()), "stride");
552 b->addBits(16, rawCount, "attribute count");
553 size_t implicitOffset = 0;
554 for (int i = 0; i < rawCount; ++i) {
555 const Attribute& attr = fAttributes[i];
556 b->appendComment(attr.isInitialized() ? attr.name() : "unusedAttr");
557 static_assert(kGrVertexAttribTypeCount < (1 << 8), "");
558 static_assert(kSkSLTypeCount < (1 << 8), "");
559 b->addBits(8, attr.isInitialized() ? attr.cpuType() : 0xff, "attrType");
560 b->addBits(8 , attr.isInitialized() ? static_cast<int>(attr.gpuType()) : 0xff,
561 "attrGpuType");
562 int16_t offset = -1;
563 if (attr.isInitialized()) {
564 if (attr.offset().has_value()) {
565 offset = *attr.offset();
566 } else {
567 offset = implicitOffset;
568 implicitOffset += Attribute::AlignOffset(attr.size());
569 }
570 }
571 b->addBits(16, static_cast<uint16_t>(offset), "attrOffset");
572 }
573}
574
575AttributeSet::Iter AttributeSet::begin() const { return Iter(fAttributes, fCount); }
576AttributeSet::Iter AttributeSet::end() const { return Iter(); }
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
static void write_passthrough_vertex_position(GrGLSLVertexBuilder *vertBuilder, const GrShaderVar &inPos, GrShaderVar *outPos)
GrGeometryProcessor::Attribute Attribute
GrGeometryProcessor::ProgramImpl ProgramImpl
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)
GrGeometryProcessor::AttributeSet AttributeSet
@ kVertex_GrShaderFlag
Definition: GrTypesPriv.h:286
@ kFragment_GrShaderFlag
Definition: GrTypesPriv.h:287
GrShaderType
Definition: GrTypesPriv.h:276
@ kFragment_GrShaderType
Definition: GrTypesPriv.h:278
@ kVertex_GrShaderType
Definition: GrTypesPriv.h:277
GrTextureType
Definition: GrTypesPriv.h:268
static const int kGrVertexAttribTypeCount
Definition: GrTypesPriv.h:352
static bool GrTextureTypeHasRestrictedSampling(GrTextureType type)
Definition: GrTypesPriv.h:294
#define SkASSERT(cond)
Definition: SkAssert.h:116
static const int kSkSLTypeCount
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 SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
constexpr uint16_t SkToU16(S x)
Definition: SkTo.h:24
GLenum type
GrTextureType textureType() const
GrGLSLUniformHandler::UniformHandle UniformHandle
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
static constexpr size_t AlignOffset(size_t offset)
constexpr bool isInitialized() const
constexpr const char * name() const
constexpr size_t size() const
constexpr SkSLType gpuType() const
void emitTransformCode(GrGLSLVertexBuilder *vb, GrGLSLUniformHandler *uniformHandler)
void setupUniformColor(GrGLSLFPFragmentBuilder *fragBuilder, GrGLSLUniformHandler *uniformHandler, const char *outputName, UniformHandle *colorUniform)
virtual void onEmitCode(EmitArgs &, GrGPArgs *)=0
GrGLSLProgramDataManager::UniformHandle UniformHandle
static void WriteOutputPosition(GrGLSLVertexBuilder *, GrGPArgs *, const char *posName)
std::tuple< FPCoordsMap, GrShaderVar > emitCode(EmitArgs &, const GrPipeline &pipeline)
std::unordered_map< const GrFragmentProcessor *, FPCoords > FPCoordsMap
static void WriteLocalCoord(GrGLSLVertexBuilder *, GrGLSLUniformHandler *, const GrShaderCaps &, GrGPArgs *, GrShaderVar localVar, const SkMatrix &localMatrix, UniformHandle *localMatrixUniform)
static void SetTransform(const GrGLSLProgramDataManager &, const GrShaderCaps &, const UniformHandle &uniform, const SkMatrix &matrix, SkMatrix *state=nullptr)
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)
Definition: SkMatrixPriv.h:181
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
static float min(float r, float g, float b)
Definition: hsl.cpp:48
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
const uint32_t fp
@ kNone
Definition: layer.h:53
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
constexpr Color operator*(T value, const Color &c)
Definition: color.h:911
const myers::Point & get< 1 >(const myers::Segment &s)
Definition: Myers.h:81
int compare(const void *untyped_lhs, const void *untyped_rhs)
Definition: skdiff.h:161
SeparatedVector2 offset
bool fMustObfuscateUniformColor
Definition: GrShaderCaps.h:51
bool fReducedShaderMode
Definition: GrShaderCaps.h:46
bool fNonsquareMatrixSupport
Definition: SkSLUtil.h:90