OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #ifndef GrPathRenderer_DEFINED | 9 #ifndef GrPathRenderer_DEFINED |
10 #define GrPathRenderer_DEFINED | 10 #define GrPathRenderer_DEFINED |
11 | 11 |
12 #include "GrDrawTarget.h" | 12 #include "GrDrawTarget.h" |
13 #include "GrPathRendererChain.h" | 13 #include "GrPathRendererChain.h" |
14 #include "GrStencil.h" | 14 #include "GrStencil.h" |
15 | 15 |
16 #include "SkDrawProcs.h" | 16 #include "SkDrawProcs.h" |
17 #include "SkStrokeRec.h" | 17 #include "SkStrokeRec.h" |
18 #include "SkTArray.h" | 18 #include "SkTArray.h" |
19 | 19 |
20 class SkPath; | 20 class SkPath; |
21 | 21 |
22 struct GrPoint; | 22 struct GrPoint; |
23 | 23 |
24 /** | 24 /** |
25 * Base class for drawing paths into a GrDrawTarget. | 25 * Base class for drawing paths into a GrDrawTarget. |
26 * | 26 * |
27 * Derived classes can use stages GrPaint::kTotalStages through GrDrawState::kN
umStages-1. The | 27 * Derived classes can use stages GrPaint::kTotalStages through GrPipelineBuild
er::kNumStages-1. |
28 * stages before GrPaint::kTotalStages are reserved for setting up the draw (i.
e., textures and | 28 * The stages before GrPaint::kTotalStages are reserved for setting up the draw
(i.e., textures and |
29 * filter masks). | 29 * filter masks). |
30 */ | 30 */ |
31 class SK_API GrPathRenderer : public SkRefCnt { | 31 class SK_API GrPathRenderer : public SkRefCnt { |
32 public: | 32 public: |
33 SK_DECLARE_INST_COUNT(GrPathRenderer) | 33 SK_DECLARE_INST_COUNT(GrPathRenderer) |
34 | 34 |
35 /** | 35 /** |
36 * This is called to install custom path renderers in every GrContext at cre
ate time. The | 36 * This is called to install custom path renderers in every GrContext at cre
ate time. The |
37 * default implementation in GrCreatePathRenderer_none.cpp does not add any
additional | 37 * default implementation in GrCreatePathRenderer_none.cpp does not add any
additional |
38 * renderers. Link against another implementation to install your own. The f
irst added is the | 38 * renderers. Link against another implementation to install your own. The f
irst added is the |
39 * most preferred path renderer, second is second most preferred, etc. | 39 * most preferred path renderer, second is second most preferred, etc. |
40 * | 40 * |
41 * @param context the context that will use the path renderer | 41 * @param context the context that will use the path renderer |
42 * @param prChain the chain to add path renderers to. | 42 * @param prChain the chain to add path renderers to. |
43 */ | 43 */ |
44 static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChai
n); | 44 static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChai
n); |
45 | 45 |
46 | 46 |
47 GrPathRenderer(); | 47 GrPathRenderer(); |
48 | 48 |
49 /** | 49 /** |
50 * A caller may wish to use a path renderer to draw a path into the stencil
buffer. However, | 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 pa
th renderer may | 51 * the path renderer itself may require use of the stencil buffer. Also a pa
th renderer may |
52 * use a GrProcessor coverage stage that sets coverage to zero to eliminate
pixels that are | 52 * use a GrProcessor coverage stage that sets coverage to zero to eliminate
pixels that are |
53 * covered by bounding geometry but outside the path. These exterior pixels
would still be | 53 * covered by bounding geometry but outside the path. These exterior pixels
would still be |
54 * rendered into the stencil. | 54 * rendered into the stencil. |
55 * | 55 * |
56 * A GrPathRenderer can provide three levels of support for stenciling paths
: | 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 GrDra
wState on the target | 57 * 1) kNoRestriction: This is the most general. The caller sets up the GrPip
elineBuilder on the target |
58 * and calls drawPath(). The path is rendered exactly as
the draw state | 58 * and calls drawPath(). The path is rendered exactly as
the draw state |
59 * indicates including support for simultaneous color and
stenciling with | 59 * indicates including support for simultaneous color and
stenciling with |
60 * arbitrary stenciling rules. Pixels partially covered b
y AA paths are | 60 * arbitrary stenciling rules. Pixels partially covered b
y AA paths are |
61 * affected by the stencil settings. | 61 * affected by the stencil settings. |
62 * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules n
or shade and stencil | 62 * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules n
or shade and stencil |
63 * simultaneously. The path renderer does support the stenc
ilPath() function | 63 * simultaneously. The path renderer does support the stenc
ilPath() function |
64 * which performs no color writes and writes a non-zero ste
ncil value to pixels | 64 * which performs no color writes and writes a non-zero ste
ncil value to pixels |
65 * covered by the path. | 65 * covered by the path. |
66 * 3) kNoSupport: This path renderer cannot be used to stencil the path. | 66 * 3) kNoSupport: This path renderer cannot be used to stencil the path. |
67 */ | 67 */ |
68 typedef GrPathRendererChain::StencilSupport StencilSupport; | 68 typedef GrPathRendererChain::StencilSupport StencilSupport; |
69 static const StencilSupport kNoSupport_StencilSupport = | 69 static const StencilSupport kNoSupport_StencilSupport = |
70 GrPathRendererChain::kNoSupport_StencilSupport; | 70 GrPathRendererChain::kNoSupport_StencilSupport; |
71 static const StencilSupport kStencilOnly_StencilSupport = | 71 static const StencilSupport kStencilOnly_StencilSupport = |
72 GrPathRendererChain::kStencilOnly_StencilSupport; | 72 GrPathRendererChain::kStencilOnly_StencilSupport; |
73 static const StencilSupport kNoRestriction_StencilSupport = | 73 static const StencilSupport kNoRestriction_StencilSupport = |
74 GrPathRendererChain::kNoRestriction_StencilSupport; | 74 GrPathRendererChain::kNoRestriction_StencilSupport; |
75 | 75 |
76 /** | 76 /** |
77 * This function is to get the stencil support for a particular path. The pa
th's fill must | 77 * This function is to get the stencil support for a particular path. The pa
th's fill must |
78 * not be an inverse type. | 78 * not be an inverse type. |
79 * | 79 * |
80 * @param target target that the path will be rendered to | 80 * @param target target that the path will be rendered to |
81 * @param path the path that will be drawn | 81 * @param path the path that will be drawn |
82 * @param stroke the stroke information (width, join, cap). | 82 * @param stroke the stroke information (width, join, cap). |
83 */ | 83 */ |
84 StencilSupport getStencilSupport(const GrDrawTarget* target, | 84 StencilSupport getStencilSupport(const GrDrawTarget* target, |
85 const GrDrawState* drawState, | 85 const GrPipelineBuilder* pipelineBuilder, |
86 const SkPath& path, | 86 const SkPath& path, |
87 const SkStrokeRec& stroke) const { | 87 const SkStrokeRec& stroke) const { |
88 SkASSERT(!path.isInverseFillType()); | 88 SkASSERT(!path.isInverseFillType()); |
89 return this->onGetStencilSupport(target, drawState, path, stroke); | 89 return this->onGetStencilSupport(target, pipelineBuilder, path, stroke); |
90 } | 90 } |
91 | 91 |
92 /** | 92 /** |
93 * Returns true if this path renderer is able to render the path. Returning
false allows the | 93 * Returns true if this path renderer is able to render the path. Returning
false allows the |
94 * caller to fallback to another path renderer This function is called when
searching for a path | 94 * caller to fallback to another path renderer This function is called when
searching for a path |
95 * renderer capable of rendering a path. | 95 * renderer capable of rendering a path. |
96 * | 96 * |
97 * @param target The target that the path will be rendered to | 97 * @param target The target that the path will be rendered to |
98 * @param drawState The drawState | 98 * @param pipelineBuilder The pipelineBuilder |
99 * @param viewMatrix The viewMatrix | 99 * @param viewMatrix The viewMatrix |
100 * @param path The path to draw | 100 * @param path The path to draw |
101 * @param stroke The stroke information (width, join, cap) | 101 * @param stroke The stroke information (width, join, cap) |
102 * @param antiAlias True if anti-aliasing is required. | 102 * @param antiAlias True if anti-aliasing is required. |
103 * | 103 * |
104 * @return true if the path can be drawn by this object, false otherwise. | 104 * @return true if the path can be drawn by this object, false otherwise. |
105 */ | 105 */ |
106 virtual bool canDrawPath(const GrDrawTarget* target, | 106 virtual bool canDrawPath(const GrDrawTarget* target, |
107 const GrDrawState* drawState, | 107 const GrPipelineBuilder* pipelineBuilder, |
108 const SkMatrix& viewMatrix, | 108 const SkMatrix& viewMatrix, |
109 const SkPath& path, | 109 const SkPath& path, |
110 const SkStrokeRec& rec, | 110 const SkStrokeRec& rec, |
111 bool antiAlias) const = 0; | 111 bool antiAlias) const = 0; |
112 /** | 112 /** |
113 * Draws the path into the draw target. If getStencilSupport() would return
kNoRestriction then | 113 * Draws the path into the draw target. If getStencilSupport() would return
kNoRestriction then |
114 * the subclass must respect the stencil settings of the target's draw state
. | 114 * the subclass must respect the stencil settings of the target's draw state
. |
115 * | 115 * |
116 * @param target The target that the path will be rendered to | 116 * @param target The target that the path will be rendered to |
117 * @param drawState The drawState | 117 * @param pipelineBuilder The pipelineBuilder |
118 * @param viewMatrix The viewMatrix | 118 * @param viewMatrix The viewMatrix |
119 * @param path the path to draw. | 119 * @param path the path to draw. |
120 * @param stroke the stroke information (width, join, cap) | 120 * @param stroke the stroke information (width, join, cap) |
121 * @param antiAlias true if anti-aliasing is required. | 121 * @param antiAlias true if anti-aliasing is required. |
122 */ | 122 */ |
123 bool drawPath(GrDrawTarget* target, | 123 bool drawPath(GrDrawTarget* target, |
124 GrDrawState* ds, | 124 GrPipelineBuilder* ds, |
125 GrColor color, | 125 GrColor color, |
126 const SkMatrix& viewMatrix, | 126 const SkMatrix& viewMatrix, |
127 const SkPath& path, | 127 const SkPath& path, |
128 const SkStrokeRec& stroke, | 128 const SkStrokeRec& stroke, |
129 bool antiAlias) { | 129 bool antiAlias) { |
130 SkASSERT(!path.isEmpty()); | 130 SkASSERT(!path.isEmpty()); |
131 SkASSERT(this->canDrawPath(target, ds, viewMatrix, path, stroke, antiAli
as)); | 131 SkASSERT(this->canDrawPath(target, ds, viewMatrix, path, stroke, antiAli
as)); |
132 SkASSERT(ds->getStencil().isDisabled() || | 132 SkASSERT(ds->getStencil().isDisabled() || |
133 kNoRestriction_StencilSupport == this->getStencilSupport(target
, ds, path, | 133 kNoRestriction_StencilSupport == this->getStencilSupport(target
, ds, path, |
134 stroke
)); | 134 stroke
)); |
135 return this->onDrawPath(target, ds, color, viewMatrix, path, stroke, ant
iAlias); | 135 return this->onDrawPath(target, ds, color, viewMatrix, path, stroke, ant
iAlias); |
136 } | 136 } |
137 | 137 |
138 /** | 138 /** |
139 * Draws the path to the stencil buffer. Assume the writable stencil bits ar
e already | 139 * Draws the path to the stencil buffer. Assume the writable stencil bits ar
e already |
140 * initialized to zero. The pixels inside the path will have non-zero stenci
l values afterwards. | 140 * initialized to zero. The pixels inside the path will have non-zero stenci
l values afterwards. |
141 * | 141 * |
142 * @param path the path to draw. | 142 * @param path the path to draw. |
143 * @param stroke the stroke information (width, join, cap) | 143 * @param stroke the stroke information (width, join, cap) |
144 * @param target target that the path will be rendered to | 144 * @param target target that the path will be rendered to |
145 */ | 145 */ |
146 void stencilPath(GrDrawTarget* target, | 146 void stencilPath(GrDrawTarget* target, |
147 GrDrawState* ds, | 147 GrPipelineBuilder* ds, |
148 const SkMatrix& viewMatrix, | 148 const SkMatrix& viewMatrix, |
149 const SkPath& path, | 149 const SkPath& path, |
150 const SkStrokeRec& stroke) { | 150 const SkStrokeRec& stroke) { |
151 SkASSERT(!path.isEmpty()); | 151 SkASSERT(!path.isEmpty()); |
152 SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(target, ds
, path, stroke)); | 152 SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(target, ds
, path, stroke)); |
153 this->onStencilPath(target, ds, viewMatrix, path, stroke); | 153 this->onStencilPath(target, ds, viewMatrix, path, stroke); |
154 } | 154 } |
155 | 155 |
156 // Helper for determining if we can treat a thin stroke as a hairline w/ cov
erage. | 156 // Helper for determining if we can treat a thin stroke as a hairline w/ cov
erage. |
157 // If we can, we draw lots faster (raster device does this same test). | 157 // If we can, we draw lots faster (raster device does this same test). |
158 static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const Sk
Matrix& matrix, | 158 static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const Sk
Matrix& matrix, |
159 SkScalar* outCoverage) { | 159 SkScalar* outCoverage) { |
160 if (stroke.isHairlineStyle()) { | 160 if (stroke.isHairlineStyle()) { |
161 if (outCoverage) { | 161 if (outCoverage) { |
162 *outCoverage = SK_Scalar1; | 162 *outCoverage = SK_Scalar1; |
163 } | 163 } |
164 return true; | 164 return true; |
165 } | 165 } |
166 return stroke.getStyle() == SkStrokeRec::kStroke_Style && | 166 return stroke.getStyle() == SkStrokeRec::kStroke_Style && |
167 SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage
); | 167 SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage
); |
168 } | 168 } |
169 | 169 |
170 protected: | 170 protected: |
171 /** | 171 /** |
172 * Subclass overrides if it has any limitations of stenciling support. | 172 * Subclass overrides if it has any limitations of stenciling support. |
173 */ | 173 */ |
174 virtual StencilSupport onGetStencilSupport(const GrDrawTarget*, | 174 virtual StencilSupport onGetStencilSupport(const GrDrawTarget*, |
175 const GrDrawState*, | 175 const GrPipelineBuilder*, |
176 const SkPath&, | 176 const SkPath&, |
177 const SkStrokeRec&) const { | 177 const SkStrokeRec&) const { |
178 return kNoRestriction_StencilSupport; | 178 return kNoRestriction_StencilSupport; |
179 } | 179 } |
180 | 180 |
181 /** | 181 /** |
182 * Subclass implementation of drawPath() | 182 * Subclass implementation of drawPath() |
183 */ | 183 */ |
184 virtual bool onDrawPath(GrDrawTarget*, | 184 virtual bool onDrawPath(GrDrawTarget*, |
185 GrDrawState*, | 185 GrPipelineBuilder*, |
186 GrColor, | 186 GrColor, |
187 const SkMatrix& viewMatrix, | 187 const SkMatrix& viewMatrix, |
188 const SkPath&, | 188 const SkPath&, |
189 const SkStrokeRec&, | 189 const SkStrokeRec&, |
190 bool antiAlias) = 0; | 190 bool antiAlias) = 0; |
191 | 191 |
192 /** | 192 /** |
193 * Subclass implementation of stencilPath(). Subclass must override iff it e
ver returns | 193 * Subclass implementation of stencilPath(). Subclass must override iff it e
ver returns |
194 * kStencilOnly in onGetStencilSupport(). | 194 * kStencilOnly in onGetStencilSupport(). |
195 */ | 195 */ |
196 virtual void onStencilPath(GrDrawTarget* target, | 196 virtual void onStencilPath(GrDrawTarget* target, |
197 GrDrawState* drawState, | 197 GrPipelineBuilder* pipelineBuilder, |
198 const SkMatrix& viewMatrix, | 198 const SkMatrix& viewMatrix, |
199 const SkPath& path, | 199 const SkPath& path, |
200 const SkStrokeRec& stroke) { | 200 const SkStrokeRec& stroke) { |
201 GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, | 201 GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, |
202 kReplace_StencilOp, | 202 kReplace_StencilOp, |
203 kReplace_StencilOp, | 203 kReplace_StencilOp, |
204 kAlways_StencilFunc, | 204 kAlways_StencilFunc, |
205 0xffff, | 205 0xffff, |
206 0xffff, | 206 0xffff, |
207 0xffff); | 207 0xffff); |
208 drawState->setStencil(kIncrementStencil); | 208 pipelineBuilder->setStencil(kIncrementStencil); |
209 drawState->setDisableColorXPFactory(); | 209 pipelineBuilder->setDisableColorXPFactory(); |
210 this->drawPath(target, drawState, GrColor_WHITE, viewMatrix, path, strok
e, false); | 210 this->drawPath(target, pipelineBuilder, GrColor_WHITE, viewMatrix, path,
stroke, false); |
211 } | 211 } |
212 | 212 |
213 // Helper for getting the device bounds of a path. Inverse filled paths will
have bounds set | 213 // Helper for getting the device bounds of a path. Inverse filled paths will
have bounds set |
214 // by devSize. Non-inverse path bounds will not necessarily be clipped to de
vSize. | 214 // by devSize. Non-inverse path bounds will not necessarily be clipped to de
vSize. |
215 static void GetPathDevBounds(const SkPath& path, | 215 static void GetPathDevBounds(const SkPath& path, |
216 int devW, | 216 int devW, |
217 int devH, | 217 int devH, |
218 const SkMatrix& matrix, | 218 const SkMatrix& matrix, |
219 SkRect* bounds); | 219 SkRect* bounds); |
220 | 220 |
221 // Helper version that gets the dev width and height from a GrSurface. | 221 // Helper version that gets the dev width and height from a GrSurface. |
222 static void GetPathDevBounds(const SkPath& path, | 222 static void GetPathDevBounds(const SkPath& path, |
223 const GrSurface* device, | 223 const GrSurface* device, |
224 const SkMatrix& matrix, | 224 const SkMatrix& matrix, |
225 SkRect* bounds) { | 225 SkRect* bounds) { |
226 GetPathDevBounds(path, device->width(), device->height(), matrix, bounds
); | 226 GetPathDevBounds(path, device->width(), device->height(), matrix, bounds
); |
227 } | 227 } |
228 | 228 |
229 private: | 229 private: |
230 | 230 |
231 typedef SkRefCnt INHERITED; | 231 typedef SkRefCnt INHERITED; |
232 }; | 232 }; |
233 | 233 |
234 #endif | 234 #endif |
OLD | NEW |