blob: f170fda10ad84e4656d3762182877a6543ed8143 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#ifndef GrDrawTarget_DEFINED
12#define GrDrawTarget_DEFINED
13
reed@google.comac10a2d2010-12-22 21:39:39 +000014#include "GrClip.h"
bsalomon@google.comaa5b6732011-07-29 15:13:20 +000015#include "GrColor.h"
16#include "GrMatrix.h"
17#include "GrRefCnt.h"
18#include "GrRenderTarget.h"
19#include "GrSamplerState.h"
bsalomon@google.comd302f142011-03-03 13:54:13 +000020#include "GrStencil.h"
bsalomon@google.comaa5b6732011-07-29 15:13:20 +000021#include "GrTexture.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000022
Scroggo97c88c22011-05-11 14:05:25 +000023#include "SkXfermode.h"
24
reed@google.comac10a2d2010-12-22 21:39:39 +000025class GrTexture;
reed@google.comac10a2d2010-12-22 21:39:39 +000026class GrClipIterator;
27class GrVertexBuffer;
28class GrIndexBuffer;
29
30class GrDrawTarget : public GrRefCnt {
31public:
32 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +000033 * Number of texture stages. Each stage takes as input a color and
34 * 2D texture coordinates. The color input to the first enabled stage is the
35 * per-vertex color or the constant color (setColor/setAlpha) if there are
36 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000037 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000038 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000039 * lookups are specified by a texture a sampler (setSamplerState). Texture
40 * coordinates for each stage come from the vertices based on a
41 * GrVertexLayout bitfield. The output fragment color is the output color of
42 * the last enabled stage. The presence or absence of texture coordinates
43 * for each stage in the vertex layout indicates whether a stage is enabled
44 * or not.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000045 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000046 enum {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000047 kNumStages = 3,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000048 kMaxTexCoords = kNumStages
49 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000050
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +000051
52 /**
53 * The absolute maximum number of edges that may be specified for
54 * a single draw call when performing edge antialiasing. This is used for
55 * the size of several static buffers, so implementations of getMaxEdges()
56 * (below) should clamp to this value.
57 */
58 enum {
59 kMaxEdges = 32
60 };
61
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000062 /**
bsalomon@google.comffca4002011-02-22 20:34:01 +000063 * Bitfield used to indicate which stages are in use.
reed@google.comac10a2d2010-12-22 21:39:39 +000064 */
bsalomon@google.comffca4002011-02-22 20:34:01 +000065 typedef int StageBitfield;
66 GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
reed@google.comac10a2d2010-12-22 21:39:39 +000067
68 /**
69 * Flags that affect rendering. Controlled using enable/disableState(). All
70 * default to disabled.
71 */
72 enum StateBits {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000073 kDither_StateBit = 0x01, //<! Perform color dithering
74 kAntialias_StateBit = 0x02, //<! Perform anti-aliasing. The render-
reed@google.comac10a2d2010-12-22 21:39:39 +000075 // target must support some form of AA
76 // (msaa, coverage sampling, etc). For
77 // GrGpu-created rendertarget/textures
78 // this is controlled by parameters
79 // passed to createTexture.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000080 kClip_StateBit = 0x04, //<! Controls whether drawing is clipped
reed@google.comac10a2d2010-12-22 21:39:39 +000081 // against the region specified by
82 // setClip.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000083 kNoColorWrites_StateBit = 0x08, //<! If set it disables writing colors.
84 // Useful while performing stencil
85 // ops.
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +000086 kEdgeAAConcave_StateBit = 0x10,//<! If set, edge AA will test edge
87 // pairs for convexity while
88 // rasterizing. Set this if the
89 // source polygon is non-convex.
bsalomon@google.comd302f142011-03-03 13:54:13 +000090
91 // subclass may use additional bits internally
92 kDummyStateBit,
93 kLastPublicStateBit = kDummyStateBit-1
94 };
95
96 enum DrawFace {
97 kBoth_DrawFace,
98 kCCW_DrawFace,
99 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +0000100 };
101
102 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000103 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000104 * Changing the clip has the side-effect of possibly zeroing
105 * out the client settable stencil bits. So multipass algorithms
106 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000107 * @param settings the stencil settings to use.
108 */
109 void setStencil(const GrStencilSettings& settings) {
110 fCurrDrawState.fStencilSettings = settings;
111 }
112
113 /**
114 * Shortcut to disable stencil testing and ops.
115 */
116 void disableStencil() {
117 fCurrDrawState.fStencilSettings.setDisabled();
118 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000119
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000120 class Edge {
121 public:
122 Edge() {}
123 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
124 GrPoint intersect(const Edge& other) {
125 return GrPoint::Make(
126 (fY * other.fZ - other.fY * fZ) /
127 (fX * other.fY - other.fX * fY),
128 (fX * other.fZ - other.fX * fZ) /
129 (other.fX * fY - fX * other.fY));
130 }
131 float fX, fY, fZ;
132 };
133
reed@google.comac10a2d2010-12-22 21:39:39 +0000134protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000135
reed@google.com8195f672011-01-12 18:14:28 +0000136 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000137 DrState() {
138 // make sure any pad is zero for memcmp
139 // all DrState members should default to something
140 // valid by the memset
141 memset(this, 0, sizeof(DrState));
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000142
143 // memset exceptions
Scroggo97c88c22011-05-11 14:05:25 +0000144 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000145 fFirstCoverageStage = kNumStages;
146
147 // pedantic assertion that our ptrs will
148 // be NULL (0 ptr is mem addr 0)
bsalomon@google.comd302f142011-03-03 13:54:13 +0000149 GrAssert((intptr_t)(void*)NULL == 0LL);
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000150
151 // default stencil setting should be disabled
bsalomon@google.comd302f142011-03-03 13:54:13 +0000152 GrAssert(fStencilSettings.isDisabled());
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000153 fFirstCoverageStage = kNumStages;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000154 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000155 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000156 GrBlendCoeff fSrcBlend;
157 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000158 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000159 GrTexture* fTextures[kNumStages];
160 GrSamplerState fSamplerStates[kNumStages];
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000161 int fFirstCoverageStage;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000162 GrRenderTarget* fRenderTarget;
163 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000164 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000165 GrColor fColorFilterColor;
166 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000167
168 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000169 GrMatrix fViewMatrix;
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000170 Edge fEdgeAAEdges[kMaxEdges];
171 int fEdgeAANumEdges;
reed@google.com8195f672011-01-12 18:14:28 +0000172 bool operator ==(const DrState& s) const {
173 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000174 }
reed@google.com8195f672011-01-12 18:14:28 +0000175 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000176 };
177
178public:
179 ///////////////////////////////////////////////////////////////////////////
180
181 GrDrawTarget();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000182 virtual ~GrDrawTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000183
184 /**
185 * Sets the current clip to the region specified by clip. All draws will be
186 * clipped against this clip if kClip_StateBit is enabled.
187 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000188 * Setting the clip may (or may not) zero out the client's stencil bits.
189 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000190 * @param description of the clipping region
191 */
192 void setClip(const GrClip& clip);
193
194 /**
195 * Gets the current clip.
196 *
197 * @return the clip.
198 */
199 const GrClip& getClip() const;
200
201 /**
202 * Sets the texture used at the next drawing call
203 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000204 * @param stage The texture stage for which the texture will be set
205 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000206 * @param texture The texture to set. Can be NULL though there is no advantage
207 * to settings a NULL texture if doing non-textured drawing
208 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000209 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000210
211 /**
212 * Retrieves the currently set texture.
213 *
214 * @return The currently set texture. The return value will be NULL if no
215 * texture has been set, NULL was most recently passed to
216 * setTexture, or the last setTexture was destroyed.
217 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000218 const GrTexture* getTexture(int stage) const;
219 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000220
221 /**
222 * Sets the rendertarget used at the next drawing call
223 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000224 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000225 */
226 void setRenderTarget(GrRenderTarget* target);
227
228 /**
229 * Retrieves the currently set rendertarget.
230 *
231 * @return The currently set render target.
232 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000233 const GrRenderTarget* getRenderTarget() const;
234 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000235
236 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000237 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000238 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000239 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000240 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000241 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000242 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000243 * @param samplerState Specifies the sampler state.
244 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000245 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000246
247 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000248 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000249 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000250 * @param stage the stage of the sampler to set
251 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000252 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000253 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
254 GrAssert(stage >= 0 && stage < kNumStages);
255 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000256 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000257
258 /**
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000259 * Shortcut for preConcatSamplerMatrix on all stages in mask with same
260 * matrix
261 */
262 void preConcatSamplerMatrices(int stageMask, const GrMatrix& matrix) {
263 for (int i = 0; i < kNumStages; ++i) {
264 if ((1 << i) & stageMask) {
265 this->preConcatSamplerMatrix(i, matrix);
266 }
267 }
268 }
269
270 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000271 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000272 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000273 * @param stage the stage to of sampler to get
274 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000275 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000276 const GrMatrix& getSamplerMatrix(int stage) const {
277 return fCurrDrawState.fSamplerStates[stage].getMatrix();
278 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000279
280 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000281 * Sets the matrix of a stage's sampler
282 *
283 * @param stage the stage of sampler set
284 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000285 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000286 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000287 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
288 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000289
290 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000291 * Sets the matrix applied to veretx positions.
292 *
293 * In the post-view-matrix space the rectangle [0,w]x[0,h]
294 * fully covers the render target. (w and h are the width and height of the
295 * the rendertarget.)
296 *
297 * @param m the matrix used to transform the vertex positions.
298 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000299 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000300
301 /**
302 * Multiplies the current view matrix by a matrix
303 *
304 * After this call V' = V*m where V is the old view matrix,
305 * m is the parameter to this function, and V' is the new view matrix.
306 * (We consider positions to be column vectors so position vector p is
307 * transformed by matrix X as p' = X*p.)
308 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000309 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000310 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000311 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000312
313 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000314 * Multiplies the current view matrix by a matrix
315 *
316 * After this call V' = m*V where V is the old view matrix,
317 * m is the parameter to this function, and V' is the new view matrix.
318 * (We consider positions to be column vectors so position vector p is
319 * transformed by matrix X as p' = X*p.)
320 *
321 * @param m the matrix used to modify the view matrix.
322 */
323 void postConcatViewMatrix(const GrMatrix& m);
324
325 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000326 * Retrieves the current view matrix
327 * @return the current view matrix.
328 */
329 const GrMatrix& getViewMatrix() const;
330
331 /**
332 * Retrieves the inverse of the current view matrix.
333 *
334 * If the current view matrix is invertible, return true, and if matrix
335 * is non-null, copy the inverse into it. If the current view matrix is
336 * non-invertible, return false and ignore the matrix parameter.
337 *
338 * @param matrix if not null, will receive a copy of the current inverse.
339 */
340 bool getViewInverse(GrMatrix* matrix) const;
341
342 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000343 * Sets color for next draw to a premultiplied-alpha color.
344 *
345 * @param the color to set.
346 */
347 void setColor(GrColor);
348
349 /**
Scroggo97c88c22011-05-11 14:05:25 +0000350 * Add a color filter that can be represented by a color and a mode.
351 */
352 void setColorFilter(GrColor, SkXfermode::Mode);
353
354 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000355 * Sets the color to be used for the next draw to be
356 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
357 *
358 * @param alpha The alpha value to set as the color.
359 */
360 void setAlpha(uint8_t alpha);
361
362 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000363 * Controls whether clockwise, counterclockwise, or both faces are drawn.
364 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000365 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000366 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000367
368 /**
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000369 * A common pattern is to compute a color with the initial stages and then
370 * modulate that color by a coverage value in later stage(s) (AA, mask-
371 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
372 * computed based on the pre-coverage-modulated color. The division of
373 * stages between color-computing and coverage-computing is specified by
374 * this method. Initially this is kNumStages (all stages are color-
375 * computing).
376 */
377 void setFirstCoverageStage(int firstCoverageStage) {
378 fCurrDrawState.fFirstCoverageStage = firstCoverageStage;
379 }
380
381 /**
382 * Gets the index of the first coverage-computing stage.
383 */
384 int getFirstCoverageStage() const {
385 return fCurrDrawState.fFirstCoverageStage;
386 }
387
388 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000389 * Gets whether the target is drawing clockwise, counterclockwise,
390 * or both faces.
391 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000392 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000393 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000394
395 /**
396 * Enable render state settings.
397 *
398 * @param flags bitfield of StateBits specifing the states to enable
399 */
400 void enableState(uint32_t stateBits);
401
402 /**
403 * Disable render state settings.
404 *
405 * @param flags bitfield of StateBits specifing the states to disable
406 */
407 void disableState(uint32_t stateBits);
408
409 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000410 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
411 }
412
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000413 bool isAntialiasState() const {
414 return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
415 }
416
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000417 bool isClipState() const {
418 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000419 }
420
bsalomon@google.comd302f142011-03-03 13:54:13 +0000421 bool isColorWriteDisabled() const {
422 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
423 }
424
reed@google.comac10a2d2010-12-22 21:39:39 +0000425 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000426 * Sets the blending function coeffecients.
427 *
428 * The blend function will be:
429 * D' = sat(S*srcCoef + D*dstCoef)
430 *
431 * where D is the existing destination color, S is the incoming source
432 * color, and D' is the new destination color that will be written. sat()
433 * is the saturation function.
434 *
435 * @param srcCoef coeffecient applied to the src color.
436 * @param dstCoef coeffecient applied to the dst color.
437 */
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000438 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
reed@google.comac10a2d2010-12-22 21:39:39 +0000439
440 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000441 * Sets the blending function constant referenced by the following blending
442 * coeffecients:
443 * kConstC_BlendCoeff
444 * kIConstC_BlendCoeff
445 * kConstA_BlendCoeff
446 * kIConstA_BlendCoeff
447 *
448 * @param constant the constant to set
449 */
450 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
451
452 /**
453 * Retrieves the last value set by setBlendConstant()
454 * @return the blending constant value
455 */
456 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
457
458 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000459 * Used to save and restore the GrGpu's drawing state
460 */
461 struct SavedDrawState {
462 private:
reed@google.com8195f672011-01-12 18:14:28 +0000463 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000464 friend class GrDrawTarget;
465 };
466
467 /**
468 * Saves the current draw state. The state can be restored at a later time
469 * with restoreDrawState.
470 *
471 * See also AutoStateRestore class.
472 *
473 * @param state will hold the state after the function returns.
474 */
475 void saveCurrentDrawState(SavedDrawState* state) const;
476
477 /**
478 * Restores previously saved draw state. The client guarantees that state
479 * was previously passed to saveCurrentDrawState and that the rendertarget
480 * and texture set at save are still valid.
481 *
482 * See also AutoStateRestore class.
483 *
484 * @param state the previously saved state to restore.
485 */
486 void restoreDrawState(const SavedDrawState& state);
487
488 /**
489 * Copies the draw state from another target to this target.
490 *
491 * @param srcTarget draw target used as src of the draw state.
492 */
493 void copyDrawState(const GrDrawTarget& srcTarget);
494
495 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000496 * The format of vertices is represented as a bitfield of flags.
497 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000498 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000499 * coordinates and per-vertex colors. Each stage can use any of the texture
500 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000501 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000502 * If no texture coordinates are specified for a stage then the stage is
503 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000504 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000505 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000506 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000507 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000508 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000509 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000510 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000511 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000512 * the order would be (position, texture coordinate 1[, color]).
513 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000514
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000515 /**
516 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000517 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000518 * @param stage the stage that will use texture coordinates.
519 * @param texCoordIdx the index of the texture coordinates to use
520 *
521 * @return the bit to add to a GrVertexLayout bitfield.
522 */
523 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
524 GrAssert(stage < kNumStages);
525 GrAssert(texCoordIdx < kMaxTexCoords);
526 return 1 << (stage + (texCoordIdx * kNumStages));
527 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000528
529 /**
530 * Determines if blend is effectively disabled.
531 *
532 * @return true if blend can be disabled without changing the rendering
533 * result given the current state including the vertex layout specified
534 * with the vertex source.
535 */
536 bool canDisableBlend() const;
537
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000538 /**
bsalomon@google.com471d4712011-08-23 15:45:25 +0000539 * Given the current draw state, vertex layout, and hw support, will HW AA
540 * lines be used (if line primitive type is drawn)? (Note that lines are
541 * always 1 pixel wide)
542 */
543 virtual bool willUseHWAALines() const = 0;
544
545 /**
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000546 * Sets the edge data required for edge antialiasing.
547 *
548 * @param edges 3 * 6 float values, representing the edge
549 * equations in Ax + By + C form
550 */
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000551 void setEdgeAAData(const Edge* edges, int numEdges);
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000552
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000553private:
554 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
555public:
556 /**
557 * Generates a bit indicating that a texture stage uses the position
558 * as its texture coordinate.
559 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000560 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000561 * coordinates.
562 *
563 * @return the bit to add to a GrVertexLayout bitfield.
564 */
565 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
566 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000567 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000568 }
569private:
570 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000571
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000572public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000573
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000574 /**
575 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000576 */
577 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000578
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000579 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
580 //<! vertices have colors
581 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
582 //<! use text vertices. (Pos
583 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000584 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000585 // text [GrGpuTextVertex vs
586 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000587 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000588 kDummyVertexLayoutBit,
589 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000590 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000591 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000592 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000593
594 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000595 * There are three methods for specifying geometry (vertices and optionally
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000596 * indices) to the draw target. When indexed drawing the indices and vertices
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000597 * can use a different method. Once geometry is specified it can be used for
598 * multiple drawIndexed and drawNonIndexed calls.
599 *
600 * Sometimes it is necessary to perform a draw while upstack code has
601 * already specified geometry that it isn't finished with. There are push
602 * pop methods
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000603 *
604 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
605 * caller's client has already provided vertex data in a format
606 * the time compatible with a GrVertexLayout. The array must contain the
607 * data at set*SourceToArray is called. The source stays in effect for
608 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
609 * again or one of the other two paths is chosen.
610 *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000611 * 2. Reserve. This is most useful when the caller has data it must
612 * transform before drawing and is not long-lived. The caller requests
613 * that the draw target make room for some amount of vertex and/or index
614 * data. The target provides ptrs to hold the vertex and/or index data.
615 *
616 * The data is writable up until the next drawIndexed, drawNonIndexed,
617 * or pushGeometrySource At this point the data is frozen and the ptrs
618 * are no longer valid.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000619 *
620 * 3. Vertex and Index Buffers. This is most useful for geometry that will
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000621 * is long-lived. SetVertexSourceToBuffer and SetIndexSourceToBuffer are
622 * used to set the buffer and subsequent drawIndexed and drawNonIndexed
623 * calls use this source until another source is set.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000624 */
625
626 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000627 * Reserves space for vertices. Draw target will use reserved vertices at
628 * at the next draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000629 *
630 * If succeeds:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000631 * if vertexCount > 0, *vertices will be the array
reed@google.comac10a2d2010-12-22 21:39:39 +0000632 * of vertices to be filled by caller. The next draw will read
633 * these vertices.
634 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000635 * If a client does not already have a vertex buffer then this is the
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000636 * preferred way to allocate vertex data. It allows the subclass of
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000637 * GrDrawTarget to decide whether to put data in buffers, to group vertex
638 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000639 *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000640 * After the next draw or pushGeometrySource the vertices ptr is no longer
641 * valid and the geometry data cannot be further modified. The contents
642 * that were put in the reserved space can be drawn by multiple draws,
643 * however.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000644 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000645 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000646 * @param vertexCount the number of vertices to reserve space for. Can be 0.
reed@google.comac10a2d2010-12-22 21:39:39 +0000647 * @param vertices will point to reserved vertex space if vertexCount is
648 * non-zero. Illegal to pass NULL if vertexCount > 0.
reed@google.comac10a2d2010-12-22 21:39:39 +0000649 *
650 * @return true if succeeded in allocating space for the vertices and false
651 * if not.
652 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000653 bool reserveVertexSpace(GrVertexLayout vertexLayout,
654 int vertexCount,
655 void** vertices);
656 /**
657 * Reserves space for indices. Draw target will use the reserved indices at
658 * the next indexed draw.
659 *
660 * If succeeds:
661 * if indexCount > 0, *indices will be the array
662 * of indices to be filled by caller. The next draw will read
663 * these indices.
664 *
665 * If a client does not already have a index buffer then this is the
666 * preferred way to allocate index data. It allows the subclass of
667 * GrDrawTarget to decide whether to put data in buffers, to group index
668 * data that uses the same state (e.g. for deferred rendering), etc.
669 *
670 * After the next indexed draw or pushGeometrySource the indices ptr is no
671 * longer valid and the geometry data cannot be further modified. The
672 * contents that were put in the reserved space can be drawn by multiple
673 * draws, however.
674 *
675 * @param indexCount the number of indices to reserve space for. Can be 0.
676 * @param indices will point to reserved index space if indexCount is
677 * non-zero. Illegal to pass NULL if indexCount > 0.
678 */
679
680 bool reserveIndexSpace(int indexCount, void** indices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000681 /**
682 * Provides hints to caller about the number of vertices and indices
683 * that can be allocated cheaply. This can be useful if caller is reserving
684 * space but doesn't know exactly how much geometry is needed.
685 *
686 * Also may hint whether the draw target should be flushed first. This is
687 * useful for deferred targets.
688 *
689 * @param vertexLayout layout of vertices caller would like to reserve
690 * @param vertexCount in: hint about how many vertices the caller would
691 * like to allocate.
692 * out: a hint about the number of vertices that can be
693 * allocated cheaply. Negative means no hint.
694 * Ignored if NULL.
695 * @param indexCount in: hint about how many indices the caller would
696 * like to allocate.
697 * out: a hint about the number of indices that can be
698 * allocated cheaply. Negative means no hint.
699 * Ignored if NULL.
700 *
701 * @return true if target should be flushed based on the input values.
702 */
703 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000704 int* vertexCount,
705 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000706
707 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000708 * Sets source of vertex data for the next draw. Array must contain
709 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000710 *
711 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000712 * @param size size of the vertex data.
713 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000714 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000715 void setVertexSourceToArray(GrVertexLayout vertexLayout,
716 const void* vertexArray,
717 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000718
719 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000720 * Sets source of index data for the next indexed draw. Array must contain
721 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000722 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000723 * @param array cpu array containing index data.
724 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000725 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000726 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000727
728 /**
729 * Sets source of vertex data for the next draw. Data does not have to be
730 * in the buffer until drawIndexed or drawNonIndexed.
731 *
732 * @param buffer vertex buffer containing vertex data. Must be
733 * unlocked before draw call.
734 * @param vertexLayout layout of the vertex data in the buffer.
735 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000736 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
737 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000738
739 /**
740 * Sets source of index data for the next indexed draw. Data does not have
741 * to be in the buffer until drawIndexed or drawNonIndexed.
742 *
743 * @param buffer index buffer containing indices. Must be unlocked
744 * before indexed draw call.
745 */
746 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000747
748 /**
749 * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
750 * source to reserved, array, or buffer before next draw. May be able to free
751 * up temporary storage allocated by setVertexSourceToArray or
752 * reserveVertexSpace.
753 */
754 void resetVertexSource();
755
756 /**
757 * Resets index source. Indexed Drawing from reset indices is illegal. Set
758 * index source to reserved, array, or buffer before next indexed draw. May
759 * be able to free up temporary storage allocated by setIndexSourceToArray
760 * or reserveIndexSpace.
761 */
762 void resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000763
764 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000765 * Pushes and resets the vertex/index sources. Any reserved vertex / index
766 * data is finalized (i.e. cannot be updated after the matching pop but can
767 * be drawn from). Must be balanced by a pop.
768 */
769 void pushGeometrySource();
770
771 /**
772 * Pops the vertex / index sources from the matching push.
773 */
774 void popGeometrySource();
775
776 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000777 * Draws indexed geometry using the current state and current vertex / index
778 * sources.
779 *
780 * @param type The type of primitives to draw.
781 * @param startVertex the vertex in the vertex array/buffer corresponding
782 * to index 0
783 * @param startIndex first index to read from index src.
784 * @param vertexCount one greater than the max index.
785 * @param indexCount the number of index elements to read. The index count
786 * is effectively trimmed to the last completely
787 * specified primitive.
788 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000789 void drawIndexed(GrPrimitiveType type,
790 int startVertex,
791 int startIndex,
792 int vertexCount,
793 int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000794
795 /**
796 * Draws non-indexed geometry using the current state and current vertex
797 * sources.
798 *
799 * @param type The type of primitives to draw.
800 * @param startVertex the vertex in the vertex array/buffer corresponding
801 * to index 0
802 * @param vertexCount one greater than the max index.
803 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000804 void drawNonIndexed(GrPrimitiveType type,
805 int startVertex,
806 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000807
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000808 /**
809 * Helper function for drawing rects. This does not use the current index
810 * and vertex sources. After returning, the vertex and index sources may
811 * have changed. They should be reestablished before the next drawIndexed
812 * or drawNonIndexed. This cannot be called between reserving and releasing
813 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000814 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000815 * drawNonIndexed.
816 * @param rect the rect to draw
817 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000818 * @param stageEnableBitfield bitmask indicating which stages are enabled.
819 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000820 * @param srcRects specifies rects for stages enabled by stageEnableMask.
821 * if stageEnableMask bit i is 1, srcRects is not NULL,
822 * and srcRects[i] is not NULL, then srcRects[i] will be
823 * used as coordinates for stage i. Otherwise, if stage i
824 * is enabled then rect is used as the coordinates.
825 * @param srcMatrices optional matrices applied to srcRects. If
826 * srcRect[i] is non-NULL and srcMatrices[i] is
827 * non-NULL then srcRect[i] will be transformed by
828 * srcMatrix[i]. srcMatrices can be NULL when no
829 * srcMatrices are desired.
830 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000831 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000832 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000833 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000834 const GrRect* srcRects[],
835 const GrMatrix* srcMatrices[]);
836
837 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000838 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000839 * matrices.
840 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000841 void drawSimpleRect(const GrRect& rect,
842 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000843 StageBitfield stageEnableBitfield) {
844 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000845 }
846
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000847 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000848 * Clear the render target. Ignores the clip and all other draw state
849 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
850 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000851 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000852 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000853
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000854 /**
855 * Returns the maximum number of edges that may be specified in a single
856 * draw call when performing edge antialiasing. This is usually limited
857 * by the number of fragment uniforms which may be uploaded. Must be a
858 * minimum of six, since a triangle's vertices each belong to two boundary
859 * edges which may be distinct.
860 */
861 virtual int getMaxEdges() const { return 6; }
862
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000863 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000864
865 class AutoStateRestore : ::GrNoncopyable {
866 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000867 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000868 AutoStateRestore(GrDrawTarget* target);
869 ~AutoStateRestore();
870
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000871 /**
872 * if this object is already saving state for param target then
873 * this does nothing. Otherise, it restores previously saved state on
874 * previous target (if any) and saves current state on param target.
875 */
876 void set(GrDrawTarget* target);
877
reed@google.comac10a2d2010-12-22 21:39:39 +0000878 private:
879 GrDrawTarget* fDrawTarget;
880 SavedDrawState fDrawState;
881 };
882
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000883 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000884
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000885 class AutoViewMatrixRestore : ::GrNoncopyable {
886 public:
887 AutoViewMatrixRestore() {
888 fDrawTarget = NULL;
889 }
890
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000891 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000892 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
893 GrAssert(NULL != target);
894 }
895
896 void set(GrDrawTarget* target) {
897 GrAssert(NULL != target);
898 if (NULL != fDrawTarget) {
899 fDrawTarget->setViewMatrix(fMatrix);
900 }
901 fDrawTarget = target;
902 fMatrix = target->getViewMatrix();
903 }
904
905 ~AutoViewMatrixRestore() {
906 if (NULL != fDrawTarget) {
907 fDrawTarget->setViewMatrix(fMatrix);
908 }
909 }
910
911 private:
912 GrDrawTarget* fDrawTarget;
913 GrMatrix fMatrix;
914 };
915
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000916 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000917
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000918 /**
919 * Sets the view matrix to I and preconcats all stage matrices enabled in
920 * mask by the view inverse. Destructor undoes these changes.
921 */
922 class AutoDeviceCoordDraw : ::GrNoncopyable {
923 public:
924 AutoDeviceCoordDraw(GrDrawTarget* target, int stageMask);
925 ~AutoDeviceCoordDraw();
926 private:
927 GrDrawTarget* fDrawTarget;
928 GrMatrix fViewMatrix;
929 GrMatrix fSamplerMatrices[kNumStages];
930 int fStageMask;
931 };
932
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000933 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000934
reed@google.comac10a2d2010-12-22 21:39:39 +0000935 class AutoReleaseGeometry : ::GrNoncopyable {
936 public:
937 AutoReleaseGeometry(GrDrawTarget* target,
938 GrVertexLayout vertexLayout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000939 int vertexCount,
940 int indexCount);
941 AutoReleaseGeometry();
942 ~AutoReleaseGeometry();
bsalomon@google.com5782d712011-01-21 21:03:59 +0000943 bool set(GrDrawTarget* target,
944 GrVertexLayout vertexLayout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000945 int vertexCount,
946 int indexCount);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000947 bool succeeded() const { return NULL != fTarget; }
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000948 void* vertices() const { GrAssert(this->succeeded()); return fVertices; }
949 void* indices() const { GrAssert(this->succeeded()); return fIndices; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000950 GrPoint* positions() const {
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000951 return static_cast<GrPoint*>(this->vertices());
reed@google.comac10a2d2010-12-22 21:39:39 +0000952 }
953
954 private:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000955 void reset();
956
reed@google.comac10a2d2010-12-22 21:39:39 +0000957 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000958 void* fVertices;
959 void* fIndices;
960 };
961
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000962 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000963
964 class AutoClipRestore : ::GrNoncopyable {
965 public:
966 AutoClipRestore(GrDrawTarget* target) {
967 fTarget = target;
968 fClip = fTarget->getClip();
969 }
970
971 ~AutoClipRestore() {
972 fTarget->setClip(fClip);
973 }
974 private:
975 GrDrawTarget* fTarget;
976 GrClip fClip;
977 };
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000978
979 ////////////////////////////////////////////////////////////////////////////
980
981 class AutoGeometryPush : ::GrNoncopyable {
982 public:
983 AutoGeometryPush(GrDrawTarget* target) {
984 GrAssert(NULL != target);
985 fTarget = target;
986 target->pushGeometrySource();
987 }
988 ~AutoGeometryPush() {
989 fTarget->popGeometrySource();
990 }
991 private:
992 GrDrawTarget* fTarget;
993 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000994
995 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000996 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000997
reed@google.comac10a2d2010-12-22 21:39:39 +0000998 /**
999 * Helper function to compute the size of a vertex from a vertex layout
1000 * @return size of a single vertex.
1001 */
1002 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001003
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001004 /**
1005 * Helper function for determining the index of texture coordinates that
1006 * is input for a texture stage. Note that a stage may instead use positions
1007 * as texture coordinates, in which case the result of the function is
1008 * indistinguishable from the case when the stage is disabled.
1009 *
1010 * @param stage the stage to query
1011 * @param vertexLayout layout to query
1012 *
1013 * @return the texture coordinate index or -1 if the stage doesn't use
1014 * separate (non-position) texture coordinates.
1015 */
1016 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001017
1018 /**
1019 * Helper function to compute the offset of texture coordinates in a vertex
1020 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +00001021 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001022 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001023 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001024 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001025
1026 /**
1027 * Helper function to compute the offset of the color in a vertex
1028 * @return offset of color in vertex layout or -1 if the
1029 * layout has no color.
1030 */
1031 static int VertexColorOffset(GrVertexLayout vertexLayout);
1032
1033 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001034 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001035 * coordinates of some index.
1036 *
1037 * @param coordIndex the tex coord index to query
1038 * @param vertexLayout layout to query
1039 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001040 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001041 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001042 */
bsalomon@google.com5782d712011-01-21 21:03:59 +00001043 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001044 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001045
reed@google.comac10a2d2010-12-22 21:39:39 +00001046 /**
1047 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001048 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001049 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001050 * @param stage the stage to query
1051 * @param vertexLayout layout to query
1052 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001053 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001054 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001055 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001056 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001057
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001058 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001059 * Helper function to compute the size of each vertex and the offsets of
1060 * texture coordinates and color. Determines tex coord offsets by tex coord
1061 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001062 * by StageTexCoordVertexLayoutBit.)
1063 *
1064 * @param vertexLayout the layout to query
1065 * @param texCoordOffsetsByIdx after return it is the offset of each
1066 * tex coord index in the vertex or -1 if
1067 * index isn't used.
1068 * @return size of a single vertex
1069 */
1070 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
1071 int texCoordOffsetsByIdx[kMaxTexCoords],
1072 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001073
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001074 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001075 * Helper function to compute the size of each vertex and the offsets of
1076 * texture coordinates and color. Determines tex coord offsets by stage
1077 * rather than by index. (Each stage can be mapped to any t.c. index
1078 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001079 * tex coords then that stage's offset will be 0 (positions are always at 0).
1080 *
1081 * @param vertexLayout the layout to query
1082 * @param texCoordOffsetsByStage after return it is the offset of each
1083 * tex coord index in the vertex or -1 if
1084 * index isn't used.
1085 * @return size of a single vertex
1086 */
1087 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1088 int texCoordOffsetsByStage[kNumStages],
1089 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001090
1091 /**
1092 * Accessing positions, texture coords, or colors, of a vertex within an
1093 * array is a hassle involving casts and simple math. These helpers exist
1094 * to keep GrDrawTarget clients' code a bit nicer looking.
1095 */
1096
1097 /**
1098 * Gets a pointer to a GrPoint of a vertex's position or texture
1099 * coordinate.
1100 * @param vertices the vetex array
1101 * @param vertexIndex the index of the vertex in the array
1102 * @param vertexSize the size of each vertex in the array
1103 * @param offset the offset in bytes of the vertex component.
1104 * Defaults to zero (corresponding to vertex position)
1105 * @return pointer to the vertex component as a GrPoint
1106 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001107 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001108 int vertexIndex,
1109 int vertexSize,
1110 int offset = 0) {
1111 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001112 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001113 vertexIndex * vertexSize);
1114 }
1115 static const GrPoint* GetVertexPoint(const void* vertices,
1116 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001117 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001118 int offset = 0) {
1119 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001120 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001121 vertexIndex * vertexSize);
1122 }
1123
1124 /**
1125 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1126 * @param vertices the vetex array
1127 * @param vertexIndex the index of the vertex in the array
1128 * @param vertexSize the size of each vertex in the array
1129 * @param offset the offset in bytes of the vertex color
1130 * @return pointer to the vertex component as a GrColor
1131 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001132 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001133 int vertexIndex,
1134 int vertexSize,
1135 int offset) {
1136 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001137 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001138 vertexIndex * vertexSize);
1139 }
1140 static const GrColor* GetVertexColor(const void* vertices,
1141 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001142 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001143 int offset) {
1144 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001145 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001146 vertexIndex * vertexSize);
1147 }
1148
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001149 static void VertexLayoutUnitTest();
1150
reed@google.comac10a2d2010-12-22 21:39:39 +00001151protected:
bsalomon@google.com471d4712011-08-23 15:45:25 +00001152
1153 // determines whether HW blending can be disabled or not
1154 static bool CanDisableBlend(GrVertexLayout layout, const DrState& state);
1155
1156 // determines whether HW AA lines can be used or not
1157 static bool CanUseHWAALines(GrVertexLayout layout, const DrState& state);
1158
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001159 enum GeometrySrcType {
1160 kNone_GeometrySrcType, //<! src has not been specified
1161 kReserved_GeometrySrcType, //<! src was set using reserve*Space
1162 kArray_GeometrySrcType, //<! src was set using set*SourceToArray
1163 kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer
1164 };
1165
1166 struct GeometrySrcState {
1167 GeometrySrcType fVertexSrc;
1168 union {
1169 // valid if src type is buffer
1170 const GrVertexBuffer* fVertexBuffer;
1171 // valid if src type is reserved or array
1172 int fVertexCount;
1173 };
1174
1175 GeometrySrcType fIndexSrc;
1176 union {
1177 // valid if src type is buffer
1178 const GrIndexBuffer* fIndexBuffer;
1179 // valid if src type is reserved or array
1180 int fIndexCount;
1181 };
1182
1183 GrVertexLayout fVertexLayout;
1184 };
1185
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001186 // given a vertex layout and a draw state, will a stage be used?
1187 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1188 const DrState& state) {
1189 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1190 }
1191
1192 bool isStageEnabled(int stage) const {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001193 return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout,
1194 fCurrDrawState);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001195 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001196
reed@google.comac10a2d2010-12-22 21:39:39 +00001197 // Helpers for GrDrawTarget subclasses that won't have private access to
1198 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001199 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001200 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001201 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001202 { return sds.fState; }
1203
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001204 // implemented by subclass to allocate space for reserved geom
1205 virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
1206 int vertexCount,
1207 void** vertices) = 0;
1208 virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0;
1209 // implemented by subclass to handle release of reserved geom space
1210 virtual void releaseReservedVertexSpace() = 0;
1211 virtual void releaseReservedIndexSpace() = 0;
1212 // subclass must consume array contents when set
1213 virtual void onSetVertexSourceToArray(const void* vertexArray,
1214 int vertexCount) = 0;
1215 virtual void onSetIndexSourceToArray(const void* indexArray,
1216 int indexCount) = 0;
1217 // subclass is notified that geom source will be set away from an array
1218 virtual void releaseVertexArray() = 0;
1219 virtual void releaseIndexArray() = 0;
1220 // subclass overrides to be notified just before geo src state
1221 // is pushed/popped.
1222 virtual void geometrySourceWillPush() = 0;
1223 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
1224 // subclass called to perform drawing
1225 virtual void onDrawIndexed(GrPrimitiveType type,
1226 int startVertex,
1227 int startIndex,
1228 int vertexCount,
1229 int indexCount) = 0;
1230 virtual void onDrawNonIndexed(GrPrimitiveType type,
1231 int startVertex,
1232 int vertexCount) = 0;
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +00001233 // subclass overrides to be notified when clip is set. Must call
1234 // INHERITED::clipwillBeSet
1235 virtual void clipWillBeSet(const GrClip& clip);
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001236
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001237 // Helpers for drawRect, protected so subclasses that override drawRect
1238 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001239 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001240 const GrRect* srcRects[]);
1241
1242 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001243 const GrMatrix* matrix,
1244 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001245 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001246 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001247 void* vertices);
1248
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001249 // accessor for derived classes
1250 const GeometrySrcState& getGeomSrc() const {
1251 return fGeoSrcStateStack.back();
1252 }
reed@google.comac10a2d2010-12-22 21:39:39 +00001253
1254 GrClip fClip;
1255
reed@google.com8195f672011-01-12 18:14:28 +00001256 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001257
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001258private:
1259 // called when setting a new vert/idx source to unref prev vb/ib
1260 void releasePreviousVertexSource();
1261 void releasePreviousIndexSource();
1262
1263 enum {
1264 kPreallocGeoSrcStateStackCnt = 4,
reed@google.comac10a2d2010-12-22 21:39:39 +00001265 };
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001266 GrAlignedSTStorage<kPreallocGeoSrcStateStackCnt,
1267 GeometrySrcState>
1268 fGeoSrcStateStackStorage;
1269 GrTArray<GeometrySrcState, true> fGeoSrcStateStack;
1270
reed@google.comac10a2d2010-12-22 21:39:39 +00001271};
1272
1273#endif