GrReducedClip.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 GrReducedClip_DEFINED
  8. #define GrReducedClip_DEFINED
  9. #include "src/core/SkClipStack.h"
  10. #include "src/core/SkTLList.h"
  11. #include "src/gpu/GrFragmentProcessor.h"
  12. #include "src/gpu/GrWindowRectangles.h"
  13. class GrCoverageCountingPathRenderer;
  14. class GrRecordingContext;
  15. class GrRenderTargetContext;
  16. /**
  17. * This class takes a clip stack and produces a reduced set of elements that are equivalent to
  18. * applying that full stack within a specified query rectangle.
  19. */
  20. class SK_API GrReducedClip {
  21. public:
  22. using Element = SkClipStack::Element;
  23. using ElementList = SkTLList<SkClipStack::Element, 16>;
  24. GrReducedClip(const SkClipStack&, const SkRect& queryBounds, const GrCaps* caps,
  25. int maxWindowRectangles = 0, int maxAnalyticFPs = 0, int maxCCPRClipPaths = 0);
  26. enum class InitialState : bool {
  27. kAllIn,
  28. kAllOut
  29. };
  30. InitialState initialState() const { return fInitialState; }
  31. /**
  32. * If hasScissor() is true, the clip mask is not valid outside this rect and the caller must
  33. * enforce this scissor during draw.
  34. */
  35. const SkIRect& scissor() const { SkASSERT(fHasScissor); return fScissor; }
  36. int left() const { return this->scissor().left(); }
  37. int top() const { return this->scissor().top(); }
  38. int width() const { return this->scissor().width(); }
  39. int height() const { return this->scissor().height(); }
  40. /**
  41. * Indicates whether scissor() is defined. It will always be defined if the maskElements() are
  42. * nonempty.
  43. */
  44. bool hasScissor() const { return fHasScissor; }
  45. /**
  46. * If nonempty, the clip mask is not valid inside these windows and the caller must clip them
  47. * out using the window rectangles GPU extension.
  48. */
  49. const GrWindowRectangles& windowRectangles() const { return fWindowRects; }
  50. /**
  51. * An ordered list of clip elements that could not be skipped or implemented by other means. If
  52. * nonempty, the caller must create an alpha and/or stencil mask for these elements and apply it
  53. * during draw.
  54. */
  55. const ElementList& maskElements() const { return fMaskElements; }
  56. /**
  57. * If maskElements() are nonempty, uniquely identifies the region of the clip mask that falls
  58. * inside of scissor().
  59. *
  60. * NOTE: since clip elements might fall outside the query bounds, different regions of the same
  61. * clip stack might have more or less restrictive IDs.
  62. *
  63. * FIXME: this prevents us from reusing a sub-rect of a perfectly good mask when that rect has
  64. * been assigned a less restrictive ID.
  65. */
  66. uint32_t maskGenID() const { SkASSERT(!fMaskElements.isEmpty()); return fMaskGenID; }
  67. /**
  68. * Indicates whether antialiasing is required to process any of the mask elements.
  69. */
  70. bool maskRequiresAA() const { SkASSERT(!fMaskElements.isEmpty()); return fMaskRequiresAA; }
  71. bool drawAlphaClipMask(GrRenderTargetContext*) const;
  72. bool drawStencilClipMask(GrRecordingContext*, GrRenderTargetContext*) const;
  73. int numAnalyticFPs() const { return fAnalyticFPs.count() + fCCPRClipPaths.count(); }
  74. /**
  75. * Called once the client knows the ID of the opList that the clip FPs will operate in. This
  76. * method finishes any outstanding work that was waiting for the opList ID, then detaches and
  77. * returns this class's list of FPs that complete the clip.
  78. *
  79. * NOTE: this must be called AFTER producing the clip mask (if any) because draw calls on
  80. * the render target context, surface allocations, and even switching render targets (pre MDB)
  81. * may cause flushes or otherwise change which opList the actual draw is going into.
  82. */
  83. std::unique_ptr<GrFragmentProcessor> finishAndDetachAnalyticFPs(
  84. GrCoverageCountingPathRenderer*, uint32_t opListID);
  85. private:
  86. void walkStack(const SkClipStack&, const SkRect& queryBounds);
  87. enum class ClipResult {
  88. kNotClipped,
  89. kClipped,
  90. kMadeEmpty
  91. };
  92. // Intersects the clip with the element's interior, regardless of inverse fill type.
  93. // NOTE: do not call for elements followed by ops that can grow the clip.
  94. ClipResult clipInsideElement(const Element*);
  95. // Intersects the clip with the element's exterior, regardless of inverse fill type.
  96. // NOTE: do not call for elements followed by ops that can grow the clip.
  97. ClipResult clipOutsideElement(const Element*);
  98. void addWindowRectangle(const SkRect& elementInteriorRect, bool elementIsAA);
  99. enum class Invert : bool {
  100. kNo = false,
  101. kYes = true
  102. };
  103. static GrClipEdgeType GetClipEdgeType(Invert, GrAA);
  104. ClipResult addAnalyticFP(const SkRect& deviceSpaceRect, Invert, GrAA);
  105. ClipResult addAnalyticFP(const SkRRect& deviceSpaceRRect, Invert, GrAA);
  106. ClipResult addAnalyticFP(const SkPath& deviceSpacePath, Invert, GrAA);
  107. void makeEmpty();
  108. const GrCaps* fCaps;
  109. const int fMaxWindowRectangles;
  110. const int fMaxAnalyticFPs;
  111. const int fMaxCCPRClipPaths;
  112. InitialState fInitialState;
  113. SkIRect fScissor;
  114. bool fHasScissor;
  115. SkRect fAAClipRect;
  116. uint32_t fAAClipRectGenID; // GenID the mask will have if includes the AA clip rect.
  117. GrWindowRectangles fWindowRects;
  118. ElementList fMaskElements;
  119. uint32_t fMaskGenID;
  120. bool fMaskRequiresAA;
  121. SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fAnalyticFPs;
  122. SkSTArray<4, SkPath> fCCPRClipPaths; // Will convert to FPs once we have an opList ID for CCPR.
  123. };
  124. #endif