Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | Private Member Functions | List of all members
GrFragmentProcessor Class Referenceabstract

#include <GrFragmentProcessor.h>

Inheritance diagram for GrFragmentProcessor:
GrProcessor BlendFragmentProcessor BlockInputFragmentProcessor ColorTableEffect GrBicubicEffect GrColorSpaceXformEffect GrConvexPolyEffect GrMatrixEffect GrModulateAtlasCoverageEffect GrPerlinNoise2Effect GrSkSLFP GrTextureEffect GrYUVtoRGBEffect LazyProxyTest::ClipFP SampleCoordEffect

Classes

class  ProgramImpl
 

Public Member Functions

virtual std::unique_ptr< GrFragmentProcessorclone () const =0
 
const GrFragmentProcessorparent () const
 
std::unique_ptr< ProgramImplmakeProgramImpl () const
 
void addToKey (const GrShaderCaps &caps, skgpu::KeyBuilder *b) const
 
int numChildProcessors () const
 
int numNonNullChildProcessors () const
 
GrFragmentProcessorchildProcessor (int index)
 
const GrFragmentProcessorchildProcessor (int index) const
 
 SkDEBUGCODE (bool isInstantiated() const ;) bool willReadDstColor() const
 
bool isBlendFunction () const
 
bool usesSampleCoordsDirectly () const
 
bool usesSampleCoords () const
 
const SkSL::SampleUsagesampleUsage () const
 
bool compatibleWithCoverageAsAlpha () const
 
bool preservesOpaqueInput () const
 
bool hasConstantOutputForConstantInput (SkPMColor4f inputColor, SkPMColor4f *outputColor) const
 
bool hasConstantOutputForConstantInput () const
 
void clearConstantOutputForConstantInputFlag ()
 
bool isEqual (const GrFragmentProcessor &that) const
 
void visitProxies (const GrVisitProxyFunc &) const
 
void visitTextureEffects (const std::function< void(const GrTextureEffect &)> &) const
 
void visitWithImpls (const std::function< void(const GrFragmentProcessor &, ProgramImpl &)> &, ProgramImpl &) const
 
GrTextureEffectasTextureEffect ()
 
const GrTextureEffectasTextureEffect () const
 
- Public Member Functions inherited from GrProcessor
virtual ~GrProcessor ()=default
 
virtual const char * name () const =0
 
void * operator new (size_t size)
 
void * operator new (size_t object_size, size_t footer_size)
 
void operator delete (void *target)
 
void * operator new (size_t size, void *placement)
 
void operator delete (void *target, void *placement)
 
template<typename T >
const Tcast () const
 
ClassID classID () const
 

Static Public Member Functions

static std::unique_ptr< GrFragmentProcessorMakeColor (SkPMColor4f color)
 
static std::unique_ptr< GrFragmentProcessorMulInputByChildAlpha (std::unique_ptr< GrFragmentProcessor > child)
 
static std::unique_ptr< GrFragmentProcessorApplyPaintAlpha (std::unique_ptr< GrFragmentProcessor > child)
 
static std::unique_ptr< GrFragmentProcessorModulateRGBA (std::unique_ptr< GrFragmentProcessor > child, const SkPMColor4f &color)
 
static std::unique_ptr< GrFragmentProcessorOverrideInput (std::unique_ptr< GrFragmentProcessor >, const SkPMColor4f &)
 
static std::unique_ptr< GrFragmentProcessorDisableCoverageAsAlpha (std::unique_ptr< GrFragmentProcessor >)
 
static std::unique_ptr< GrFragmentProcessorDestColor ()
 
static std::unique_ptr< GrFragmentProcessorSwizzleOutput (std::unique_ptr< GrFragmentProcessor >, const skgpu::Swizzle &)
 
static std::unique_ptr< GrFragmentProcessorClampOutput (std::unique_ptr< GrFragmentProcessor >)
 
static std::unique_ptr< GrFragmentProcessorCompose (std::unique_ptr< GrFragmentProcessor > f, std::unique_ptr< GrFragmentProcessor > g)
 
static std::unique_ptr< GrFragmentProcessorColorMatrix (std::unique_ptr< GrFragmentProcessor > child, const float matrix[20], bool unpremulInput, bool clampRGBOutput, bool premulOutput)
 
static std::unique_ptr< GrFragmentProcessorSurfaceColor ()
 
static std::unique_ptr< GrFragmentProcessorDeviceSpace (std::unique_ptr< GrFragmentProcessor >)
 
static std::unique_ptr< GrFragmentProcessorRect (std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkRect)
 
static GrFPResult Circle (std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, float radius)
 
static GrFPResult Ellipse (std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, SkPoint radii, const GrShaderCaps &)
 
static std::unique_ptr< GrFragmentProcessorHighPrecision (std::unique_ptr< GrFragmentProcessor >)
 

Protected Types

enum  OptimizationFlags : uint32_t {
  kNone_OptimizationFlags , kCompatibleWithCoverageAsAlpha_OptimizationFlag = 0x1 , kPreservesOpaqueInput_OptimizationFlag = 0x2 , kConstantOutputForConstantInput_OptimizationFlag = 0x4 ,
  kAll_OptimizationFlags
}
 

Protected Member Functions

 GrFragmentProcessor (ClassID classID, OptimizationFlags optimizationFlags)
 
 GrFragmentProcessor (const GrFragmentProcessor &src)
 
OptimizationFlags optimizationFlags () const
 
void registerChild (std::unique_ptr< GrFragmentProcessor > child, SkSL::SampleUsage sampleUsage=SkSL::SampleUsage::PassThrough())
 
void cloneAndRegisterAllChildProcessors (const GrFragmentProcessor &src)
 
void setUsesSampleCoordsDirectly ()
 
void setWillReadDstColor ()
 
void setIsBlendFunction ()
 
void mergeOptimizationFlags (OptimizationFlags flags)
 
- Protected Member Functions inherited from GrProcessor
 GrProcessor (ClassID classID)
 
 GrProcessor (const GrProcessor &)=delete
 
GrProcessoroperator= (const GrProcessor &)=delete
 

Static Protected Member Functions

static OptimizationFlags ModulateForSamplerOptFlags (SkAlphaType alphaType, bool samplingDecal)
 
static OptimizationFlags ModulateForClampedSamplerOptFlags (SkAlphaType alphaType)
 
static OptimizationFlags ProcessorOptimizationFlags (const GrFragmentProcessor *fp)
 
static SkPMColor4f ConstantOutputForConstantInput (const GrFragmentProcessor *fp, const SkPMColor4f &input)
 

Private Member Functions

virtual SkPMColor4f constantOutputForConstantInput (const SkPMColor4f &) const
 
virtual std::unique_ptr< ProgramImplonMakeProgramImpl () const =0
 
virtual void onAddToKey (const GrShaderCaps &, skgpu::KeyBuilder *) const =0
 
virtual bool onIsEqual (const GrFragmentProcessor &) const =0
 

Additional Inherited Members

- Public Types inherited from GrProcessor
enum  ClassID {
  kNull_ClassID , kAttributeTestProcessor_ClassID , kBigKeyProcessor_ClassID , kBlendFragmentProcessor_ClassID ,
  kBlockInputFragmentProcessor_ClassID , kButtCapStrokedCircleGeometryProcessor_ClassID , kCircleGeometryProcessor_ClassID , kCircularRRectEffect_ClassID ,
  kClockwiseTestProcessor_ClassID , kColorTableEffect_ClassID , kCoverageSetOpXP_ClassID , kCustomXP_ClassID ,
  kDashingCircleEffect_ClassID , kDashingLineEffect_ClassID , kDefaultGeoProc_ClassID , kDeviceSpace_ClassID ,
  kDIEllipseGeometryProcessor_ClassID , kDisableColorXP_ClassID , kDrawAtlasPathShader_ClassID , kEllipseGeometryProcessor_ClassID ,
  kEllipticalRRectEffect_ClassID , kFwidthSquircleTestProcessor_ClassID , kGP_ClassID , kGrBicubicEffect_ClassID ,
  kGrBitmapTextGeoProc_ClassID , kGrColorSpaceXformEffect_ClassID , kGrConicEffect_ClassID , kGrConvexPolyEffect_ClassID ,
  kGrDiffuseLightingEffect_ClassID , kGrDisplacementMapEffect_ClassID , kGrDistanceFieldA8TextGeoProc_ClassID , kGrDistanceFieldLCDTextGeoProc_ClassID ,
  kGrDistanceFieldPathGeoProc_ClassID , kGrFillRRectOp_Processor_ClassID , kGrGaussianConvolutionFragmentProcessor_ClassID , kGrMatrixConvolutionEffect_ClassID ,
  kGrMatrixEffect_ClassID , kGrMeshTestProcessor_ClassID , kGrMorphologyEffect_ClassID , kGrPerlinNoise2Effect_ClassID ,
  kGrPipelineDynamicStateTestProcessor_ClassID , kGrQuadEffect_ClassID , kGrRRectShadowGeoProc_ClassID , kGrSkSLFP_ClassID ,
  kGrSpecularLightingEffect_ClassID , kGrTextureEffect_ClassID , kGrUnrolledBinaryGradientColorizer_ClassID , kGrYUVtoRGBEffect_ClassID ,
  kHighPrecisionFragmentProcessor_ClassID , kLatticeGP_ClassID , kPDLCDXferProcessor_ClassID , kPorterDuffXferProcessor_ClassID ,
  kPremulFragmentProcessor_ClassID , kQuadEdgeEffect_ClassID , kQuadPerEdgeAAGeometryProcessor_ClassID , kSeriesFragmentProcessor_ClassID ,
  kShaderPDXferProcessor_ClassID , kSurfaceColorProcessor_ClassID , kSwizzleFragmentProcessor_ClassID , kTessellate_BoundingBoxShader_ClassID ,
  kTessellate_GrModulateAtlasCoverageEffect_ClassID , kTessellate_GrStrokeTessellationShader_ClassID , kTessellate_HullShader_ClassID , kTessellate_MiddleOutShader_ClassID ,
  kTessellate_SimpleTriangleShader_ClassID , kTessellationTestTriShader_ClassID , kTestFP_ClassID , kTestRectOp_ClassID ,
  kVertexColorSpaceBenchGP_ClassID , kVerticesGP_ClassID
}
 
- Protected Attributes inherited from GrProcessor
const ClassID fClassID
 

Detailed Description

Provides custom fragment shader code. Fragment processors receive an input position and produce an output color. They may contain uniforms and may have children fragment processors that are sampled.

Definition at line 45 of file GrFragmentProcessor.h.

Member Enumeration Documentation

◆ OptimizationFlags

enum GrFragmentProcessor::OptimizationFlags : uint32_t
protected
Enumerator
kNone_OptimizationFlags 
kCompatibleWithCoverageAsAlpha_OptimizationFlag 
kPreservesOpaqueInput_OptimizationFlag 
kConstantOutputForConstantInput_OptimizationFlag 
kAll_OptimizationFlags 

Definition at line 307 of file GrFragmentProcessor.h.

Constructor & Destructor Documentation

◆ GrFragmentProcessor() [1/2]

GrFragmentProcessor::GrFragmentProcessor ( ClassID  classID,
OptimizationFlags  optimizationFlags 
)
inlineprotected

Definition at line 346 of file GrFragmentProcessor.h.

347 : INHERITED(classID), fFlags(optimizationFlags) {
349 }
#define SkASSERT(cond)
Definition SkAssert.h:116
OptimizationFlags optimizationFlags() const
ClassID classID() const

◆ GrFragmentProcessor() [2/2]

GrFragmentProcessor::GrFragmentProcessor ( const GrFragmentProcessor src)
inlineexplicitprotected

Definition at line 351 of file GrFragmentProcessor.h.

352 : INHERITED(src.classID()), fFlags(src.fFlags) {
354 }
void cloneAndRegisterAllChildProcessors(const GrFragmentProcessor &src)

Member Function Documentation

◆ addToKey()

void GrFragmentProcessor::addToKey ( const GrShaderCaps caps,
skgpu::KeyBuilder b 
) const
inline

Definition at line 184 of file GrFragmentProcessor.h.

184 {
185 this->onAddToKey(caps, b);
186 for (const auto& child : fChildProcessors) {
187 if (child) {
188 child->addToKey(caps, b);
189 }
190 }
191 }
virtual void onAddToKey(const GrShaderCaps &, skgpu::KeyBuilder *) const =0
static bool b

◆ ApplyPaintAlpha()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::ApplyPaintAlpha ( std::unique_ptr< GrFragmentProcessor child)
static

Invokes child with an opaque version of the input color, then applies the input alpha to the result. Used to incorporate paint alpha to the evaluation of an SkShader tree FP.

Definition at line 214 of file GrFragmentProcessor.cpp.

215 {
216 SkASSERT(child);
218 "uniform colorFilter fp;"
219 "half4 main(half4 inColor) {"
220 "return fp.eval(inColor.rgb1) * inColor.a;"
221 "}"
222 );
223 return GrSkSLFP::Make(effect, "ApplyPaintAlpha", /*inputFP=*/nullptr,
226 "fp", std::move(child));
227}
SkRuntimeEffect * SkMakeRuntimeEffect(SkRuntimeEffect::Result(*make)(SkString, const SkRuntimeEffect::Options &), const char *sksl, SkRuntimeEffect::Options options=SkRuntimeEffect::Options{})
static std::unique_ptr< GrSkSLFP > Make(const SkRuntimeEffect *effect, const char *name, std::unique_ptr< GrFragmentProcessor > inputFP, OptFlags optFlags, Args &&... args)
Definition GrSkSLFP.h:158
static Result MakeForColorFilter(SkString sksl, const Options &)

◆ asTextureEffect() [1/2]

GrTextureEffect * GrFragmentProcessor::asTextureEffect ( )

Definition at line 81 of file GrFragmentProcessor.cpp.

81 {
82 if (this->classID() == kGrTextureEffect_ClassID) {
83 return static_cast<GrTextureEffect*>(this);
84 }
85 return nullptr;
86}
@ kGrTextureEffect_ClassID
Definition GrProcessor.h:71

◆ asTextureEffect() [2/2]

const GrTextureEffect * GrFragmentProcessor::asTextureEffect ( ) const

Definition at line 88 of file GrFragmentProcessor.cpp.

88 {
89 if (this->classID() == kGrTextureEffect_ClassID) {
90 return static_cast<const GrTextureEffect*>(this);
91 }
92 return nullptr;
93}

◆ childProcessor() [1/2]

GrFragmentProcessor * GrFragmentProcessor::childProcessor ( int  index)
inline

Definition at line 196 of file GrFragmentProcessor.h.

196{ return fChildProcessors[index].get(); }

◆ childProcessor() [2/2]

const GrFragmentProcessor * GrFragmentProcessor::childProcessor ( int  index) const
inline

Definition at line 197 of file GrFragmentProcessor.h.

197 {
198 return fChildProcessors[index].get();
199 }

◆ Circle()

GrFPResult GrFragmentProcessor::Circle ( std::unique_ptr< GrFragmentProcessor inputFP,
GrClipEdgeType  edgeType,
SkPoint  center,
float  radius 
)
static

Definition at line 647 of file GrFragmentProcessor.cpp.

650 {
651 // A radius below half causes the implicit insetting done by this processor to become
652 // inverted. We could handle this case by making the processor code more complicated.
653 if (radius < .5f && GrClipEdgeTypeIsInverseFill(edgeType)) {
654 return GrFPFailure(std::move(inputFP));
655 }
656
659 "uniform int edgeType;" // GrClipEdgeType, specialized
660 // The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.5)) for regular
661 // fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills.
662 "uniform float4 circle;"
663
664 "half4 main(float2 xy) {"
665 // TODO: Right now the distance to circle calculation is performed in a space normalized
666 // to the radius and then denormalized. This is to mitigate overflow on devices that
667 // don't have full float.
668 "half d;"
669 "if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {"
670 "d = half((length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z);"
671 "} else {"
672 "d = half((1.0 - length((circle.xy - sk_FragCoord.xy) * circle.w)) * circle.z);"
673 "}"
674 "return half4((edgeType == kFillAA || edgeType == kInverseFillAA)"
675 "? saturate(d)"
676 ": (d > 0.5 ? 1 : 0));"
677 "}"
678 );
679
680 SkScalar effectiveRadius = radius;
681 if (GrClipEdgeTypeIsInverseFill(edgeType)) {
682 effectiveRadius -= 0.5f;
683 // When the radius is 0.5 effectiveRadius is 0 which causes an inf * 0 in the shader.
684 effectiveRadius = std::max(0.001f, effectiveRadius);
685 } else {
686 effectiveRadius += 0.5f;
687 }
688 SkV4 circle = {center.fX, center.fY, effectiveRadius, SkScalarInvert(effectiveRadius)};
689
690 auto circleFP = GrSkSLFP::Make(effect, "Circle", /*inputFP=*/nullptr,
692 "edgeType", GrSkSLFP::Specialize(static_cast<int>(edgeType)),
693 "circle", circle);
694 return GrFPSuccess(GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(inputFP),
695 std::move(circleFP)));
696}
#define CLIP_EDGE_SKSL
static GrFPResult GrFPSuccess(std::unique_ptr< GrFragmentProcessor > fp)
static GrFPResult GrFPFailure(std::unique_ptr< GrFragmentProcessor > fp)
static constexpr bool GrClipEdgeTypeIsInverseFill(const GrClipEdgeType edgeType)
#define SkScalarInvert(x)
Definition SkScalar.h:73
static SkScalar center(float pos0, float pos1)
static GrSpecializedUniform< T > Specialize(const T &value)
Definition GrSkSLFP.h:76
static Result MakeForShader(SkString sksl, const Options &)
float SkScalar
Definition extension.cpp:12
Definition SkM44.h:98

◆ ClampOutput()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::ClampOutput ( std::unique_ptr< GrFragmentProcessor fp)
static

Returns a fragment processor that calls the passed in fragment processor, and then clamps the output to [0, 1].

Definition at line 236 of file GrFragmentProcessor.cpp.

237 {
238 SkASSERT(fp);
240 "half4 main(half4 inColor) {"
241 "return saturate(inColor);"
242 "}"
243 );
245 return GrSkSLFP::Make(effect, "Clamp", std::move(fp),
247}
static bool SupportsConstantOutputForConstantInput(const SkRuntimeEffect *effect)

◆ clearConstantOutputForConstantInputFlag()

void GrFragmentProcessor::clearConstantOutputForConstantInputFlag ( )
inline

Definition at line 277 of file GrFragmentProcessor.h.

277 {
278 fFlags &= ~kConstantOutputForConstantInput_OptimizationFlag;
279 }

◆ clone()

virtual std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::clone ( ) const
pure virtual

Makes a copy of this fragment processor that draws equivalently to the original. If the processor has child processors they are cloned as well.

Implemented in SampleCoordEffect, GrBicubicEffect, BlendFragmentProcessor, ColorTableEffect, GrConvexPolyEffect, GrMatrixEffect, GrModulateAtlasCoverageEffect, GrPerlinNoise2Effect, GrSkSLFP, GrTextureEffect, GrYUVtoRGBEffect, GrColorSpaceXformEffect, LazyProxyTest::ClipFP, and BlockInputFragmentProcessor.

◆ cloneAndRegisterAllChildProcessors()

void GrFragmentProcessor::cloneAndRegisterAllChildProcessors ( const GrFragmentProcessor src)
protected

This method takes an existing fragment processor, clones all of its children, and registers the clones as children of this fragment processor.

Definition at line 183 of file GrFragmentProcessor.cpp.

183 {
184 for (int i = 0; i < src.numChildProcessors(); ++i) {
185 if (auto fp = src.childProcessor(i)) {
186 this->registerChild(fp->clone(), fp->sampleUsage());
187 } else {
188 this->registerChild(nullptr);
189 }
190 }
191}
void registerChild(std::unique_ptr< GrFragmentProcessor > child, SkSL::SampleUsage sampleUsage=SkSL::SampleUsage::PassThrough())
const uint32_t fp

◆ ColorMatrix()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::ColorMatrix ( std::unique_ptr< GrFragmentProcessor child,
const float  matrix[20],
bool  unpremulInput,
bool  clampRGBOutput,
bool  premulOutput 
)
static

Definition at line 456 of file GrFragmentProcessor.cpp.

461 {
463 "uniform half4x4 m;"
464 "uniform half4 v;"
465 "uniform int unpremulInput;" // always specialized
466 "uniform int clampRGBOutput;" // always specialized
467 "uniform int premulOutput;" // always specialized
468 "half4 main(half4 color) {"
469 "if (bool(unpremulInput)) {"
470 "color = unpremul(color);"
471 "}"
472 "color = m * color + v;"
473 "if (bool(clampRGBOutput)) {"
474 "color = saturate(color);"
475 "} else {"
476 "color.a = saturate(color.a);"
477 "}"
478 "if (bool(premulOutput)) {"
479 "color.rgb *= color.a;"
480 "}"
481 "return color;"
482 "}"
483 );
485
486 SkM44 m44(matrix[ 0], matrix[ 1], matrix[ 2], matrix[ 3],
487 matrix[ 5], matrix[ 6], matrix[ 7], matrix[ 8],
488 matrix[10], matrix[11], matrix[12], matrix[13],
489 matrix[15], matrix[16], matrix[17], matrix[18]);
490 SkV4 v4 = {matrix[4], matrix[9], matrix[14], matrix[19]};
491 return GrSkSLFP::Make(effect, "ColorMatrix", std::move(child), GrSkSLFP::OptFlags::kNone,
492 "m", m44,
493 "v", v4,
494 "unpremulInput", GrSkSLFP::Specialize(unpremulInput ? 1 : 0),
495 "clampRGBOutput", GrSkSLFP::Specialize(clampRGBOutput ? 1 : 0),
496 "premulOutput", GrSkSLFP::Specialize(premulOutput ? 1 : 0));
497}
static SkV4 v4(SkV3 v, SkScalar w)
Definition SkM44.cpp:329
Definition SkM44.h:150
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258

◆ compatibleWithCoverageAsAlpha()

bool GrFragmentProcessor::compatibleWithCoverageAsAlpha ( ) const
inline

A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color output under the following scenario:

  • all the color fragment processors report true to this query,
  • all the coverage fragment processors report true to this query,
  • the blend mode arithmetic allows for it it. To be compatible a fragment processor's output must be a modulation of its input color or alpha with a computed premultiplied color or alpha that is in 0..1 range. The computed color or alpha that is modulated against the input cannot depend on the input's alpha. The computed value cannot depend on the input's color channels unless it unpremultiplies the input color channels by the input alpha.

Definition at line 250 of file GrFragmentProcessor.h.

250 {
252 }
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35

◆ Compose()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::Compose ( std::unique_ptr< GrFragmentProcessor f,
std::unique_ptr< GrFragmentProcessor g 
)
static

Returns a fragment processor that composes two fragment processors f and g into f(g(x)). This is equivalent to running them in series (g, then f). This is not the same as transfer-mode composition; there is no blending step.

Definition at line 366 of file GrFragmentProcessor.cpp.

367 {
368 class ComposeProcessor : public GrFragmentProcessor {
369 public:
370 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> f,
371 std::unique_ptr<GrFragmentProcessor> g) {
372 return std::unique_ptr<GrFragmentProcessor>(new ComposeProcessor(std::move(f),
373 std::move(g)));
374 }
375
376 const char* name() const override { return "Compose"; }
377
378 std::unique_ptr<GrFragmentProcessor> clone() const override {
379 return std::unique_ptr<GrFragmentProcessor>(new ComposeProcessor(*this));
380 }
381
382 private:
383 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
384 class Impl : public ProgramImpl {
385 public:
386 void emitCode(EmitArgs& args) override {
387 SkString result = this->invokeChild(1, args); // g(x)
388 result = this->invokeChild(0, result.c_str(), args); // f(g(x))
389 args.fFragBuilder->codeAppendf("return %s;", result.c_str());
390 }
391 };
392 return std::make_unique<Impl>();
393 }
394
395 ComposeProcessor(std::unique_ptr<GrFragmentProcessor> f,
396 std::unique_ptr<GrFragmentProcessor> g)
397 : INHERITED(kSeriesFragmentProcessor_ClassID,
398 f->optimizationFlags() & g->optimizationFlags()) {
399 this->registerChild(std::move(f));
400 this->registerChild(std::move(g));
401 }
402
403 ComposeProcessor(const ComposeProcessor& that) : INHERITED(that) {}
404
405 void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override {}
406
407 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
408
409 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
410 SkPMColor4f color = inColor;
411 color = ConstantOutputForConstantInput(this->childProcessor(1), color);
412 color = ConstantOutputForConstantInput(this->childProcessor(0), color);
413 return color;
414 }
415
417 };
418
419 // Allow either of the composed functions to be null.
420 if (f == nullptr) {
421 return g;
422 }
423 if (g == nullptr) {
424 return f;
425 }
426
427 // Run an optimization pass on this composition.
428 GrProcessorAnalysisColor inputColor;
429 inputColor.setToUnknown();
430
431 std::unique_ptr<GrFragmentProcessor> series[2] = {std::move(g), std::move(f)};
432 GrColorFragmentProcessorAnalysis info(inputColor, series, std::size(series));
433
434 SkPMColor4f knownColor;
435 int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
436 switch (leadingFPsToEliminate) {
437 default:
438 // We shouldn't eliminate more than we started with.
439 SkASSERT(leadingFPsToEliminate <= 2);
440 [[fallthrough]];
441 case 0:
442 // Compose the two processors as requested.
443 return ComposeProcessor::Make(/*f=*/std::move(series[1]), /*g=*/std::move(series[0]));
444 case 1:
445 // Replace the first processor with a constant color.
446 return ComposeProcessor::Make(/*f=*/std::move(series[1]),
447 /*g=*/MakeColor(knownColor));
448 case 2:
449 // Replace the entire composition with a constant color.
450 return MakeColor(knownColor);
451 }
452}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
SkColor4f color
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
#define INHERITED(method,...)
static std::unique_ptr< GrFragmentProcessor > MakeColor(SkPMColor4f color)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
const char * name
Definition fuchsia.cc:50

◆ ConstantOutputForConstantInput()

static SkPMColor4f GrFragmentProcessor::ConstantOutputForConstantInput ( const GrFragmentProcessor fp,
const SkPMColor4f input 
)
inlinestaticprotected

This allows one subclass to access another subclass's implementation of constantOutputForConstantInput. It must only be called when hasConstantOutputForConstantInput() is known to be true.

Definition at line 370 of file GrFragmentProcessor.h.

371 {
372 if (fp) {
373 SkASSERT(fp->hasConstantOutputForConstantInput());
374 return fp->constantOutputForConstantInput(input);
375 } else {
376 return input;
377 }
378 }

◆ constantOutputForConstantInput()

virtual SkPMColor4f GrFragmentProcessor::constantOutputForConstantInput ( const SkPMColor4f ) const
inlineprivatevirtual

Reimplemented in GrBicubicEffect, GrSkSLFP, BlendFragmentProcessor, GrColorSpaceXformEffect, and GrMatrixEffect.

Definition at line 424 of file GrFragmentProcessor.h.

424 {
425 SK_ABORT("Subclass must override this if advertising this optimization.");
426 }
#define SK_ABORT(message,...)
Definition SkAssert.h:70

◆ DestColor()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::DestColor ( )
static

Returns a fragment processor which returns args.fDestColor. This is only meaningful in contexts like blenders, which use a source and dest color.)

Definition at line 355 of file GrFragmentProcessor.cpp.

355 {
357 "half4 main(half4 src, half4 dst) {"
358 "return dst;"
359 "}"
360 );
361 return GrSkSLFP::Make(effect, "DestColor", /*inputFP=*/nullptr, GrSkSLFP::OptFlags::kNone);
362}
static Result MakeForBlender(SkString sksl, const Options &)

◆ DeviceSpace()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::DeviceSpace ( std::unique_ptr< GrFragmentProcessor fp)
static

Returns a fragment processor that calls the passed in fragment processor, but evaluates it in device-space (rather than local space).

Definition at line 541 of file GrFragmentProcessor.cpp.

542 {
543 if (!fp) {
544 return nullptr;
545 }
546
548 public:
549 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
550 return std::unique_ptr<GrFragmentProcessor>(new DeviceSpace(std::move(fp)));
551 }
552
553 private:
554 DeviceSpace(std::unique_ptr<GrFragmentProcessor> fp)
556 // Passing FragCoord here is the reason this is a subclass and not a runtime-FP.
557 this->registerChild(std::move(fp), SkSL::SampleUsage::FragCoord());
558 }
559
560 std::unique_ptr<GrFragmentProcessor> clone() const override {
561 auto child = this->childProcessor(0)->clone();
562 return std::unique_ptr<GrFragmentProcessor>(new DeviceSpace(std::move(child)));
563 }
564
567 }
568
569 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
570 class Impl : public ProgramImpl {
571 public:
572 Impl() = default;
573 void emitCode(ProgramImpl::EmitArgs& args) override {
574 auto child = this->invokeChild(0, args.fInputColor, args, "sk_FragCoord.xy");
575 args.fFragBuilder->codeAppendf("return %s;", child.c_str());
576 }
577 };
578 return std::make_unique<Impl>();
579 }
580
581 void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override {}
582
583 bool onIsEqual(const GrFragmentProcessor& processor) const override { return true; }
584
585 const char* name() const override { return "DeviceSpace"; }
586 };
587
588 return DeviceSpace::Make(std::move(fp));
589}
virtual SkPMColor4f constantOutputForConstantInput(const SkPMColor4f &) const
virtual std::unique_ptr< GrFragmentProcessor > clone() const =0
static std::unique_ptr< GrFragmentProcessor > DeviceSpace(std::unique_ptr< GrFragmentProcessor >)
GrFragmentProcessor * childProcessor(int index)
virtual bool onIsEqual(const GrFragmentProcessor &) const =0
virtual std::unique_ptr< ProgramImpl > onMakeProgramImpl() const =0
virtual const char * name() const =0
@ kDeviceSpace_ClassID
Definition GrProcessor.h:41
static SampleUsage FragCoord()

◆ DisableCoverageAsAlpha()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::DisableCoverageAsAlpha ( std::unique_ptr< GrFragmentProcessor fp)
static

Returns a parent fragment processor that adopts the passed fragment processor as a child. The parent will simply return the child's color, but disable the coverage-as-alpha optimization.

Definition at line 340 of file GrFragmentProcessor.cpp.

341 {
342 if (!fp || !fp->compatibleWithCoverageAsAlpha()) {
343 return fp;
344 }
346 "half4 main(half4 inColor) { return inColor; }"
347 );
349 return GrSkSLFP::Make(effect, "DisableCoverageAsAlpha", std::move(fp),
351}

◆ Ellipse()

GrFPResult GrFragmentProcessor::Ellipse ( std::unique_ptr< GrFragmentProcessor inputFP,
GrClipEdgeType  edgeType,
SkPoint  center,
SkPoint  radii,
const GrShaderCaps caps 
)
static

Definition at line 698 of file GrFragmentProcessor.cpp.

702 {
703 const bool medPrecision = !caps.fFloatIs32Bits;
704
705 // Small radii produce bad results on devices without full float.
706 if (medPrecision && (radii.fX < 0.5f || radii.fY < 0.5f)) {
707 return GrFPFailure(std::move(inputFP));
708 }
709 // Very narrow ellipses produce bad results on devices without full float
710 if (medPrecision && (radii.fX > 255*radii.fY || radii.fY > 255*radii.fX)) {
711 return GrFPFailure(std::move(inputFP));
712 }
713 // Very large ellipses produce bad results on devices without full float
714 if (medPrecision && (radii.fX > 16384 || radii.fY > 16384)) {
715 return GrFPFailure(std::move(inputFP));
716 }
717
720 "uniform int edgeType;" // GrClipEdgeType, specialized
721 "uniform int medPrecision;" // !sk_Caps.floatIs32Bits, specialized
722
723 "uniform float4 ellipse;"
724 "uniform float2 scale;" // only for medPrecision
725
726 "half4 main(float2 xy) {"
727 // d is the offset to the ellipse center
728 "float2 d = sk_FragCoord.xy - ellipse.xy;"
729 // If we're on a device with a "real" mediump then we'll do the distance computation in
730 // a space that is normalized by the larger radius or 128, whichever is smaller. The
731 // scale uniform will be scale, 1/scale. The inverse squared radii uniform values are
732 // already in this normalized space. The center is not.
733 "if (bool(medPrecision)) {"
734 "d *= scale.y;"
735 "}"
736 "float2 Z = d * ellipse.zw;"
737 // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
738 "float implicit = dot(Z, d) - 1;"
739 // grad_dot is the squared length of the gradient of the implicit.
740 "float grad_dot = 4 * dot(Z, Z);"
741 // Avoid calling inversesqrt on zero.
742 "if (bool(medPrecision)) {"
743 "grad_dot = max(grad_dot, 6.1036e-5);"
744 "} else {"
745 "grad_dot = max(grad_dot, 1.1755e-38);"
746 "}"
747 "float approx_dist = implicit * inversesqrt(grad_dot);"
748 "if (bool(medPrecision)) {"
749 "approx_dist *= scale.x;"
750 "}"
751
752 "half alpha;"
753 "if (edgeType == kFillBW) {"
754 "alpha = approx_dist > 0.0 ? 0.0 : 1.0;"
755 "} else if (edgeType == kFillAA) {"
756 "alpha = saturate(0.5 - half(approx_dist));"
757 "} else if (edgeType == kInverseFillBW) {"
758 "alpha = approx_dist > 0.0 ? 1.0 : 0.0;"
759 "} else {" // edgeType == kInverseFillAA
760 "alpha = saturate(0.5 + half(approx_dist));"
761 "}"
762 "return half4(alpha);"
763 "}"
764 );
765
766 float invRXSqd;
767 float invRYSqd;
768 SkV2 scale = {1, 1};
769 // If we're using a scale factor to work around precision issues, choose the larger radius as
770 // the scale factor. The inv radii need to be pre-adjusted by the scale factor.
771 if (medPrecision) {
772 if (radii.fX > radii.fY) {
773 invRXSqd = 1.f;
774 invRYSqd = (radii.fX * radii.fX) / (radii.fY * radii.fY);
775 scale = {radii.fX, 1.f / radii.fX};
776 } else {
777 invRXSqd = (radii.fY * radii.fY) / (radii.fX * radii.fX);
778 invRYSqd = 1.f;
779 scale = {radii.fY, 1.f / radii.fY};
780 }
781 } else {
782 invRXSqd = 1.f / (radii.fX * radii.fX);
783 invRYSqd = 1.f / (radii.fY * radii.fY);
784 }
785 SkV4 ellipse = {center.fX, center.fY, invRXSqd, invRYSqd};
786
787 auto ellipseFP = GrSkSLFP::Make(effect, "Ellipse", /*inputFP=*/nullptr,
789 "edgeType", GrSkSLFP::Specialize(static_cast<int>(edgeType)),
790 "medPrecision", GrSkSLFP::Specialize<int>(medPrecision),
791 "ellipse", ellipse,
792 "scale", scale);
793 return GrFPSuccess(GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(ellipseFP),
794 std::move(inputFP)));
795}
const Scalar scale
float fX
x-axis value
float fY
y-axis value
Definition SkM44.h:19

◆ hasConstantOutputForConstantInput() [1/2]

bool GrFragmentProcessor::hasConstantOutputForConstantInput ( ) const
inline

Definition at line 273 of file GrFragmentProcessor.h.

◆ hasConstantOutputForConstantInput() [2/2]

bool GrFragmentProcessor::hasConstantOutputForConstantInput ( SkPMColor4f  inputColor,
SkPMColor4f outputColor 
) const
inline

Tests whether given a constant input color the processor produces a constant output color (for all fragments). If true outputColor will contain the constant color produces for inputColor.

Definition at line 266 of file GrFragmentProcessor.h.

266 {
268 *outputColor = this->constantOutputForConstantInput(inputColor);
269 return true;
270 }
271 return false;
272 }

◆ HighPrecision()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::HighPrecision ( std::unique_ptr< GrFragmentProcessor fp)
static

Returns a fragment processor that calls the passed in fragment processor, but ensures the entire program is compiled with high-precision types.

Definition at line 799 of file GrFragmentProcessor.cpp.

800 {
801 class HighPrecisionFragmentProcessor : public GrFragmentProcessor {
802 public:
803 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
804 return std::unique_ptr<GrFragmentProcessor>(
805 new HighPrecisionFragmentProcessor(std::move(fp)));
806 }
807
808 const char* name() const override { return "HighPrecision"; }
809
810 std::unique_ptr<GrFragmentProcessor> clone() const override {
811 return Make(this->childProcessor(0)->clone());
812 }
813
814 private:
815 HighPrecisionFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp)
816 : INHERITED(kHighPrecisionFragmentProcessor_ClassID,
817 ProcessorOptimizationFlags(fp.get())) {
818 this->registerChild(std::move(fp));
819 }
820
821 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
822 class Impl : public ProgramImpl {
823 public:
824 void emitCode(EmitArgs& args) override {
825 SkString childColor = this->invokeChild(0, args);
826
827 args.fFragBuilder->forceHighPrecision();
828 args.fFragBuilder->codeAppendf("return %s;", childColor.c_str());
829 }
830 };
831 return std::make_unique<Impl>();
832 }
833
834 void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override {}
835 bool onIsEqual(const GrFragmentProcessor& other) const override { return true; }
836
837 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
838 return ConstantOutputForConstantInput(this->childProcessor(0), input);
839 }
840
842 };
843
844 return HighPrecisionFragmentProcessor::Make(std::move(fp));
845}
const char * c_str() const
Definition SkString.h:133
const myers::Point & get(const myers::Segment &)

◆ isBlendFunction()

bool GrFragmentProcessor::isBlendFunction ( ) const
inline

Does the SkSL for this FP take two colors as its input arguments?

Definition at line 209 of file GrFragmentProcessor.h.

209 {
210 return SkToBool(fFlags & kIsBlendFunction_Flag);
211 }

◆ isEqual()

bool GrFragmentProcessor::isEqual ( const GrFragmentProcessor that) const

Returns true if this and other processor conservatively draw identically. It can only return true when the two processor are of the same subclass (i.e. they return the same object from from getFactory()).

A return value of true from isEqual() should not be used to test whether the processor would generate the same shader code. To test for identical code generation use addToKey.

Definition at line 25 of file GrFragmentProcessor.cpp.

25 {
26 if (this->classID() != that.classID()) {
27 return false;
28 }
29 if (this->sampleUsage() != that.sampleUsage()) {
30 return false;
31 }
32 if (!this->onIsEqual(that)) {
33 return false;
34 }
35 if (this->numChildProcessors() != that.numChildProcessors()) {
36 return false;
37 }
38 for (int i = 0; i < this->numChildProcessors(); ++i) {
39 auto thisChild = this->childProcessor(i),
40 thatChild = that .childProcessor(i);
41 if (SkToBool(thisChild) != SkToBool(thatChild)) {
42 return false;
43 }
44 if (thisChild && !thisChild->isEqual(*thatChild)) {
45 return false;
46 }
47 }
48 return true;
49}
const SkSL::SampleUsage & sampleUsage() const

◆ MakeColor()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::MakeColor ( SkPMColor4f  color)
static

Always returns 'color'.

Definition at line 193 of file GrFragmentProcessor.cpp.

193 {
194 // Use ColorFilter signature/factory to get the constant output for constant input optimization
196 "uniform half4 color;"
197 "half4 main(half4 inColor) { return color; }"
198 );
200 return GrSkSLFP::Make(effect, "color_fp", /*inputFP=*/nullptr,
202 : GrSkSLFP::OptFlags::kNone,
203 "color", color);
204}

◆ makeProgramImpl()

std::unique_ptr< GrFragmentProcessor::ProgramImpl > GrFragmentProcessor::makeProgramImpl ( ) const

Definition at line 119 of file GrFragmentProcessor.cpp.

119 {
120 std::unique_ptr<ProgramImpl> impl = this->onMakeProgramImpl();
121 impl->fChildProcessors.push_back_n(fChildProcessors.size());
122 for (int i = 0; i < fChildProcessors.size(); ++i) {
123 impl->fChildProcessors[i] = fChildProcessors[i] ? fChildProcessors[i]->makeProgramImpl()
124 : nullptr;
125 }
126 return impl;
127}
int size() const
Definition SkTArray.h:416

◆ mergeOptimizationFlags()

void GrFragmentProcessor::mergeOptimizationFlags ( OptimizationFlags  flags)
inlineprotected

Definition at line 418 of file GrFragmentProcessor.h.

418 {
420 fFlags &= (flags | ~kAll_OptimizationFlags);
421 }
FlutterSemanticsFlag flags

◆ ModulateForClampedSamplerOptFlags()

static OptimizationFlags GrFragmentProcessor::ModulateForClampedSamplerOptFlags ( SkAlphaType  alphaType)
inlinestaticprotected

Definition at line 337 of file GrFragmentProcessor.h.

337 {
338 if (alphaType == kOpaque_SkAlphaType) {
341 } else {
343 }
344 }
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28

◆ ModulateForSamplerOptFlags()

static OptimizationFlags GrFragmentProcessor::ModulateForSamplerOptFlags ( SkAlphaType  alphaType,
bool  samplingDecal 
)
inlinestaticprotected

Can be used as a helper to decide which fragment processor OptimizationFlags should be set. This assumes that the subclass output color will be a modulation of the input color with a value read from a texture of the passed color type and that the texture contains premultiplied color or alpha values that are in range.

Since there are multiple ways in which a sampler may have its coordinates clamped or wrapped, callers must determine on their own if the sampling uses a decal strategy in any way, in which case the texture may become transparent regardless of the color type.

Definition at line 328 of file GrFragmentProcessor.h.

328 {
329 if (samplingDecal) {
331 } else {
332 return ModulateForClampedSamplerOptFlags(alphaType);
333 }
334 }
static OptimizationFlags ModulateForClampedSamplerOptFlags(SkAlphaType alphaType)

◆ ModulateRGBA()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::ModulateRGBA ( std::unique_ptr< GrFragmentProcessor child,
const SkPMColor4f color 
)
static

Returns a fragment processor that generates the passed-in color, modulated by the child's RGBA color. The child's input color will be the parent's fInputColor. (Pass a null FP to use the color from fInputColor instead of a child FP.)

Definition at line 229 of file GrFragmentProcessor.cpp.

230 {
231 auto colorFP = MakeColor(color);
232 return GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(colorFP),
233 std::move(inputFP));
234}

◆ MulInputByChildAlpha()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::MulInputByChildAlpha ( std::unique_ptr< GrFragmentProcessor child)
static

Returns the input color, modulated by the child's alpha.

output = input * child.a

Definition at line 206 of file GrFragmentProcessor.cpp.

207 {
208 if (!fp) {
209 return nullptr;
210 }
211 return GrBlendFragmentProcessor::Make<SkBlendMode::kSrcIn>(/*src=*/nullptr, std::move(fp));
212}

◆ numChildProcessors()

int GrFragmentProcessor::numChildProcessors ( ) const
inline

Definition at line 193 of file GrFragmentProcessor.h.

193{ return fChildProcessors.size(); }

◆ numNonNullChildProcessors()

int GrFragmentProcessor::numNonNullChildProcessors ( ) const

Definition at line 129 of file GrFragmentProcessor.cpp.

129 {
130 return std::count_if(fChildProcessors.begin(), fChildProcessors.end(),
131 [](const auto& c) { return c != nullptr; });
132}

◆ onAddToKey()

virtual void GrFragmentProcessor::onAddToKey ( const GrShaderCaps ,
skgpu::KeyBuilder  
) const
privatepure virtual

◆ onIsEqual()

virtual bool GrFragmentProcessor::onIsEqual ( const GrFragmentProcessor ) const
privatepure virtual

Subclass implements this to support isEqual(). It will only be called if it is known that the two processors are of the same subclass (i.e. have the same ClassID).

Implemented in SampleCoordEffect, GrBicubicEffect, ColorTableEffect, GrMatrixEffect, GrSkSLFP, GrTextureEffect, GrYUVtoRGBEffect, GrColorSpaceXformEffect, LazyProxyTest::ClipFP, BlockInputFragmentProcessor, BlendFragmentProcessor, GrConvexPolyEffect, GrPerlinNoise2Effect, and GrModulateAtlasCoverageEffect.

◆ onMakeProgramImpl()

virtual std::unique_ptr< ProgramImpl > GrFragmentProcessor::onMakeProgramImpl ( ) const
privatepure virtual

Returns a new instance of the appropriate ProgramImpl subclass for the given GrFragmentProcessor. It will emit the appropriate code and live with the cached program to setup uniform data for each draw that uses the program.

Implemented in SampleCoordEffect, GrBicubicEffect, BlendFragmentProcessor, ColorTableEffect, GrConvexPolyEffect, GrMatrixEffect, GrModulateAtlasCoverageEffect, GrPerlinNoise2Effect, GrSkSLFP, GrTextureEffect, GrYUVtoRGBEffect, GrColorSpaceXformEffect, LazyProxyTest::ClipFP, and BlockInputFragmentProcessor.

◆ optimizationFlags()

OptimizationFlags GrFragmentProcessor::optimizationFlags ( ) const
inlineprotected

Definition at line 356 of file GrFragmentProcessor.h.

356 {
357 return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
358 }

◆ OverrideInput()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::OverrideInput ( std::unique_ptr< GrFragmentProcessor fp,
const SkPMColor4f color 
)
static

Returns a parent fragment processor that adopts the passed fragment processor as a child. The parent will ignore its input color and instead feed the passed in color as input to the child.

Definition at line 319 of file GrFragmentProcessor.cpp.

320 {
321 if (!fp) {
322 return nullptr;
323 }
325 "uniform colorFilter fp;" // Declared as colorFilter so we can pass a color
326 "uniform half4 color;"
327 "half4 main(half4 inColor) {"
328 "return fp.eval(color);"
329 "}"
330 );
331 return GrSkSLFP::Make(effect, "OverrideInput", /*inputFP=*/nullptr,
333 : GrSkSLFP::OptFlags::kNone,
334 "fp", std::move(fp),
335 "color", color);
336}
Definition ref_ptr.h:256

◆ parent()

const GrFragmentProcessor * GrFragmentProcessor::parent ( ) const
inline

Definition at line 180 of file GrFragmentProcessor.h.

180{ return fParent; }

◆ preservesOpaqueInput()

bool GrFragmentProcessor::preservesOpaqueInput ( ) const
inline

If this is true then all opaque input colors to the processor produce opaque output colors.

Definition at line 257 of file GrFragmentProcessor.h.

257 {
259 }

◆ ProcessorOptimizationFlags()

static OptimizationFlags GrFragmentProcessor::ProcessorOptimizationFlags ( const GrFragmentProcessor fp)
inlinestaticprotected

Useful when you can't call fp->optimizationFlags() on a base class object from a subclass.

Definition at line 361 of file GrFragmentProcessor.h.

361 {
362 return fp ? fp->optimizationFlags() : kAll_OptimizationFlags;
363 }

◆ Rect()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::Rect ( std::unique_ptr< GrFragmentProcessor inputFP,
GrClipEdgeType  edgeType,
SkRect  rect 
)
static

"Shape" FPs, often used for clipping. Each one evaluates a particular kind of shape (rect, circle, ellipse), and modulates the coverage of that shape against the results of the input FP. GrClipEdgeType is used to select inverse/normal fill, and AA or non-AA edges.

Definition at line 604 of file GrFragmentProcessor.cpp.

605 {
608 "uniform int edgeType;" // GrClipEdgeType, specialized
609 "uniform float4 rectUniform;"
610
611 "half4 main(float2 xy) {"
612 "half coverage;"
613 "if (edgeType == kFillBW || edgeType == kInverseFillBW) {"
614 // non-AA
615 "coverage = half(all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw),"
616 "float4(rectUniform.xy, sk_FragCoord.xy))));"
617 "} else {"
618 // compute coverage relative to left and right edges, add, then subtract 1 to
619 // account for double counting. And similar for top/bottom.
620 "half4 dists4 = saturate(half4(1, 1, -1, -1) *"
621 "half4(sk_FragCoord.xyxy - rectUniform));"
622 "half2 dists2 = dists4.xy + dists4.zw - 1;"
623 "coverage = dists2.x * dists2.y;"
624 "}"
625
626 "if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {"
627 "coverage = 1.0 - coverage;"
628 "}"
629
630 "return half4(coverage);"
631 "}"
632 );
633
634 SkASSERT(rect.isSorted());
635 // The AA math in the shader evaluates to 0 at the uploaded coordinates, so outset by 0.5
636 // to interpolate from 0 at a half pixel inset and 1 at a half pixel outset of rect.
637 SkRect rectUniform = GrClipEdgeTypeIsAA(edgeType) ? rect.makeOutset(.5f, .5f) : rect;
638
639 auto rectFP = GrSkSLFP::Make(effect, "Rect", /*inputFP=*/nullptr,
641 "edgeType", GrSkSLFP::Specialize(static_cast<int>(edgeType)),
642 "rectUniform", rectUniform);
643 return GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(rectFP),
644 std::move(inputFP));
645}
static constexpr bool GrClipEdgeTypeIsAA(const GrClipEdgeType edgeType)
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350

◆ registerChild()

void GrFragmentProcessor::registerChild ( std::unique_ptr< GrFragmentProcessor child,
SkSL::SampleUsage  sampleUsage = SkSL::SampleUsage::PassThrough() 
)
protected

FragmentProcessor subclasses call this from their constructor to register any child FragmentProcessors they have. This must be called AFTER all texture accesses and coord transforms have been added. This is for processors whose shader code will be composed of nested processors whose output colors will be combined somehow to produce its output color. Registering these child processors will allow the ProgramBuilder to automatically handle their transformed coords and texture accesses and mangle their uniform and output color names.

The SampleUsage parameter describes all of the ways that the child is sampled by the parent.

Definition at line 146 of file GrFragmentProcessor.cpp.

147 {
149
150 if (!child) {
151 fChildProcessors.push_back(nullptr);
152 return;
153 }
154
155 // The child should not have been attached to another FP already and not had any sampling
156 // strategy set on it.
157 SkASSERT(!child->fParent && !child->sampleUsage().isSampled());
158
159 // Configure child's sampling state first
160 child->fUsage = sampleUsage;
161
162 // Propagate the "will read dest-color" flag up to parent FPs.
163 if (child->willReadDstColor()) {
164 this->setWillReadDstColor();
165 }
166
167 // If this child receives passthrough or matrix transformed coords from its parent then note
168 // that the parent's coords are used indirectly to ensure that they aren't omitted.
169 if ((sampleUsage.isPassThrough() || sampleUsage.isUniformMatrix()) &&
170 child->usesSampleCoords()) {
171 fFlags |= kUsesSampleCoordsIndirectly_Flag;
172 }
173
174 // Record that the child is attached to us; this FP is the source of any uniform data needed
175 // to evaluate the child sample matrix.
176 child->fParent = this;
177 fChildProcessors.push_back(std::move(child));
178
179 // Validate: our sample strategy comes from a parent we shouldn't have yet.
180 SkASSERT(!fUsage.isSampled() && !fParent);
181}
bool isPassThrough() const
bool isSampled() const
bool isUniformMatrix() const

◆ sampleUsage()

const SkSL::SampleUsage & GrFragmentProcessor::sampleUsage ( ) const
inline

Definition at line 234 of file GrFragmentProcessor.h.

234 {
235 return fUsage;
236 }

◆ setIsBlendFunction()

void GrFragmentProcessor::setIsBlendFunction ( )
inlineprotected

Definition at line 414 of file GrFragmentProcessor.h.

414 {
415 fFlags |= kIsBlendFunction_Flag;
416 }

◆ setUsesSampleCoordsDirectly()

void GrFragmentProcessor::setUsesSampleCoordsDirectly ( )
inlineprotected

Definition at line 402 of file GrFragmentProcessor.h.

402 {
403 fFlags |= kUsesSampleCoordsDirectly_Flag;
404 }

◆ setWillReadDstColor()

void GrFragmentProcessor::setWillReadDstColor ( )
inlineprotected

Definition at line 408 of file GrFragmentProcessor.h.

408 {
409 fFlags |= kWillReadDstColor_Flag;
410 }

◆ SkDEBUGCODE()

GrFragmentProcessor::SkDEBUGCODE ( bool isInstantiated() const ;  ) const
inline

Do any of the FPs in this tree read back the color from the destination surface?

Definition at line 201 of file GrFragmentProcessor.h.

204 {
205 return SkToBool(fFlags & kWillReadDstColor_Flag);
206 }

◆ SurfaceColor()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::SurfaceColor ( )
static

Returns a fragment processor that reads back the color on the surface being painted; that is, sampling this will return the color of the pixel that is currently being painted over.

Definition at line 501 of file GrFragmentProcessor.cpp.

501 {
502 class SurfaceColorProcessor : public GrFragmentProcessor {
503 public:
504 static std::unique_ptr<GrFragmentProcessor> Make() {
505 return std::unique_ptr<GrFragmentProcessor>(new SurfaceColorProcessor());
506 }
507
508 std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(); }
509
510 const char* name() const override { return "SurfaceColor"; }
511
512 private:
513 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
514 class Impl : public ProgramImpl {
515 public:
516 void emitCode(EmitArgs& args) override {
517 const char* dstColor = args.fFragBuilder->dstColor();
518 args.fFragBuilder->codeAppendf("return %s;", dstColor);
519 }
520 };
521 return std::make_unique<Impl>();
522 }
523
524 SurfaceColorProcessor()
525 : INHERITED(kSurfaceColorProcessor_ClassID, kNone_OptimizationFlags) {
526 this->setWillReadDstColor();
527 }
528
529 void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override {}
530
531 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
532
534 };
535
536 return SurfaceColorProcessor::Make();
537}

◆ SwizzleOutput()

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessor::SwizzleOutput ( std::unique_ptr< GrFragmentProcessor fp,
const skgpu::Swizzle swizzle 
)
static

Returns a fragment processor that calls the passed in fragment processor, and then swizzles the output.

Definition at line 249 of file GrFragmentProcessor.cpp.

250 {
251 class SwizzleFragmentProcessor : public GrFragmentProcessor {
252 public:
253 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
254 const skgpu::Swizzle& swizzle) {
255 return std::unique_ptr<GrFragmentProcessor>(
256 new SwizzleFragmentProcessor(std::move(fp), swizzle));
257 }
258
259 const char* name() const override { return "Swizzle"; }
260
261 std::unique_ptr<GrFragmentProcessor> clone() const override {
262 return Make(this->childProcessor(0)->clone(), fSwizzle);
263 }
264
265 private:
266 SwizzleFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp,
267 const skgpu::Swizzle& swizzle)
268 : INHERITED(kSwizzleFragmentProcessor_ClassID, ProcessorOptimizationFlags(fp.get()))
269 , fSwizzle(swizzle) {
270 this->registerChild(std::move(fp));
271 }
272
273 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
274 class Impl : public ProgramImpl {
275 public:
276 void emitCode(EmitArgs& args) override {
277 SkString childColor = this->invokeChild(0, args);
278
279 const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
280 const skgpu::Swizzle& swizzle = sfp.fSwizzle;
281 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
282
283 fragBuilder->codeAppendf("return %s.%s;",
284 childColor.c_str(), swizzle.asString().c_str());
285 }
286 };
287 return std::make_unique<Impl>();
288 }
289
290 void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder* b) const override {
291 b->add32(fSwizzle.asKey());
292 }
293
294 bool onIsEqual(const GrFragmentProcessor& other) const override {
295 const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
296 return fSwizzle == sfp.fSwizzle;
297 }
298
299 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
300 return fSwizzle.applyTo(ConstantOutputForConstantInput(this->childProcessor(0), input));
301 }
302
303 skgpu::Swizzle fSwizzle;
304
306 };
307
308 if (!fp) {
309 return nullptr;
310 }
311 if (skgpu::Swizzle::RGBA() == swizzle) {
312 return fp;
313 }
314 return SwizzleFragmentProcessor::Make(std::move(fp), swizzle);
315}
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
const T & cast() const
static constexpr Swizzle RGBA()
Definition Swizzle.h:66

◆ usesSampleCoords()

bool GrFragmentProcessor::usesSampleCoords ( ) const
inline

True if this FP uses its input coordinates or if any descendant FP uses them through a chain of non-explicit sample usages. (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is decided at FP-tree construction time and is not affected by lifting coords to varyings.

Definition at line 227 of file GrFragmentProcessor.h.

227 {
228 return SkToBool(fFlags & (kUsesSampleCoordsDirectly_Flag |
229 kUsesSampleCoordsIndirectly_Flag));
230 }

◆ usesSampleCoordsDirectly()

bool GrFragmentProcessor::usesSampleCoordsDirectly ( ) const
inline

True if this FP refers directly to the sample coordinate parameter of its function (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is decided at FP-tree construction time and is not affected by lifting coords to varyings.

Definition at line 218 of file GrFragmentProcessor.h.

218 {
219 return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag);
220 }

◆ visitProxies()

void GrFragmentProcessor::visitProxies ( const GrVisitProxyFunc func) const

Definition at line 51 of file GrFragmentProcessor.cpp.

51 {
52 this->visitTextureEffects([&func](const GrTextureEffect& te) {
53 func(te.view().proxy(), te.samplerState().mipmapped());
54 });
55}
void visitTextureEffects(const std::function< void(const GrTextureEffect &)> &) const
constexpr skgpu::Mipmapped mipmapped() const
GrSurfaceProxy * proxy() const
const GrSurfaceProxyView & view() const
GrSamplerState samplerState() const

◆ visitTextureEffects()

void GrFragmentProcessor::visitTextureEffects ( const std::function< void(const GrTextureEffect &)> &  func) const

Definition at line 57 of file GrFragmentProcessor.cpp.

58 {
59 if (auto* te = this->asTextureEffect()) {
60 func(*te);
61 }
62 for (auto& child : fChildProcessors) {
63 if (child) {
64 child->visitTextureEffects(func);
65 }
66 }
67}
GrTextureEffect * asTextureEffect()

◆ visitWithImpls()

void GrFragmentProcessor::visitWithImpls ( const std::function< void(const GrFragmentProcessor &, ProgramImpl &)> &  f,
ProgramImpl impl 
) const

Definition at line 69 of file GrFragmentProcessor.cpp.

71 {
72 f(*this, impl);
73 SkASSERT(impl.numChildProcessors() == this->numChildProcessors());
74 for (int i = 0; i < this->numChildProcessors(); ++i) {
75 if (const auto* child = this->childProcessor(i)) {
76 child->visitWithImpls(f, *impl.childProcessor(i));
77 }
78 }
79}
ProgramImpl * childProcessor(int index) const

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