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" |
11 | 11 |
12 #include "SkDistanceFieldGen.h" | 12 #include "SkDistanceFieldGen.h" |
13 | 13 |
14 #include "gl/GrGLFragmentProcessor.h" | 14 #include "gl/GrGLFragmentProcessor.h" |
15 #include "gl/GrGLTexture.h" | 15 #include "gl/GrGLTexture.h" |
16 #include "gl/GrGLGeometryProcessor.h" | 16 #include "gl/GrGLGeometryProcessor.h" |
17 #include "gl/builders/GrGLProgramBuilder.h" | 17 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
| 18 #include "glsl/GrGLSLProgramBuilder.h" |
18 #include "glsl/GrGLSLProgramDataManager.h" | 19 #include "glsl/GrGLSLProgramDataManager.h" |
| 20 #include "glsl/GrGLSLVertexShaderBuilder.h" |
19 | 21 |
20 // Assuming a radius of a little less than the diagonal of the fragment | 22 // Assuming a radius of a little less than the diagonal of the fragment |
21 #define SK_DistanceFieldAAFactor "0.65" | 23 #define SK_DistanceFieldAAFactor "0.65" |
22 | 24 |
23 class GrGLDistanceFieldA8TextGeoProc : public GrGLGeometryProcessor { | 25 class GrGLDistanceFieldA8TextGeoProc : public GrGLGeometryProcessor { |
24 public: | 26 public: |
25 GrGLDistanceFieldA8TextGeoProc() | 27 GrGLDistanceFieldA8TextGeoProc() |
26 : fViewMatrix(SkMatrix::InvalidMatrix()) | 28 : fViewMatrix(SkMatrix::InvalidMatrix()) |
27 , fColor(GrColor_ILLEGAL) | 29 , fColor(GrColor_ILLEGAL) |
28 #ifdef SK_GAMMA_APPLY_TO_A8 | 30 #ifdef SK_GAMMA_APPLY_TO_A8 |
29 , fDistanceAdjust(-1.0f) | 31 , fDistanceAdjust(-1.0f) |
30 #endif | 32 #endif |
31 {} | 33 {} |
32 | 34 |
33 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 35 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
34 const GrDistanceFieldA8TextGeoProc& dfTexEffect = | 36 const GrDistanceFieldA8TextGeoProc& dfTexEffect = |
35 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); | 37 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); |
36 GrGLSLGPBuilder* pb = args.fPB; | 38 GrGLSLGPBuilder* pb = args.fPB; |
37 GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); | 39 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); |
38 SkAssertResult(fsBuilder->enableFeature( | 40 SkAssertResult(fsBuilder->enableFeature( |
39 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 41 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
40 | 42 |
41 GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); | 43 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); |
42 | 44 |
43 // emit attributes | 45 // emit attributes |
44 vsBuilder->emitAttributes(dfTexEffect); | 46 vsBuilder->emitAttributes(dfTexEffect); |
45 | 47 |
46 #ifdef SK_GAMMA_APPLY_TO_A8 | 48 #ifdef SK_GAMMA_APPLY_TO_A8 |
47 // adjust based on gamma | 49 // adjust based on gamma |
48 const char* distanceAdjustUniName = nullptr; | 50 const char* distanceAdjustUniName = nullptr; |
49 // width, height, 1/(3*width) | 51 // width, height, 1/(3*width) |
50 fDistanceAdjustUni = pb->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 52 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, |
51 kFloat_GrSLType, kDefault_GrSLPrecision, | 53 kFloat_GrSLType, kDefault_GrSLPrecision, |
52 "DistanceAdjust", &distanceAdjustUniName); | 54 "DistanceAdjust", &distanceAdjustUniName); |
53 #endif | 55 #endif |
54 | 56 |
55 // Setup pass through color | 57 // Setup pass through color |
56 if (!dfTexEffect.colorIgnored()) { | 58 if (!dfTexEffect.colorIgnored()) { |
57 if (dfTexEffect.hasVertexColor()) { | 59 if (dfTexEffect.hasVertexColor()) { |
58 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); | 60 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); |
59 } else { | 61 } else { |
60 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); | 62 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 public: | 280 public: |
279 GrGLDistanceFieldPathGeoProc() | 281 GrGLDistanceFieldPathGeoProc() |
280 : fViewMatrix(SkMatrix::InvalidMatrix()) | 282 : fViewMatrix(SkMatrix::InvalidMatrix()) |
281 , fColor(GrColor_ILLEGAL) | 283 , fColor(GrColor_ILLEGAL) |
282 , fTextureSize(SkISize::Make(-1, -1)) {} | 284 , fTextureSize(SkISize::Make(-1, -1)) {} |
283 | 285 |
284 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 286 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
285 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); | 287 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); |
286 | 288 |
287 GrGLSLGPBuilder* pb = args.fPB; | 289 GrGLSLGPBuilder* pb = args.fPB; |
288 GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); | 290 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); |
289 SkAssertResult(fsBuilder->enableFeature( | 291 SkAssertResult(fsBuilder->enableFeature( |
290 GrGLFragmentShaderBuilder::kStandardDerivat
ives_GLSLFeature)); | 292 GrGLSLFragmentShaderBuilder::kStandardDeriv
atives_GLSLFeature)); |
291 | 293 |
292 GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); | 294 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); |
293 | 295 |
294 // emit attributes | 296 // emit attributes |
295 vsBuilder->emitAttributes(dfTexEffect); | 297 vsBuilder->emitAttributes(dfTexEffect); |
296 | 298 |
297 GrGLSLVertToFrag v(kVec2f_GrSLType); | 299 GrGLSLVertToFrag v(kVec2f_GrSLType); |
298 pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); | 300 pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); |
299 | 301 |
300 // setup pass through color | 302 // setup pass through color |
301 if (!dfTexEffect.colorIgnored()) { | 303 if (!dfTexEffect.colorIgnored()) { |
302 if (dfTexEffect.hasVertexColor()) { | 304 if (dfTexEffect.hasVertexColor()) { |
303 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); | 305 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); |
304 } else { | 306 } else { |
305 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); | 307 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); |
306 } | 308 } |
307 } | 309 } |
308 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); | 310 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); |
309 | 311 |
310 // Setup position | 312 // Setup position |
311 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf
fect.viewMatrix(), | 313 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf
fect.viewMatrix(), |
312 &fViewMatrixUniform); | 314 &fViewMatrixUniform); |
313 | 315 |
314 // emit transforms | 316 // emit transforms |
315 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()-
>fName, | 317 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()-
>fName, |
316 args.fTransformsIn, args.fTransformsOut); | 318 args.fTransformsIn, args.fTransformsOut); |
317 | 319 |
318 const char* textureSizeUniName = nullptr; | 320 const char* textureSizeUniName = nullptr; |
319 fTextureSizeUni = pb->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, | 321 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil
ity, |
320 kVec2f_GrSLType, kDefault_GrSLPrecision
, | 322 kVec2f_GrSLType, kDefault_GrSLPrecision
, |
321 "TextureSize", &textureSizeUniName); | 323 "TextureSize", &textureSizeUniName); |
322 | 324 |
323 // Use highp to work around aliasing issues | 325 // Use highp to work around aliasing issues |
324 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 326 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
325 kHigh_GrSLPrecisi
on)); | 327 kHigh_GrSLPrecisi
on)); |
326 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); | 328 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); |
327 | 329 |
328 fsBuilder->codeAppend("float texColor = "); | 330 fsBuilder->codeAppend("float texColor = "); |
329 fsBuilder->appendTextureLookup(args.fSamplers[0], | 331 fsBuilder->appendTextureLookup(args.fSamplers[0], |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 GrGLDistanceFieldLCDTextGeoProc() | 496 GrGLDistanceFieldLCDTextGeoProc() |
495 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { | 497 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { |
496 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); | 498 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); |
497 } | 499 } |
498 | 500 |
499 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 501 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
500 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = | 502 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = |
501 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); | 503 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); |
502 GrGLSLGPBuilder* pb = args.fPB; | 504 GrGLSLGPBuilder* pb = args.fPB; |
503 | 505 |
504 GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); | 506 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); |
505 | 507 |
506 // emit attributes | 508 // emit attributes |
507 vsBuilder->emitAttributes(dfTexEffect); | 509 vsBuilder->emitAttributes(dfTexEffect); |
508 | 510 |
509 // setup pass through color | 511 // setup pass through color |
510 if (!dfTexEffect.colorIgnored()) { | 512 if (!dfTexEffect.colorIgnored()) { |
511 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); | 513 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); |
512 } | 514 } |
513 | 515 |
514 // Setup position | 516 // Setup position |
(...skipping 19 matching lines...) Expand all Loading... |
534 SkScalar recipHeight = 1.0f / atlas->height(); | 536 SkScalar recipHeight = 1.0f / atlas->height(); |
535 | 537 |
536 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 538 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
537 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 539 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
538 vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), | 540 vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), |
539 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, | 541 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, |
540 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, | 542 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, |
541 dfTexEffect.inTextureCoords()->fName); | 543 dfTexEffect.inTextureCoords()->fName); |
542 | 544 |
543 // add frag shader code | 545 // add frag shader code |
544 GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); | 546 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); |
545 | 547 |
546 SkAssertResult(fsBuilder->enableFeature( | 548 SkAssertResult(fsBuilder->enableFeature( |
547 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 549 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
548 | 550 |
549 // create LCD offset adjusted by inverse of transform | 551 // create LCD offset adjusted by inverse of transform |
550 // Use highp to work around aliasing issues | 552 // Use highp to work around aliasing issues |
551 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 553 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
552 kHigh_GrSLPrecisi
on)); | 554 kHigh_GrSLPrecisi
on)); |
553 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 555 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
554 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), | 556 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), |
555 kHigh_GrSLPrecisi
on)); | 557 kHigh_GrSLPrecisi
on)); |
556 | 558 |
557 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); | 559 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); |
(...skipping 30 matching lines...) Expand all Loading... |
588 fsBuilder->codeAppend("\ttexColor = "); | 590 fsBuilder->codeAppend("\ttexColor = "); |
589 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_
GrSLType); | 591 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_
GrSLType); |
590 fsBuilder->codeAppend(";\n"); | 592 fsBuilder->codeAppend(";\n"); |
591 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); | 593 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); |
592 | 594 |
593 fsBuilder->codeAppend("\tdistance = " | 595 fsBuilder->codeAppend("\tdistance = " |
594 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF
ieldThreshold"));"); | 596 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF
ieldThreshold"));"); |
595 | 597 |
596 // adjust width based on gamma | 598 // adjust width based on gamma |
597 const char* distanceAdjustUniName = nullptr; | 599 const char* distanceAdjustUniName = nullptr; |
598 fDistanceAdjustUni = pb->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 600 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, |
599 kVec3f_GrSLType, kDefault_GrSLPrecision, | 601 kVec3f_GrSLType, kDefault_GrSLPrecision, |
600 "DistanceAdjust", &distanceAdjustUniName); | 602 "DistanceAdjust", &distanceAdjustUniName); |
601 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 603 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
602 | 604 |
603 // To be strictly correct, we should compute the anti-aliasing factor se
parately | 605 // To be strictly correct, we should compute the anti-aliasing factor se
parately |
604 // for each color component. However, this is only important when using
perspective | 606 // for each color component. However, this is only important when using
perspective |
605 // transformations, and even then using a single factor seems like a rea
sonable | 607 // transformations, and even then using a single factor seems like a rea
sonable |
606 // trade-off between quality and speed. | 608 // trade-off between quality and speed. |
607 fsBuilder->codeAppend("float afwidth;"); | 609 fsBuilder->codeAppend("float afwidth;"); |
608 if (isUniformScale) { | 610 if (isUniformScale) { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 753 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
752 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 754 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
753 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 755 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
754 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), | 756 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), |
755 GrTest::TestMatrix(d->fRandom), | 757 GrTest::TestMatrix(d->fRandom), |
756 d->fTextures[texIdx], params, | 758 d->fTextures[texIdx], params, |
757 wa, | 759 wa, |
758 flags, | 760 flags, |
759 d->fRandom->nextBool()); | 761 d->fRandom->nextBool()); |
760 } | 762 } |
OLD | NEW |