GrAppliedClip.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright 2016 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. #ifndef GrAppliedClip_DEFINED
  8. #define GrAppliedClip_DEFINED
  9. #include "src/gpu/GrFragmentProcessor.h"
  10. #include "src/gpu/GrScissorState.h"
  11. #include "src/gpu/GrWindowRectsState.h"
  12. #include "src/core/SkClipStack.h"
  13. /**
  14. * Produced by GrHardClip. It provides a set of modifications to the hardware drawing state that
  15. * implement the clip.
  16. */
  17. class GrAppliedHardClip {
  18. public:
  19. GrAppliedHardClip() = default;
  20. GrAppliedHardClip(GrAppliedHardClip&& that) = default;
  21. GrAppliedHardClip(const GrAppliedHardClip&) = delete;
  22. const GrScissorState& scissorState() const { return fScissorState; }
  23. const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
  24. uint32_t stencilStackID() const { return fStencilStackID; }
  25. bool hasStencilClip() const { return SkClipStack::kInvalidGenID != fStencilStackID; }
  26. /**
  27. * Intersects the applied clip with the provided rect. Returns false if the draw became empty.
  28. * 'clippedDrawBounds' will be intersected with 'irect'. This returns false if the clip becomes
  29. * empty or the draw no longer intersects the clip. In either case the draw can be skipped.
  30. */
  31. bool addScissor(const SkIRect& irect, SkRect* clippedDrawBounds) {
  32. return fScissorState.intersect(irect) && clippedDrawBounds->intersect(SkRect::Make(irect));
  33. }
  34. void addWindowRectangles(const GrWindowRectsState& windowState) {
  35. SkASSERT(!fWindowRectsState.enabled());
  36. fWindowRectsState = windowState;
  37. }
  38. void addWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) {
  39. SkASSERT(!fWindowRectsState.enabled());
  40. fWindowRectsState.set(windows, mode);
  41. }
  42. void addStencilClip(uint32_t stencilStackID) {
  43. SkASSERT(SkClipStack::kInvalidGenID == fStencilStackID);
  44. fStencilStackID = stencilStackID;
  45. }
  46. bool doesClip() const {
  47. return fScissorState.enabled() || this->hasStencilClip() || fWindowRectsState.enabled();
  48. }
  49. bool operator==(const GrAppliedHardClip& that) const {
  50. return fScissorState == that.fScissorState &&
  51. fWindowRectsState == that.fWindowRectsState &&
  52. fStencilStackID == that.fStencilStackID;
  53. }
  54. bool operator!=(const GrAppliedHardClip& that) const { return !(*this == that); }
  55. private:
  56. GrScissorState fScissorState;
  57. GrWindowRectsState fWindowRectsState;
  58. uint32_t fStencilStackID = SkClipStack::kInvalidGenID;
  59. };
  60. /**
  61. * Produced by GrClip. It provides a set of modifications to GrPipeline that implement the clip.
  62. */
  63. class GrAppliedClip {
  64. public:
  65. GrAppliedClip() = default;
  66. GrAppliedClip(GrAppliedClip&& that) = default;
  67. GrAppliedClip(const GrAppliedClip&) = delete;
  68. const GrScissorState& scissorState() const { return fHardClip.scissorState(); }
  69. const GrWindowRectsState& windowRectsState() const { return fHardClip.windowRectsState(); }
  70. uint32_t stencilStackID() const { return fHardClip.stencilStackID(); }
  71. bool hasStencilClip() const { return fHardClip.hasStencilClip(); }
  72. int numClipCoverageFragmentProcessors() const { return fClipCoverageFPs.count(); }
  73. const GrFragmentProcessor* clipCoverageFragmentProcessor(int i) const {
  74. SkASSERT(fClipCoverageFPs[i]);
  75. return fClipCoverageFPs[i].get();
  76. }
  77. std::unique_ptr<const GrFragmentProcessor> detachClipCoverageFragmentProcessor(int i) {
  78. SkASSERT(fClipCoverageFPs[i]);
  79. return std::move(fClipCoverageFPs[i]);
  80. }
  81. GrAppliedHardClip& hardClip() { return fHardClip; }
  82. void addCoverageFP(std::unique_ptr<GrFragmentProcessor> fp) {
  83. SkASSERT(fp);
  84. fClipCoverageFPs.push_back(std::move(fp));
  85. }
  86. bool doesClip() const {
  87. return fHardClip.doesClip() || !fClipCoverageFPs.empty();
  88. }
  89. bool operator==(const GrAppliedClip& that) const {
  90. if (fHardClip != that.fHardClip ||
  91. fClipCoverageFPs.count() != that.fClipCoverageFPs.count()) {
  92. return false;
  93. }
  94. for (int i = 0; i < fClipCoverageFPs.count(); ++i) {
  95. if (!fClipCoverageFPs[i] || !that.fClipCoverageFPs[i]) {
  96. if (fClipCoverageFPs[i] == that.fClipCoverageFPs[i]) {
  97. continue; // Both are null.
  98. }
  99. return false;
  100. }
  101. if (!fClipCoverageFPs[i]->isEqual(*that.fClipCoverageFPs[i])) {
  102. return false;
  103. }
  104. }
  105. return true;
  106. }
  107. bool operator!=(const GrAppliedClip& that) const { return !(*this == that); }
  108. void visitProxies(const GrOp::VisitProxyFunc& func) const {
  109. for (const std::unique_ptr<GrFragmentProcessor>& fp : fClipCoverageFPs) {
  110. if (fp) { // This might be called after detach.
  111. fp->visitProxies(func);
  112. }
  113. }
  114. }
  115. private:
  116. GrAppliedHardClip fHardClip;
  117. SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fClipCoverageFPs;
  118. };
  119. #endif