Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | List of all members
GrDistanceFieldA8TextGeoProc::Impl Class Reference
Inheritance diagram for GrDistanceFieldA8TextGeoProc::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 39 of file GrDistanceFieldGeoProc.cpp.

Member Function Documentation

◆ onEmitCode()

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

Implements GrGeometryProcessor::ProgramImpl.

Definition at line 67 of file GrDistanceFieldGeoProc.cpp.

67 {
68 const GrDistanceFieldA8TextGeoProc& dfTexEffect =
70 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
71
72 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
73 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
74 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
75
76 // emit attributes
77 varyingHandler->emitAttributes(dfTexEffect);
78
79 const char* atlasDimensionsInvName;
80 fAtlasDimensionsInvUniform = uniformHandler->addUniform(nullptr,
83 "AtlasDimensionsInv",
84 &atlasDimensionsInvName);
85#ifdef SK_GAMMA_APPLY_TO_A8
86 // adjust based on gamma
87 const char* distanceAdjustUniName = nullptr;
88 // width, height, 1/(3*width)
89 fDistanceAdjustUni = uniformHandler->addUniform(nullptr, kFragment_GrShaderFlag,
90 SkSLType::kHalf, "DistanceAdjust",
91 &distanceAdjustUniName);
92#endif
93
94 // Setup pass through color
95 fragBuilder->codeAppendf("half4 %s;\n", args.fOutputColor);
96 varyingHandler->addPassThroughAttribute(dfTexEffect.fInColor.asShaderVar(),
97 args.fOutputColor);
98
99 // Setup position
100 gpArgs->fPositionVar = dfTexEffect.fInPosition.asShaderVar();
101 WriteLocalCoord(vertBuilder,
102 uniformHandler,
103 *args.fShaderCaps,
104 gpArgs,
105 gpArgs->fPositionVar,
106 dfTexEffect.fLocalMatrix,
107 &fLocalMatrixUniform);
108
109 // add varyings
110 GrGLSLVarying uv, texIdx, st;
112 dfTexEffect.numTextureSamplers(),
113 dfTexEffect.fInTextureCoords.name(),
114 atlasDimensionsInvName,
115 &uv,
116 &texIdx,
117 &st);
118
119 bool isUniformScale = (dfTexEffect.fFlags & kUniformScale_DistanceFieldEffectMask) ==
121 bool isSimilarity = SkToBool(dfTexEffect.fFlags & kSimilarity_DistanceFieldEffectFlag );
122 bool isGammaCorrect = SkToBool(dfTexEffect.fFlags & kGammaCorrect_DistanceFieldEffectFlag);
123 bool isAliased = SkToBool(dfTexEffect.fFlags & kAliased_DistanceFieldEffectFlag );
124
125 // Use highp to work around aliasing issues
126 fragBuilder->codeAppendf("float2 uv = %s;\n", uv.fsIn());
127 fragBuilder->codeAppend("half4 texColor;");
129 texIdx, "uv", "texColor");
130
131 fragBuilder->codeAppend("half distance = "
133#ifdef SK_GAMMA_APPLY_TO_A8
134 // adjust width based on gamma
135 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
136#endif
137
138 fragBuilder->codeAppend("half afwidth;");
139 if (isUniformScale) {
140 // For uniform scale, we adjust for the effect of the transformation on the distance
141 // by using the length of the gradient of the t coordinate in the y direction.
142 // We use st coordinates to ensure we're mapping 1:1 from texel space to pixel space.
143
144 // this gives us a smooth step across approximately one fragment
145 if (args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
146 fragBuilder->codeAppendf(
147 "afwidth = abs(" SK_DistanceFieldAAFactor "*half(dFdy(%s.y)));", st.fsIn());
148 } else {
149 fragBuilder->codeAppendf(
150 "afwidth = abs(" SK_DistanceFieldAAFactor "*half(dFdx(%s.x)));", st.fsIn());
151 }
152 } else if (isSimilarity) {
153 // For similarity transform, we adjust the effect of the transformation on the distance
154 // by using the length of the gradient of the texture coordinates. We use st coordinates
155 // to ensure we're mapping 1:1 from texel space to pixel space.
156 // We use the y gradient because there is a bug in the Mali 400 in the x direction.
157
158 // this gives us a smooth step across approximately one fragment
159 if (args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
160 fragBuilder->codeAppendf("half st_grad_len = length(half2(dFdy(%s)));", st.fsIn());
161 } else {
162 fragBuilder->codeAppendf("half st_grad_len = length(half2(dFdx(%s)));", st.fsIn());
163 }
164 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
165 } else {
166 // For general transforms, to determine the amount of correction we multiply a unit
167 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
168 // (which is the inverse transform for this fragment) and take the length of the result.
169 fragBuilder->codeAppend("half2 dist_grad = half2(float2(dFdx(distance), "
170 "dFdy(distance)));");
171 // the length of the gradient may be 0, so we need to check for this
172 // this also compensates for the Adreno, which likes to drop tiles on division by 0
173 fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);");
174 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
175 fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);");
176 fragBuilder->codeAppend("} else {");
177 fragBuilder->codeAppend("dist_grad = dist_grad*half(inversesqrt(dg_len2));");
178 fragBuilder->codeAppend("}");
179
180 fragBuilder->codeAppendf("half2 Jdx = half2(dFdx(%s));", st.fsIn());
181 fragBuilder->codeAppendf("half2 Jdy = half2(dFdy(%s));", st.fsIn());
182 fragBuilder->codeAppend("half2 grad = half2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
183 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
184
185 // this gives us a smooth step across approximately one fragment
186 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
187 }
188
189 if (isAliased) {
190 fragBuilder->codeAppend("half val = distance > 0 ? 1.0 : 0.0;");
191 } else if (isGammaCorrect) {
192 // The smoothstep falloff compensates for the non-linear sRGB response curve. If we are
193 // doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want
194 // distance mapped linearly to coverage, so use a linear step:
195 fragBuilder->codeAppend(
196 "half val = saturate((distance + afwidth) / (2.0 * afwidth));");
197 } else {
198 fragBuilder->codeAppend("half val = smoothstep(-afwidth, afwidth, distance);");
199 }
200
201 fragBuilder->codeAppendf("half4 %s = half4(val);", args.fOutputCoverage);
202 }
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
@ kAliased_DistanceFieldEffectFlag
@ kUniformScale_DistanceFieldEffectMask
@ kVertex_GrShaderFlag
@ kFragment_GrShaderFlag
#define SK_DistanceFieldMultiplier
#define SK_DistanceFieldThreshold
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
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)
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 GrDistanceFieldA8TextGeoProc::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 41 of file GrDistanceFieldGeoProc.cpp.

43 {
45
46#ifdef SK_GAMMA_APPLY_TO_A8
47 float distanceAdjust = dfa8gp.fDistanceAdjust;
48 if (distanceAdjust != fDistanceAdjust) {
49 fDistanceAdjust = distanceAdjust;
50 pdman.set1f(fDistanceAdjustUni, distanceAdjust);
51 }
52#endif
53
54 const SkISize& atlasDimensions = dfa8gp.fAtlasDimensions;
55 SkASSERT(SkIsPow2(atlasDimensions.fWidth) && SkIsPow2(atlasDimensions.fHeight));
56
57 if (fAtlasDimensions != atlasDimensions) {
58 pdman.set2f(fAtlasDimensionsInvUniform,
59 1.0f / atlasDimensions.fWidth,
60 1.0f / atlasDimensions.fHeight);
61 fAtlasDimensions = atlasDimensions;
62 }
63 SetTransform(pdman, shaderCaps, fLocalMatrixUniform, dfa8gp.fLocalMatrix, &fLocalMatrix);
64 }
#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: