GrCCClipProcessor.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * Copyright 2017 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/gpu/ccpr/GrCCClipProcessor.h"
  8. #include "include/gpu/GrTexture.h"
  9. #include "src/core/SkMakeUnique.h"
  10. #include "src/gpu/GrTextureProxy.h"
  11. #include "src/gpu/ccpr/GrCCClipPath.h"
  12. #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
  13. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  14. GrCCClipProcessor::GrCCClipProcessor(const GrCCClipPath* clipPath, IsCoverageCount isCoverageCount,
  15. MustCheckBounds mustCheckBounds)
  16. : INHERITED(kGrCCClipProcessor_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
  17. , fClipPath(clipPath)
  18. , fIsCoverageCount(IsCoverageCount::kYes == isCoverageCount)
  19. , fMustCheckBounds(MustCheckBounds::kYes == mustCheckBounds)
  20. , fAtlasAccess(sk_ref_sp(fClipPath->atlasLazyProxy()), GrSamplerState::Filter::kNearest,
  21. GrSamplerState::WrapMode::kClamp) {
  22. SkASSERT(fAtlasAccess.proxy());
  23. this->setTextureSamplerCnt(1);
  24. }
  25. std::unique_ptr<GrFragmentProcessor> GrCCClipProcessor::clone() const {
  26. return skstd::make_unique<GrCCClipProcessor>(
  27. fClipPath, IsCoverageCount(fIsCoverageCount), MustCheckBounds(fMustCheckBounds));
  28. }
  29. void GrCCClipProcessor::onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const {
  30. const SkPath& clipPath = fClipPath->deviceSpacePath();
  31. uint32_t key = (fIsCoverageCount) ? (uint32_t)GrFillRuleForSkPath(clipPath) : 0;
  32. key = (key << 1) | ((clipPath.isInverseFillType()) ? 1 : 0);
  33. key = (key << 1) | ((fMustCheckBounds) ? 1 : 0);
  34. b->add32(key);
  35. }
  36. bool GrCCClipProcessor::onIsEqual(const GrFragmentProcessor& fp) const {
  37. const GrCCClipProcessor& that = fp.cast<GrCCClipProcessor>();
  38. // Each ClipPath path has a unique atlas proxy, so hasSameSamplersAndAccesses should have
  39. // already weeded out FPs with different ClipPaths.
  40. SkASSERT(that.fClipPath->deviceSpacePath().getGenerationID() ==
  41. fClipPath->deviceSpacePath().getGenerationID());
  42. return that.fClipPath->deviceSpacePath().getFillType() ==
  43. fClipPath->deviceSpacePath().getFillType() &&
  44. that.fIsCoverageCount == fIsCoverageCount && that.fMustCheckBounds == fMustCheckBounds;
  45. }
  46. class GrCCClipProcessor::Impl : public GrGLSLFragmentProcessor {
  47. public:
  48. void emitCode(EmitArgs& args) override {
  49. const GrCCClipProcessor& proc = args.fFp.cast<GrCCClipProcessor>();
  50. GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
  51. GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
  52. f->codeAppend ("half coverage;");
  53. if (proc.fMustCheckBounds) {
  54. const char* pathIBounds;
  55. fPathIBoundsUniform = uniHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
  56. "path_ibounds", &pathIBounds);
  57. f->codeAppendf("if (all(greaterThan(float4(sk_FragCoord.xy, %s.zw), "
  58. "float4(%s.xy, sk_FragCoord.xy)))) {",
  59. pathIBounds, pathIBounds);
  60. }
  61. const char* atlasTransform;
  62. fAtlasTransformUniform = uniHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
  63. "atlas_transform", &atlasTransform);
  64. f->codeAppendf("float2 texcoord = sk_FragCoord.xy * %s.xy + %s.zw;",
  65. atlasTransform, atlasTransform);
  66. f->codeAppend ("coverage = ");
  67. f->appendTextureLookup(args.fTexSamplers[0], "texcoord", kHalf2_GrSLType);
  68. f->codeAppend (".a;");
  69. if (proc.fIsCoverageCount) {
  70. auto fillRule = GrFillRuleForSkPath(proc.fClipPath->deviceSpacePath());
  71. if (GrFillRule::kEvenOdd == fillRule) {
  72. f->codeAppend ("half t = mod(abs(coverage), 2);");
  73. f->codeAppend ("coverage = 1 - abs(t - 1);");
  74. } else {
  75. SkASSERT(GrFillRule::kNonzero == fillRule);
  76. f->codeAppend ("coverage = min(abs(coverage), 1);");
  77. }
  78. }
  79. if (proc.fMustCheckBounds) {
  80. f->codeAppend ("} else {");
  81. f->codeAppend ( "coverage = 0;");
  82. f->codeAppend ("}");
  83. }
  84. if (proc.fClipPath->deviceSpacePath().isInverseFillType()) {
  85. f->codeAppend ("coverage = 1 - coverage;");
  86. }
  87. f->codeAppendf("%s = %s * coverage;", args.fOutputColor, args.fInputColor);
  88. }
  89. void onSetData(const GrGLSLProgramDataManager& pdman,
  90. const GrFragmentProcessor& fp) override {
  91. const GrCCClipProcessor& proc = fp.cast<GrCCClipProcessor>();
  92. if (proc.fMustCheckBounds) {
  93. const SkRect pathIBounds = SkRect::Make(proc.fClipPath->pathDevIBounds());
  94. pdman.set4f(fPathIBoundsUniform, pathIBounds.left(), pathIBounds.top(),
  95. pathIBounds.right(), pathIBounds.bottom());
  96. }
  97. const SkVector& scale = proc.fClipPath->atlasScale();
  98. const SkVector& trans = proc.fClipPath->atlasTranslate();
  99. pdman.set4f(fAtlasTransformUniform, scale.x(), scale.y(), trans.x(), trans.y());
  100. }
  101. private:
  102. UniformHandle fPathIBoundsUniform;
  103. UniformHandle fAtlasTransformUniform;
  104. };
  105. GrGLSLFragmentProcessor* GrCCClipProcessor::onCreateGLSLInstance() const {
  106. return new Impl();
  107. }