1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef GrPathRenderer_DEFINED 11 #define GrPathRenderer_DEFINED 12 13 #include "GrDrawTarget.h" 14 #include "GrPathRendererChain.h" 15 #include "GrStencil.h" 16 17 #include "SkStrokeRec.h" 18 #include "SkTArray.h" 19 20 class SkPath; 21 22 struct GrPoint; 23 24 /** 25 * Base class for drawing paths into a GrDrawTarget. 26 * 27 * Derived classes can use stages GrPaint::kTotalStages through GrDrawState::kNumStages-1. The 28 * stages before GrPaint::kTotalStages are reserved for setting up the draw (i.e., textures and 29 * filter masks). 30 */ 31 class GR_API GrPathRenderer : public GrRefCnt { 32 public: 33 SK_DECLARE_INST_COUNT(GrPathRenderer) 34 35 /** 36 * This is called to install custom path renderers in every GrContext at create time. The 37 * default implementation in GrCreatePathRenderer_none.cpp does not add any additional 38 * renderers. Link against another implementation to install your own. The first added is the 39 * most preferred path renderer, second is second most preferred, etc. 40 * 41 * @param context the context that will use the path renderer 42 * @param prChain the chain to add path renderers to. 43 */ 44 static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChain); 45 46 47 GrPathRenderer(); 48 49 /** 50 * A caller may wish to use a path renderer to draw a path into the stencil buffer. However, 51 * the path renderer itself may require use of the stencil buffer. Also a path renderer may 52 * use a GrEffect coverage stage that sets coverage to zero to eliminate pixels that are covered 53 * by bounding geometry but outside the path. These exterior pixels would still be rendered into 54 * the stencil. 55 * 56 * A GrPathRenderer can provide three levels of support for stenciling paths: 57 * 1) kNoRestriction: This is the most general. The caller sets up the GrDrawState on the target 58 * and calls drawPath(). The path is rendered exactly as the draw state 59 * indicates including support for simultaneous color and stenciling with 60 * arbitrary stenciling rules. Pixels partially covered by AA paths are 61 * affected by the stencil settings. 62 * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil 63 * simultaneously. The path renderer does support the stencilPath() function 64 * which performs no color writes and writes a non-zero stencil value to pixels 65 * covered by the path. 66 * 3) kNoSupport: This path renderer cannot be used to stencil the path. 67 */ 68 typedef GrPathRendererChain::StencilSupport StencilSupport; 69 static const StencilSupport kNoSupport_StencilSupport = 70 GrPathRendererChain::kNoSupport_StencilSupport; 71 static const StencilSupport kStencilOnly_StencilSupport = 72 GrPathRendererChain::kStencilOnly_StencilSupport; 73 static const StencilSupport kNoRestriction_StencilSupport = 74 GrPathRendererChain::kNoRestriction_StencilSupport; 75 76 /** 77 * This function is to get the stencil support for a particular path. The path's fill must 78 * not be an inverse type. 79 * 80 * @param target target that the path will be rendered to 81 * @param path the path that will be drawn 82 * @param stroke the stroke information (width, join, cap). 83 */ 84 StencilSupport getStencilSupport(const SkPath& path, 85 const SkStrokeRec& stroke, 86 const GrDrawTarget* target) const { 87 GrAssert(!path.isInverseFillType()); 88 return this->onGetStencilSupport(path, stroke, target); 89 } 90 91 /** 92 * Returns true if this path renderer is able to render the path. Returning false allows the 93 * caller to fallback to another path renderer This function is called when searching for a path 94 * renderer capable of rendering a path. 95 * 96 * @param path The path to draw 97 * @param stroke The stroke information (width, join, cap) 98 * @param target The target that the path will be rendered to 99 * @param antiAlias True if anti-aliasing is required. 100 * 101 * @return true if the path can be drawn by this object, false otherwise. 102 */ 103 virtual bool canDrawPath(const SkPath& path, 104 const SkStrokeRec& rec, 105 const GrDrawTarget* target, 106 bool antiAlias) const = 0; 107 /** 108 * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then 109 * the subclass must respect the stencil settings of the target's draw state. 110 * 111 * @param path the path to draw. 112 * @param stroke the stroke information (width, join, cap) 113 * @param target target that the path will be rendered to 114 * @param antiAlias true if anti-aliasing is required. 115 */ 116 bool drawPath(const SkPath& path, 117 const SkStrokeRec& stroke, 118 GrDrawTarget* target, 119 bool antiAlias) { 120 GrAssert(this->canDrawPath(path, stroke, target, antiAlias)); 121 GrAssert(target->drawState()->getStencil().isDisabled() || 122 kNoRestriction_StencilSupport == this->getStencilSupport(path, stroke, target)); 123 return this->onDrawPath(path, stroke, target, antiAlias); 124 } 125 126 /** 127 * Draws the path to the stencil buffer. Assume the writable stencil bits are already 128 * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards. 129 * 130 * @param path the path to draw. 131 * @param stroke the stroke information (width, join, cap) 132 * @param target target that the path will be rendered to 133 */ 134 void stencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) { 135 GrAssert(kNoSupport_StencilSupport != this->getStencilSupport(path, stroke, target)); 136 this->onStencilPath(path, stroke, target); 137 } 138 139 protected: 140 /** 141 * Subclass overrides if it has any limitations of stenciling support. 142 */ 143 virtual StencilSupport onGetStencilSupport(const SkPath&, 144 const SkStrokeRec&, 145 const GrDrawTarget*) const { 146 return kNoRestriction_StencilSupport; 147 } 148 149 /** 150 * Subclass implementation of drawPath() 151 */ 152 virtual bool onDrawPath(const SkPath& path, 153 const SkStrokeRec& stroke, 154 GrDrawTarget* target, 155 bool antiAlias) = 0; 156 157 /** 158 * Subclass implementation of stencilPath(). Subclass must override iff it ever returns 159 * kStencilOnly in onGetStencilSupport(). 160 */ 161 virtual void onStencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) { 162 GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); 163 GrDrawState* drawState = target->drawState(); 164 GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, 165 kReplace_StencilOp, 166 kReplace_StencilOp, 167 kAlways_StencilFunc, 168 0xffff, 169 0xffff, 170 0xffff); 171 drawState->setStencil(kIncrementStencil); 172 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); 173 this->drawPath(path, stroke, target, false); 174 } 175 176 private: 177 178 typedef GrRefCnt INHERITED; 179 }; 180 181 #endif 182