44 if (thisChild && !thisChild->isEqual(*thatChild)) {
62 for (
auto& child : fChildProcessors) {
64 child->visitTextureEffects(func);
95#if defined(GR_TEST_UTILS)
99 for (
int index = 0; index <
fp.numChildProcessors(); ++index) {
100 text->appendf(
"\n%s(#%d) -> ", indent.
c_str(), index);
102 text->append(childFP->dumpInfo());
104 recursive_dump_tree_info(*childFP, indent,
text);
106 text->append(
"null");
111SkString GrFragmentProcessor::dumpTreeInfo()
const {
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()
130 return std::count_if(fChildProcessors.
begin(), fChildProcessors.
end(),
131 [](
const auto& c) { return c != nullptr; });
135bool GrFragmentProcessor::isInstantiated()
const {
157 SkASSERT(!child->fParent && !child->sampleUsage().isSampled());
163 if (child->willReadDstColor()) {
170 child->usesSampleCoords()) {
171 fFlags |= kUsesSampleCoordsIndirectly_Flag;
176 child->fParent =
this;
177 fChildProcessors.
push_back(std::move(child));
184 for (
int i = 0;
i <
src.numChildProcessors(); ++
i) {
185 if (
auto fp =
src.childProcessor(
i)) {
196 "uniform half4 color;"
197 "half4 main(half4 inColor) { return color; }"
207 std::unique_ptr<GrFragmentProcessor>
fp) {
211 return GrBlendFragmentProcessor::Make<SkBlendMode::kSrcIn>(
nullptr, std::move(
fp));
215 std::unique_ptr<GrFragmentProcessor> child) {
218 "uniform colorFilter fp;"
219 "half4 main(half4 inColor) {"
220 "return fp.eval(inColor.rgb1) * inColor.a;"
226 "fp", std::move(child));
232 return GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(colorFP),
237 std::unique_ptr<GrFragmentProcessor>
fp) {
240 "half4 main(half4 inColor) {"
241 "return saturate(inColor);"
253 static std::unique_ptr<GrFragmentProcessor>
Make(std::unique_ptr<GrFragmentProcessor>
fp,
255 return std::unique_ptr<GrFragmentProcessor>(
256 new SwizzleFragmentProcessor(std::move(
fp), swizzle));
259 const char*
name()
const override {
return "Swizzle"; }
261 std::unique_ptr<GrFragmentProcessor>
clone()
const override {
266 SwizzleFragmentProcessor(std::unique_ptr<GrFragmentProcessor>
fp,
269 , fSwizzle(swizzle) {
276 void emitCode(EmitArgs&
args)
override {
279 const SwizzleFragmentProcessor& sfp =
args.fFp.cast<SwizzleFragmentProcessor>();
284 childColor.
c_str(), swizzle.asString().c_str());
287 return std::make_unique<Impl>();
291 b->add32(fSwizzle.asKey());
295 const SwizzleFragmentProcessor& sfp = other.
cast<SwizzleFragmentProcessor>();
296 return fSwizzle == sfp.fSwizzle;
325 "uniform colorFilter fp;"
326 "uniform half4 color;"
327 "half4 main(half4 inColor) {"
328 "return fp.eval(color);"
341 std::unique_ptr<GrFragmentProcessor>
fp) {
342 if (!
fp || !
fp->compatibleWithCoverageAsAlpha()) {
346 "half4 main(half4 inColor) { return inColor; }"
357 "half4 main(half4 src, half4 dst) {"
367 std::unique_ptr<GrFragmentProcessor>
f, std::unique_ptr<GrFragmentProcessor> g) {
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),
376 const char*
name()
const override {
return "Compose"; }
378 std::unique_ptr<GrFragmentProcessor>
clone()
const override {
379 return std::unique_ptr<GrFragmentProcessor>(
new ComposeProcessor(*
this));
386 void emitCode(EmitArgs&
args)
override {
389 args.fFragBuilder->codeAppendf(
"return %s;",
result.c_str());
392 return std::make_unique<Impl>();
395 ComposeProcessor(std::unique_ptr<GrFragmentProcessor>
f,
396 std::unique_ptr<GrFragmentProcessor> g)
398 f->optimizationFlags() & g->optimizationFlags()) {
403 ComposeProcessor(
const ComposeProcessor& that) :
INHERITED(that) {}
431 std::unique_ptr<GrFragmentProcessor> series[2] = {std::move(g), std::move(
f)};
435 int leadingFPsToEliminate =
info.initialProcessorsToEliminate(&knownColor);
436 switch (leadingFPsToEliminate) {
439 SkASSERT(leadingFPsToEliminate <= 2);
457 std::unique_ptr<GrFragmentProcessor> child,
465 "uniform int unpremulInput;"
466 "uniform int clampRGBOutput;"
467 "uniform int premulOutput;"
468 "half4 main(half4 color) {"
469 "if (bool(unpremulInput)) {"
470 "color = unpremul(color);"
472 "color = m * color + v;"
473 "if (bool(clampRGBOutput)) {"
474 "color = saturate(color);"
476 "color.a = saturate(color.a);"
478 "if (bool(premulOutput)) {"
479 "color.rgb *= color.a;"
504 static std::unique_ptr<GrFragmentProcessor>
Make() {
505 return std::unique_ptr<GrFragmentProcessor>(
new SurfaceColorProcessor());
508 std::unique_ptr<GrFragmentProcessor>
clone()
const override {
return Make(); }
510 const char*
name()
const override {
return "SurfaceColor"; }
516 void emitCode(EmitArgs&
args)
override {
517 const char* dstColor =
args.fFragBuilder->dstColor();
518 args.fFragBuilder->codeAppendf(
"return %s;", dstColor);
521 return std::make_unique<Impl>();
524 SurfaceColorProcessor()
542 std::unique_ptr<GrFragmentProcessor>
fp) {
549 static std::unique_ptr<GrFragmentProcessor>
Make(std::unique_ptr<GrFragmentProcessor>
fp) {
550 return std::unique_ptr<GrFragmentProcessor>(
new DeviceSpace(std::move(
fp)));
560 std::unique_ptr<GrFragmentProcessor>
clone()
const override {
562 return std::unique_ptr<GrFragmentProcessor>(
new DeviceSpace(std::move(child)));
574 auto child = this->invokeChild(0,
args.fInputColor,
args,
"sk_FragCoord.xy");
575 args.fFragBuilder->codeAppendf(
"return %s;", child.c_str());
578 return std::make_unique<Impl>();
585 const char*
name()
const override {
return "DeviceSpace"; }
593#define CLIP_EDGE_SKSL \
594 "const int kFillBW = 0;" \
595 "const int kFillAA = 1;" \
596 "const int kInverseFillBW = 2;" \
597 "const int kInverseFillAA = 3;"
608 "uniform int edgeType;"
609 "uniform float4 rectUniform;"
611 "half4 main(float2 xy) {"
613 "if (edgeType == kFillBW || edgeType == kInverseFillBW) {"
615 "coverage = half(all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw),"
616 "float4(rectUniform.xy, sk_FragCoord.xy))));"
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;"
626 "if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {"
627 "coverage = 1.0 - coverage;"
630 "return half4(coverage);"
642 "rectUniform", rectUniform);
643 return GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(rectFP),
659 "uniform int edgeType;"
662 "uniform float4 circle;"
664 "half4 main(float2 xy) {"
669 "if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {"
670 "d = half((length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z);"
672 "d = half((1.0 - length((circle.xy - sk_FragCoord.xy) * circle.w)) * circle.z);"
674 "return half4((edgeType == kFillAA || edgeType == kInverseFillAA)"
676 ": (d > 0.5 ? 1 : 0));"
682 effectiveRadius -= 0.5f;
684 effectiveRadius =
std::max(0.001f, effectiveRadius);
686 effectiveRadius += 0.5f;
694 return GrFPSuccess(GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(inputFP),
695 std::move(circleFP)));
706 if (medPrecision && (radii.
fX < 0.5f || radii.
fY < 0.5f)) {
710 if (medPrecision && (radii.
fX > 255*radii.
fY || radii.
fY > 255*radii.
fX)) {
714 if (medPrecision && (radii.
fX > 16384 || radii.
fY > 16384)) {
720 "uniform int edgeType;"
721 "uniform int medPrecision;"
723 "uniform float4 ellipse;"
724 "uniform float2 scale;"
726 "half4 main(float2 xy) {"
728 "float2 d = sk_FragCoord.xy - ellipse.xy;"
733 "if (bool(medPrecision)) {"
736 "float2 Z = d * ellipse.zw;"
738 "float implicit = dot(Z, d) - 1;"
740 "float grad_dot = 4 * dot(Z, Z);"
742 "if (bool(medPrecision)) {"
743 "grad_dot = max(grad_dot, 6.1036e-5);"
745 "grad_dot = max(grad_dot, 1.1755e-38);"
747 "float approx_dist = implicit * inversesqrt(grad_dot);"
748 "if (bool(medPrecision)) {"
749 "approx_dist *= scale.x;"
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;"
760 "alpha = saturate(0.5 + half(approx_dist));"
762 "return half4(alpha);"
772 if (radii.
fX > radii.
fY) {
774 invRYSqd = (radii.
fX * radii.
fX) / (radii.
fY * radii.
fY);
777 invRXSqd = (radii.
fY * radii.
fY) / (radii.
fX * radii.
fX);
782 invRXSqd = 1.f / (radii.
fX * radii.
fX);
783 invRYSqd = 1.f / (radii.
fY * radii.
fY);
790 "medPrecision", GrSkSLFP::Specialize<int>(medPrecision),
793 return GrFPSuccess(GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(ellipseFP),
794 std::move(inputFP)));
800 std::unique_ptr<GrFragmentProcessor>
fp) {
803 static std::unique_ptr<GrFragmentProcessor>
Make(std::unique_ptr<GrFragmentProcessor>
fp) {
804 return std::unique_ptr<GrFragmentProcessor>(
805 new HighPrecisionFragmentProcessor(std::move(
fp)));
808 const char*
name()
const override {
return "HighPrecision"; }
810 std::unique_ptr<GrFragmentProcessor>
clone()
const override {
815 HighPrecisionFragmentProcessor(std::unique_ptr<GrFragmentProcessor>
fp)
824 void emitCode(EmitArgs&
args)
override {
827 args.fFragBuilder->forceHighPrecision();
828 args.fFragBuilder->codeAppendf(
"return %s;", childColor.
c_str());
831 return std::make_unique<Impl>();
857 const char* inputColor,
858 const char* destColor,
860 std::string_view skslCoords) {
864 inputColor =
args.fInputColor;
878 destColor =
args.fFp.isBlendFunction() ?
args.fDestColor :
"half4(1)";
880 invocation.appendf(
", %s", destColor);
887 if (
args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
890 if (!skslCoords.empty()) {
891 invocation.appendf(
", %.*s", (
int)skslCoords.size(), skslCoords.data());
893 invocation.appendf(
", %s",
args.fSampleCoord);
897 invocation.append(
")");
902 const char* inputColor,
903 const char* destColor,
908 inputColor =
args.fInputColor;
930 destColor =
args.fFp.isBlendFunction() ?
args.fDestColor :
"half4(1)";
932 invocation.appendf(
", %s", destColor);
943 if (
args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
947 invocation.appendf(
", proj((%s) * %s.xy1)", matrixName.
c_str(),
args.fSampleCoord);
948 }
else if (
args.fShaderCaps->fNonsquareMatrixSupport) {
949 invocation.appendf(
", float3x2(%s) * %s.xy1", matrixName.
c_str(),
args.fSampleCoord);
951 invocation.appendf(
", ((%s) * %s.xy1).xy", matrixName.
c_str(),
args.fSampleCoord);
955 invocation.append(
")");
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
GrFragmentProcessor::ProgramImpl ProgramImpl
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
static constexpr bool GrClipEdgeTypeIsInverseFill(const GrClipEdgeType edgeType)
static constexpr bool GrClipEdgeTypeIsAA(const GrClipEdgeType edgeType)
static SkV4 v4(SkV3 v, SkScalar w)
SkRuntimeEffect * SkMakeRuntimeEffect(SkRuntimeEffect::Result(*make)(SkString, const SkRuntimeEffect::Options &), const char *sksl, SkRuntimeEffect::Options options=SkRuntimeEffect::Options{})
#define SkScalarInvert(x)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
static constexpr bool SkToBool(const T &x)
static SkScalar center(float pos0, float pos1)
SkString invokeChildWithMatrix(int childIndex, EmitArgs &parentArgs)
const char * functionName() const
void setData(const GrGLSLProgramDataManager &pdman, const GrFragmentProcessor &processor)
virtual void onSetData(const GrGLSLProgramDataManager &, const GrFragmentProcessor &)
SkString invokeChild(int childIndex, EmitArgs &parentArgs, std::string_view skslCoords={})
int numChildProcessors() const
ProgramImpl * childProcessor(int index) const
void cloneAndRegisterAllChildProcessors(const GrFragmentProcessor &src)
virtual SkPMColor4f constantOutputForConstantInput(const SkPMColor4f &) const
static std::unique_ptr< GrFragmentProcessor > SwizzleOutput(std::unique_ptr< GrFragmentProcessor >, const skgpu::Swizzle &)
void setWillReadDstColor()
static std::unique_ptr< GrFragmentProcessor > ClampOutput(std::unique_ptr< GrFragmentProcessor >)
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
int numChildProcessors() const
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 std::unique_ptr< GrFragmentProcessor > OverrideInput(std::unique_ptr< GrFragmentProcessor >, const SkPMColor4f &)
static std::unique_ptr< GrFragmentProcessor > SurfaceColor()
GrTextureEffect * asTextureEffect()
bool isEqual(const GrFragmentProcessor &that) const
GrFragmentProcessor * childProcessor(int index)
void visitProxies(const GrVisitProxyFunc &) const
bool isBlendFunction() const
void visitWithImpls(const std::function< void(const GrFragmentProcessor &, ProgramImpl &)> &, ProgramImpl &) const
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)
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
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)
@ kNone_OptimizationFlags
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)
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
virtual std::unique_ptr< ProgramImpl > onMakeProgramImpl() const =0
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
virtual const char * name() const =0
@ kSurfaceColorProcessor_ClassID
@ kSeriesFragmentProcessor_ClassID
@ kHighPrecisionFragmentProcessor_ClassID
@ kGrTextureEffect_ClassID
@ kSwizzleFragmentProcessor_ClassID
constexpr skgpu::Mipmapped mipmapped() const
const SkString & getName() const
@ kCompatibleWithCoverageAsAlpha
static std::unique_ptr< GrSkSLFP > Make(const SkRuntimeEffect *effect, const char *name, std::unique_ptr< GrFragmentProcessor > inputFP, OptFlags optFlags, Args &&... args)
static GrSpecializedUniform< T > Specialize(const T &value)
GrSurfaceProxy * proxy() const
const GrSurfaceProxyView & view() const
GrTexture * texture() const
GrSamplerState samplerState() const
static bool SupportsConstantOutputForConstantInput(const SkRuntimeEffect *effect)
static Result MakeForColorFilter(SkString sksl, const Options &)
static Result MakeForBlender(SkString sksl, const Options &)
static Result MakeForShader(SkString sksl, const Options &)
bool isPassThrough() const
bool isUniformMatrix() const
static const char * MatrixUniformName()
bool hasPerspective() const
static SampleUsage FragCoord()
void append(const char text[])
const char * c_str() const
static constexpr Swizzle RGBA()
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Dart_NativeFunction function
static float max(float r, float g, float b)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
unsigned useCenter Optional< SkMatrix > matrix
sk_sp< SkBlender > blender SkRect rect
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