| 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 "GrDistanceFieldTextureEffect.h" | 8 #include "GrDistanceFieldTextureEffect.h" |
| 9 #include "GrInvariantOutput.h" | 9 #include "GrInvariantOutput.h" |
| 10 #include "gl/builders/GrGLProgramBuilder.h" | 10 #include "gl/builders/GrGLProgramBuilder.h" |
| 11 #include "gl/GrGLProcessor.h" | 11 #include "gl/GrGLProcessor.h" |
| 12 #include "gl/GrGLSL.h" | 12 #include "gl/GrGLSL.h" |
| 13 #include "gl/GrGLTexture.h" | 13 #include "gl/GrGLTexture.h" |
| 14 #include "gl/GrGLGeometryProcessor.h" | 14 #include "gl/GrGLGeometryProcessor.h" |
| 15 #include "GrTBackendProcessorFactory.h" | 15 #include "GrTBackendProcessorFactory.h" |
| 16 #include "GrTexture.h" | 16 #include "GrTexture.h" |
| 17 | 17 |
| 18 #include "SkDistanceFieldGen.h" | 18 #include "SkDistanceFieldGen.h" |
| 19 | 19 |
| 20 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/
2 | 20 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/
2 |
| 21 #define SK_DistanceFieldAAFactor "0.7071" | 21 #define SK_DistanceFieldAAFactor "0.7071" |
| 22 | 22 |
| 23 class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor { | 23 class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor { |
| 24 public: | 24 public: |
| 25 GrGLDistanceFieldTextureEffect(const GrBackendProcessorFactory& factory, | 25 GrGLDistanceFieldTextureEffect(const GrBackendProcessorFactory& factory, |
| 26 const GrGeometryProcessor&, | 26 const GrProcessor&) |
| 27 const GrBatchTracker&) | |
| 28 : INHERITED (factory) | 27 : INHERITED (factory) |
| 29 , fTextureSize(SkISize::Make(-1,-1)) | 28 , fTextureSize(SkISize::Make(-1,-1)) |
| 30 #ifdef SK_GAMMA_APPLY_TO_A8 | 29 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 31 , fLuminance(-1.0f) | 30 , fLuminance(-1.0f) |
| 32 #endif | 31 #endif |
| 33 {} | 32 {} |
| 34 | 33 |
| 35 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 34 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
| 36 const GrDistanceFieldTextureEffect& dfTexEffect = | 35 const GrDistanceFieldTextureEffect& dfTexEffect = |
| 37 args.fGP.cast<GrDistanceFieldTextureEffect>(); | 36 args.fGP.cast<GrDistanceFieldTextureEffect>(); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 fsBuilder->codeAppend("\tvec4 gammaColor = "); | 117 fsBuilder->codeAppend("\tvec4 gammaColor = "); |
| 119 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; | 118 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; |
| 120 fsBuilder->codeAppend(";\n"); | 119 fsBuilder->codeAppend(";\n"); |
| 121 fsBuilder->codeAppend("\tval = gammaColor.r;\n"); | 120 fsBuilder->codeAppend("\tval = gammaColor.r;\n"); |
| 122 #endif | 121 #endif |
| 123 | 122 |
| 124 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 123 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
| 125 } | 124 } |
| 126 | 125 |
| 127 virtual void setData(const GrGLProgramDataManager& pdman, | 126 virtual void setData(const GrGLProgramDataManager& pdman, |
| 128 const GrGeometryProcessor& proc, | 127 const GrProcessor& effect) SK_OVERRIDE { |
| 129 const GrBatchTracker&) SK_OVERRIDE { | |
| 130 SkASSERT(fTextureSizeUni.isValid()); | 128 SkASSERT(fTextureSizeUni.isValid()); |
| 131 | 129 |
| 132 GrTexture* texture = proc.texture(0); | 130 GrTexture* texture = effect.texture(0); |
| 133 if (texture->width() != fTextureSize.width() || | 131 if (texture->width() != fTextureSize.width() || |
| 134 texture->height() != fTextureSize.height()) { | 132 texture->height() != fTextureSize.height()) { |
| 135 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 133 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
| 136 pdman.set2f(fTextureSizeUni, | 134 pdman.set2f(fTextureSizeUni, |
| 137 SkIntToScalar(fTextureSize.width()), | 135 SkIntToScalar(fTextureSize.width()), |
| 138 SkIntToScalar(fTextureSize.height())); | 136 SkIntToScalar(fTextureSize.height())); |
| 139 } | 137 } |
| 140 #ifdef SK_GAMMA_APPLY_TO_A8 | 138 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 141 const GrDistanceFieldTextureEffect& dfTexEffect = | 139 const GrDistanceFieldTextureEffect& dfTexEffect = |
| 142 proc.cast<GrDistanceFieldTextureEffect>(); | 140 effect.cast<GrDistanceFieldTextureEffect>(); |
| 143 float luminance = dfTexEffect.getLuminance(); | 141 float luminance = dfTexEffect.getLuminance(); |
| 144 if (luminance != fLuminance) { | 142 if (luminance != fLuminance) { |
| 145 pdman.set1f(fLuminanceUni, luminance); | 143 pdman.set1f(fLuminanceUni, luminance); |
| 146 fLuminance = luminance; | 144 fLuminance = luminance; |
| 147 } | 145 } |
| 148 #endif | 146 #endif |
| 149 } | 147 } |
| 150 | 148 |
| 151 static inline void GenKey(const GrGeometryProcessor& processor, | 149 static inline void GenKey(const GrProcessor& processor, const GrGLCaps&, |
| 152 const GrBatchTracker&, | |
| 153 const GrGLCaps&, | |
| 154 GrProcessorKeyBuilder* b) { | 150 GrProcessorKeyBuilder* b) { |
| 155 const GrDistanceFieldTextureEffect& dfTexEffect = | 151 const GrDistanceFieldTextureEffect& dfTexEffect = |
| 156 processor.cast<GrDistanceFieldTextureEffect>(); | 152 processor.cast<GrDistanceFieldTextureEffect>(); |
| 157 | 153 |
| 158 b->add32(dfTexEffect.getFlags()); | 154 b->add32(dfTexEffect.getFlags()); |
| 159 } | 155 } |
| 160 | 156 |
| 161 private: | 157 private: |
| 162 GrGLProgramDataManager::UniformHandle fTextureSizeUni; | 158 GrGLProgramDataManager::UniformHandle fTextureSizeUni; |
| 163 SkISize fTextureSize; | 159 SkISize fTextureSize; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 #endif | 248 #endif |
| 253 random->nextBool() ? | 249 random->nextBool() ? |
| 254 kSimilarity_DistanceFieldEff
ectFlag : 0); | 250 kSimilarity_DistanceFieldEff
ectFlag : 0); |
| 255 } | 251 } |
| 256 | 252 |
| 257 /////////////////////////////////////////////////////////////////////////////// | 253 /////////////////////////////////////////////////////////////////////////////// |
| 258 | 254 |
| 259 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor { | 255 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor { |
| 260 public: | 256 public: |
| 261 GrGLDistanceFieldNoGammaTextureEffect(const GrBackendProcessorFactory& facto
ry, | 257 GrGLDistanceFieldNoGammaTextureEffect(const GrBackendProcessorFactory& facto
ry, |
| 262 const GrGeometryProcessor&, | 258 const GrProcessor& effect) |
| 263 const GrBatchTracker&) | |
| 264 : INHERITED(factory) | 259 : INHERITED(factory) |
| 265 , fTextureSize(SkISize::Make(-1, -1)) {} | 260 , fTextureSize(SkISize::Make(-1, -1)) {} |
| 266 | 261 |
| 267 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 262 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
| 268 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = | 263 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
| 269 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); | 264 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); |
| 270 | 265 |
| 271 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 266 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 272 SkAssertResult(fsBuilder->enableFeature( | 267 SkAssertResult(fsBuilder->enableFeature( |
| 273 GrGLFragmentShaderBuilder::kStandardDerivat
ives_GLSLFeature)); | 268 GrGLFragmentShaderBuilder::kStandardDerivat
ives_GLSLFeature)); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 | 331 |
| 337 // this gives us a smooth step across approximately one fragment | 332 // this gives us a smooth step across approximately one fragment |
| 338 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length
(grad);"); | 333 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length
(grad);"); |
| 339 } | 334 } |
| 340 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc
e);"); | 335 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc
e);"); |
| 341 | 336 |
| 342 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 337 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
| 343 } | 338 } |
| 344 | 339 |
| 345 virtual void setData(const GrGLProgramDataManager& pdman, | 340 virtual void setData(const GrGLProgramDataManager& pdman, |
| 346 const GrGeometryProcessor& proc, | 341 const GrProcessor& effect) SK_OVERRIDE { |
| 347 const GrBatchTracker&) SK_OVERRIDE { | |
| 348 SkASSERT(fTextureSizeUni.isValid()); | 342 SkASSERT(fTextureSizeUni.isValid()); |
| 349 | 343 |
| 350 GrTexture* texture = proc.texture(0); | 344 GrTexture* texture = effect.texture(0); |
| 351 if (texture->width() != fTextureSize.width() || | 345 if (texture->width() != fTextureSize.width() || |
| 352 texture->height() != fTextureSize.height()) { | 346 texture->height() != fTextureSize.height()) { |
| 353 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 347 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
| 354 pdman.set2f(fTextureSizeUni, | 348 pdman.set2f(fTextureSizeUni, |
| 355 SkIntToScalar(fTextureSize.width()), | 349 SkIntToScalar(fTextureSize.width()), |
| 356 SkIntToScalar(fTextureSize.height())); | 350 SkIntToScalar(fTextureSize.height())); |
| 357 } | 351 } |
| 358 } | 352 } |
| 359 | 353 |
| 360 static inline void GenKey(const GrGeometryProcessor& proc, | 354 static inline void GenKey(const GrProcessor& effect, const GrGLCaps&, |
| 361 const GrBatchTracker&, | |
| 362 const GrGLCaps&, | |
| 363 GrProcessorKeyBuilder* b) { | 355 GrProcessorKeyBuilder* b) { |
| 364 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = | 356 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
| 365 proc.cast<GrDistanceFieldNoGammaTextureEffect>(); | 357 effect.cast<GrDistanceFieldNoGammaTextureEffect>(); |
| 366 | 358 |
| 367 b->add32(dfTexEffect.getFlags()); | 359 b->add32(dfTexEffect.getFlags()); |
| 368 } | 360 } |
| 369 | 361 |
| 370 private: | 362 private: |
| 371 GrGLProgramDataManager::UniformHandle fTextureSizeUni; | 363 GrGLProgramDataManager::UniformHandle fTextureSizeUni; |
| 372 SkISize fTextureSize; | 364 SkISize fTextureSize; |
| 373 | 365 |
| 374 typedef GrGLGeometryProcessor INHERITED; | 366 typedef GrGLGeometryProcessor INHERITED; |
| 375 }; | 367 }; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 | 423 |
| 432 return GrDistanceFieldNoGammaTextureEffect::Create(textures[texIdx], params, | 424 return GrDistanceFieldNoGammaTextureEffect::Create(textures[texIdx], params, |
| 433 random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0); | 425 random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0); |
| 434 } | 426 } |
| 435 | 427 |
| 436 /////////////////////////////////////////////////////////////////////////////// | 428 /////////////////////////////////////////////////////////////////////////////// |
| 437 | 429 |
| 438 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { | 430 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { |
| 439 public: | 431 public: |
| 440 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory, | 432 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory, |
| 441 const GrGeometryProcessor&, | 433 const GrProcessor&) |
| 442 const GrBatchTracker&) | |
| 443 : INHERITED (factory) | 434 : INHERITED (factory) |
| 444 , fTextureSize(SkISize::Make(-1,-1)) | 435 , fTextureSize(SkISize::Make(-1,-1)) |
| 445 , fTextColor(GrColor_ILLEGAL) {} | 436 , fTextColor(GrColor_ILLEGAL) {} |
| 446 | 437 |
| 447 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 438 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
| 448 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 439 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
| 449 args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); | 440 args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); |
| 450 | 441 |
| 451 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 442 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 452 GrGLVertToFrag v(kVec2f_GrSLType); | 443 GrGLVertToFrag v(kVec2f_GrSLType); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); | 556 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); |
| 566 fsBuilder->codeAppend("\tgammaColor = "); | 557 fsBuilder->codeAppend("\tgammaColor = "); |
| 567 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; | 558 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; |
| 568 fsBuilder->codeAppend(";\n"); | 559 fsBuilder->codeAppend(";\n"); |
| 569 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); | 560 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); |
| 570 | 561 |
| 571 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 562 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
| 572 } | 563 } |
| 573 | 564 |
| 574 virtual void setData(const GrGLProgramDataManager& pdman, | 565 virtual void setData(const GrGLProgramDataManager& pdman, |
| 575 const GrGeometryProcessor& processor, | 566 const GrProcessor& processor) SK_OVERRIDE { |
| 576 const GrBatchTracker&) SK_OVERRIDE { | |
| 577 SkASSERT(fTextureSizeUni.isValid()); | 567 SkASSERT(fTextureSizeUni.isValid()); |
| 578 SkASSERT(fTextColorUni.isValid()); | 568 SkASSERT(fTextColorUni.isValid()); |
| 579 | 569 |
| 580 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 570 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
| 581 processor.cast<GrDistanceFieldLCDTextureEffect>(); | 571 processor.cast<GrDistanceFieldLCDTextureEffect>(); |
| 582 GrTexture* texture = processor.texture(0); | 572 GrTexture* texture = processor.texture(0); |
| 583 if (texture->width() != fTextureSize.width() || | 573 if (texture->width() != fTextureSize.width() || |
| 584 texture->height() != fTextureSize.height()) { | 574 texture->height() != fTextureSize.height()) { |
| 585 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 575 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
| 586 float delta = 1.0f/(3.0f*texture->width()); | 576 float delta = 1.0f/(3.0f*texture->width()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 597 if (textColor != fTextColor) { | 587 if (textColor != fTextColor) { |
| 598 static const float ONE_OVER_255 = 1.f / 255.f; | 588 static const float ONE_OVER_255 = 1.f / 255.f; |
| 599 pdman.set3f(fTextColorUni, | 589 pdman.set3f(fTextColorUni, |
| 600 GrColorUnpackR(textColor) * ONE_OVER_255, | 590 GrColorUnpackR(textColor) * ONE_OVER_255, |
| 601 GrColorUnpackG(textColor) * ONE_OVER_255, | 591 GrColorUnpackG(textColor) * ONE_OVER_255, |
| 602 GrColorUnpackB(textColor) * ONE_OVER_255); | 592 GrColorUnpackB(textColor) * ONE_OVER_255); |
| 603 fTextColor = textColor; | 593 fTextColor = textColor; |
| 604 } | 594 } |
| 605 } | 595 } |
| 606 | 596 |
| 607 static inline void GenKey(const GrGeometryProcessor& processor, | 597 static inline void GenKey(const GrProcessor& processor, const GrGLCaps&, |
| 608 const GrBatchTracker&, | |
| 609 const GrGLCaps&, | |
| 610 GrProcessorKeyBuilder* b) { | 598 GrProcessorKeyBuilder* b) { |
| 611 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 599 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
| 612 processor.cast<GrDistanceFieldLCDTextureEffect>(); | 600 processor.cast<GrDistanceFieldLCDTextureEffect>(); |
| 613 | 601 |
| 614 b->add32(dfTexEffect.getFlags()); | 602 b->add32(dfTexEffect.getFlags()); |
| 615 } | 603 } |
| 616 | 604 |
| 617 private: | 605 private: |
| 618 GrGLProgramDataManager::UniformHandle fTextureSizeUni; | 606 GrGLProgramDataManager::UniformHandle fTextureSizeUni; |
| 619 SkISize fTextureSize; | 607 SkISize fTextureSize; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 random->nextULessThan(256), | 674 random->nextULessThan(256), |
| 687 random->nextULessThan(256)); | 675 random->nextULessThan(256)); |
| 688 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 676 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
| 689 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 677 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
| 690 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 678 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
| 691 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, | 679 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, |
| 692 textures[texIdx2], params2, | 680 textures[texIdx2], params2, |
| 693 textColor, | 681 textColor, |
| 694 flags); | 682 flags); |
| 695 } | 683 } |
| OLD | NEW |