34#if !defined(SK_DISABLE_SDF_TEXT)
37#define SK_DistanceFieldAAFactor "0.65"
46#ifdef SK_GAMMA_APPLY_TO_A8
47 float distanceAdjust = dfa8gp.fDistanceAdjust;
48 if (distanceAdjust != fDistanceAdjust) {
49 fDistanceAdjust = distanceAdjust;
50 pdman.
set1f(fDistanceAdjustUni, distanceAdjust);
54 const SkISize& atlasDimensions = dfa8gp.fAtlasDimensions;
57 if (fAtlasDimensions != atlasDimensions) {
58 pdman.
set2f(fAtlasDimensionsInvUniform,
59 1.0f / atlasDimensions.
fWidth,
60 1.0f / atlasDimensions.
fHeight);
61 fAtlasDimensions = atlasDimensions;
63 SetTransform(pdman, shaderCaps, fLocalMatrixUniform, dfa8gp.fLocalMatrix, &fLocalMatrix);
79 const char* atlasDimensionsInvName;
80 fAtlasDimensionsInvUniform = uniformHandler->
addUniform(
nullptr,
84 &atlasDimensionsInvName);
85#ifdef SK_GAMMA_APPLY_TO_A8
87 const char* distanceAdjustUniName =
nullptr;
91 &distanceAdjustUniName);
95 fragBuilder->codeAppendf(
"half4 %s;\n",
args.fOutputColor);
106 dfTexEffect.fLocalMatrix,
107 &fLocalMatrixUniform);
113 dfTexEffect.fInTextureCoords.
name(),
114 atlasDimensionsInvName,
126 fragBuilder->codeAppendf(
"float2 uv = %s;\n", uv.
fsIn());
127 fragBuilder->codeAppend(
"half4 texColor;");
129 texIdx,
"uv",
"texColor");
131 fragBuilder->codeAppend(
"half distance = "
133#ifdef SK_GAMMA_APPLY_TO_A8
135 fragBuilder->codeAppendf(
"distance -= %s;", distanceAdjustUniName);
138 fragBuilder->codeAppend(
"half afwidth;");
139 if (isUniformScale) {
145 if (
args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
146 fragBuilder->codeAppendf(
149 fragBuilder->codeAppendf(
152 }
else if (isSimilarity) {
159 if (
args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
160 fragBuilder->codeAppendf(
"half st_grad_len = length(half2(dFdy(%s)));", st.
fsIn());
162 fragBuilder->codeAppendf(
"half st_grad_len = length(half2(dFdx(%s)));", st.
fsIn());
169 fragBuilder->codeAppend(
"half2 dist_grad = half2(float2(dFdx(distance), "
170 "dFdy(distance)));");
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(
"}");
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);");
190 fragBuilder->codeAppend(
"half val = distance > 0 ? 1.0 : 0.0;");
191 }
else if (isGammaCorrect) {
195 fragBuilder->codeAppend(
196 "half val = saturate((distance + afwidth) / (2.0 * afwidth));");
198 fragBuilder->codeAppend(
"half val = smoothstep(-afwidth, afwidth, distance);");
201 fragBuilder->codeAppendf(
"half4 %s = half4(val);",
args.fOutputCoverage);
205#ifdef SK_GAMMA_APPLY_TO_A8
206 float fDistanceAdjust = -1.f;
208 SkISize fAtlasDimensions = {-1, -1};
220GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(
const GrShaderCaps& caps,
224#ifdef SK_GAMMA_APPLY_TO_A8
225 float distanceAdjust,
229 :
INHERITED(kGrDistanceFieldA8TextGeoProc_ClassID)
230 , fLocalMatrix(localMatrix)
232#ifdef SK_GAMMA_APPLY_TO_A8
233 , fDistanceAdjust(distanceAdjust)
252 for (
int i = 0; i < numViews; ++i) {
268 if (!fTextureSamplers[0].isInitialized()) {
272 for (
int i = 0; i < numViews; ++i) {
276 if (!fTextureSamplers[i].isInitialized()) {
287 key |= ProgramImpl::ComputeMatrixKey(caps, fLocalMatrix) << 16;
294 return std::make_unique<Impl>();
301#if defined(GR_TEST_UTILS)
303 auto [view, ct, at] =
d->randomAlphaOnlyView();
306 GrTest::TestWrapModes(
d->fRandom, wrapModes);
308 ? GrSamplerState::Filter::kLinear
316 SkMatrix localMatrix = GrTest::TestMatrix(
d->fRandom);
317#ifdef SK_GAMMA_APPLY_TO_A8
318 float lum =
d->fRandom->nextF();
323#ifdef SK_GAMMA_APPLY_TO_A8
341 SetTransform(pdman, shaderCaps, fLocalMatrixUniform, dfpgp.fLocalMatrix, &fLocalMatrix);
343 const SkISize& atlasDimensions = dfpgp.fAtlasDimensions;
345 if (fAtlasDimensions != atlasDimensions) {
346 pdman.
set2f(fAtlasDimensionsInvUniform,
347 1.0f / atlasDimensions.
fWidth,
348 1.0f / atlasDimensions.
fHeight);
349 fAtlasDimensions = atlasDimensions;
367 const char* atlasDimensionsInvName;
368 fAtlasDimensionsInvUniform = uniformHandler->
addUniform(
nullptr,
371 "AtlasDimensionsInv",
372 &atlasDimensionsInvName);
377 dfPathEffect.fInTextureCoords.
name(),
378 atlasDimensionsInvName,
384 fragBuilder->codeAppendf(
"half4 %s;",
args.fOutputColor);
390 WriteLocalCoord(vertBuilder,
395 dfPathEffect.fLocalMatrix,
396 &fLocalMatrixUniform);
399 fragBuilder->codeAppendf(
"float2 uv = %s;", uv.
fsIn());
400 fragBuilder->codeAppend(
"half4 texColor;");
404 fragBuilder->codeAppend(
"half distance = "
407 fragBuilder->codeAppend(
"half afwidth;");
412 if (isUniformScale) {
418 if (
args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
419 fragBuilder->codeAppendf(
422 fragBuilder->codeAppendf(
425 }
else if (isSimilarity) {
431 if (
args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
432 fragBuilder->codeAppendf(
"half st_grad_len = half(length(dFdy(%s)));", st.
fsIn());
434 fragBuilder->codeAppendf(
"half st_grad_len = half(length(dFdx(%s)));", st.
fsIn());
441 fragBuilder->codeAppend(
"half2 dist_grad = half2(dFdx(distance), "
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(
"}");
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);");
463 if (isGammaCorrect) {
464 fragBuilder->codeAppend(
465 "half val = saturate((distance + afwidth) / (2.0 * afwidth));");
467 fragBuilder->codeAppend(
"half val = smoothstep(-afwidth, afwidth, distance);");
470 fragBuilder->codeAppendf(
"half4 %s = half4(val);",
args.fOutputCoverage);
474 UniformHandle fLocalMatrixUniform;
477 UniformHandle fAtlasDimensionsInvUniform;
484GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
const GrShaderCaps& caps,
491 , fLocalMatrix(localMatrix)
506 for (
int i = 0; i < numViews; ++i) {
522 if (!fTextureSamplers[0].isInitialized()) {
526 for (
int i = 0; i < numViews; ++i) {
530 if (!fTextureSamplers[i].isInitialized()) {
539 uint32_t
key = fFlags;
540 key |= ProgramImpl::ComputeMatrixKey(caps, fLocalMatrix) << 16;
548 return std::make_unique<Impl>();
555#if defined(GR_TEST_UTILS)
557 auto [view, ct, at] =
d->randomAlphaOnlyView();
560 GrTest::TestWrapModes(
d->fRandom, wrapModes);
562 ? GrSamplerState::Filter::kLinear
571 SkMatrix localMatrix = GrTest::TestMatrix(
d->fRandom);
588 SkASSERT(fDistanceAdjustUni.isValid());
592 if (wa != fDistanceAdjust) {
593 pdman.
set3f(fDistanceAdjustUni, wa.fR, wa.fG, wa.fB);
594 fDistanceAdjust = wa;
597 const SkISize& atlasDimensions = dflcd.fAtlasDimensions;
599 if (fAtlasDimensions != atlasDimensions) {
600 pdman.
set2f(fAtlasDimensionsInvUniform,
601 1.0f / atlasDimensions.
fWidth,
602 1.0f / atlasDimensions.
fHeight);
603 fAtlasDimensions = atlasDimensions;
605 SetTransform(pdman, shaderCaps, fLocalMatrixUniform, dflcd.fLocalMatrix, &fLocalMatrix);
620 const char* atlasDimensionsInvName;
621 fAtlasDimensionsInvUniform = uniformHandler->
addUniform(
nullptr,
624 "AtlasDimensionsInv",
625 &atlasDimensionsInvName);
636 WriteLocalCoord(vertBuilder,
641 dfTexEffect.fLocalMatrix,
642 &fLocalMatrixUniform);
648 dfTexEffect.fInTextureCoords.
name(),
649 atlasDimensionsInvName,
657 vertBuilder->codeAppendf(
"%s = -%s.x/3.0;", delta.vsOut(), atlasDimensionsInvName);
659 vertBuilder->codeAppendf(
"%s = %s.x/3.0;", delta.vsOut(), atlasDimensionsInvName);
672 if (isUniformScale) {
673 if (
args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
674 fragBuilder->
codeAppendf(
"half st_grad_len = half(abs(dFdy(%s.y)));", st.
fsIn());
676 fragBuilder->
codeAppendf(
"half st_grad_len = half(abs(dFdx(%s.x)));", st.
fsIn());
678 fragBuilder->
codeAppendf(
"half2 offset = half2(half(st_grad_len*%s), 0.0);",
680 }
else if (isSimilarity) {
683 if (
args.fShaderCaps->fAvoidDfDxForGradientsWhenPossible) {
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));",
690 fragBuilder->
codeAppendf(
"half2 st_grad = half2(dFdx(%s));", st.
fsIn());
691 fragBuilder->
codeAppendf(
"half2 offset = half(%s)*st_grad;", delta.fsIn());
693 fragBuilder->
codeAppend(
"half st_grad_len = length(st_grad);");
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());
705 texIdx,
"uv",
"texColor");
709 fragBuilder->
codeAppend(
"distance.y = texColor.r;");
711 fragBuilder->
codeAppend(
"half2 uv_adjusted = half2(uv) - offset;");
713 texIdx,
"uv_adjusted",
"texColor");
714 fragBuilder->
codeAppend(
"distance.x = texColor.r;");
716 fragBuilder->
codeAppend(
"uv_adjusted = half2(uv) + offset;");
718 texIdx,
"uv_adjusted",
"texColor");
719 fragBuilder->
codeAppend(
"distance.z = texColor.r;");
725 const char* distanceAdjustUniName =
nullptr;
728 &distanceAdjustUniName);
729 fragBuilder->
codeAppendf(
"distance -= %s;", distanceAdjustUniName);
748 fragBuilder->
codeAppend(
"half2 dist_grad = half2(half(dFdx(distance.r)), "
749 "half(dFdy(distance.r)));");
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);");
756 fragBuilder->
codeAppend(
"dist_grad = dist_grad*half(inversesqrt(dg_len2));");
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);");
768 if (isGammaCorrect) {
770 "half4(saturate((distance + half3(afwidth)) / half3(2.0 * afwidth)), 1.0);",
771 args.fOutputCoverage);
774 "half4 %s = half4(smoothstep(half3(-afwidth), half3(afwidth), distance), 1.0);",
775 args.fOutputCoverage);
780 DistanceAdjust fDistanceAdjust = DistanceAdjust::Make(1.0f, 1.0f, 1.0f);
781 SkISize fAtlasDimensions = {-1, -1};
784 UniformHandle fDistanceAdjustUni;
785 UniformHandle fAtlasDimensionsInvUniform;
786 UniformHandle fLocalMatrixUniform;
791GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(
const GrShaderCaps& caps,
795 DistanceAdjust distanceAdjust,
799 , fLocalMatrix(localMatrix)
800 , fDistanceAdjust(distanceAdjust)
819 for (
int i = 0; i < numViews; ++i) {
835 if (!fTextureSamplers[0].isInitialized()) {
839 for (
int i = 0; i < numViews; ++i) {
843 if (!fTextureSamplers[i].isInitialized()) {
853 key |= ProgramImpl::ComputeMatrixKey(caps, fLocalMatrix);
861 return std::make_unique<Impl>();
868#if defined(GR_TEST_UTILS)
870 auto [view, ct, at] =
d->randomView();
873 GrTest::TestWrapModes(
d->fRandom, wrapModes);
875 ? GrSamplerState::Filter::kLinear
877 DistanceAdjust wa = { 0.0f, 0.1f, -0.1f };
884 SkMatrix localMatrix = GrTest::TestMatrix(
d->fRandom);
887 1, samplerState, wa,
flags, localMatrix);
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
@ kWideColor_DistanceFieldEffectFlag
@ kUseLCD_DistanceFieldEffectFlag
@ kPerspective_DistanceFieldEffectFlag
@ kSimilarity_DistanceFieldEffectFlag
@ kBGR_DistanceFieldEffectFlag
@ kScaleOnly_DistanceFieldEffectFlag
@ kAliased_DistanceFieldEffectFlag
@ kUniformScale_DistanceFieldEffectMask
@ kPath_DistanceFieldEffectMask
@ kNonLCD_DistanceFieldEffectMask
@ kLCD_DistanceFieldEffectMask
GrFragmentProcessor::ProgramImpl ProgramImpl
#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
@ kFloat2_GrVertexAttribType
@ kUShort2_GrVertexAttribType
@ kUByte4_norm_GrVertexAttribType
@ kFloat3_GrVertexAttribType
#define SK_DistanceFieldMultiplier
#define SK_DistanceFieldThreshold
constexpr bool SkIsPow2(T value)
#define INHERITED(method,...)
static constexpr bool SkToBool(const T &x)
void setData(const GrGLSLProgramDataManager &pdman, const GrShaderCaps &shaderCaps, const GrGeometryProcessor &geomProc) override
void onEmitCode(EmitArgs &args, GrGPArgs *gpArgs) override
static GrGeometryProcessor * Make(SkArenaAlloc *arena, const GrShaderCaps &caps, const GrSurfaceProxyView *views, int numActiveViews, GrSamplerState params, uint32_t flags, const SkMatrix &localMatrixIfUsesLocalCoords)
void addNewViews(const GrSurfaceProxyView *views, int numViews, GrSamplerState)
void addToKey(const GrShaderCaps &, skgpu::KeyBuilder *) const override
std::unique_ptr< ProgramImpl > makeProgramImpl(const GrShaderCaps &) const override
static constexpr int kMaxTextures
void onEmitCode(EmitArgs &args, GrGPArgs *gpArgs) override
void setData(const GrGLSLProgramDataManager &pdman, const GrShaderCaps &shaderCaps, const GrGeometryProcessor &geomProc) override
static GrGeometryProcessor * Make(SkArenaAlloc *arena, const GrShaderCaps &caps, const GrSurfaceProxyView *views, int numActiveViews, GrSamplerState params, DistanceAdjust distanceAdjust, uint32_t flags, const SkMatrix &localMatrixIfUsesLocalCoords)
void addNewViews(const GrSurfaceProxyView *, int numActiveViews, GrSamplerState)
std::unique_ptr< ProgramImpl > makeProgramImpl(const GrShaderCaps &) const override
static constexpr int kMaxTextures
void addToKey(const GrShaderCaps &, skgpu::KeyBuilder *) const override
void setData(const GrGLSLProgramDataManager &pdman, const GrShaderCaps &shaderCaps, const GrGeometryProcessor &geomProc) override
void onEmitCode(EmitArgs &args, GrGPArgs *gpArgs) override
void addNewViews(const GrSurfaceProxyView *, int numActiveViews, GrSamplerState)
void addToKey(const GrShaderCaps &, skgpu::KeyBuilder *) const override
static GrGeometryProcessor * Make(SkArenaAlloc *arena, const GrShaderCaps &caps, const GrSurfaceProxyView *views, int numActiveViews, GrSamplerState params, const SkMatrix &localMatrix, uint32_t flags)
static constexpr int kMaxTextures
std::unique_ptr< ProgramImpl > makeProgramImpl(const GrShaderCaps &) const override
virtual void set2f(UniformHandle, float, float) const =0
virtual void set3f(UniformHandle, float, float, float) const =0
virtual void set1f(UniformHandle, float v0) const =0
void codeAppend(const char *str)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
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
GrShaderVar asShaderVar() const
constexpr const char * name() const
GrGLSLProgramDataManager::UniformHandle UniformHandle
static void WriteLocalCoord(GrGLSLVertexBuilder *, GrGLSLUniformHandler *, const GrShaderCaps &, GrGPArgs *, GrShaderVar localVar, const SkMatrix &localMatrix, UniformHandle *localMatrixUniform)
static void SetTransform(const GrGLSLProgramDataManager &, const GrShaderCaps &, const UniformHandle &uniform, const SkMatrix &matrix, SkMatrix *state=nullptr)
void reset(GrSamplerState, const GrBackendFormat &, const skgpu::Swizzle &)
int numTextureSamplers() const
void setTextureSamplerCnt(int cnt)
static Attribute MakeColorAttribute(const char *name, bool wideColor)
void setVertexAttributesWithImplicitOffsets(const Attribute *attrs, int attrCount)
@ kGrDistanceFieldLCDTextGeoProc_ClassID
@ kGrDistanceFieldPathGeoProc_ClassID
skgpu::Swizzle swizzle() const
GrSurfaceProxy * proxy() const
const GrBackendFormat & backendFormat() const
SkISize dimensions() const
bool hasPerspective() const
static const SkMatrix & InvalidMatrix()
const EmbeddedViewParams * params
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static float lum(float r, float g, float b)