GrPathRenderer.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright 2011 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 GrPathRenderer_DEFINED
  8. #define GrPathRenderer_DEFINED
  9. #include "include/core/SkRefCnt.h"
  10. #include "include/private/GrTypesPriv.h"
  11. #include "include/private/SkTArray.h"
  12. class GrCaps;
  13. class GrClip;
  14. class GrFixedClip;
  15. class GrHardClip;
  16. class GrPaint;
  17. class GrRecordingContext;
  18. class GrRenderTargetContext;
  19. class GrRenderTargetProxy;
  20. class GrShape;
  21. class GrStyle;
  22. struct GrUserStencilSettings;
  23. struct SkIRect;
  24. class SkMatrix;
  25. class SkPath;
  26. /**
  27. * Base class for drawing paths into a GrOpList.
  28. */
  29. class SK_API GrPathRenderer : public SkRefCnt {
  30. public:
  31. GrPathRenderer();
  32. /**
  33. * A caller may wish to use a path renderer to draw a path into the stencil buffer. However,
  34. * the path renderer itself may require use of the stencil buffer. Also a path renderer may
  35. * use a GrProcessor coverage stage that sets coverage to zero to eliminate pixels that are
  36. * covered by bounding geometry but outside the path. These exterior pixels would still be
  37. * rendered into the stencil.
  38. *
  39. * A GrPathRenderer can provide three levels of support for stenciling paths:
  40. * 1) kNoRestriction: This is the most general. The caller passes a GrPaint and calls drawPath().
  41. * The path is rendered exactly as the draw state indicates including support
  42. * for simultaneous color and stenciling with arbitrary stenciling rules.
  43. * Pixels partially covered by AA paths are affected by the stencil settings.
  44. * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil
  45. * simultaneously. The path renderer does support the stencilPath() function
  46. * which performs no color writes and writes a non-zero stencil value to pixels
  47. * covered by the path.
  48. * 3) kNoSupport: This path renderer cannot be used to stencil the path.
  49. */
  50. enum StencilSupport {
  51. kNoSupport_StencilSupport,
  52. kStencilOnly_StencilSupport,
  53. kNoRestriction_StencilSupport,
  54. };
  55. /**
  56. * This function is to get the stencil support for a particular path. The path's fill must
  57. * not be an inverse type. The path will always be filled and not stroked.
  58. *
  59. * @param shape the shape that will be drawn. Must be simple fill styled and non-inverse
  60. * filled.
  61. */
  62. StencilSupport getStencilSupport(const GrShape& shape) const;
  63. enum class CanDrawPath {
  64. kNo,
  65. kAsBackup, // i.e. This renderer is better than SW fallback if no others can draw the path.
  66. kYes
  67. };
  68. struct CanDrawPathArgs {
  69. SkDEBUGCODE(CanDrawPathArgs() { memset(this, 0, sizeof(*this)); }) // For validation.
  70. const GrCaps* fCaps;
  71. const GrRenderTargetProxy* fProxy;
  72. const SkIRect* fClipConservativeBounds;
  73. const SkMatrix* fViewMatrix;
  74. const GrShape* fShape;
  75. GrAAType fAAType;
  76. bool fTargetIsWrappedVkSecondaryCB;
  77. // This is only used by GrStencilAndCoverPathRenderer
  78. bool fHasUserStencilSettings;
  79. #ifdef SK_DEBUG
  80. void validate() const {
  81. SkASSERT(fCaps);
  82. SkASSERT(fProxy);
  83. SkASSERT(fClipConservativeBounds);
  84. SkASSERT(fViewMatrix);
  85. SkASSERT(fShape);
  86. }
  87. #endif
  88. };
  89. /**
  90. * Returns how well this path renderer is able to render the given path. Returning kNo or
  91. * kAsBackup allows the caller to keep searching for a better path renderer. This function is
  92. * called when searching for the best path renderer to draw a path.
  93. */
  94. CanDrawPath canDrawPath(const CanDrawPathArgs& args) const {
  95. SkDEBUGCODE(args.validate();)
  96. return this->onCanDrawPath(args);
  97. }
  98. struct DrawPathArgs {
  99. GrRecordingContext* fContext;
  100. GrPaint&& fPaint;
  101. const GrUserStencilSettings* fUserStencilSettings;
  102. GrRenderTargetContext* fRenderTargetContext;
  103. const GrClip* fClip;
  104. const SkIRect* fClipConservativeBounds;
  105. const SkMatrix* fViewMatrix;
  106. const GrShape* fShape;
  107. GrAAType fAAType;
  108. bool fGammaCorrect;
  109. #ifdef SK_DEBUG
  110. void validate() const {
  111. SkASSERT(fContext);
  112. SkASSERT(fUserStencilSettings);
  113. SkASSERT(fRenderTargetContext);
  114. SkASSERT(fClip);
  115. SkASSERT(fClipConservativeBounds);
  116. SkASSERT(fViewMatrix);
  117. SkASSERT(fShape);
  118. }
  119. #endif
  120. };
  121. /**
  122. * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
  123. * the subclass must respect the stencil settings.
  124. */
  125. bool drawPath(const DrawPathArgs& args);
  126. /**
  127. * Args to stencilPath(). fAAType cannot be kCoverage.
  128. */
  129. struct StencilPathArgs {
  130. SkDEBUGCODE(StencilPathArgs() { memset(this, 0, sizeof(*this)); }) // For validation.
  131. GrRecordingContext* fContext;
  132. GrRenderTargetContext* fRenderTargetContext;
  133. const GrHardClip* fClip;
  134. const SkIRect* fClipConservativeBounds;
  135. const SkMatrix* fViewMatrix;
  136. const GrShape* fShape;
  137. GrAA fDoStencilMSAA;
  138. SkDEBUGCODE(void validate() const);
  139. };
  140. /**
  141. * Draws the path to the stencil buffer. Assume the writable stencil bits are already
  142. * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
  143. */
  144. void stencilPath(const StencilPathArgs& args) {
  145. SkDEBUGCODE(args.validate();)
  146. SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape));
  147. this->onStencilPath(args);
  148. }
  149. // Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
  150. // If we can, we draw lots faster (raster device does this same test).
  151. static bool IsStrokeHairlineOrEquivalent(const GrStyle&, const SkMatrix&,
  152. SkScalar* outCoverage);
  153. protected:
  154. // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
  155. // by devSize. Non-inverse path bounds will not necessarily be clipped to devSize.
  156. static void GetPathDevBounds(const SkPath& path,
  157. int devW,
  158. int devH,
  159. const SkMatrix& matrix,
  160. SkRect* bounds);
  161. private:
  162. /**
  163. * Subclass overrides if it has any limitations of stenciling support.
  164. */
  165. virtual StencilSupport onGetStencilSupport(const GrShape&) const {
  166. return kNoRestriction_StencilSupport;
  167. }
  168. /**
  169. * Subclass implementation of drawPath()
  170. */
  171. virtual bool onDrawPath(const DrawPathArgs& args) = 0;
  172. /**
  173. * Subclass implementation of canDrawPath()
  174. */
  175. virtual CanDrawPath onCanDrawPath(const CanDrawPathArgs& args) const = 0;
  176. /**
  177. * Subclass implementation of stencilPath(). Subclass must override iff it ever returns
  178. * kStencilOnly in onGetStencilSupport().
  179. */
  180. virtual void onStencilPath(const StencilPathArgs&);
  181. typedef SkRefCnt INHERITED;
  182. };
  183. #endif