| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDistanceFieldGeoProc.h" | 8 #include "GrDistanceFieldGeoProc.h" |
| 9 #include "GrInvariantOutput.h" | 9 #include "GrInvariantOutput.h" |
| 10 #include "GrTexture.h" | 10 #include "GrTexture.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 , fColor(GrColor_ILLEGAL) | 28 , fColor(GrColor_ILLEGAL) |
| 29 #ifdef SK_GAMMA_APPLY_TO_A8 | 29 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 30 , fDistanceAdjust(-1.0f) | 30 , fDistanceAdjust(-1.0f) |
| 31 #endif | 31 #endif |
| 32 {} | 32 {} |
| 33 | 33 |
| 34 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 34 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
| 35 const GrDistanceFieldA8TextGeoProc& dfTexEffect = | 35 const GrDistanceFieldA8TextGeoProc& dfTexEffect = |
| 36 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); | 36 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); |
| 37 GrGLSLGPBuilder* pb = args.fPB; | 37 GrGLSLGPBuilder* pb = args.fPB; |
| 38 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); | 38 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 39 SkAssertResult(fsBuilder->enableFeature( | 39 SkAssertResult(fragBuilder->enableFeature( |
| 40 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 40 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
| 41 | 41 |
| 42 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); | 42 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| 43 | 43 |
| 44 // emit attributes | 44 // emit attributes |
| 45 vsBuilder->emitAttributes(dfTexEffect); | 45 vertBuilder->emitAttributes(dfTexEffect); |
| 46 | 46 |
| 47 #ifdef SK_GAMMA_APPLY_TO_A8 | 47 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 48 // adjust based on gamma | 48 // adjust based on gamma |
| 49 const char* distanceAdjustUniName = nullptr; | 49 const char* distanceAdjustUniName = nullptr; |
| 50 // width, height, 1/(3*width) | 50 // width, height, 1/(3*width) |
| 51 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, | 51 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, |
| 52 kFloat_GrSLType, kDefault_GrSLPrecision, | 52 kFloat_GrSLType, kDefault_GrSLPrecision, |
| 53 "DistanceAdjust", &distanceAdjustUniName); | 53 "DistanceAdjust", &distanceAdjustUniName); |
| 54 #endif | 54 #endif |
| 55 | 55 |
| 56 // Setup pass through color | 56 // Setup pass through color |
| 57 if (!dfTexEffect.colorIgnored()) { | 57 if (!dfTexEffect.colorIgnored()) { |
| 58 if (dfTexEffect.hasVertexColor()) { | 58 if (dfTexEffect.hasVertexColor()) { |
| 59 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); | 59 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); |
| 60 } else { | 60 } else { |
| 61 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); | 61 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 | 64 |
| 65 // Setup position | 65 // Setup position |
| 66 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf
fect.viewMatrix(), | 66 this->setupPosition(pb, |
| 67 vertBuilder, |
| 68 gpArgs, |
| 69 dfTexEffect.inPosition()->fName, |
| 70 dfTexEffect.viewMatrix(), |
| 67 &fViewMatrixUniform); | 71 &fViewMatrixUniform); |
| 68 | 72 |
| 69 // emit transforms | 73 // emit transforms |
| 70 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()-
>fName, | 74 this->emitTransforms(pb, |
| 71 args.fTransformsIn, args.fTransformsOut); | 75 vertBuilder, |
| 76 gpArgs->fPositionVar, |
| 77 dfTexEffect.inPosition()->fName, |
| 78 args.fTransformsIn, |
| 79 args.fTransformsOut); |
| 72 | 80 |
| 73 // add varyings | 81 // add varyings |
| 74 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 82 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
| 75 GrGLSLVertToFrag st(kVec2f_GrSLType); | 83 GrGLSLVertToFrag st(kVec2f_GrSLType); |
| 76 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 84 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
| 77 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); | 85 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| 78 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor
ds()->fName); | 86 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo
ords()->fName); |
| 79 | 87 |
| 80 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float | 88 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float |
| 81 SkASSERT(dfTexEffect.numTextures() == 1); | 89 SkASSERT(dfTexEffect.numTextures() == 1); |
| 82 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); | 90 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); |
| 83 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; | 91 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; |
| 84 SkScalar recipWidth = 1.0f / atlas->width(); | 92 SkScalar recipWidth = 1.0f / atlas->width(); |
| 85 SkScalar recipHeight = 1.0f / atlas->height(); | 93 SkScalar recipHeight = 1.0f / atlas->height(); |
| 86 | 94 |
| 87 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 95 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
| 88 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 96 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| 89 vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), | 97 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), |
| 90 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, | 98 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, |
| 91 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, | 99 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, |
| 92 dfTexEffect.inTextureCoords()->fName); | 100 dfTexEffect.inTextureCoords()->fName); |
| 93 | 101 |
| 94 // Use highp to work around aliasing issues | 102 // Use highp to work around aliasing issues |
| 95 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 103 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
| 96 kHigh_GrSLPrecisi
on)); | 104 kHigh_GrSLPreci
sion)); |
| 97 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 105 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
| 98 | 106 |
| 99 fsBuilder->codeAppend("\tfloat texColor = "); | 107 fragBuilder->codeAppend("\tfloat texColor = "); |
| 100 fsBuilder->appendTextureLookup(args.fSamplers[0], | 108 fragBuilder->appendTextureLookup(args.fSamplers[0], |
| 101 "uv", | 109 "uv", |
| 102 kVec2f_GrSLType); | 110 kVec2f_GrSLType); |
| 103 fsBuilder->codeAppend(".r;\n"); | 111 fragBuilder->codeAppend(".r;\n"); |
| 104 fsBuilder->codeAppend("\tfloat distance = " | 112 fragBuilder->codeAppend("\tfloat distance = " |
| 105 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie
ldThreshold ");"); | 113 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie
ldThreshold ");"); |
| 106 #ifdef SK_GAMMA_APPLY_TO_A8 | 114 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 107 // adjust width based on gamma | 115 // adjust width based on gamma |
| 108 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 116 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
| 109 #endif | 117 #endif |
| 110 | 118 |
| 111 fsBuilder->codeAppend("float afwidth;"); | 119 fragBuilder->codeAppend("float afwidth;"); |
| 112 if (isSimilarity) { | 120 if (isSimilarity) { |
| 113 // For uniform scale, we adjust for the effect of the transformation
on the distance | 121 // For uniform scale, we adjust for the effect of the transformation
on the distance |
| 114 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 122 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
| 115 // to ensure we're mapping 1:1 from texel space to pixel space. | 123 // to ensure we're mapping 1:1 from texel space to pixel space. |
| 116 | 124 |
| 117 // this gives us a smooth step across approximately one fragment | 125 // this gives us a smooth step across approximately one fragment |
| 118 // we use y to work around a Mali400 bug in the x direction | 126 // we use y to work around a Mali400 bug in the x direction |
| 119 fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*d
Fdy(%s.y));", | 127 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "
*dFdy(%s.y));", |
| 120 st.fsIn()); | 128 st.fsIn()); |
| 121 } else { | 129 } else { |
| 122 // For general transforms, to determine the amount of correction we
multiply a unit | 130 // For general transforms, to determine the amount of correction we
multiply a unit |
| 123 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 131 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
| 124 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 132 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
| 125 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(di
stance));"); | 133 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(
distance));"); |
| 126 // the length of the gradient may be 0, so we need to check for this | 134 // the length of the gradient may be 0, so we need to check for this |
| 127 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 | 135 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 |
| 128 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); | 136 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"
); |
| 129 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); | 137 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); |
| 130 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); | 138 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); |
| 131 fsBuilder->codeAppend("} else {"); | 139 fragBuilder->codeAppend("} else {"); |
| 132 fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);")
; | 140 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);
"); |
| 133 fsBuilder->codeAppend("}"); | 141 fragBuilder->codeAppend("}"); |
| 134 | 142 |
| 135 fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn()); | 143 fragBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn()); |
| 136 fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn()); | 144 fragBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn()); |
| 137 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra
d.y*Jdy.x,"); | 145 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g
rad.y*Jdy.x,"); |
| 138 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra
d.y*Jdy.y);"); | 146 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g
rad.y*Jdy.y);"); |
| 139 | 147 |
| 140 // this gives us a smooth step across approximately one fragment | 148 // this gives us a smooth step across approximately one fragment |
| 141 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length
(grad);"); | 149 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng
th(grad);"); |
| 142 } | 150 } |
| 143 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc
e);"); | 151 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista
nce);"); |
| 144 | 152 |
| 145 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 153 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
| 146 } | 154 } |
| 147 | 155 |
| 148 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { | 156 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { |
| 149 #ifdef SK_GAMMA_APPLY_TO_A8 | 157 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 150 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi
eldA8TextGeoProc>(); | 158 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi
eldA8TextGeoProc>(); |
| 151 float distanceAdjust = dfTexEffect.getDistanceAdjust(); | 159 float distanceAdjust = dfTexEffect.getDistanceAdjust(); |
| 152 if (distanceAdjust != fDistanceAdjust) { | 160 if (distanceAdjust != fDistanceAdjust) { |
| 153 pdman.set1f(fDistanceAdjustUni, distanceAdjust); | 161 pdman.set1f(fDistanceAdjustUni, distanceAdjust); |
| 154 fDistanceAdjust = distanceAdjust; | 162 fDistanceAdjust = distanceAdjust; |
| 155 } | 163 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 public: | 287 public: |
| 280 GrGLDistanceFieldPathGeoProc() | 288 GrGLDistanceFieldPathGeoProc() |
| 281 : fViewMatrix(SkMatrix::InvalidMatrix()) | 289 : fViewMatrix(SkMatrix::InvalidMatrix()) |
| 282 , fColor(GrColor_ILLEGAL) | 290 , fColor(GrColor_ILLEGAL) |
| 283 , fTextureSize(SkISize::Make(-1, -1)) {} | 291 , fTextureSize(SkISize::Make(-1, -1)) {} |
| 284 | 292 |
| 285 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 293 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
| 286 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); | 294 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); |
| 287 | 295 |
| 288 GrGLSLGPBuilder* pb = args.fPB; | 296 GrGLSLGPBuilder* pb = args.fPB; |
| 289 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); | 297 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 290 SkAssertResult(fsBuilder->enableFeature( | 298 SkAssertResult(fragBuilder->enableFeature( |
| 291 GrGLSLFragmentShaderBuilder::kStandardDeriv
atives_GLSLFeature)); | 299 GrGLSLFragmentShaderBuilder::kStandardDeriv
atives_GLSLFeature)); |
| 292 | 300 |
| 293 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); | 301 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| 294 | 302 |
| 295 // emit attributes | 303 // emit attributes |
| 296 vsBuilder->emitAttributes(dfTexEffect); | 304 vertBuilder->emitAttributes(dfTexEffect); |
| 297 | 305 |
| 298 GrGLSLVertToFrag v(kVec2f_GrSLType); | 306 GrGLSLVertToFrag v(kVec2f_GrSLType); |
| 299 pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); | 307 pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); |
| 300 | 308 |
| 301 // setup pass through color | 309 // setup pass through color |
| 302 if (!dfTexEffect.colorIgnored()) { | 310 if (!dfTexEffect.colorIgnored()) { |
| 303 if (dfTexEffect.hasVertexColor()) { | 311 if (dfTexEffect.hasVertexColor()) { |
| 304 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); | 312 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); |
| 305 } else { | 313 } else { |
| 306 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); | 314 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); |
| 307 } | 315 } |
| 308 } | 316 } |
| 309 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); | 317 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoo
rds()->fName); |
| 310 | 318 |
| 311 // Setup position | 319 // Setup position |
| 312 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf
fect.viewMatrix(), | 320 this->setupPosition(pb, |
| 321 vertBuilder, |
| 322 gpArgs, |
| 323 dfTexEffect.inPosition()->fName, |
| 324 dfTexEffect.viewMatrix(), |
| 313 &fViewMatrixUniform); | 325 &fViewMatrixUniform); |
| 314 | 326 |
| 315 // emit transforms | 327 // emit transforms |
| 316 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()-
>fName, | 328 this->emitTransforms(pb, |
| 317 args.fTransformsIn, args.fTransformsOut); | 329 vertBuilder, |
| 330 gpArgs->fPositionVar, |
| 331 dfTexEffect.inPosition()->fName, |
| 332 args.fTransformsIn, |
| 333 args.fTransformsOut); |
| 318 | 334 |
| 319 const char* textureSizeUniName = nullptr; | 335 const char* textureSizeUniName = nullptr; |
| 320 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil
ity, | 336 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil
ity, |
| 321 kVec2f_GrSLType, kDefault_GrSLPrecision
, | 337 kVec2f_GrSLType, kDefault_GrSLPrecision
, |
| 322 "TextureSize", &textureSizeUniName); | 338 "TextureSize", &textureSizeUniName); |
| 323 | 339 |
| 324 // Use highp to work around aliasing issues | 340 // Use highp to work around aliasing issues |
| 325 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 341 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
| 326 kHigh_GrSLPrecisi
on)); | 342 kHigh_GrSLPreci
sion)); |
| 327 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); | 343 fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); |
| 328 | 344 |
| 329 fsBuilder->codeAppend("float texColor = "); | 345 fragBuilder->codeAppend("float texColor = "); |
| 330 fsBuilder->appendTextureLookup(args.fSamplers[0], | 346 fragBuilder->appendTextureLookup(args.fSamplers[0], |
| 331 "uv", | 347 "uv", |
| 332 kVec2f_GrSLType); | 348 kVec2f_GrSLType); |
| 333 fsBuilder->codeAppend(".r;"); | 349 fragBuilder->codeAppend(".r;"); |
| 334 fsBuilder->codeAppend("float distance = " | 350 fragBuilder->codeAppend("float distance = " |
| 335 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold
");"); | 351 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold
");"); |
| 336 | 352 |
| 337 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 353 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
| 338 kHigh_GrSLPrecisi
on)); | 354 kHigh_GrSLPreci
sion)); |
| 339 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); | 355 fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); |
| 340 fsBuilder->codeAppend("float afwidth;"); | 356 fragBuilder->codeAppend("float afwidth;"); |
| 341 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { | 357 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
| 342 // For uniform scale, we adjust for the effect of the transformation
on the distance | 358 // For uniform scale, we adjust for the effect of the transformation
on the distance |
| 343 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 359 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
| 344 // to ensure we're mapping 1:1 from texel space to pixel space. | 360 // to ensure we're mapping 1:1 from texel space to pixel space. |
| 345 | 361 |
| 346 // this gives us a smooth step across approximately one fragment | 362 // this gives us a smooth step across approximately one fragment |
| 347 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF
dy(st.y));"); | 363 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
dFdy(st.y));"); |
| 348 } else { | 364 } else { |
| 349 // For general transforms, to determine the amount of correction we
multiply a unit | 365 // For general transforms, to determine the amount of correction we
multiply a unit |
| 350 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 366 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
| 351 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 367 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
| 352 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(di
stance));"); | 368 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(
distance));"); |
| 353 // the length of the gradient may be 0, so we need to check for this | 369 // the length of the gradient may be 0, so we need to check for this |
| 354 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 | 370 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 |
| 355 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); | 371 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"
); |
| 356 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); | 372 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); |
| 357 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); | 373 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); |
| 358 fsBuilder->codeAppend("} else {"); | 374 fragBuilder->codeAppend("} else {"); |
| 359 fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);")
; | 375 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);
"); |
| 360 fsBuilder->codeAppend("}"); | 376 fragBuilder->codeAppend("}"); |
| 361 | 377 |
| 362 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); | 378 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
| 363 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); | 379 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
| 364 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra
d.y*Jdy.x,"); | 380 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g
rad.y*Jdy.x,"); |
| 365 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra
d.y*Jdy.y);"); | 381 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g
rad.y*Jdy.y);"); |
| 366 | 382 |
| 367 // this gives us a smooth step across approximately one fragment | 383 // this gives us a smooth step across approximately one fragment |
| 368 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length
(grad);"); | 384 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng
th(grad);"); |
| 369 } | 385 } |
| 370 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc
e);"); | 386 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista
nce);"); |
| 371 | 387 |
| 372 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 388 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
| 373 } | 389 } |
| 374 | 390 |
| 375 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { | 391 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { |
| 376 SkASSERT(fTextureSizeUni.isValid()); | 392 SkASSERT(fTextureSizeUni.isValid()); |
| 377 | 393 |
| 378 GrTexture* texture = proc.texture(0); | 394 GrTexture* texture = proc.texture(0); |
| 379 if (texture->width() != fTextureSize.width() || | 395 if (texture->width() != fTextureSize.width() || |
| 380 texture->height() != fTextureSize.height()) { | 396 texture->height() != fTextureSize.height()) { |
| 381 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 397 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
| 382 pdman.set2f(fTextureSizeUni, | 398 pdman.set2f(fTextureSizeUni, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 GrGLDistanceFieldLCDTextGeoProc() | 511 GrGLDistanceFieldLCDTextGeoProc() |
| 496 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { | 512 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { |
| 497 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); | 513 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); |
| 498 } | 514 } |
| 499 | 515 |
| 500 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 516 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
| 501 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = | 517 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = |
| 502 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); | 518 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); |
| 503 GrGLSLGPBuilder* pb = args.fPB; | 519 GrGLSLGPBuilder* pb = args.fPB; |
| 504 | 520 |
| 505 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); | 521 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| 506 | 522 |
| 507 // emit attributes | 523 // emit attributes |
| 508 vsBuilder->emitAttributes(dfTexEffect); | 524 vertBuilder->emitAttributes(dfTexEffect); |
| 525 |
| 526 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 509 | 527 |
| 510 // setup pass through color | 528 // setup pass through color |
| 511 if (!dfTexEffect.colorIgnored()) { | 529 if (!dfTexEffect.colorIgnored()) { |
| 512 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); | 530 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorU
niform); |
| 513 } | 531 } |
| 514 | 532 |
| 515 // Setup position | 533 // Setup position |
| 516 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf
fect.viewMatrix(), | 534 this->setupPosition(pb, |
| 535 vertBuilder, |
| 536 gpArgs, |
| 537 dfTexEffect.inPosition()->fName, |
| 538 dfTexEffect.viewMatrix(), |
| 517 &fViewMatrixUniform); | 539 &fViewMatrixUniform); |
| 518 | 540 |
| 519 // emit transforms | 541 // emit transforms |
| 520 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()-
>fName, | 542 this->emitTransforms(pb, |
| 521 args.fTransformsIn, args.fTransformsOut); | 543 vertBuilder, |
| 544 gpArgs->fPositionVar, |
| 545 dfTexEffect.inPosition()->fName, |
| 546 args.fTransformsIn, |
| 547 args.fTransformsOut); |
| 522 | 548 |
| 523 // set up varyings | 549 // set up varyings |
| 524 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); | 550 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); |
| 525 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 551 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
| 526 GrGLSLVertToFrag st(kVec2f_GrSLType); | 552 GrGLSLVertToFrag st(kVec2f_GrSLType); |
| 527 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); | 553 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| 528 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor
ds()->fName); | 554 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo
ords()->fName); |
| 529 | 555 |
| 530 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float | 556 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float |
| 531 SkASSERT(dfTexEffect.numTextures() == 1); | 557 SkASSERT(dfTexEffect.numTextures() == 1); |
| 532 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); | 558 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); |
| 533 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; | 559 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; |
| 534 SkScalar recipWidth = 1.0f / atlas->width(); | 560 SkScalar recipWidth = 1.0f / atlas->width(); |
| 535 SkScalar recipHeight = 1.0f / atlas->height(); | 561 SkScalar recipHeight = 1.0f / atlas->height(); |
| 536 | 562 |
| 537 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 563 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
| 538 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 564 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| 539 vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), | 565 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), |
| 540 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, | 566 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, |
| 541 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, | 567 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, |
| 542 dfTexEffect.inTextureCoords()->fName); | 568 dfTexEffect.inTextureCoords()->fName); |
| 543 | 569 |
| 544 // add frag shader code | 570 // add frag shader code |
| 545 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); | |
| 546 | 571 |
| 547 SkAssertResult(fsBuilder->enableFeature( | 572 SkAssertResult(fragBuilder->enableFeature( |
| 548 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 573 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
| 549 | 574 |
| 550 // create LCD offset adjusted by inverse of transform | 575 // create LCD offset adjusted by inverse of transform |
| 551 // Use highp to work around aliasing issues | 576 // Use highp to work around aliasing issues |
| 552 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 577 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
| 553 kHigh_GrSLPrecisi
on)); | 578 kHigh_GrSLPreci
sion)); |
| 554 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 579 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
| 555 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 580 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
| 556 kHigh_GrSLPrecisi
on)); | 581 kHigh_GrSLPreci
sion)); |
| 557 | 582 |
| 558 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); | 583 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); |
| 559 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { | 584 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { |
| 560 fsBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG,
lcdDelta); | 585 fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DI
G, lcdDelta); |
| 561 } else { | 586 } else { |
| 562 fsBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG,
lcdDelta); | 587 fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG
, lcdDelta); |
| 563 } | 588 } |
| 564 if (isUniformScale) { | 589 if (isUniformScale) { |
| 565 fsBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn()); | 590 fragBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn()); |
| 566 fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);"); | 591 fragBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);"); |
| 567 } else { | 592 } else { |
| 568 fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); | 593 fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); |
| 569 | 594 |
| 570 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); | 595 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
| 571 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); | 596 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
| 572 fsBuilder->codeAppend("vec2 offset = delta*Jdx;"); | 597 fragBuilder->codeAppend("vec2 offset = delta*Jdx;"); |
| 573 } | 598 } |
| 574 | 599 |
| 575 // green is distance to uv center | 600 // green is distance to uv center |
| 576 fsBuilder->codeAppend("\tvec4 texColor = "); | 601 fragBuilder->codeAppend("\tvec4 texColor = "); |
| 577 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType)
; | 602 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLTyp
e); |
| 578 fsBuilder->codeAppend(";\n"); | 603 fragBuilder->codeAppend(";\n"); |
| 579 fsBuilder->codeAppend("\tvec3 distance;\n"); | 604 fragBuilder->codeAppend("\tvec3 distance;\n"); |
| 580 fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); | 605 fragBuilder->codeAppend("\tdistance.y = texColor.r;\n"); |
| 581 // red is distance to left offset | 606 // red is distance to left offset |
| 582 fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); | 607 fragBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); |
| 583 fsBuilder->codeAppend("\ttexColor = "); | 608 fragBuilder->codeAppend("\ttexColor = "); |
| 584 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_
GrSLType); | 609 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2
f_GrSLType); |
| 585 fsBuilder->codeAppend(";\n"); | 610 fragBuilder->codeAppend(";\n"); |
| 586 fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); | 611 fragBuilder->codeAppend("\tdistance.x = texColor.r;\n"); |
| 587 // blue is distance to right offset | 612 // blue is distance to right offset |
| 588 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); | 613 fragBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); |
| 589 fsBuilder->codeAppend("\ttexColor = "); | 614 fragBuilder->codeAppend("\ttexColor = "); |
| 590 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_
GrSLType); | 615 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2
f_GrSLType); |
| 591 fsBuilder->codeAppend(";\n"); | 616 fragBuilder->codeAppend(";\n"); |
| 592 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); | 617 fragBuilder->codeAppend("\tdistance.z = texColor.r;\n"); |
| 593 | 618 |
| 594 fsBuilder->codeAppend("\tdistance = " | 619 fragBuilder->codeAppend("\tdistance = " |
| 595 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF
ieldThreshold"));"); | 620 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF
ieldThreshold"));"); |
| 596 | 621 |
| 597 // adjust width based on gamma | 622 // adjust width based on gamma |
| 598 const char* distanceAdjustUniName = nullptr; | 623 const char* distanceAdjustUniName = nullptr; |
| 599 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, | 624 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, |
| 600 kVec3f_GrSLType, kDefault_GrSLPrecision, | 625 kVec3f_GrSLType, kDefault_GrSLPrecision, |
| 601 "DistanceAdjust", &distanceAdjustUniName); | 626 "DistanceAdjust", &distanceAdjustUniName); |
| 602 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 627 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
| 603 | 628 |
| 604 // To be strictly correct, we should compute the anti-aliasing factor se
parately | 629 // To be strictly correct, we should compute the anti-aliasing factor se
parately |
| 605 // for each color component. However, this is only important when using
perspective | 630 // for each color component. However, this is only important when using
perspective |
| 606 // transformations, and even then using a single factor seems like a rea
sonable | 631 // transformations, and even then using a single factor seems like a rea
sonable |
| 607 // trade-off between quality and speed. | 632 // trade-off between quality and speed. |
| 608 fsBuilder->codeAppend("float afwidth;"); | 633 fragBuilder->codeAppend("float afwidth;"); |
| 609 if (isUniformScale) { | 634 if (isUniformScale) { |
| 610 // For uniform scale, we adjust for the effect of the transformation
on the distance | 635 // For uniform scale, we adjust for the effect of the transformation
on the distance |
| 611 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 636 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
| 612 // to ensure we're mapping 1:1 from texel space to pixel space. | 637 // to ensure we're mapping 1:1 from texel space to pixel space. |
| 613 | 638 |
| 614 // this gives us a smooth step across approximately one fragment | 639 // this gives us a smooth step across approximately one fragment |
| 615 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;"); | 640 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;"
); |
| 616 } else { | 641 } else { |
| 617 // For general transforms, to determine the amount of correction we
multiply a unit | 642 // For general transforms, to determine the amount of correction we
multiply a unit |
| 618 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 643 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
| 619 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 644 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
| 620 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(
distance.r));"); | 645 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFd
y(distance.r));"); |
| 621 // the length of the gradient may be 0, so we need to check for this | 646 // the length of the gradient may be 0, so we need to check for this |
| 622 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 | 647 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 |
| 623 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); | 648 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"
); |
| 624 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); | 649 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); |
| 625 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); | 650 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); |
| 626 fsBuilder->codeAppend("} else {"); | 651 fragBuilder->codeAppend("} else {"); |
| 627 fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);")
; | 652 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);
"); |
| 628 fsBuilder->codeAppend("}"); | 653 fragBuilder->codeAppend("}"); |
| 629 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra
d.y*Jdy.x,"); | 654 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g
rad.y*Jdy.x,"); |
| 630 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra
d.y*Jdy.y);"); | 655 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g
rad.y*Jdy.y);"); |
| 631 | 656 |
| 632 // this gives us a smooth step across approximately one fragment | 657 // this gives us a smooth step across approximately one fragment |
| 633 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length
(grad);"); | 658 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng
th(grad);"); |
| 634 } | 659 } |
| 635 | 660 |
| 636 fsBuilder->codeAppend( | 661 fragBuilder->codeAppend( |
| 637 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth),
distance), 1.0);"); | 662 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth),
distance), 1.0);"); |
| 638 // set alpha to be max of rgb coverage | 663 // set alpha to be max of rgb coverage |
| 639 fsBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);"); | 664 fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);"); |
| 640 | 665 |
| 641 fsBuilder->codeAppendf("%s = val;", args.fOutputCoverage); | 666 fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage); |
| 642 } | 667 } |
| 643 | 668 |
| 644 void setData(const GrGLSLProgramDataManager& pdman, | 669 void setData(const GrGLSLProgramDataManager& pdman, |
| 645 const GrPrimitiveProcessor& processor) override { | 670 const GrPrimitiveProcessor& processor) override { |
| 646 SkASSERT(fDistanceAdjustUni.isValid()); | 671 SkASSERT(fDistanceAdjustUni.isValid()); |
| 647 | 672 |
| 648 const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFi
eldLCDTextGeoProc>(); | 673 const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFi
eldLCDTextGeoProc>(); |
| 649 GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.getDistanceAdju
st(); | 674 GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.getDistanceAdju
st(); |
| 650 if (wa != fDistanceAdjust) { | 675 if (wa != fDistanceAdjust) { |
| 651 pdman.set3f(fDistanceAdjustUni, | 676 pdman.set3f(fDistanceAdjustUni, |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 777 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
| 753 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 778 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
| 754 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 779 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
| 755 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), | 780 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), |
| 756 GrTest::TestMatrix(d->fRandom), | 781 GrTest::TestMatrix(d->fRandom), |
| 757 d->fTextures[texIdx], params, | 782 d->fTextures[texIdx], params, |
| 758 wa, | 783 wa, |
| 759 flags, | 784 flags, |
| 760 d->fRandom->nextBool()); | 785 d->fRandom->nextBool()); |
| 761 } | 786 } |
| OLD | NEW |