blob: 67c3a93cb5d71efd4b799c4fa35fc9e9ae376123 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000010#ifndef GrPathRenderer_DEFINED
11#define GrPathRenderer_DEFINED
12
13#include "GrDrawTarget.h"
bsalomon@google.comee435122011-07-01 14:57:55 +000014#include "SkTemplates.h"
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000015
reed@google.com07f3ee12011-05-16 17:21:57 +000016class SkPath;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000017struct GrPoint;
18
19/**
20 * Base class for drawing paths into a GrDrawTarget.
bsalomon@google.comee435122011-07-01 14:57:55 +000021 * Paths may be drawn multiple times as when tiling for supersampling. The
22 * calls on GrPathRenderer to draw a path will look like this:
23 *
24 * pr->setPath(target, path, fill, translate); // sets the path to draw
25 * pr->drawPath(...); // draw the path
26 * pr->drawPath(...);
27 * ...
28 * pr->clearPath(); // finished with the path
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000029 */
bsalomon@google.com67dc5482011-04-04 18:45:32 +000030class GR_API GrPathRenderer : public GrRefCnt {
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000031public:
tomhudson@google.comd22b6e42011-06-24 15:53:40 +000032 GrPathRenderer(void);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000033 /**
34 * Returns true if this path renderer is able to render the path.
35 * Returning false allows the caller to fallback to another path renderer.
36 *
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000037 * @param path The path to draw
38 * @param fill The fill rule to use
39 *
40 * @return true if the path can be drawn by this object, false otherwise.
41 */
bsalomon@google.comee435122011-07-01 14:57:55 +000042 virtual bool canDrawPath(const SkPath& path, GrPathFill fill) const = 0;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000043
44 /**
45 * For complex clips Gr uses the stencil buffer. The path renderer must be
46 * able to render paths into the stencil buffer. However, the path renderer
bsalomon@google.comee435122011-07-01 14:57:55 +000047 * itself may require the stencil buffer to resolve the path fill rule.
48 * This function queries whether the path render needs its own stencil
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000049 * pass. If this returns false then drawPath() should not modify the
bsalomon@google.comee435122011-07-01 14:57:55 +000050 * the target's stencil settings but use those already set on target. The
51 * target is passed as a param in case the answer depends upon draw state.
52 * The view matrix and render target set on the draw target may change
53 * before setPath/drawPath is called and so shouldn't be considered.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000054 *
55 * @param target target that the path will be rendered to
56 * @param path the path that will be drawn
57 * @param fill the fill rule that will be used, will never be an inverse
58 * rule.
59 *
60 * @return false if this path renderer can generate interior-only fragments
61 * without changing the stencil settings on the target. If it
62 * returns true the drawPathToStencil will be used when rendering
63 * clips.
64 */
65 virtual bool requiresStencilPass(const GrDrawTarget* target,
reed@google.com07f3ee12011-05-16 17:21:57 +000066 const SkPath& path,
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000067 GrPathFill fill) const { return false; }
68
69 /**
bsalomon@google.comee435122011-07-01 14:57:55 +000070 * @return true if the path renderer can perform anti-aliasing (aside from
71 * having FSAA enabled for a render target). Target is provided to
72 * communicate the draw state (blend mode, stage settings, etc).
73 */
74 virtual bool supportsAA(GrDrawTarget* target,
75 const SkPath& path,
76 GrPathFill fill) { return false; }
77
78 /**
79 * Sets the path to render and target to render into. All calls to drawPath
80 * and drawPathToStencil must occur between setPath and clearPath. The
81 * path cannot be modified externally between setPath and clearPath. The
82 * path may be drawn several times (e.g. tiled supersampler). The target's
83 * state may change between setPath and drawPath* calls. However, if the
84 * path renderer specified vertices/indices during setPath or drawPath*
85 * they will still be set at subsequent drawPath* calls until the next
86 * clearPath. The target's draw state may change between drawPath* calls
87 * so if the subclass does any caching of tesselation, etc. then it must
88 * validate that target parameters that guided the decisions still hold.
89 *
90 * @param target the target to draw into.
91 * @param path the path to draw.
92 * @param fill the fill rule to apply.
93 * @param translate optional additional translation to apply to
94 * the path. NULL means (0,0).
95 */
96 void setPath(GrDrawTarget* target,
97 const SkPath* path,
98 GrPathFill fill,
99 const GrPoint* translate);
100
101 /**
102 * Notifies path renderer that path set in setPath is no longer in use.
103 */
104 void clearPath();
105
106 /**
107 * Draws the path into the draw target. If requiresStencilBuffer returned
108 * false then the target may be setup for stencil rendering (since the
109 * path renderer didn't claim that it needs to use the stencil internally).
110 *
111 * Only called between setPath / clearPath.
112 *
113 * @param stages bitfield that indicates which stages are
114 * in use. All enabled stages expect positions
115 * as texture coordinates. The path renderer
116 * use the remaining stages for its path
117 * filling algorithm.
118 */
119 virtual void drawPath(GrDrawTarget::StageBitfield stages) = 0;
120
121 /**
122 * Draws the path to the stencil buffer. Assume the writable stencil bits
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000123 * are already initialized to zero. Fill will always be either
124 * kWinding_PathFill or kEvenOdd_PathFill.
125 *
126 * Only called if requiresStencilPass returns true for the same combo of
127 * target, path, and fill. Never called with an inverse fill.
128 *
129 * The default implementation assumes the path filling algorithm doesn't
130 * require a separate stencil pass and so crashes.
131 *
bsalomon@google.comee435122011-07-01 14:57:55 +0000132 * Only called between setPath / clearPath.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000133 */
bsalomon@google.comee435122011-07-01 14:57:55 +0000134 virtual void drawPathToStencil() {
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000135 GrCrash("Unexpected call to drawPathToStencil.");
136 }
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000137
138 /**
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000139 * This is called to install a custom path renderer in every GrContext at
140 * create time. The default implementation in GrCreatePathRenderer_none.cpp
141 * returns NULL. Link against another implementation to install your own.
142 */
143 static GrPathRenderer* CreatePathRenderer();
144
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000145 /**
146 * Multiply curve tolerance by the given value, increasing or decreasing
147 * the maximum error permitted in tesselating curves with short straight
148 * line segments.
149 */
150 void scaleCurveTolerance(GrScalar multiplier) {
151 GrAssert(multiplier > 0);
152 fCurveTolerance = SkScalarMul(fCurveTolerance, multiplier);
153 }
154
bsalomon@google.comee435122011-07-01 14:57:55 +0000155 /**
156 * Helper that sets a path and automatically remove it in destructor.
157 */
158 class AutoClearPath {
159 public:
160 AutoClearPath() {
161 fPathRenderer = NULL;
162 }
163 AutoClearPath(GrPathRenderer* pr,
164 GrDrawTarget* target,
165 const SkPath* path,
166 GrPathFill fill,
167 const GrPoint* translate) {
168 GrAssert(NULL != pr);
169 pr->setPath(target, path, fill, translate);
170 fPathRenderer = pr;
171 }
172 void set(GrPathRenderer* pr,
173 GrDrawTarget* target,
174 const SkPath* path,
175 GrPathFill fill,
176 const GrPoint* translate) {
177 if (NULL != fPathRenderer) {
178 fPathRenderer->clearPath();
179 }
180 GrAssert(NULL != pr);
181 pr->setPath(target, path, fill, translate);
182 fPathRenderer = pr;
183 }
184 ~AutoClearPath() {
185 if (NULL != fPathRenderer) {
186 fPathRenderer->clearPath();
187 }
188 }
189 private:
190 GrPathRenderer* fPathRenderer;
191 };
192
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000193protected:
bsalomon@google.comee435122011-07-01 14:57:55 +0000194
195 // subclass can override these to be notified just after a path is set
196 // and just before the path is cleared.
197 virtual void pathWasSet() {}
198 virtual void pathWillClear() {}
199
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000200 GrScalar fCurveTolerance;
bsalomon@google.comee435122011-07-01 14:57:55 +0000201 const SkPath* fPath;
202 GrDrawTarget* fTarget;
203 GrPathFill fFill;
204 GrPoint fTranslate;
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000205
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000206private:
207
208 typedef GrRefCnt INHERITED;
209};
210
211/**
212 * Subclass that renders the path using the stencil buffer to resolve fill
213 * rules (e.g. winding, even-odd)
214 */
bsalomon@google.com67dc5482011-04-04 18:45:32 +0000215class GR_API GrDefaultPathRenderer : public GrPathRenderer {
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000216public:
217 GrDefaultPathRenderer(bool separateStencilSupport,
218 bool stencilWrapOpsSupport);
219
bsalomon@google.comee435122011-07-01 14:57:55 +0000220 virtual bool canDrawPath(const SkPath& path,
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000221 GrPathFill fill) const { return true; }
222
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000223 virtual bool requiresStencilPass(const GrDrawTarget* target,
reed@google.com07f3ee12011-05-16 17:21:57 +0000224 const SkPath& path,
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000225 GrPathFill fill) const;
bsalomon@google.comee435122011-07-01 14:57:55 +0000226
227 virtual void drawPath(GrDrawTarget::StageBitfield stages);
228 virtual void drawPathToStencil();
229
230protected:
231 virtual void pathWillClear();
232
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000233private:
234
bsalomon@google.comee435122011-07-01 14:57:55 +0000235 void onDrawPath(GrDrawTarget::StageBitfield stages, bool stencilOnly);
236
bsalomon@google.com25fd36c2011-07-06 17:41:08 +0000237 bool createGeom(GrScalar srcSpaceTol,
bsalomon@google.comee435122011-07-01 14:57:55 +0000238 GrDrawTarget::StageBitfield stages);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000239
240 bool fSeparateStencil;
241 bool fStencilWrapOps;
242
bsalomon@google.comee435122011-07-01 14:57:55 +0000243 int fSubpathCount;
244 SkAutoSTMalloc<8, uint16_t> fSubpathVertCount;
bsalomon@google.com25fd36c2011-07-06 17:41:08 +0000245 int fIndexCnt;
246 int fVertexCnt;
bsalomon@google.comee435122011-07-01 14:57:55 +0000247 GrScalar fPreviousSrcTol;
248 GrDrawTarget::StageBitfield fPreviousStages;
bsalomon@google.com25fd36c2011-07-06 17:41:08 +0000249 GrPrimitiveType fPrimitiveType;
250 bool fUseIndexedDraw;
bsalomon@google.comee435122011-07-01 14:57:55 +0000251
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000252 typedef GrPathRenderer INHERITED;
253};
254
255#endif
bsalomon@google.comee435122011-07-01 14:57:55 +0000256