604 {
607 "uniform int edgeType;"
608 "uniform float4 rectUniform;"
609
610 "half4 main(float2 xy) {"
611 "half coverage;"
612 "if (edgeType == kFillBW || edgeType == kInverseFillBW) {"
613
614 "coverage = half(all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw),"
615 "float4(rectUniform.xy, sk_FragCoord.xy))));"
616 "} else {"
617
618
619 "half4 dists4 = saturate(half4(1, 1, -1, -1) *"
620 "half4(sk_FragCoord.xyxy - rectUniform));"
621 "half2 dists2 = dists4.xy + dists4.zw - 1;"
622 "coverage = dists2.x * dists2.y;"
623 "}"
624
625 "if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {"
626 "coverage = 1.0 - coverage;"
627 "}"
628
629 "return half4(coverage);"
630 "}"
631 );
632
634
635
637
641 "rectUniform", rectUniform);
642 return GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(rectFP),
643 std::move(inputFP));
644}
645
649 float radius) {
650
651
654 }
655
658 "uniform int edgeType;"
659
660
661 "uniform float4 circle;"
662
663 "half4 main(float2 xy) {"
664
665
666
667 "half d;"
668 "if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {"
669 "d = half((length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z);"
670 "} else {"
671 "d = half((1.0 - length((circle.xy - sk_FragCoord.xy) * circle.w)) * circle.z);"
672 "}"
673 "return half4((edgeType == kFillAA || edgeType == kInverseFillAA)"
674 "? saturate(d)"
675 ": (d > 0.5 ? 1 : 0));"
676 "}"
677 );
678
681 effectiveRadius -= 0.5f;
682
683 effectiveRadius = std::max(0.001f, effectiveRadius);
684 } else {
685 effectiveRadius += 0.5f;
686 }
688
692 "circle", circle);
693 return GrFPSuccess(GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(inputFP),
694 std::move(circleFP)));
695}
696
703
704
705 if (medPrecision && (radii.
fX < 0.5f || radii.
fY < 0.5f)) {
707 }
708
709 if (medPrecision && (radii.
fX > 255*radii.
fY || radii.
fY > 255*radii.
fX)) {
711 }
712
713 if (medPrecision && (radii.
fX > 16384 || radii.
fY > 16384)) {
715 }
716
719 "uniform int edgeType;"
720 "uniform int medPrecision;"
721
722 "uniform float4 ellipse;"
723 "uniform float2 scale;"
724
725 "half4 main(float2 xy) {"
726
727 "float2 d = sk_FragCoord.xy - ellipse.xy;"
728
729
730
731
732 "if (bool(medPrecision)) {"
733 "d *= scale.y;"
734 "}"
735 "float2 Z = d * ellipse.zw;"
736
737 "float implicit = dot(Z, d) - 1;"
738
739 "float grad_dot = 4 * dot(Z, Z);"
740
741 "if (bool(medPrecision)) {"
742 "grad_dot = max(grad_dot, 6.1036e-5);"
743 "} else {"
744 "grad_dot = max(grad_dot, 1.1755e-38);"
745 "}"
746 "float approx_dist = implicit * inversesqrt(grad_dot);"
747 "if (bool(medPrecision)) {"
748 "approx_dist *= scale.x;"
749 "}"
750
751 "half alpha;"
752 "if (edgeType == kFillBW) {"
753 "alpha = approx_dist > 0.0 ? 0.0 : 1.0;"
754 "} else if (edgeType == kFillAA) {"
755 "alpha = saturate(0.5 - half(approx_dist));"
756 "} else if (edgeType == kInverseFillBW) {"
757 "alpha = approx_dist > 0.0 ? 1.0 : 0.0;"
758 "} else {"
759 "alpha = saturate(0.5 + half(approx_dist));"
760 "}"
761 "return half4(alpha);"
762 "}"
763 );
764
765 float invRXSqd;
766 float invRYSqd;
768
769
770 if (medPrecision) {
771 if (radii.
fX > radii.
fY) {
772 invRXSqd = 1.f;
773 invRYSqd = (radii.
fX * radii.
fX) / (radii.
fY * radii.
fY);
775 } else {
776 invRXSqd = (radii.
fY * radii.
fY) / (radii.
fX * radii.
fX);
777 invRYSqd = 1.f;
779 }
780 } else {
781 invRXSqd = 1.f / (radii.
fX * radii.
fX);
782 invRYSqd = 1.f / (radii.
fY * radii.
fY);
783 }
785
789 "medPrecision", GrSkSLFP::Specialize<int>(medPrecision),
790 "ellipse", ellipse,
792 return GrFPSuccess(GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(ellipseFP),
793 std::move(inputFP)));
794}
795
796
797
799 std::unique_ptr<GrFragmentProcessor> fp) {
801 public:
802 static std::unique_ptr<GrFragmentProcessor>
Make(std::unique_ptr<GrFragmentProcessor> fp) {
803 return std::unique_ptr<GrFragmentProcessor>(
804 new HighPrecisionFragmentProcessor(std::move(fp)));
805 }
806
807 const char*
name()
const override {
return "HighPrecision"; }
808
809 std::unique_ptr<GrFragmentProcessor> clone() const override {
810 return Make(this->childProcessor(0)->clone());
811 }
812
813 private:
814 HighPrecisionFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp)
815 :
INHERITED(kHighPrecisionFragmentProcessor_ClassID,
816 ProcessorOptimizationFlags(
fp.
get())) {
817 this->registerChild(std::move(fp));
818 }
819
820 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
822 public:
823 void emitCode(EmitArgs&
args)
override {
825
826 args.fFragBuilder->forceHighPrecision();
827 args.fFragBuilder->codeAppendf(
"return %s;", childColor.
c_str());
828 }
829 };
830 return std::make_unique<Impl>();
831 }
832
835
837 return ConstantOutputForConstantInput(this->childProcessor(0), input);
838 }
839
841 };
842
843 return HighPrecisionFragmentProcessor::Make(std::move(fp));
844}
845
846
847
849
853}
854
856 const char* inputColor,
857 const char* destColor,
859 std::string_view skslCoords) {
861
862 if (!inputColor) {
863 inputColor =
args.fInputColor;
864 }
865
867 if (!childProc) {
868
870 }
871
873 inputColor);
874
876 if (!destColor) {
877 destColor =
args.fFp.isBlendFunction() ?
args.fDestColor :
"half4(1)";
878 }
879 invocation.appendf(", %s", destColor);
880 }
881
882
883
885
886 if (
args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
888
889 if (!skslCoords.empty()) {
890 invocation.appendf(", %.*s", (int)skslCoords.size(), skslCoords.data());
891 } else {
892 invocation.appendf(
", %s",
args.fSampleCoord);
893 }
894 }
895
896 invocation.append(")");
897 return invocation;
898}
899
901 const char* inputColor,
902 const char* destColor,
905
906 if (!inputColor) {
907 inputColor =
args.fInputColor;
908 }
909
911 if (!childProc) {
912
914 }
915
917
918
923
925 inputColor);
926
928 if (!destColor) {
929 destColor =
args.fFp.isBlendFunction() ?
args.fDestColor :
"half4(1)";
930 }
931 invocation.appendf(", %s", destColor);
932 }
933
934
935
936
937
938
939
940
941
942 if (
args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
943
944
946 invocation.appendf(
", proj((%s) * %s.xy1)", matrixName.c_str(),
args.fSampleCoord);
947 }
else if (
args.fShaderCaps->fNonsquareMatrixSupport) {
948 invocation.appendf(
", float3x2(%s) * %s.xy1", matrixName.c_str(),
args.fSampleCoord);
949 } else {
950 invocation.appendf(
", ((%s) * %s.xy1).xy", matrixName.c_str(),
args.fSampleCoord);
951 }
952 }
953
954 invocation.append(")");
955 return invocation;
956}
static GrFPResult GrFPSuccess(std::unique_ptr< GrFragmentProcessor > fp)
std::tuple< bool, std::unique_ptr< GrFragmentProcessor > > GrFPResult
static GrFPResult GrFPFailure(std::unique_ptr< GrFragmentProcessor > fp)
static constexpr bool GrClipEdgeTypeIsInverseFill(const GrClipEdgeType edgeType)
static constexpr bool GrClipEdgeTypeIsAA(const GrClipEdgeType edgeType)
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
#define INHERITED(method,...)
SkRuntimeEffect * SkMakeRuntimeEffect(SkRuntimeEffect::Result(*make)(SkString, const SkRuntimeEffect::Options &), const char *sksl, SkRuntimeEffect::Options options=SkRuntimeEffect::Options{})
#define SkScalarInvert(x)
SK_API SkString static SkString SkStringPrintf()
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={})
ProgramImpl * childProcessor(int index) const
static GrFPResult Circle(std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, float radius)
GrFragmentProcessor * childProcessor(int index)
bool isBlendFunction() const
const SkSL::SampleUsage & sampleUsage() const
static std::unique_ptr< GrFragmentProcessor > HighPrecision(std::unique_ptr< GrFragmentProcessor >)
static GrFPResult Ellipse(std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, SkPoint radii, const GrShaderCaps &)
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)
static Result MakeForShader(SkString sksl, const Options &)
bool isUniformMatrix() const
static const char * MatrixUniformName()
bool hasPerspective() const
const char * c_str() const
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
sk_sp< SkBlender > blender SkRect rect
const myers::Point & get(const myers::Segment &)