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

Member Function Documentation

◆ onEmitCode()

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

Implements GrGeometryProcessor::ProgramImpl.

Definition at line 354 of file GrDistanceFieldGeoProc.cpp.

354 {
355 const GrDistanceFieldPathGeoProc& dfPathEffect =
357
358 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
359
360 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
361 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
362 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
363
364 // emit attributes
365 varyingHandler->emitAttributes(dfPathEffect);
366
367 const char* atlasDimensionsInvName;
368 fAtlasDimensionsInvUniform = uniformHandler->addUniform(nullptr,
371 "AtlasDimensionsInv",
372 &atlasDimensionsInvName);
373
374 GrGLSLVarying uv, texIdx, st;
376 dfPathEffect.numTextureSamplers(),
377 dfPathEffect.fInTextureCoords.name(),
378 atlasDimensionsInvName,
379 &uv,
380 &texIdx,
381 &st);
382
383 // setup pass through color
384 fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
385 varyingHandler->addPassThroughAttribute(dfPathEffect.fInColor.asShaderVar(),
386 args.fOutputColor);
387
388 // Setup position (output position is pass through, local coords are transformed)
389 gpArgs->fPositionVar = dfPathEffect.fInPosition.asShaderVar();
390 WriteLocalCoord(vertBuilder,
391 uniformHandler,
392 *args.fShaderCaps,
393 gpArgs,
394 gpArgs->fPositionVar,
395 dfPathEffect.fLocalMatrix,
396 &fLocalMatrixUniform);
397
398 // Use highp to work around aliasing issues
399 fragBuilder->codeAppendf("float2 uv = %s;", uv.fsIn());
400 fragBuilder->codeAppend("half4 texColor;");
401 append_multitexture_lookup(args, dfPathEffect.numTextureSamplers(), texIdx, "uv",
402 "texColor");
403
404 fragBuilder->codeAppend("half distance = "
406
407 fragBuilder->codeAppend("half afwidth;");
408 bool isUniformScale = (dfPathEffect.fFlags & kUniformScale_DistanceFieldEffectMask) ==
410 bool isSimilarity = SkToBool(dfPathEffect.fFlags & kSimilarity_DistanceFieldEffectFlag );
411 bool isGammaCorrect = SkToBool(dfPathEffect.fFlags & kGammaCorrect_DistanceFieldEffectFlag);
412 if (isUniformScale) {
413 // For uniform scale, we adjust for the effect of the transformation on the distance
414 // by using the length of the gradient of the t coordinate in the y direction.
415 // We use st coordinates to ensure we're mapping 1:1 from texel space to pixel space.
416
417 // this gives us a smooth step across approximately one fragment
418 if (args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
419 fragBuilder->codeAppendf(
420 "afwidth = abs(" SK_DistanceFieldAAFactor "*half(dFdy(%s.y)));", st.fsIn());
421 } else {
422 fragBuilder->codeAppendf(
423 "afwidth = abs(" SK_DistanceFieldAAFactor "*half(dFdx(%s.x)));", st.fsIn());
424 }
425 } else if (isSimilarity) {
426 // For similarity transform, we adjust the effect of the transformation on the distance
427 // by using the length of the gradient of the texture coordinates. We use st coordinates
428 // to ensure we're mapping 1:1 from texel space to pixel space.
429
430 // this gives us a smooth step across approximately one fragment
431 if (args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
432 fragBuilder->codeAppendf("half st_grad_len = half(length(dFdy(%s)));", st.fsIn());
433 } else {
434 fragBuilder->codeAppendf("half st_grad_len = half(length(dFdx(%s)));", st.fsIn());
435 }
436 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
437 } else {
438 // For general transforms, to determine the amount of correction we multiply a unit
439 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
440 // (which is the inverse transform for this fragment) and take the length of the result.
441 fragBuilder->codeAppend("half2 dist_grad = half2(dFdx(distance), "
442 "dFdy(distance));");
443 // the length of the gradient may be 0, so we need to check for this
444 // this also compensates for the Adreno, which likes to drop tiles on division by 0
445 fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);");
446 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
447 fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);");
448 fragBuilder->codeAppend("} else {");
449 fragBuilder->codeAppend("dist_grad = dist_grad*half(inversesqrt(dg_len2));");
450 fragBuilder->codeAppend("}");
451
452 fragBuilder->codeAppendf("half2 Jdx = half2(dFdx(%s));", st.fsIn());
453 fragBuilder->codeAppendf("half2 Jdy = half2(dFdy(%s));", st.fsIn());
454 fragBuilder->codeAppend("half2 grad = half2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
455 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
456
457 // this gives us a smooth step across approximately one fragment
458 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
459 }
460 // The smoothstep falloff compensates for the non-linear sRGB response curve. If we are
461 // doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want distance
462 // mapped linearly to coverage, so use a linear step:
463 if (isGammaCorrect) {
464 fragBuilder->codeAppend(
465 "half val = saturate((distance + afwidth) / (2.0 * afwidth));");
466 } else {
467 fragBuilder->codeAppend("half val = smoothstep(-afwidth, afwidth, distance);");
468 }
469
470 fragBuilder->codeAppendf("half4 %s = half4(val);", args.fOutputCoverage);
471 }
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
@ kUniformScale_DistanceFieldEffectMask
@ kVertex_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 GrDistanceFieldPathGeoProc::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 334 of file GrDistanceFieldGeoProc.cpp.

336 {
338
339 // We always set the matrix uniform. It's used to transform from from device to local
340 // for the local coord variable.
341 SetTransform(pdman, shaderCaps, fLocalMatrixUniform, dfpgp.fLocalMatrix, &fLocalMatrix);
342
343 const SkISize& atlasDimensions = dfpgp.fAtlasDimensions;
344 SkASSERT(SkIsPow2(atlasDimensions.fWidth) && SkIsPow2(atlasDimensions.fHeight));
345 if (fAtlasDimensions != atlasDimensions) {
346 pdman.set2f(fAtlasDimensionsInvUniform,
347 1.0f / atlasDimensions.fWidth,
348 1.0f / atlasDimensions.fHeight);
349 fAtlasDimensions = atlasDimensions;
350 }
351 }
#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: