Flutter Engine
The Flutter Engine
GrFragmentProcessor.h
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
8#ifndef GrFragmentProcessor_DEFINED
9#define GrFragmentProcessor_DEFINED
10
16#include "src/sksl/SkSLString.h"
17
18#include <tuple>
19
22class GrPaint;
23class GrPipeline;
24struct GrShaderCaps;
25class GrTextureEffect;
26
27namespace skgpu {
28class KeyBuilder;
29class Swizzle;
30}
31
32/**
33 * Some fragment-processor creation methods have preconditions that might not be satisfied by the
34 * calling code. Those methods can return a `GrFPResult` from their factory methods. If creation
35 * succeeds, the new fragment processor is created and `success` is true. If a precondition is not
36 * met, `success` is set to false and the input FP is returned unchanged.
37 */
39using GrFPResult = std::tuple<bool /*success*/, std::unique_ptr<GrFragmentProcessor>>;
40
41/** Provides custom fragment shader code. Fragment processors receive an input position and
42 produce an output color. They may contain uniforms and may have children fragment processors
43 that are sampled.
44 */
46public:
47 /**
48 * Every GrFragmentProcessor must be capable of creating a subclass of ProgramImpl. The
49 * ProgramImpl emits the fragment shader code that implements the GrFragmentProcessor, is
50 * attached to the generated backend API pipeline/program and used to extract uniform data from
51 * GrFragmentProcessor instances.
52 */
53 class ProgramImpl;
54
55 /** Always returns 'color'. */
56 static std::unique_ptr<GrFragmentProcessor> MakeColor(SkPMColor4f color);
57
58 /**
59 * Returns the input color, modulated by the child's alpha.
60 *
61 * output = input * child.a
62 */
63 static std::unique_ptr<GrFragmentProcessor> MulInputByChildAlpha(
64 std::unique_ptr<GrFragmentProcessor> child);
65
66 /**
67 * Invokes child with an opaque version of the input color, then applies the input alpha to
68 * the result. Used to incorporate paint alpha to the evaluation of an SkShader tree FP.
69 */
70 static std::unique_ptr<GrFragmentProcessor> ApplyPaintAlpha(
71 std::unique_ptr<GrFragmentProcessor> child);
72
73 /**
74 * Returns a fragment processor that generates the passed-in color, modulated by the child's
75 * RGBA color. The child's input color will be the parent's fInputColor. (Pass a null FP to use
76 * the color from fInputColor instead of a child FP.)
77 */
78 static std::unique_ptr<GrFragmentProcessor> ModulateRGBA(
79 std::unique_ptr<GrFragmentProcessor> child, const SkPMColor4f& color);
80
81 /**
82 * Returns a parent fragment processor that adopts the passed fragment processor as a child.
83 * The parent will ignore its input color and instead feed the passed in color as input to the
84 * child.
85 */
86 static std::unique_ptr<GrFragmentProcessor> OverrideInput(std::unique_ptr<GrFragmentProcessor>,
87 const SkPMColor4f&);
88
89 /**
90 * Returns a parent fragment processor that adopts the passed fragment processor as a child.
91 * The parent will simply return the child's color, but disable the coverage-as-alpha
92 * optimization.
93 */
94 static std::unique_ptr<GrFragmentProcessor> DisableCoverageAsAlpha(
95 std::unique_ptr<GrFragmentProcessor>);
96
97 /**
98 * Returns a fragment processor which returns `args.fDestColor`. This is only meaningful in
99 * contexts like blenders, which use a source and dest color.)
100 */
101 static std::unique_ptr<GrFragmentProcessor> DestColor();
102
103 /**
104 * Returns a fragment processor that calls the passed in fragment processor, and then swizzles
105 * the output.
106 */
107 static std::unique_ptr<GrFragmentProcessor> SwizzleOutput(std::unique_ptr<GrFragmentProcessor>,
108 const skgpu::Swizzle&);
109
110 /**
111 * Returns a fragment processor that calls the passed in fragment processor, and then clamps
112 * the output to [0, 1].
113 */
114 static std::unique_ptr<GrFragmentProcessor> ClampOutput(std::unique_ptr<GrFragmentProcessor>);
115
116 /**
117 * Returns a fragment processor that composes two fragment processors `f` and `g` into f(g(x)).
118 * This is equivalent to running them in series (`g`, then `f`). This is not the same as
119 * transfer-mode composition; there is no blending step.
120 */
121 static std::unique_ptr<GrFragmentProcessor> Compose(std::unique_ptr<GrFragmentProcessor> f,
122 std::unique_ptr<GrFragmentProcessor> g);
123
124 /*
125 * Returns a fragment processor that calls the passed in fragment processor, then runs the
126 * resulting color through the supplied color matrix.
127 */
128 static std::unique_ptr<GrFragmentProcessor> ColorMatrix(
129 std::unique_ptr<GrFragmentProcessor> child,
130 const float matrix[20],
131 bool unpremulInput,
132 bool clampRGBOutput,
133 bool premulOutput);
134
135 /**
136 * Returns a fragment processor that reads back the color on the surface being painted; that is,
137 * sampling this will return the color of the pixel that is currently being painted over.
138 */
139 static std::unique_ptr<GrFragmentProcessor> SurfaceColor();
140
141 /**
142 * Returns a fragment processor that calls the passed in fragment processor, but evaluates it
143 * in device-space (rather than local space).
144 */
145 static std::unique_ptr<GrFragmentProcessor> DeviceSpace(std::unique_ptr<GrFragmentProcessor>);
146
147 /**
148 * "Shape" FPs, often used for clipping. Each one evaluates a particular kind of shape (rect,
149 * circle, ellipse), and modulates the coverage of that shape against the results of the input
150 * FP. GrClipEdgeType is used to select inverse/normal fill, and AA or non-AA edges.
151 */
152 static std::unique_ptr<GrFragmentProcessor> Rect(std::unique_ptr<GrFragmentProcessor>,
154 SkRect);
155
156 static GrFPResult Circle(std::unique_ptr<GrFragmentProcessor>,
159 float radius);
160
161 static GrFPResult Ellipse(std::unique_ptr<GrFragmentProcessor>,
164 SkPoint radii,
165 const GrShaderCaps&);
166
167 /**
168 * Returns a fragment processor that calls the passed in fragment processor, but ensures the
169 * entire program is compiled with high-precision types.
170 */
171 static std::unique_ptr<GrFragmentProcessor> HighPrecision(std::unique_ptr<GrFragmentProcessor>);
172
173 /**
174 * Makes a copy of this fragment processor that draws equivalently to the original.
175 * If the processor has child processors they are cloned as well.
176 */
177 virtual std::unique_ptr<GrFragmentProcessor> clone() const = 0;
178
179 // The FP this was registered with as a child function. This will be null if this is a root.
180 const GrFragmentProcessor* parent() const { return fParent; }
181
182 std::unique_ptr<ProgramImpl> makeProgramImpl() const;
183
184 void addToKey(const GrShaderCaps& caps, skgpu::KeyBuilder* b) const {
185 this->onAddToKey(caps, b);
186 for (const auto& child : fChildProcessors) {
187 if (child) {
188 child->addToKey(caps, b);
189 }
190 }
191 }
192
193 int numChildProcessors() const { return fChildProcessors.size(); }
194 int numNonNullChildProcessors() const;
195
196 GrFragmentProcessor* childProcessor(int index) { return fChildProcessors[index].get(); }
197 const GrFragmentProcessor* childProcessor(int index) const {
198 return fChildProcessors[index].get();
199 }
200
201 SkDEBUGCODE(bool isInstantiated() const;)
202
203 /** Do any of the FPs in this tree read back the color from the destination surface? */
204 bool willReadDstColor() const {
205 return SkToBool(fFlags & kWillReadDstColor_Flag);
206 }
207
208 /** Does the SkSL for this FP take two colors as its input arguments? */
209 bool isBlendFunction() const {
210 return SkToBool(fFlags & kIsBlendFunction_Flag);
211 }
212
213 /**
214 * True if this FP refers directly to the sample coordinate parameter of its function
215 * (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is decided at FP-tree construction
216 * time and is not affected by lifting coords to varyings.
217 */
219 return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag);
220 }
221
222 /**
223 * True if this FP uses its input coordinates or if any descendant FP uses them through a chain
224 * of non-explicit sample usages. (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is
225 * decided at FP-tree construction time and is not affected by lifting coords to varyings.
226 */
227 bool usesSampleCoords() const {
228 return SkToBool(fFlags & (kUsesSampleCoordsDirectly_Flag |
229 kUsesSampleCoordsIndirectly_Flag));
230 }
231
232 // The SampleUsage describing how this FP is invoked by its parent. This only reflects the
233 // immediate sampling from parent to this FP.
235 return fUsage;
236 }
237
238 /**
239 * A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color
240 * output under the following scenario:
241 * * all the color fragment processors report true to this query,
242 * * all the coverage fragment processors report true to this query,
243 * * the blend mode arithmetic allows for it it.
244 * To be compatible a fragment processor's output must be a modulation of its input color or
245 * alpha with a computed premultiplied color or alpha that is in 0..1 range. The computed color
246 * or alpha that is modulated against the input cannot depend on the input's alpha. The computed
247 * value cannot depend on the input's color channels unless it unpremultiplies the input color
248 * channels by the input alpha.
249 */
252 }
253
254 /**
255 * If this is true then all opaque input colors to the processor produce opaque output colors.
256 */
257 bool preservesOpaqueInput() const {
259 }
260
261 /**
262 * Tests whether given a constant input color the processor produces a constant output color
263 * (for all fragments). If true outputColor will contain the constant color produces for
264 * inputColor.
265 */
266 bool hasConstantOutputForConstantInput(SkPMColor4f inputColor, SkPMColor4f* outputColor) const {
268 *outputColor = this->constantOutputForConstantInput(inputColor);
269 return true;
270 }
271 return false;
272 }
275 }
276
278 fFlags &= ~kConstantOutputForConstantInput_OptimizationFlag;
279 }
280
281 /** Returns true if this and other processor conservatively draw identically. It can only return
282 true when the two processor are of the same subclass (i.e. they return the same object from
283 from getFactory()).
284
285 A return value of true from isEqual() should not be used to test whether the processor would
286 generate the same shader code. To test for identical code generation use addToKey.
287 */
288 bool isEqual(const GrFragmentProcessor& that) const;
289
290 void visitProxies(const GrVisitProxyFunc&) const;
291
292 void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
293
295 ProgramImpl&) const;
296
298 const GrTextureEffect* asTextureEffect() const;
299
300#if defined(GR_TEST_UTILS)
301 // Generates debug info for this processor tree by recursively calling dumpInfo() on this
302 // processor and its children.
303 SkString dumpTreeInfo() const;
304#endif
305
306protected:
307 enum OptimizationFlags : uint32_t {
315 };
317
318 /**
319 * Can be used as a helper to decide which fragment processor OptimizationFlags should be set.
320 * This assumes that the subclass output color will be a modulation of the input color with a
321 * value read from a texture of the passed color type and that the texture contains
322 * premultiplied color or alpha values that are in range.
323 *
324 * Since there are multiple ways in which a sampler may have its coordinates clamped or wrapped,
325 * callers must determine on their own if the sampling uses a decal strategy in any way, in
326 * which case the texture may become transparent regardless of the color type.
327 */
328 static OptimizationFlags ModulateForSamplerOptFlags(SkAlphaType alphaType, bool samplingDecal) {
329 if (samplingDecal) {
331 } else {
332 return ModulateForClampedSamplerOptFlags(alphaType);
333 }
334 }
335
336 // As above, but callers should somehow ensure or assert their sampler still uses clamping
338 if (alphaType == kOpaque_SkAlphaType) {
341 } else {
343 }
344 }
345
349 }
350
354 }
355
357 return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
358 }
359
360 /** Useful when you can't call fp->optimizationFlags() on a base class object from a subclass.*/
362 return fp ? fp->optimizationFlags() : kAll_OptimizationFlags;
363 }
364
365 /**
366 * This allows one subclass to access another subclass's implementation of
367 * constantOutputForConstantInput. It must only be called when
368 * hasConstantOutputForConstantInput() is known to be true.
369 */
371 const SkPMColor4f& input) {
372 if (fp) {
373 SkASSERT(fp->hasConstantOutputForConstantInput());
374 return fp->constantOutputForConstantInput(input);
375 } else {
376 return input;
377 }
378 }
379
380 /**
381 * FragmentProcessor subclasses call this from their constructor to register any child
382 * FragmentProcessors they have. This must be called AFTER all texture accesses and coord
383 * transforms have been added.
384 * This is for processors whose shader code will be composed of nested processors whose output
385 * colors will be combined somehow to produce its output color. Registering these child
386 * processors will allow the ProgramBuilder to automatically handle their transformed coords and
387 * texture accesses and mangle their uniform and output color names.
388 *
389 * The SampleUsage parameter describes all of the ways that the child is sampled by the parent.
390 */
391 void registerChild(std::unique_ptr<GrFragmentProcessor> child,
393
394 /**
395 * This method takes an existing fragment processor, clones all of its children, and registers
396 * the clones as children of this fragment processor.
397 */
399
400 // FP implementations must call this function if their matching ProgramImpl's emitCode()
401 // function uses the EmitArgs::fSampleCoord variable in generated SkSL.
403 fFlags |= kUsesSampleCoordsDirectly_Flag;
404 }
405
406 // FP implementations must set this flag if their ProgramImpl's emitCode() function calls
407 // dstColor() to read back the framebuffer.
409 fFlags |= kWillReadDstColor_Flag;
410 }
411
412 // FP implementations must set this flag if their ProgramImpl's emitCode() function emits a
413 // blend function (taking two color inputs instead of just one).
415 fFlags |= kIsBlendFunction_Flag;
416 }
417
420 fFlags &= (flags | ~kAll_OptimizationFlags);
421 }
422
423private:
424 virtual SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& /* inputColor */) const {
425 SK_ABORT("Subclass must override this if advertising this optimization.");
426 }
427
428 /**
429 * Returns a new instance of the appropriate ProgramImpl subclass for the given
430 * GrFragmentProcessor. It will emit the appropriate code and live with the cached program
431 * to setup uniform data for each draw that uses the program.
432 */
433 virtual std::unique_ptr<ProgramImpl> onMakeProgramImpl() const = 0;
434
435 virtual void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const = 0;
436
437 /**
438 * Subclass implements this to support isEqual(). It will only be called if it is known that
439 * the two processors are of the same subclass (i.e. have the same ClassID).
440 */
441 virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
442
443 enum PrivateFlags {
444 kFirstPrivateFlag = kAll_OptimizationFlags + 1,
445
446 // Propagates up the FP tree to either root or first explicit sample usage.
447 kUsesSampleCoordsIndirectly_Flag = kFirstPrivateFlag,
448
449 // Does not propagate at all. It means this FP uses its input sample coords in some way.
450 // Note passthrough and matrix sampling of children don't count as a usage of the coords.
451 // Because indirect sampling stops at an explicit sample usage it is imperative that a FP
452 // that calculates explicit coords for its children using its own sample coords sets this.
453 kUsesSampleCoordsDirectly_Flag = kFirstPrivateFlag << 1,
454
455 // Does not propagate at all.
456 kIsBlendFunction_Flag = kFirstPrivateFlag << 2,
457
458 // Propagates up the FP tree to the root.
459 kWillReadDstColor_Flag = kFirstPrivateFlag << 3,
460 };
461
463 const GrFragmentProcessor* fParent = nullptr;
464 uint32_t fFlags = 0;
465 SkSL::SampleUsage fUsage;
466
467 using INHERITED = GrProcessor;
468};
469
470//////////////////////////////////////////////////////////////////////////////
471
473public:
474 ProgramImpl() = default;
475
476 virtual ~ProgramImpl() = default;
477
479 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
480
481 /** Called when the program stage should insert its code into the shaders. The code in each
482 shader will be in its own block ({}) and so locally scoped names will not collide across
483 stages.
484
485 @param fragBuilder Interface used to emit code in the shaders.
486 @param uniformHandler Interface used for accessing information about our uniforms
487 @param caps The capabilities of the GPU which will render this FP
488 @param fp The processor that generated this program stage.
489 @param inputColor A half4 that holds the input color to the stage in the FS (or the
490 source color, for blend processors). nullptr inputs are converted
491 to "half4(1.0)" (solid white) during construction.
492 TODO: Better system for communicating optimization info
493 (e.g. input color is solid white, trans black, known to be opaque,
494 etc.) that allows the processor to communicate back similar known
495 info about its output.
496 @param destColor A half4 that holds the dest color to the stage. Only meaningful
497 when the "is blend processor" FP flag is set.
498 @param sampleCoord The name of a local coord reference to a float2 variable. Only
499 meaningful when the "references sample coords" FP flag is set.
500 */
501 struct EmitArgs {
503 GrGLSLUniformHandler* uniformHandler,
504 const GrShaderCaps* caps,
505 const GrFragmentProcessor& fp,
506 const char* inputColor,
507 const char* destColor,
508 const char* sampleCoord)
509 : fFragBuilder(fragBuilder)
510 , fUniformHandler(uniformHandler)
511 , fShaderCaps(caps)
512 , fFp(fp)
513 , fInputColor(inputColor ? inputColor : "half4(1.0)")
514 , fDestColor(destColor)
515 , fSampleCoord(sampleCoord) {}
520 const char* fInputColor;
521 const char* fDestColor;
522 const char* fSampleCoord;
523 };
524
525 virtual void emitCode(EmitArgs&) = 0;
526
527 // This does not recurse to any attached child processors. Recursing the entire processor tree
528 // is the responsibility of the caller.
529 void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
530
531 int numChildProcessors() const { return fChildProcessors.size(); }
532
533 ProgramImpl* childProcessor(int index) const { return fChildProcessors[index].get(); }
534
536 SkASSERT(fFunctionName.isEmpty());
537 fFunctionName = std::move(name);
538 }
539
540 const char* functionName() const {
541 SkASSERT(!fFunctionName.isEmpty());
542 return fFunctionName.c_str();
543 }
544
545 // Invoke the child with the default input and destination colors (solid white)
546 inline SkString invokeChild(int childIndex,
547 EmitArgs& parentArgs,
548 std::string_view skslCoords = {}) {
549 return this->invokeChild(childIndex,
550 /*inputColor=*/nullptr,
551 /*destColor=*/nullptr,
552 parentArgs,
553 skslCoords);
554 }
555
556 inline SkString invokeChildWithMatrix(int childIndex, EmitArgs& parentArgs) {
557 return this->invokeChildWithMatrix(childIndex,
558 /*inputColor=*/nullptr,
559 /*destColor=*/nullptr,
560 parentArgs);
561 }
562
563 // Invoke the child with the default destination color (solid white)
564 inline SkString invokeChild(int childIndex,
565 const char* inputColor,
566 EmitArgs& parentArgs,
567 std::string_view skslCoords = {}) {
568 return this->invokeChild(childIndex,
569 inputColor,
570 /*destColor=*/nullptr,
571 parentArgs,
572 skslCoords);
573 }
574
575 inline SkString invokeChildWithMatrix(int childIndex,
576 const char* inputColor,
577 EmitArgs& parentArgs) {
578 return this->invokeChildWithMatrix(childIndex,
579 inputColor,
580 /*destColor=*/nullptr,
581 parentArgs);
582 }
583
584 /** Invokes a child proc in its own scope. Pass in the parent's EmitArgs and invokeChild will
585 * automatically extract the coords and samplers of that child and pass them on to the child's
586 * emitCode(). Also, any uniforms or functions emitted by the child will have their names
587 * mangled to prevent redefinitions. The returned string contains the output color (as a call
588 * to the child's helper function). It is legal to pass nullptr as inputColor, since all
589 * fragment processors are required to work without an input color.
590 *
591 * When skslCoords is empty, the child is invoked at the sample coordinates from parentArgs.
592 * When skslCoords is not empty, is must be an SkSL expression that evaluates to a float2.
593 * That expression is passed to the child's processor function as the "_coords" argument.
594 */
595 SkString invokeChild(int childIndex,
596 const char* inputColor,
597 const char* destColor,
598 EmitArgs& parentArgs,
599 std::string_view skslCoords = {});
600
601 /**
602 * As invokeChild, but transforms the coordinates according to the matrix expression attached
603 * to the child's SampleUsage object. This is only valid if the child is sampled with a
604 * const-uniform matrix.
605 */
606 SkString invokeChildWithMatrix(int childIndex,
607 const char* inputColor,
608 const char* destColor,
609 EmitArgs& parentArgs);
610
611 /**
612 * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
613 * GLSLFPS. If initialized with an array color followed by coverage processors installed in a
614 * program thenthe iteration order will agree with a GrFragmentProcessor::Iter initialized with
615 * a GrPipeline that produces the same program key.
616 */
617 class Iter {
618 public:
619 Iter(std::unique_ptr<ProgramImpl> fps[], int cnt);
620 Iter(ProgramImpl& fp) { fFPStack.push_back(&fp); }
621
625 explicit operator bool() const { return !fFPStack.empty(); }
626
627 // Because each iterator carries a stack we want to avoid copies.
628 Iter(const Iter&) = delete;
629 Iter& operator=(const Iter&) = delete;
630
631 private:
633 };
634
635private:
636 /**
637 * A ProgramImpl instance can be reused with any GrFragmentProcessor that produces the same
638 * the same key; this function reads data from a GrFragmentProcessor and uploads any
639 * uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
640 * parameter is guaranteed to be of the same type that created this ProgramImpl and
641 * to have an identical key as the one that created this ProgramImpl.
642 */
644
645 // The (mangled) name of our entry-point function
646 SkString fFunctionName;
647
649
651};
652
653//////////////////////////////////////////////////////////////////////////////
654
656
657static inline GrFPResult GrFPFailure(std::unique_ptr<GrFragmentProcessor> fp) {
658 return {false, std::move(fp)};
659}
660static inline GrFPResult GrFPSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
661 SkASSERT(fp);
662 return {true, std::move(fp)};
663}
664// Equivalent to GrFPSuccess except it allows the returned fragment processor to be null.
665static inline GrFPResult GrFPNullableSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
666 return {true, std::move(fp)};
667}
668
669#endif
static GrFPResult GrFPNullableSuccess(std::unique_ptr< GrFragmentProcessor > fp)
static GrFPResult GrFPSuccess(std::unique_ptr< GrFragmentProcessor > fp)
std::tuple< bool, std::unique_ptr< GrFragmentProcessor > > GrFPResult
static GrFPResult GrFPFailure(std::unique_ptr< GrFragmentProcessor > fp)
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
Definition: GrTypesPriv.h:943
GrClipEdgeType
Definition: GrTypesPriv.h:361
uint16_t fFlags
Definition: ShapeLayer.cpp:106
SkAlphaType
Definition: SkAlphaType.h:26
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SK_MAKE_BITFIELD_OPS(X)
Definition: SkMacros.h:66
#define SK_DECL_BITFIELD_OPS_FRIENDS(X)
Definition: SkMacros.h:86
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
static SkScalar center(float pos0, float pos1)
Iter(std::unique_ptr< ProgramImpl > fps[], int cnt)
Iter & operator=(const Iter &)=delete
SkString invokeChildWithMatrix(int childIndex, EmitArgs &parentArgs)
GrGLSLUniformHandler::SamplerHandle SamplerHandle
SkString invokeChildWithMatrix(int childIndex, const char *inputColor, EmitArgs &parentArgs)
SkString invokeChild(int childIndex, const char *inputColor, EmitArgs &parentArgs, std::string_view skslCoords={})
void setData(const GrGLSLProgramDataManager &pdman, const GrFragmentProcessor &processor)
virtual void onSetData(const GrGLSLProgramDataManager &, const GrFragmentProcessor &)
GrGLSLUniformHandler::UniformHandle UniformHandle
SkString invokeChild(int childIndex, EmitArgs &parentArgs, std::string_view skslCoords={})
virtual void emitCode(EmitArgs &)=0
ProgramImpl * childProcessor(int index) const
void cloneAndRegisterAllChildProcessors(const GrFragmentProcessor &src)
bool usesSampleCoordsDirectly() const
virtual SkPMColor4f constantOutputForConstantInput(const SkPMColor4f &) const
static std::unique_ptr< GrFragmentProcessor > SwizzleOutput(std::unique_ptr< GrFragmentProcessor >, const skgpu::Swizzle &)
void clearConstantOutputForConstantInputFlag()
static std::unique_ptr< GrFragmentProcessor > ClampOutput(std::unique_ptr< GrFragmentProcessor >)
bool preservesOpaqueInput() const
void addToKey(const GrShaderCaps &caps, skgpu::KeyBuilder *b) const
static GrFPResult Circle(std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, float radius)
GrFragmentProcessor(ClassID classID, OptimizationFlags optimizationFlags)
virtual std::unique_ptr< GrFragmentProcessor > clone() const =0
int numNonNullChildProcessors() const
static OptimizationFlags ProcessorOptimizationFlags(const GrFragmentProcessor *fp)
static std::unique_ptr< GrFragmentProcessor > MakeColor(SkPMColor4f color)
std::unique_ptr< ProgramImpl > makeProgramImpl() const
bool hasConstantOutputForConstantInput(SkPMColor4f inputColor, SkPMColor4f *outputColor) const
void mergeOptimizationFlags(OptimizationFlags flags)
static std::unique_ptr< GrFragmentProcessor > ModulateRGBA(std::unique_ptr< GrFragmentProcessor > child, const SkPMColor4f &color)
static std::unique_ptr< GrFragmentProcessor > DeviceSpace(std::unique_ptr< GrFragmentProcessor >)
static OptimizationFlags ModulateForClampedSamplerOptFlags(SkAlphaType alphaType)
SkDEBUGCODE(bool isInstantiated() const ;) bool willReadDstColor() const
static std::unique_ptr< GrFragmentProcessor > OverrideInput(std::unique_ptr< GrFragmentProcessor >, const SkPMColor4f &)
const GrFragmentProcessor * parent() const
static std::unique_ptr< GrFragmentProcessor > SurfaceColor()
GrTextureEffect * asTextureEffect()
bool isEqual(const GrFragmentProcessor &that) const
GrFragmentProcessor * childProcessor(int index)
void visitProxies(const GrVisitProxyFunc &) const
void visitWithImpls(const std::function< void(const GrFragmentProcessor &, ProgramImpl &)> &, ProgramImpl &) const
GrFragmentProcessor(const GrFragmentProcessor &src)
void registerChild(std::unique_ptr< GrFragmentProcessor > child, SkSL::SampleUsage sampleUsage=SkSL::SampleUsage::PassThrough())
static std::unique_ptr< GrFragmentProcessor > Rect(std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkRect)
static std::unique_ptr< GrFragmentProcessor > ApplyPaintAlpha(std::unique_ptr< GrFragmentProcessor > child)
OptimizationFlags optimizationFlags() const
static std::unique_ptr< GrFragmentProcessor > MulInputByChildAlpha(std::unique_ptr< GrFragmentProcessor > child)
const SkSL::SampleUsage & sampleUsage() const
virtual void onAddToKey(const GrShaderCaps &, skgpu::KeyBuilder *) const =0
bool compatibleWithCoverageAsAlpha() const
static std::unique_ptr< GrFragmentProcessor > HighPrecision(std::unique_ptr< GrFragmentProcessor >)
static std::unique_ptr< GrFragmentProcessor > DestColor()
static std::unique_ptr< GrFragmentProcessor > ColorMatrix(std::unique_ptr< GrFragmentProcessor > child, const float matrix[20], bool unpremulInput, bool clampRGBOutput, bool premulOutput)
static std::unique_ptr< GrFragmentProcessor > DisableCoverageAsAlpha(std::unique_ptr< GrFragmentProcessor >)
static std::unique_ptr< GrFragmentProcessor > Compose(std::unique_ptr< GrFragmentProcessor > f, std::unique_ptr< GrFragmentProcessor > g)
bool hasConstantOutputForConstantInput() const
const GrFragmentProcessor * childProcessor(int index) const
static SkPMColor4f ConstantOutputForConstantInput(const GrFragmentProcessor *fp, const SkPMColor4f &input)
virtual bool onIsEqual(const GrFragmentProcessor &) const =0
static GrFPResult Ellipse(std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, SkPoint radii, const GrShaderCaps &)
void visitTextureEffects(const std::function< void(const GrTextureEffect &)> &) const
static OptimizationFlags ModulateForSamplerOptFlags(SkAlphaType alphaType, bool samplingDecal)
virtual std::unique_ptr< ProgramImpl > onMakeProgramImpl() const =0
GrGLSLProgramDataManager::UniformHandle UniformHandle
GrProcessor(ClassID classID)
Definition: GrProcessor.h:132
ClassID classID() const
Definition: GrProcessor.h:129
virtual const char * name() const =0
static SampleUsage PassThrough()
bool isEmpty() const
Definition: SkString.h:130
const char * c_str() const
Definition: SkString.h:133
int size() const
Definition: SkTArray.h:421
DlColor color
static bool b
FlutterSemanticsFlag flags
Dart_NativeFunction function
Definition: fuchsia.cc:51
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
const uint32_t fp
Definition: GpuTools.h:21
Definition: ref_ptr.h:256
EmitArgs(GrGLSLFPFragmentBuilder *fragBuilder, GrGLSLUniformHandler *uniformHandler, const GrShaderCaps *caps, const GrFragmentProcessor &fp, const char *inputColor, const char *destColor, const char *sampleCoord)