GrCoverageSetOpXP.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright 2014 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/GrCaps.h"
  8. #include "src/gpu/GrColor.h"
  9. #include "src/gpu/GrPipeline.h"
  10. #include "src/gpu/GrProcessor.h"
  11. #include "src/gpu/GrRenderTargetContext.h"
  12. #include "src/gpu/effects/GrCoverageSetOpXP.h"
  13. #include "src/gpu/glsl/GrGLSLBlend.h"
  14. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  15. #include "src/gpu/glsl/GrGLSLUniformHandler.h"
  16. #include "src/gpu/glsl/GrGLSLXferProcessor.h"
  17. class CoverageSetOpXP : public GrXferProcessor {
  18. public:
  19. CoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage)
  20. : INHERITED(kCoverageSetOpXP_ClassID)
  21. , fRegionOp(regionOp)
  22. , fInvertCoverage(invertCoverage) {}
  23. const char* name() const override { return "Coverage Set Op"; }
  24. GrGLSLXferProcessor* createGLSLInstance() const override;
  25. bool invertCoverage() const { return fInvertCoverage; }
  26. private:
  27. void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
  28. void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
  29. bool onIsEqual(const GrXferProcessor& xpBase) const override {
  30. const CoverageSetOpXP& xp = xpBase.cast<CoverageSetOpXP>();
  31. return (fRegionOp == xp.fRegionOp &&
  32. fInvertCoverage == xp.fInvertCoverage);
  33. }
  34. SkRegion::Op fRegionOp;
  35. bool fInvertCoverage;
  36. typedef GrXferProcessor INHERITED;
  37. };
  38. ///////////////////////////////////////////////////////////////////////////////
  39. class GLCoverageSetOpXP : public GrGLSLXferProcessor {
  40. public:
  41. GLCoverageSetOpXP(const GrProcessor&) {}
  42. ~GLCoverageSetOpXP() override {}
  43. static void GenKey(const GrProcessor& processor, const GrShaderCaps& caps,
  44. GrProcessorKeyBuilder* b) {
  45. const CoverageSetOpXP& xp = processor.cast<CoverageSetOpXP>();
  46. uint32_t key = xp.invertCoverage() ? 0x0 : 0x1;
  47. b->add32(key);
  48. }
  49. private:
  50. void emitOutputsForBlendState(const EmitArgs& args) override {
  51. const CoverageSetOpXP& xp = args.fXP.cast<CoverageSetOpXP>();
  52. GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
  53. if (xp.invertCoverage()) {
  54. fragBuilder->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.fInputCoverage);
  55. } else {
  56. fragBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage);
  57. }
  58. }
  59. void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
  60. typedef GrGLSLXferProcessor INHERITED;
  61. };
  62. ///////////////////////////////////////////////////////////////////////////////
  63. void CoverageSetOpXP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
  64. GrProcessorKeyBuilder* b) const {
  65. GLCoverageSetOpXP::GenKey(*this, caps, b);
  66. }
  67. GrGLSLXferProcessor* CoverageSetOpXP::createGLSLInstance() const {
  68. return new GLCoverageSetOpXP(*this);
  69. }
  70. void CoverageSetOpXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const {
  71. switch (fRegionOp) {
  72. case SkRegion::kReplace_Op:
  73. blendInfo->fSrcBlend = kOne_GrBlendCoeff;
  74. blendInfo->fDstBlend = kZero_GrBlendCoeff;
  75. break;
  76. case SkRegion::kIntersect_Op:
  77. blendInfo->fSrcBlend = kDC_GrBlendCoeff;
  78. blendInfo->fDstBlend = kZero_GrBlendCoeff;
  79. break;
  80. case SkRegion::kUnion_Op:
  81. blendInfo->fSrcBlend = kOne_GrBlendCoeff;
  82. blendInfo->fDstBlend = kISC_GrBlendCoeff;
  83. break;
  84. case SkRegion::kXOR_Op:
  85. blendInfo->fSrcBlend = kIDC_GrBlendCoeff;
  86. blendInfo->fDstBlend = kISC_GrBlendCoeff;
  87. break;
  88. case SkRegion::kDifference_Op:
  89. blendInfo->fSrcBlend = kZero_GrBlendCoeff;
  90. blendInfo->fDstBlend = kISC_GrBlendCoeff;
  91. break;
  92. case SkRegion::kReverseDifference_Op:
  93. blendInfo->fSrcBlend = kIDC_GrBlendCoeff;
  94. blendInfo->fDstBlend = kZero_GrBlendCoeff;
  95. break;
  96. }
  97. blendInfo->fBlendConstant = SK_PMColor4fTRANSPARENT;
  98. }
  99. ///////////////////////////////////////////////////////////////////////////////
  100. constexpr GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp,
  101. bool invertCoverage)
  102. : fRegionOp(regionOp), fInvertCoverage(invertCoverage) {}
  103. const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool invertCoverage) {
  104. // If these objects are constructed as static constexpr by cl.exe (2015 SP2) the vtables are
  105. // null.
  106. #ifdef SK_BUILD_FOR_WIN
  107. #define _CONSTEXPR_
  108. #else
  109. #define _CONSTEXPR_ constexpr
  110. #endif
  111. switch (regionOp) {
  112. case SkRegion::kReplace_Op: {
  113. if (invertCoverage) {
  114. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gReplaceCDXPFI(
  115. SkRegion::kReplace_Op, true);
  116. return &gReplaceCDXPFI;
  117. } else {
  118. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gReplaceCDXPF(
  119. SkRegion::kReplace_Op, false);
  120. return &gReplaceCDXPF;
  121. }
  122. }
  123. case SkRegion::kIntersect_Op: {
  124. if (invertCoverage) {
  125. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gIntersectCDXPFI(
  126. SkRegion::kIntersect_Op, true);
  127. return &gIntersectCDXPFI;
  128. } else {
  129. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gIntersectCDXPF(
  130. SkRegion::kIntersect_Op, false);
  131. return &gIntersectCDXPF;
  132. }
  133. }
  134. case SkRegion::kUnion_Op: {
  135. if (invertCoverage) {
  136. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gUnionCDXPFI(SkRegion::kUnion_Op,
  137. true);
  138. return &gUnionCDXPFI;
  139. } else {
  140. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gUnionCDXPF(SkRegion::kUnion_Op,
  141. false);
  142. return &gUnionCDXPF;
  143. }
  144. }
  145. case SkRegion::kXOR_Op: {
  146. if (invertCoverage) {
  147. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gXORCDXPFI(SkRegion::kXOR_Op,
  148. true);
  149. return &gXORCDXPFI;
  150. } else {
  151. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gXORCDXPF(SkRegion::kXOR_Op,
  152. false);
  153. return &gXORCDXPF;
  154. }
  155. }
  156. case SkRegion::kDifference_Op: {
  157. if (invertCoverage) {
  158. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gDifferenceCDXPFI(
  159. SkRegion::kDifference_Op, true);
  160. return &gDifferenceCDXPFI;
  161. } else {
  162. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gDifferenceCDXPF(
  163. SkRegion::kDifference_Op, false);
  164. return &gDifferenceCDXPF;
  165. }
  166. }
  167. case SkRegion::kReverseDifference_Op: {
  168. if (invertCoverage) {
  169. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gRevDiffCDXPFI(
  170. SkRegion::kReverseDifference_Op, true);
  171. return &gRevDiffCDXPFI;
  172. } else {
  173. static _CONSTEXPR_ const GrCoverageSetOpXPFactory gRevDiffCDXPF(
  174. SkRegion::kReverseDifference_Op, false);
  175. return &gRevDiffCDXPF;
  176. }
  177. }
  178. }
  179. #undef _CONSTEXPR_
  180. SK_ABORT("Unknown region op.");
  181. return nullptr;
  182. }
  183. sk_sp<const GrXferProcessor> GrCoverageSetOpXPFactory::makeXferProcessor(
  184. const GrProcessorAnalysisColor&,
  185. GrProcessorAnalysisCoverage,
  186. bool hasMixedSamples,
  187. const GrCaps& caps,
  188. GrClampType) const {
  189. // We don't support inverting coverage with mixed samples. We don't expect to ever want this in
  190. // the future, however we could at some point make this work using an inverted coverage
  191. // modulation table. Note that an inverted table still won't work if there are coverage procs.
  192. if (fInvertCoverage && hasMixedSamples) {
  193. SkASSERT(false);
  194. return nullptr;
  195. }
  196. return sk_sp<GrXferProcessor>(new CoverageSetOpXP(fRegionOp, fInvertCoverage));
  197. }
  198. GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory);
  199. #if GR_TEST_UTILS
  200. const GrXPFactory* GrCoverageSetOpXPFactory::TestGet(GrProcessorTestData* d) {
  201. SkRegion::Op regionOp = SkRegion::Op(d->fRandom->nextULessThan(SkRegion::kLastOp + 1));
  202. bool invertCoverage = d->fRandom->nextBool();
  203. return GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage);
  204. }
  205. #endif