blob: 6bc91b58a361be73cae05848817fce618ddc4e9f [file] [log] [blame]
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +00001/*
2 Copyright 2011 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17#ifndef GrPathRenderer_DEFINED
18#define GrPathRenderer_DEFINED
19
20#include "GrDrawTarget.h"
bsalomon@google.comee435122011-07-01 14:57:55 +000021#include "SkTemplates.h"
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000022
reed@google.com07f3ee12011-05-16 17:21:57 +000023class SkPath;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000024struct GrPoint;
25
26/**
27 * Base class for drawing paths into a GrDrawTarget.
bsalomon@google.comee435122011-07-01 14:57:55 +000028 * Paths may be drawn multiple times as when tiling for supersampling. The
29 * calls on GrPathRenderer to draw a path will look like this:
30 *
31 * pr->setPath(target, path, fill, translate); // sets the path to draw
32 * pr->drawPath(...); // draw the path
33 * pr->drawPath(...);
34 * ...
35 * pr->clearPath(); // finished with the path
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000036 */
bsalomon@google.com67dc5482011-04-04 18:45:32 +000037class GR_API GrPathRenderer : public GrRefCnt {
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000038public:
tomhudson@google.comd22b6e42011-06-24 15:53:40 +000039 GrPathRenderer(void);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000040 /**
41 * Returns true if this path renderer is able to render the path.
42 * Returning false allows the caller to fallback to another path renderer.
43 *
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000044 * @param path The path to draw
45 * @param fill The fill rule to use
46 *
47 * @return true if the path can be drawn by this object, false otherwise.
48 */
bsalomon@google.comee435122011-07-01 14:57:55 +000049 virtual bool canDrawPath(const SkPath& path, GrPathFill fill) const = 0;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000050
51 /**
52 * For complex clips Gr uses the stencil buffer. The path renderer must be
53 * able to render paths into the stencil buffer. However, the path renderer
bsalomon@google.comee435122011-07-01 14:57:55 +000054 * itself may require the stencil buffer to resolve the path fill rule.
55 * This function queries whether the path render needs its own stencil
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000056 * pass. If this returns false then drawPath() should not modify the
bsalomon@google.comee435122011-07-01 14:57:55 +000057 * the target's stencil settings but use those already set on target. The
58 * target is passed as a param in case the answer depends upon draw state.
59 * The view matrix and render target set on the draw target may change
60 * before setPath/drawPath is called and so shouldn't be considered.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000061 *
62 * @param target target that the path will be rendered to
63 * @param path the path that will be drawn
64 * @param fill the fill rule that will be used, will never be an inverse
65 * rule.
66 *
67 * @return false if this path renderer can generate interior-only fragments
68 * without changing the stencil settings on the target. If it
69 * returns true the drawPathToStencil will be used when rendering
70 * clips.
71 */
72 virtual bool requiresStencilPass(const GrDrawTarget* target,
reed@google.com07f3ee12011-05-16 17:21:57 +000073 const SkPath& path,
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000074 GrPathFill fill) const { return false; }
75
76 /**
bsalomon@google.comee435122011-07-01 14:57:55 +000077 * @return true if the path renderer can perform anti-aliasing (aside from
78 * having FSAA enabled for a render target). Target is provided to
79 * communicate the draw state (blend mode, stage settings, etc).
80 */
81 virtual bool supportsAA(GrDrawTarget* target,
82 const SkPath& path,
83 GrPathFill fill) { return false; }
84
85 /**
86 * Sets the path to render and target to render into. All calls to drawPath
87 * and drawPathToStencil must occur between setPath and clearPath. The
88 * path cannot be modified externally between setPath and clearPath. The
89 * path may be drawn several times (e.g. tiled supersampler). The target's
90 * state may change between setPath and drawPath* calls. However, if the
91 * path renderer specified vertices/indices during setPath or drawPath*
92 * they will still be set at subsequent drawPath* calls until the next
93 * clearPath. The target's draw state may change between drawPath* calls
94 * so if the subclass does any caching of tesselation, etc. then it must
95 * validate that target parameters that guided the decisions still hold.
96 *
97 * @param target the target to draw into.
98 * @param path the path to draw.
99 * @param fill the fill rule to apply.
100 * @param translate optional additional translation to apply to
101 * the path. NULL means (0,0).
102 */
103 void setPath(GrDrawTarget* target,
104 const SkPath* path,
105 GrPathFill fill,
106 const GrPoint* translate);
107
108 /**
109 * Notifies path renderer that path set in setPath is no longer in use.
110 */
111 void clearPath();
112
113 /**
114 * Draws the path into the draw target. If requiresStencilBuffer returned
115 * false then the target may be setup for stencil rendering (since the
116 * path renderer didn't claim that it needs to use the stencil internally).
117 *
118 * Only called between setPath / clearPath.
119 *
120 * @param stages bitfield that indicates which stages are
121 * in use. All enabled stages expect positions
122 * as texture coordinates. The path renderer
123 * use the remaining stages for its path
124 * filling algorithm.
125 */
126 virtual void drawPath(GrDrawTarget::StageBitfield stages) = 0;
127
128 /**
129 * Draws the path to the stencil buffer. Assume the writable stencil bits
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000130 * are already initialized to zero. Fill will always be either
131 * kWinding_PathFill or kEvenOdd_PathFill.
132 *
133 * Only called if requiresStencilPass returns true for the same combo of
134 * target, path, and fill. Never called with an inverse fill.
135 *
136 * The default implementation assumes the path filling algorithm doesn't
137 * require a separate stencil pass and so crashes.
138 *
bsalomon@google.comee435122011-07-01 14:57:55 +0000139 * Only called between setPath / clearPath.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000140 */
bsalomon@google.comee435122011-07-01 14:57:55 +0000141 virtual void drawPathToStencil() {
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000142 GrCrash("Unexpected call to drawPathToStencil.");
143 }
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000144
145 /**
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000146 * This is called to install a custom path renderer in every GrContext at
147 * create time. The default implementation in GrCreatePathRenderer_none.cpp
148 * returns NULL. Link against another implementation to install your own.
149 */
150 static GrPathRenderer* CreatePathRenderer();
151
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000152 /**
153 * Multiply curve tolerance by the given value, increasing or decreasing
154 * the maximum error permitted in tesselating curves with short straight
155 * line segments.
156 */
157 void scaleCurveTolerance(GrScalar multiplier) {
158 GrAssert(multiplier > 0);
159 fCurveTolerance = SkScalarMul(fCurveTolerance, multiplier);
160 }
161
bsalomon@google.comee435122011-07-01 14:57:55 +0000162 /**
163 * Helper that sets a path and automatically remove it in destructor.
164 */
165 class AutoClearPath {
166 public:
167 AutoClearPath() {
168 fPathRenderer = NULL;
169 }
170 AutoClearPath(GrPathRenderer* pr,
171 GrDrawTarget* target,
172 const SkPath* path,
173 GrPathFill fill,
174 const GrPoint* translate) {
175 GrAssert(NULL != pr);
176 pr->setPath(target, path, fill, translate);
177 fPathRenderer = pr;
178 }
179 void set(GrPathRenderer* pr,
180 GrDrawTarget* target,
181 const SkPath* path,
182 GrPathFill fill,
183 const GrPoint* translate) {
184 if (NULL != fPathRenderer) {
185 fPathRenderer->clearPath();
186 }
187 GrAssert(NULL != pr);
188 pr->setPath(target, path, fill, translate);
189 fPathRenderer = pr;
190 }
191 ~AutoClearPath() {
192 if (NULL != fPathRenderer) {
193 fPathRenderer->clearPath();
194 }
195 }
196 private:
197 GrPathRenderer* fPathRenderer;
198 };
199
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000200protected:
bsalomon@google.comee435122011-07-01 14:57:55 +0000201
202 // subclass can override these to be notified just after a path is set
203 // and just before the path is cleared.
204 virtual void pathWasSet() {}
205 virtual void pathWillClear() {}
206
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000207 GrScalar fCurveTolerance;
bsalomon@google.comee435122011-07-01 14:57:55 +0000208 const SkPath* fPath;
209 GrDrawTarget* fTarget;
210 GrPathFill fFill;
211 GrPoint fTranslate;
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000212
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000213private:
214
215 typedef GrRefCnt INHERITED;
216};
217
218/**
219 * Subclass that renders the path using the stencil buffer to resolve fill
220 * rules (e.g. winding, even-odd)
221 */
bsalomon@google.com67dc5482011-04-04 18:45:32 +0000222class GR_API GrDefaultPathRenderer : public GrPathRenderer {
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000223public:
224 GrDefaultPathRenderer(bool separateStencilSupport,
225 bool stencilWrapOpsSupport);
226
bsalomon@google.comee435122011-07-01 14:57:55 +0000227 virtual bool canDrawPath(const SkPath& path,
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000228 GrPathFill fill) const { return true; }
229
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000230 virtual bool requiresStencilPass(const GrDrawTarget* target,
reed@google.com07f3ee12011-05-16 17:21:57 +0000231 const SkPath& path,
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000232 GrPathFill fill) const;
bsalomon@google.comee435122011-07-01 14:57:55 +0000233
234 virtual void drawPath(GrDrawTarget::StageBitfield stages);
235 virtual void drawPathToStencil();
236
237protected:
238 virtual void pathWillClear();
239
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000240private:
241
bsalomon@google.comee435122011-07-01 14:57:55 +0000242 void onDrawPath(GrDrawTarget::StageBitfield stages, bool stencilOnly);
243
244 void createGeom(GrScalar srcSpaceTolSqd,
245 GrDrawTarget::StageBitfield stages);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000246
247 bool fSeparateStencil;
248 bool fStencilWrapOps;
249
bsalomon@google.comee435122011-07-01 14:57:55 +0000250 int fSubpathCount;
251 SkAutoSTMalloc<8, uint16_t> fSubpathVertCount;
252 GrScalar fPreviousSrcTol;
253 GrDrawTarget::StageBitfield fPreviousStages;
254
255
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000256 typedef GrPathRenderer INHERITED;
257};
258
259#endif
bsalomon@google.comee435122011-07-01 14:57:55 +0000260