Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
EllipticalRRectEffect::Impl Class Reference
Inheritance diagram for EllipticalRRectEffect::Impl:
GrFragmentProcessor::ProgramImpl

Public Member Functions

void emitCode (EmitArgs &) override
 
- Public Member Functions inherited from GrFragmentProcessor::ProgramImpl
 ProgramImpl ()=default
 
virtual ~ProgramImpl ()=default
 
virtual void emitCode (EmitArgs &)=0
 
void setData (const GrGLSLProgramDataManager &pdman, const GrFragmentProcessor &processor)
 
int numChildProcessors () const
 
ProgramImplchildProcessor (int index) const
 
void setFunctionName (SkString name)
 
const char * functionName () const
 
SkString invokeChild (int childIndex, EmitArgs &parentArgs, std::string_view skslCoords={})
 
SkString invokeChildWithMatrix (int childIndex, EmitArgs &parentArgs)
 
SkString invokeChild (int childIndex, const char *inputColor, EmitArgs &parentArgs, std::string_view skslCoords={})
 
SkString invokeChildWithMatrix (int childIndex, const char *inputColor, EmitArgs &parentArgs)
 
SkString invokeChild (int childIndex, const char *inputColor, const char *destColor, EmitArgs &parentArgs, std::string_view skslCoords={})
 
SkString invokeChildWithMatrix (int childIndex, const char *inputColor, const char *destColor, EmitArgs &parentArgs)
 

Additional Inherited Members

- Public Types inherited from GrFragmentProcessor::ProgramImpl
using UniformHandle = GrGLSLUniformHandler::UniformHandle
 
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle
 

Detailed Description

Definition at line 532 of file GrRRectEffect.cpp.

Member Function Documentation

◆ emitCode()

void EllipticalRRectEffect::Impl::emitCode ( EmitArgs args)
overridevirtual

Implements GrFragmentProcessor::ProgramImpl.

Definition at line 545 of file GrRRectEffect.cpp.

545 {
546 const EllipticalRRectEffect& erre = args.fFp.cast<EllipticalRRectEffect>();
547 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
548 const char *rectName;
549 // The inner rect is the rrect bounds inset by the x/y radii
550 fInnerRectUniform = uniformHandler->addUniform(&erre, kFragment_GrShaderFlag, SkSLType::kFloat4,
551 "innerRect", &rectName);
552
553 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
554 // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
555 // to the ellipse center. The vector is pinned in x and y to be in the quarter-plane relevant
556 // to that corner. This means that points near the interior near the rrect top edge will have
557 // a vector that points straight up for both the TL left and TR corners. Computing an
558 // alpha from this vector at either the TR or TL corner will give the correct result. Similarly,
559 // fragments near the other three edges will get the correct AA. Fragments in the interior of
560 // the rrect will have a (0,0) vector at all four corners. So long as the radii > 0.5 they will
561 // correctly produce an alpha value of 1 at all four corners. We take the min of all the alphas.
562 //
563 // The code below is a simplified version of the above that performs maxs on the vector
564 // components before computing distances and alpha values so that only one distance computation
565 // need be computed to determine the min alpha.
566 fragBuilder->codeAppendf("float2 dxy0 = %s.LT - sk_FragCoord.xy;", rectName);
567 fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.RB;", rectName);
568
569
570 const char* scaleName = nullptr;
571 if (elliptical_effect_uses_scale(*args.fShaderCaps, erre.fRRect)) {
572 fScaleUniform = uniformHandler->addUniform(&erre, kFragment_GrShaderFlag, SkSLType::kHalf2,
573 "scale", &scaleName);
574 }
575
576 // The uniforms with the inv squared radii are highp to prevent underflow.
577 switch (erre.fRRect.getType()) {
579 const char *invRadiiXYSqdName;
580 fInvRadiiSqdUniform = uniformHandler->addUniform(&erre,
583 "invRadiiXY",
584 &invRadiiXYSqdName);
585 fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
586 if (scaleName) {
587 fragBuilder->codeAppendf("dxy *= %s.y;", scaleName);
588 }
589 // Z is the x/y offsets divided by squared radii.
590 fragBuilder->codeAppendf("float2 Z = dxy * %s.xy;", invRadiiXYSqdName);
591 break;
592 }
594 const char *invRadiiLTRBSqdName;
595 fInvRadiiSqdUniform = uniformHandler->addUniform(&erre,
598 "invRadiiLTRB",
599 &invRadiiLTRBSqdName);
600 if (scaleName) {
601 fragBuilder->codeAppendf("dxy0 *= %s.y;", scaleName);
602 fragBuilder->codeAppendf("dxy1 *= %s.y;", scaleName);
603 }
604 fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
605 // Z is the x/y offsets divided by squared radii. We only care about the (at most) one
606 // corner where both the x and y offsets are positive, hence the maxes. (The inverse
607 // squared radii will always be positive.)
608 fragBuilder->codeAppendf("float2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);",
609 invRadiiLTRBSqdName, invRadiiLTRBSqdName);
610
611 break;
612 }
613 default:
614 SK_ABORT("RRect should always be simple or nine-patch.");
615 }
616 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
617 fragBuilder->codeAppend("half implicit = half(dot(Z, dxy) - 1.0);");
618 // grad_dot is the squared length of the gradient of the implicit.
619 fragBuilder->codeAppend("half grad_dot = half(4.0 * dot(Z, Z));");
620 // avoid calling inversesqrt on zero.
621 fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
622 fragBuilder->codeAppend("half approx_dist = implicit * half(inversesqrt(grad_dot));");
623 if (scaleName) {
624 fragBuilder->codeAppendf("approx_dist *= %s.x;", scaleName);
625 }
626
627 if (erre.fEdgeType == GrClipEdgeType::kFillAA) {
628 fragBuilder->codeAppend("half alpha = clamp(0.5 - approx_dist, 0.0, 1.0);");
629 } else {
630 fragBuilder->codeAppend("half alpha = clamp(0.5 + approx_dist, 0.0, 1.0);");
631 }
632
633 SkString inputSample = this->invokeChild(/*childIndex=*/0, args);
634
635 fragBuilder->codeAppendf("return %s * alpha;", inputSample.c_str());
636}
static bool elliptical_effect_uses_scale(const GrShaderCaps &caps, const SkRRect &rrect)
@ kFragment_GrShaderFlag
Definition: GrTypesPriv.h:287
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
SkString invokeChild(int childIndex, EmitArgs &parentArgs, std::string_view skslCoords={})
void codeAppend(const char *str)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
@ kSimple_Type
non-zero width and height with equal radii
Definition: SkRRect.h:70
@ kNinePatch_Type
non-zero width and height with axis-aligned radii
Definition: SkRRect.h:71
const char * c_str() const
Definition: SkString.h:133
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

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