Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | List of all members
GrDistanceFieldLCDTextGeoProc::Impl Class Reference
Inheritance diagram for GrDistanceFieldLCDTextGeoProc::Impl:
GrGeometryProcessor::ProgramImpl

Public Member Functions

void setData (const GrGLSLProgramDataManager &pdman, const GrShaderCaps &shaderCaps, const GrGeometryProcessor &geomProc) override
 
- Public Member Functions inherited from GrGeometryProcessor::ProgramImpl
virtual ~ProgramImpl ()=default
 
std::tuple< FPCoordsMap, GrShaderVaremitCode (EmitArgs &, const GrPipeline &pipeline)
 
void emitTransformCode (GrGLSLVertexBuilder *vb, GrGLSLUniformHandler *uniformHandler)
 

Private Member Functions

void onEmitCode (EmitArgs &args, GrGPArgs *gpArgs) override
 

Additional Inherited Members

- Public Types inherited from GrGeometryProcessor::ProgramImpl
using UniformHandle = GrGLSLProgramDataManager::UniformHandle
 
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle
 
using FPCoordsMap = std::unordered_map< const GrFragmentProcessor *, FPCoords >
 
- Static Public Member Functions inherited from GrGeometryProcessor::ProgramImpl
static uint32_t ComputeMatrixKey (const GrShaderCaps &caps, const SkMatrix &mat)
 
static uint32_t ComputeMatrixKeys (const GrShaderCaps &shaderCaps, const SkMatrix &viewMatrix, const SkMatrix &localMatrix)
 
static uint32_t AddMatrixKeys (const GrShaderCaps &shaderCaps, uint32_t flags, const SkMatrix &viewMatrix, const SkMatrix &localMatrix)
 
- Static Public Attributes inherited from GrGeometryProcessor::ProgramImpl
static constexpr int kMatrixKeyBits = 2
 
- Protected Member Functions inherited from GrGeometryProcessor::ProgramImpl
void setupUniformColor (GrGLSLFPFragmentBuilder *fragBuilder, GrGLSLUniformHandler *uniformHandler, const char *outputName, UniformHandle *colorUniform)
 
- Static Protected Member Functions inherited from GrGeometryProcessor::ProgramImpl
static void SetTransform (const GrGLSLProgramDataManager &, const GrShaderCaps &, const UniformHandle &uniform, const SkMatrix &matrix, SkMatrix *state=nullptr)
 
static void WriteOutputPosition (GrGLSLVertexBuilder *, GrGPArgs *, const char *posName)
 
static void WriteOutputPosition (GrGLSLVertexBuilder *, GrGLSLUniformHandler *, const GrShaderCaps &, GrGPArgs *, const char *posName, const SkMatrix &viewMatrix, UniformHandle *viewMatrixUniform)
 
static void WriteLocalCoord (GrGLSLVertexBuilder *, GrGLSLUniformHandler *, const GrShaderCaps &, GrGPArgs *, GrShaderVar localVar, const SkMatrix &localMatrix, UniformHandle *localMatrixUniform)
 

Detailed Description

Definition at line 583 of file GrDistanceFieldGeoProc.cpp.

Member Function Documentation

◆ onEmitCode()

void GrDistanceFieldLCDTextGeoProc::Impl::onEmitCode ( EmitArgs args,
GrGPArgs gpArgs 
)
inlineoverrideprivatevirtual

Implements GrGeometryProcessor::ProgramImpl.

Definition at line 609 of file GrDistanceFieldGeoProc.cpp.

609 {
610 const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
612
613 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
614 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
615 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
616
617 // emit attributes
618 varyingHandler->emitAttributes(dfTexEffect);
619
620 const char* atlasDimensionsInvName;
621 fAtlasDimensionsInvUniform = uniformHandler->addUniform(nullptr,
624 "AtlasDimensionsInv",
625 &atlasDimensionsInvName);
626
627 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
628
629 // setup pass through color
630 fragBuilder->codeAppendf("half4 %s;\n", args.fOutputColor);
631 varyingHandler->addPassThroughAttribute(dfTexEffect.fInColor.asShaderVar(),
632 args.fOutputColor);
633
634 // Setup position
635 gpArgs->fPositionVar = dfTexEffect.fInPosition.asShaderVar();
636 WriteLocalCoord(vertBuilder,
637 uniformHandler,
638 *args.fShaderCaps,
639 gpArgs,
640 dfTexEffect.fInPosition.asShaderVar(),
641 dfTexEffect.fLocalMatrix,
642 &fLocalMatrixUniform);
643
644 // set up varyings
645 GrGLSLVarying uv, texIdx, st;
647 dfTexEffect.numTextureSamplers(),
648 dfTexEffect.fInTextureCoords.name(),
649 atlasDimensionsInvName,
650 &uv,
651 &texIdx,
652 &st);
653
655 varyingHandler->addVarying("Delta", &delta);
656 if (dfTexEffect.fFlags & kBGR_DistanceFieldEffectFlag) {
657 vertBuilder->codeAppendf("%s = -%s.x/3.0;", delta.vsOut(), atlasDimensionsInvName);
658 } else {
659 vertBuilder->codeAppendf("%s = %s.x/3.0;", delta.vsOut(), atlasDimensionsInvName);
660 }
661
662 // add frag shader code
663 bool isUniformScale = (dfTexEffect.fFlags & kUniformScale_DistanceFieldEffectMask) ==
665 bool isSimilarity = SkToBool(dfTexEffect.fFlags & kSimilarity_DistanceFieldEffectFlag );
666 bool isGammaCorrect = SkToBool(dfTexEffect.fFlags & kGammaCorrect_DistanceFieldEffectFlag);
667
668 // create LCD offset adjusted by inverse of transform
669 // Use highp to work around aliasing issues
670 fragBuilder->codeAppendf("float2 uv = %s;\n", uv.fsIn());
671
672 if (isUniformScale) {
673 if (args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
674 fragBuilder->codeAppendf("half st_grad_len = half(abs(dFdy(%s.y)));", st.fsIn());
675 } else {
676 fragBuilder->codeAppendf("half st_grad_len = half(abs(dFdx(%s.x)));", st.fsIn());
677 }
678 fragBuilder->codeAppendf("half2 offset = half2(half(st_grad_len*%s), 0.0);",
679 delta.fsIn());
680 } else if (isSimilarity) {
681 // For a similarity matrix with rotation, the gradient will not be aligned
682 // with the texel coordinate axes, so we need to calculate it.
683 if (args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
684 // We use dFdy instead and rotate -90 degrees to get the gradient in the x
685 // direction.
686 fragBuilder->codeAppendf("half2 st_grad = half2(dFdy(%s));", st.fsIn());
687 fragBuilder->codeAppendf("half2 offset = half2(%s*float2(st_grad.y, -st_grad.x));",
688 delta.fsIn());
689 } else {
690 fragBuilder->codeAppendf("half2 st_grad = half2(dFdx(%s));", st.fsIn());
691 fragBuilder->codeAppendf("half2 offset = half(%s)*st_grad;", delta.fsIn());
692 }
693 fragBuilder->codeAppend("half st_grad_len = length(st_grad);");
694 } else {
695 fragBuilder->codeAppendf("half2 st = half2(%s);\n", st.fsIn());
696
697 fragBuilder->codeAppend("half2 Jdx = half2(dFdx(st));");
698 fragBuilder->codeAppend("half2 Jdy = half2(dFdy(st));");
699 fragBuilder->codeAppendf("half2 offset = half2(half(%s))*Jdx;", delta.fsIn());
700 }
701
702 // sample the texture by index
703 fragBuilder->codeAppend("half4 texColor;");
705 texIdx, "uv", "texColor");
706
707 // green is distance to uv center
708 fragBuilder->codeAppend("half3 distance;");
709 fragBuilder->codeAppend("distance.y = texColor.r;");
710 // red is distance to left offset
711 fragBuilder->codeAppend("half2 uv_adjusted = half2(uv) - offset;");
713 texIdx, "uv_adjusted", "texColor");
714 fragBuilder->codeAppend("distance.x = texColor.r;");
715 // blue is distance to right offset
716 fragBuilder->codeAppend("uv_adjusted = half2(uv) + offset;");
718 texIdx, "uv_adjusted", "texColor");
719 fragBuilder->codeAppend("distance.z = texColor.r;");
720
721 fragBuilder->codeAppend("distance = "
722 "half3(" SK_DistanceFieldMultiplier ")*(distance - half3(" SK_DistanceFieldThreshold"));");
723
724 // adjust width based on gamma
725 const char* distanceAdjustUniName = nullptr;
726 fDistanceAdjustUni = uniformHandler->addUniform(nullptr, kFragment_GrShaderFlag,
727 SkSLType::kHalf3, "DistanceAdjust",
728 &distanceAdjustUniName);
729 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
730
731 // To be strictly correct, we should compute the anti-aliasing factor separately
732 // for each color component. However, this is only important when using perspective
733 // transformations, and even then using a single factor seems like a reasonable
734 // trade-off between quality and speed.
735 fragBuilder->codeAppend("half afwidth;");
736 if (isSimilarity) {
737 // For similarity transform (uniform scale-only is a subset of this), we adjust for the
738 // effect of the transformation on the distance by using the length of the gradient of
739 // the texture coordinates. We use st coordinates to ensure we're mapping 1:1 from texel
740 // space to pixel space.
741
742 // this gives us a smooth step across approximately one fragment
743 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*st_grad_len;");
744 } else {
745 // For general transforms, to determine the amount of correction we multiply a unit
746 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
747 // (which is the inverse transform for this fragment) and take the length of the result.
748 fragBuilder->codeAppend("half2 dist_grad = half2(half(dFdx(distance.r)), "
749 "half(dFdy(distance.r)));");
750 // the length of the gradient may be 0, so we need to check for this
751 // this also compensates for the Adreno, which likes to drop tiles on division by 0
752 fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);");
753 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
754 fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);");
755 fragBuilder->codeAppend("} else {");
756 fragBuilder->codeAppend("dist_grad = dist_grad*half(inversesqrt(dg_len2));");
757 fragBuilder->codeAppend("}");
758 fragBuilder->codeAppend("half2 grad = half2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
759 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
760
761 // this gives us a smooth step across approximately one fragment
762 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
763 }
764
765 // The smoothstep falloff compensates for the non-linear sRGB response curve. If we are
766 // doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want distance
767 // mapped linearly to coverage, so use a linear step:
768 if (isGammaCorrect) {
769 fragBuilder->codeAppendf("half4 %s = "
770 "half4(saturate((distance + half3(afwidth)) / half3(2.0 * afwidth)), 1.0);",
771 args.fOutputCoverage);
772 } else {
773 fragBuilder->codeAppendf(
774 "half4 %s = half4(smoothstep(half3(-afwidth), half3(afwidth), distance), 1.0);",
775 args.fOutputCoverage);
776 }
777 }
static void append_index_uv_varyings(GrGeometryProcessor::ProgramImpl::EmitArgs &args, int numTextureSamplers, const char *inTexCoordsName, const char *atlasDimensionsInvName, GrGLSLVarying *uv, GrGLSLVarying *texIdx, GrGLSLVarying *st)
static void append_multitexture_lookup(GrGeometryProcessor::ProgramImpl::EmitArgs &args, int numTextureSamplers, const GrGLSLVarying &texIdx, const char *coordName, const char *colorName)
#define SK_DistanceFieldAAFactor
@ kGammaCorrect_DistanceFieldEffectFlag
@ kSimilarity_DistanceFieldEffectFlag
@ kBGR_DistanceFieldEffectFlag
@ kUniformScale_DistanceFieldEffectMask
@ kVertex_GrShaderFlag
@ kFragment_GrShaderFlag
#define SK_DistanceFieldMultiplier
#define SK_DistanceFieldThreshold
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
void codeAppend(const char *str)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
UniformHandle addUniform(const GrProcessor *owner, uint32_t visibility, SkSLType type, const char *name, const char **outName=nullptr)
void emitAttributes(const GrGeometryProcessor &)
void addPassThroughAttribute(const GrShaderVar &vsVar, const char *output, Interpolation=Interpolation::kInterpolated)
void addVarying(const char *name, GrGLSLVarying *varying, Interpolation=Interpolation::kInterpolated)
const char * fsIn() const
constexpr const char * name() const
static void WriteLocalCoord(GrGLSLVertexBuilder *, GrGLSLUniformHandler *, const GrShaderCaps &, GrGPArgs *, GrShaderVar localVar, const SkMatrix &localMatrix, UniformHandle *localMatrixUniform)
const T & cast() const
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

◆ setData()

void GrDistanceFieldLCDTextGeoProc::Impl::setData ( const GrGLSLProgramDataManager ,
const GrShaderCaps ,
const GrGeometryProcessor  
)
inlineoverridevirtual

A ProgramImpl instance can be reused with any GrGeometryProcessor that produces the same key. This function reads data from a GrGeometryProcessor and updates any uniform variables required by the shaders created in emitCode(). The GrGeometryProcessor parameter is guaranteed to be of the same type and to have an identical processor key as the GrGeometryProcessor that created this ProgramImpl.

Implements GrGeometryProcessor::ProgramImpl.

Definition at line 585 of file GrDistanceFieldGeoProc.cpp.

587 {
588 SkASSERT(fDistanceAdjustUni.isValid());
589
591 GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.fDistanceAdjust;
592 if (wa != fDistanceAdjust) {
593 pdman.set3f(fDistanceAdjustUni, wa.fR, wa.fG, wa.fB);
594 fDistanceAdjust = wa;
595 }
596
597 const SkISize& atlasDimensions = dflcd.fAtlasDimensions;
598 SkASSERT(SkIsPow2(atlasDimensions.fWidth) && SkIsPow2(atlasDimensions.fHeight));
599 if (fAtlasDimensions != atlasDimensions) {
600 pdman.set2f(fAtlasDimensionsInvUniform,
601 1.0f / atlasDimensions.fWidth,
602 1.0f / atlasDimensions.fHeight);
603 fAtlasDimensions = atlasDimensions;
604 }
605 SetTransform(pdman, shaderCaps, fLocalMatrixUniform, dflcd.fLocalMatrix, &fLocalMatrix);
606 }
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr bool SkIsPow2(T value)
Definition SkMath.h:51
static void SetTransform(const GrGLSLProgramDataManager &, const GrShaderCaps &, const UniformHandle &uniform, const SkMatrix &matrix, SkMatrix *state=nullptr)
int32_t fHeight
Definition SkSize.h:18
int32_t fWidth
Definition SkSize.h:17

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