blob: 177c363c6f1809c67b63c69c48389f11a5af7c4c [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 * The DrawTarget may reserve some of the high bits of the stencil. The draw
104 * target will automatically trim reference and mask values so that the
105 * client doesn't overwrite these bits.
106 * The number of bits available is relative to the currently set render
107 *target.
108 * @return the number of bits usable by the draw target client.
reed@google.comac10a2d2010-12-22 21:39:39 +0000109 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000110 int getUsableStencilBits() const {
111 int bits = fCurrDrawState.fRenderTarget->stencilBits();
112 if (bits) {
113 return bits - 1;
114 } else {
115 return 0;
116 }
117 }
118
119 /**
120 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000121 * Changing the clip has the side-effect of possibly zeroing
122 * out the client settable stencil bits. So multipass algorithms
123 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000124 * @param settings the stencil settings to use.
125 */
126 void setStencil(const GrStencilSettings& settings) {
127 fCurrDrawState.fStencilSettings = settings;
128 }
129
130 /**
131 * Shortcut to disable stencil testing and ops.
132 */
133 void disableStencil() {
134 fCurrDrawState.fStencilSettings.setDisabled();
135 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000136
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000137 class Edge {
138 public:
139 Edge() {}
140 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
141 GrPoint intersect(const Edge& other) {
142 return GrPoint::Make(
143 (fY * other.fZ - other.fY * fZ) /
144 (fX * other.fY - other.fX * fY),
145 (fX * other.fZ - other.fX * fZ) /
146 (other.fX * fY - fX * other.fY));
147 }
148 float fX, fY, fZ;
149 };
150
reed@google.comac10a2d2010-12-22 21:39:39 +0000151protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000152
reed@google.com8195f672011-01-12 18:14:28 +0000153 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000154 DrState() {
155 // make sure any pad is zero for memcmp
156 // all DrState members should default to something
157 // valid by the memset
158 memset(this, 0, sizeof(DrState));
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000159
160 // memset exceptions
Scroggo97c88c22011-05-11 14:05:25 +0000161 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000162 fFirstCoverageStage = kNumStages;
163
164 // pedantic assertion that our ptrs will
165 // be NULL (0 ptr is mem addr 0)
bsalomon@google.comd302f142011-03-03 13:54:13 +0000166 GrAssert((intptr_t)(void*)NULL == 0LL);
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000167
168 // default stencil setting should be disabled
bsalomon@google.comd302f142011-03-03 13:54:13 +0000169 GrAssert(fStencilSettings.isDisabled());
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000170 fFirstCoverageStage = kNumStages;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000171 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000172 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000173 GrBlendCoeff fSrcBlend;
174 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000175 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000176 GrTexture* fTextures[kNumStages];
177 GrSamplerState fSamplerStates[kNumStages];
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000178 int fFirstCoverageStage;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000179 GrRenderTarget* fRenderTarget;
180 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000181 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000182 GrColor fColorFilterColor;
183 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000184
185 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000186 GrMatrix fViewMatrix;
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000187 Edge fEdgeAAEdges[kMaxEdges];
188 int fEdgeAANumEdges;
reed@google.com8195f672011-01-12 18:14:28 +0000189 bool operator ==(const DrState& s) const {
190 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000191 }
reed@google.com8195f672011-01-12 18:14:28 +0000192 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000193 };
194
195public:
196 ///////////////////////////////////////////////////////////////////////////
197
198 GrDrawTarget();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000199 virtual ~GrDrawTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000200
201 /**
202 * Sets the current clip to the region specified by clip. All draws will be
203 * clipped against this clip if kClip_StateBit is enabled.
204 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000205 * Setting the clip may (or may not) zero out the client's stencil bits.
206 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000207 * @param description of the clipping region
208 */
209 void setClip(const GrClip& clip);
210
211 /**
212 * Gets the current clip.
213 *
214 * @return the clip.
215 */
216 const GrClip& getClip() const;
217
218 /**
219 * Sets the texture used at the next drawing call
220 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000221 * @param stage The texture stage for which the texture will be set
222 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000223 * @param texture The texture to set. Can be NULL though there is no advantage
224 * to settings a NULL texture if doing non-textured drawing
225 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000226 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000227
228 /**
229 * Retrieves the currently set texture.
230 *
231 * @return The currently set texture. The return value will be NULL if no
232 * texture has been set, NULL was most recently passed to
233 * setTexture, or the last setTexture was destroyed.
234 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000235 const GrTexture* getTexture(int stage) const;
236 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000237
238 /**
239 * Sets the rendertarget used at the next drawing call
240 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000241 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000242 */
243 void setRenderTarget(GrRenderTarget* target);
244
245 /**
246 * Retrieves the currently set rendertarget.
247 *
248 * @return The currently set render target.
249 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000250 const GrRenderTarget* getRenderTarget() const;
251 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000252
253 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000254 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000255 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000256 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000257 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000258 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000259 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000260 * @param samplerState Specifies the sampler state.
261 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000262 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000263
264 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000265 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000266 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000267 * @param stage the stage of the sampler to set
268 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000269 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000270 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
271 GrAssert(stage >= 0 && stage < kNumStages);
272 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000273 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000274
275 /**
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000276 * Shortcut for preConcatSamplerMatrix on all stages in mask with same
277 * matrix
278 */
279 void preConcatSamplerMatrices(int stageMask, const GrMatrix& matrix) {
280 for (int i = 0; i < kNumStages; ++i) {
281 if ((1 << i) & stageMask) {
282 this->preConcatSamplerMatrix(i, matrix);
283 }
284 }
285 }
286
287 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000288 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000289 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000290 * @param stage the stage to of sampler to get
291 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000292 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000293 const GrMatrix& getSamplerMatrix(int stage) const {
294 return fCurrDrawState.fSamplerStates[stage].getMatrix();
295 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000296
297 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000298 * Sets the matrix of a stage's sampler
299 *
300 * @param stage the stage of sampler set
301 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000302 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000303 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000304 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
305 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000306
307 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000308 * Sets the matrix applied to veretx positions.
309 *
310 * In the post-view-matrix space the rectangle [0,w]x[0,h]
311 * fully covers the render target. (w and h are the width and height of the
312 * the rendertarget.)
313 *
314 * @param m the matrix used to transform the vertex positions.
315 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000316 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000317
318 /**
319 * Multiplies the current view matrix by a matrix
320 *
321 * After this call V' = V*m where V is the old view matrix,
322 * m is the parameter to this function, and V' is the new view matrix.
323 * (We consider positions to be column vectors so position vector p is
324 * transformed by matrix X as p' = X*p.)
325 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000326 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000327 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000328 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000329
330 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000331 * Multiplies the current view matrix by a matrix
332 *
333 * After this call V' = m*V where V is the old view matrix,
334 * m is the parameter to this function, and V' is the new view matrix.
335 * (We consider positions to be column vectors so position vector p is
336 * transformed by matrix X as p' = X*p.)
337 *
338 * @param m the matrix used to modify the view matrix.
339 */
340 void postConcatViewMatrix(const GrMatrix& m);
341
342 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000343 * Retrieves the current view matrix
344 * @return the current view matrix.
345 */
346 const GrMatrix& getViewMatrix() const;
347
348 /**
349 * Retrieves the inverse of the current view matrix.
350 *
351 * If the current view matrix is invertible, return true, and if matrix
352 * is non-null, copy the inverse into it. If the current view matrix is
353 * non-invertible, return false and ignore the matrix parameter.
354 *
355 * @param matrix if not null, will receive a copy of the current inverse.
356 */
357 bool getViewInverse(GrMatrix* matrix) const;
358
359 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000360 * Sets color for next draw to a premultiplied-alpha color.
361 *
362 * @param the color to set.
363 */
364 void setColor(GrColor);
365
366 /**
Scroggo97c88c22011-05-11 14:05:25 +0000367 * Add a color filter that can be represented by a color and a mode.
368 */
369 void setColorFilter(GrColor, SkXfermode::Mode);
370
371 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000372 * Sets the color to be used for the next draw to be
373 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
374 *
375 * @param alpha The alpha value to set as the color.
376 */
377 void setAlpha(uint8_t alpha);
378
379 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000380 * Controls whether clockwise, counterclockwise, or both faces are drawn.
381 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000382 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000383 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000384
385 /**
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000386 * A common pattern is to compute a color with the initial stages and then
387 * modulate that color by a coverage value in later stage(s) (AA, mask-
388 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
389 * computed based on the pre-coverage-modulated color. The division of
390 * stages between color-computing and coverage-computing is specified by
391 * this method. Initially this is kNumStages (all stages are color-
392 * computing).
393 */
394 void setFirstCoverageStage(int firstCoverageStage) {
395 fCurrDrawState.fFirstCoverageStage = firstCoverageStage;
396 }
397
398 /**
399 * Gets the index of the first coverage-computing stage.
400 */
401 int getFirstCoverageStage() const {
402 return fCurrDrawState.fFirstCoverageStage;
403 }
404
405 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000406 * Gets whether the target is drawing clockwise, counterclockwise,
407 * or both faces.
408 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000409 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000410 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000411
412 /**
413 * Enable render state settings.
414 *
415 * @param flags bitfield of StateBits specifing the states to enable
416 */
417 void enableState(uint32_t stateBits);
418
419 /**
420 * Disable render state settings.
421 *
422 * @param flags bitfield of StateBits specifing the states to disable
423 */
424 void disableState(uint32_t stateBits);
425
426 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000427 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
428 }
429
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000430 bool isAntialiasState() const {
431 return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
432 }
433
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000434 bool isClipState() const {
435 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000436 }
437
bsalomon@google.comd302f142011-03-03 13:54:13 +0000438 bool isColorWriteDisabled() const {
439 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
440 }
441
reed@google.comac10a2d2010-12-22 21:39:39 +0000442 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000443 * Sets the blending function coeffecients.
444 *
445 * The blend function will be:
446 * D' = sat(S*srcCoef + D*dstCoef)
447 *
448 * where D is the existing destination color, S is the incoming source
449 * color, and D' is the new destination color that will be written. sat()
450 * is the saturation function.
451 *
452 * @param srcCoef coeffecient applied to the src color.
453 * @param dstCoef coeffecient applied to the dst color.
454 */
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000455 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
reed@google.comac10a2d2010-12-22 21:39:39 +0000456
457 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000458 * Sets the blending function constant referenced by the following blending
459 * coeffecients:
460 * kConstC_BlendCoeff
461 * kIConstC_BlendCoeff
462 * kConstA_BlendCoeff
463 * kIConstA_BlendCoeff
464 *
465 * @param constant the constant to set
466 */
467 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
468
469 /**
470 * Retrieves the last value set by setBlendConstant()
471 * @return the blending constant value
472 */
473 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
474
475 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000476 * Used to save and restore the GrGpu's drawing state
477 */
478 struct SavedDrawState {
479 private:
reed@google.com8195f672011-01-12 18:14:28 +0000480 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000481 friend class GrDrawTarget;
482 };
483
484 /**
485 * Saves the current draw state. The state can be restored at a later time
486 * with restoreDrawState.
487 *
488 * See also AutoStateRestore class.
489 *
490 * @param state will hold the state after the function returns.
491 */
492 void saveCurrentDrawState(SavedDrawState* state) const;
493
494 /**
495 * Restores previously saved draw state. The client guarantees that state
496 * was previously passed to saveCurrentDrawState and that the rendertarget
497 * and texture set at save are still valid.
498 *
499 * See also AutoStateRestore class.
500 *
501 * @param state the previously saved state to restore.
502 */
503 void restoreDrawState(const SavedDrawState& state);
504
505 /**
506 * Copies the draw state from another target to this target.
507 *
508 * @param srcTarget draw target used as src of the draw state.
509 */
510 void copyDrawState(const GrDrawTarget& srcTarget);
511
512 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000513 * The format of vertices is represented as a bitfield of flags.
514 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000515 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000516 * coordinates and per-vertex colors. Each stage can use any of the texture
517 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000518 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000519 * If no texture coordinates are specified for a stage then the stage is
520 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000521 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000522 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000523 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000524 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000525 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000526 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000527 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000528 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000529 * the order would be (position, texture coordinate 1[, color]).
530 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000531
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000532 /**
533 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000534 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000535 * @param stage the stage that will use texture coordinates.
536 * @param texCoordIdx the index of the texture coordinates to use
537 *
538 * @return the bit to add to a GrVertexLayout bitfield.
539 */
540 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
541 GrAssert(stage < kNumStages);
542 GrAssert(texCoordIdx < kMaxTexCoords);
543 return 1 << (stage + (texCoordIdx * kNumStages));
544 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000545
546 /**
547 * Determines if blend is effectively disabled.
548 *
549 * @return true if blend can be disabled without changing the rendering
550 * result given the current state including the vertex layout specified
551 * with the vertex source.
552 */
553 bool canDisableBlend() const;
554
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000555 /**
556 * Sets the edge data required for edge antialiasing.
557 *
558 * @param edges 3 * 6 float values, representing the edge
559 * equations in Ax + By + C form
560 */
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000561 void setEdgeAAData(const Edge* edges, int numEdges);
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000562
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000563private:
564 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
565public:
566 /**
567 * Generates a bit indicating that a texture stage uses the position
568 * as its texture coordinate.
569 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000570 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000571 * coordinates.
572 *
573 * @return the bit to add to a GrVertexLayout bitfield.
574 */
575 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
576 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000577 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000578 }
579private:
580 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000581
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000582public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000583
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000584 /**
585 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000586 */
587 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000588
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000589 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
590 //<! vertices have colors
591 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
592 //<! use text vertices. (Pos
593 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000594 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000595 // text [GrGpuTextVertex vs
596 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000597 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000598 kDummyVertexLayoutBit,
599 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000600 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000601 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000602 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000603
604 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000605 * There are three methods for specifying geometry (vertices and optionally
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000606 * indices) to the draw target. When indexed drawing the indices and vertices
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000607 * can use a different method. Once geometry is specified it can be used for
608 * multiple drawIndexed and drawNonIndexed calls.
609 *
610 * Sometimes it is necessary to perform a draw while upstack code has
611 * already specified geometry that it isn't finished with. There are push
612 * pop methods
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000613 *
614 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
615 * caller's client has already provided vertex data in a format
616 * the time compatible with a GrVertexLayout. The array must contain the
617 * data at set*SourceToArray is called. The source stays in effect for
618 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
619 * again or one of the other two paths is chosen.
620 *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000621 * 2. Reserve. This is most useful when the caller has data it must
622 * transform before drawing and is not long-lived. The caller requests
623 * that the draw target make room for some amount of vertex and/or index
624 * data. The target provides ptrs to hold the vertex and/or index data.
625 *
626 * The data is writable up until the next drawIndexed, drawNonIndexed,
627 * or pushGeometrySource At this point the data is frozen and the ptrs
628 * are no longer valid.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000629 *
630 * 3. Vertex and Index Buffers. This is most useful for geometry that will
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000631 * is long-lived. SetVertexSourceToBuffer and SetIndexSourceToBuffer are
632 * used to set the buffer and subsequent drawIndexed and drawNonIndexed
633 * calls use this source until another source is set.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000634 */
635
636 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000637 * Reserves space for vertices. Draw target will use reserved vertices at
638 * at the next draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000639 *
640 * If succeeds:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000641 * if vertexCount > 0, *vertices will be the array
reed@google.comac10a2d2010-12-22 21:39:39 +0000642 * of vertices to be filled by caller. The next draw will read
643 * these vertices.
644 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000645 * If a client does not already have a vertex buffer then this is the
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000646 * preferred way to allocate vertex data. It allows the subclass of
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000647 * GrDrawTarget to decide whether to put data in buffers, to group vertex
648 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000649 *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000650 * After the next draw or pushGeometrySource the vertices ptr is no longer
651 * valid and the geometry data cannot be further modified. The contents
652 * that were put in the reserved space can be drawn by multiple draws,
653 * however.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000654 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000655 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000656 * @param vertexCount the number of vertices to reserve space for. Can be 0.
reed@google.comac10a2d2010-12-22 21:39:39 +0000657 * @param vertices will point to reserved vertex space if vertexCount is
658 * non-zero. Illegal to pass NULL if vertexCount > 0.
reed@google.comac10a2d2010-12-22 21:39:39 +0000659 *
660 * @return true if succeeded in allocating space for the vertices and false
661 * if not.
662 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000663 bool reserveVertexSpace(GrVertexLayout vertexLayout,
664 int vertexCount,
665 void** vertices);
666 /**
667 * Reserves space for indices. Draw target will use the reserved indices at
668 * the next indexed draw.
669 *
670 * If succeeds:
671 * if indexCount > 0, *indices will be the array
672 * of indices to be filled by caller. The next draw will read
673 * these indices.
674 *
675 * If a client does not already have a index buffer then this is the
676 * preferred way to allocate index data. It allows the subclass of
677 * GrDrawTarget to decide whether to put data in buffers, to group index
678 * data that uses the same state (e.g. for deferred rendering), etc.
679 *
680 * After the next indexed draw or pushGeometrySource the indices ptr is no
681 * longer valid and the geometry data cannot be further modified. The
682 * contents that were put in the reserved space can be drawn by multiple
683 * draws, however.
684 *
685 * @param indexCount the number of indices to reserve space for. Can be 0.
686 * @param indices will point to reserved index space if indexCount is
687 * non-zero. Illegal to pass NULL if indexCount > 0.
688 */
689
690 bool reserveIndexSpace(int indexCount, void** indices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000691 /**
692 * Provides hints to caller about the number of vertices and indices
693 * that can be allocated cheaply. This can be useful if caller is reserving
694 * space but doesn't know exactly how much geometry is needed.
695 *
696 * Also may hint whether the draw target should be flushed first. This is
697 * useful for deferred targets.
698 *
699 * @param vertexLayout layout of vertices caller would like to reserve
700 * @param vertexCount in: hint about how many vertices the caller would
701 * like to allocate.
702 * out: a hint about the number of vertices that can be
703 * allocated cheaply. Negative means no hint.
704 * Ignored if NULL.
705 * @param indexCount in: hint about how many indices the caller would
706 * like to allocate.
707 * out: a hint about the number of indices that can be
708 * allocated cheaply. Negative means no hint.
709 * Ignored if NULL.
710 *
711 * @return true if target should be flushed based on the input values.
712 */
713 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000714 int* vertexCount,
715 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000716
717 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000718 * Sets source of vertex data for the next draw. Array must contain
719 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000720 *
721 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000722 * @param size size of the vertex data.
723 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000724 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000725 void setVertexSourceToArray(GrVertexLayout vertexLayout,
726 const void* vertexArray,
727 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000728
729 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000730 * Sets source of index data for the next indexed draw. Array must contain
731 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000732 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000733 * @param array cpu array containing index data.
734 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000735 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000736 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000737
738 /**
739 * Sets source of vertex data for the next draw. Data does not have to be
740 * in the buffer until drawIndexed or drawNonIndexed.
741 *
742 * @param buffer vertex buffer containing vertex data. Must be
743 * unlocked before draw call.
744 * @param vertexLayout layout of the vertex data in the buffer.
745 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000746 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
747 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000748
749 /**
750 * Sets source of index data for the next indexed draw. Data does not have
751 * to be in the buffer until drawIndexed or drawNonIndexed.
752 *
753 * @param buffer index buffer containing indices. Must be unlocked
754 * before indexed draw call.
755 */
756 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000757
758 /**
759 * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
760 * source to reserved, array, or buffer before next draw. May be able to free
761 * up temporary storage allocated by setVertexSourceToArray or
762 * reserveVertexSpace.
763 */
764 void resetVertexSource();
765
766 /**
767 * Resets index source. Indexed Drawing from reset indices is illegal. Set
768 * index source to reserved, array, or buffer before next indexed draw. May
769 * be able to free up temporary storage allocated by setIndexSourceToArray
770 * or reserveIndexSpace.
771 */
772 void resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000773
774 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000775 * Pushes and resets the vertex/index sources. Any reserved vertex / index
776 * data is finalized (i.e. cannot be updated after the matching pop but can
777 * be drawn from). Must be balanced by a pop.
778 */
779 void pushGeometrySource();
780
781 /**
782 * Pops the vertex / index sources from the matching push.
783 */
784 void popGeometrySource();
785
786 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000787 * Draws indexed geometry using the current state and current vertex / index
788 * sources.
789 *
790 * @param type The type of primitives to draw.
791 * @param startVertex the vertex in the vertex array/buffer corresponding
792 * to index 0
793 * @param startIndex first index to read from index src.
794 * @param vertexCount one greater than the max index.
795 * @param indexCount the number of index elements to read. The index count
796 * is effectively trimmed to the last completely
797 * specified primitive.
798 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000799 void drawIndexed(GrPrimitiveType type,
800 int startVertex,
801 int startIndex,
802 int vertexCount,
803 int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000804
805 /**
806 * Draws non-indexed geometry using the current state and current vertex
807 * sources.
808 *
809 * @param type The type of primitives to draw.
810 * @param startVertex the vertex in the vertex array/buffer corresponding
811 * to index 0
812 * @param vertexCount one greater than the max index.
813 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000814 void drawNonIndexed(GrPrimitiveType type,
815 int startVertex,
816 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000817
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000818 /**
819 * Helper function for drawing rects. This does not use the current index
820 * and vertex sources. After returning, the vertex and index sources may
821 * have changed. They should be reestablished before the next drawIndexed
822 * or drawNonIndexed. This cannot be called between reserving and releasing
823 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000824 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000825 * drawNonIndexed.
826 * @param rect the rect to draw
827 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000828 * @param stageEnableBitfield bitmask indicating which stages are enabled.
829 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000830 * @param srcRects specifies rects for stages enabled by stageEnableMask.
831 * if stageEnableMask bit i is 1, srcRects is not NULL,
832 * and srcRects[i] is not NULL, then srcRects[i] will be
833 * used as coordinates for stage i. Otherwise, if stage i
834 * is enabled then rect is used as the coordinates.
835 * @param srcMatrices optional matrices applied to srcRects. If
836 * srcRect[i] is non-NULL and srcMatrices[i] is
837 * non-NULL then srcRect[i] will be transformed by
838 * srcMatrix[i]. srcMatrices can be NULL when no
839 * srcMatrices are desired.
840 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000841 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000842 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000843 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000844 const GrRect* srcRects[],
845 const GrMatrix* srcMatrices[]);
846
847 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000848 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000849 * matrices.
850 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000851 void drawSimpleRect(const GrRect& rect,
852 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000853 StageBitfield stageEnableBitfield) {
854 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000855 }
856
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000857 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000858 * Clear the render target. Ignores the clip and all other draw state
859 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
860 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000861 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000862 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000863
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000864 /**
865 * Returns the maximum number of edges that may be specified in a single
866 * draw call when performing edge antialiasing. This is usually limited
867 * by the number of fragment uniforms which may be uploaded. Must be a
868 * minimum of six, since a triangle's vertices each belong to two boundary
869 * edges which may be distinct.
870 */
871 virtual int getMaxEdges() const { return 6; }
872
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000873 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000874
875 class AutoStateRestore : ::GrNoncopyable {
876 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000877 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000878 AutoStateRestore(GrDrawTarget* target);
879 ~AutoStateRestore();
880
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000881 /**
882 * if this object is already saving state for param target then
883 * this does nothing. Otherise, it restores previously saved state on
884 * previous target (if any) and saves current state on param target.
885 */
886 void set(GrDrawTarget* target);
887
reed@google.comac10a2d2010-12-22 21:39:39 +0000888 private:
889 GrDrawTarget* fDrawTarget;
890 SavedDrawState fDrawState;
891 };
892
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000893 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000894
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000895 class AutoViewMatrixRestore : ::GrNoncopyable {
896 public:
897 AutoViewMatrixRestore() {
898 fDrawTarget = NULL;
899 }
900
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000901 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000902 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
903 GrAssert(NULL != target);
904 }
905
906 void set(GrDrawTarget* target) {
907 GrAssert(NULL != target);
908 if (NULL != fDrawTarget) {
909 fDrawTarget->setViewMatrix(fMatrix);
910 }
911 fDrawTarget = target;
912 fMatrix = target->getViewMatrix();
913 }
914
915 ~AutoViewMatrixRestore() {
916 if (NULL != fDrawTarget) {
917 fDrawTarget->setViewMatrix(fMatrix);
918 }
919 }
920
921 private:
922 GrDrawTarget* fDrawTarget;
923 GrMatrix fMatrix;
924 };
925
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000926 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000927
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000928 /**
929 * Sets the view matrix to I and preconcats all stage matrices enabled in
930 * mask by the view inverse. Destructor undoes these changes.
931 */
932 class AutoDeviceCoordDraw : ::GrNoncopyable {
933 public:
934 AutoDeviceCoordDraw(GrDrawTarget* target, int stageMask);
935 ~AutoDeviceCoordDraw();
936 private:
937 GrDrawTarget* fDrawTarget;
938 GrMatrix fViewMatrix;
939 GrMatrix fSamplerMatrices[kNumStages];
940 int fStageMask;
941 };
942
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000943 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000944
reed@google.comac10a2d2010-12-22 21:39:39 +0000945 class AutoReleaseGeometry : ::GrNoncopyable {
946 public:
947 AutoReleaseGeometry(GrDrawTarget* target,
948 GrVertexLayout vertexLayout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000949 int vertexCount,
950 int indexCount);
951 AutoReleaseGeometry();
952 ~AutoReleaseGeometry();
bsalomon@google.com5782d712011-01-21 21:03:59 +0000953 bool set(GrDrawTarget* target,
954 GrVertexLayout vertexLayout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000955 int vertexCount,
956 int indexCount);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000957 bool succeeded() const { return NULL != fTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000958 void* vertices() const { return fVertices; }
959 void* indices() const { return fIndices; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000960 GrPoint* positions() const {
961 return static_cast<GrPoint*>(fVertices);
962 }
963
964 private:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000965 void reset();
966
reed@google.comac10a2d2010-12-22 21:39:39 +0000967 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000968 void* fVertices;
969 void* fIndices;
970 };
971
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000972 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000973
974 class AutoClipRestore : ::GrNoncopyable {
975 public:
976 AutoClipRestore(GrDrawTarget* target) {
977 fTarget = target;
978 fClip = fTarget->getClip();
979 }
980
981 ~AutoClipRestore() {
982 fTarget->setClip(fClip);
983 }
984 private:
985 GrDrawTarget* fTarget;
986 GrClip fClip;
987 };
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000988
989 ////////////////////////////////////////////////////////////////////////////
990
991 class AutoGeometryPush : ::GrNoncopyable {
992 public:
993 AutoGeometryPush(GrDrawTarget* target) {
994 GrAssert(NULL != target);
995 fTarget = target;
996 target->pushGeometrySource();
997 }
998 ~AutoGeometryPush() {
999 fTarget->popGeometrySource();
1000 }
1001 private:
1002 GrDrawTarget* fTarget;
1003 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001004
1005 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001006 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +00001007
reed@google.comac10a2d2010-12-22 21:39:39 +00001008 /**
1009 * Helper function to compute the size of a vertex from a vertex layout
1010 * @return size of a single vertex.
1011 */
1012 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001013
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001014 /**
1015 * Helper function for determining the index of texture coordinates that
1016 * is input for a texture stage. Note that a stage may instead use positions
1017 * as texture coordinates, in which case the result of the function is
1018 * indistinguishable from the case when the stage is disabled.
1019 *
1020 * @param stage the stage to query
1021 * @param vertexLayout layout to query
1022 *
1023 * @return the texture coordinate index or -1 if the stage doesn't use
1024 * separate (non-position) texture coordinates.
1025 */
1026 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001027
1028 /**
1029 * Helper function to compute the offset of texture coordinates in a vertex
1030 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +00001031 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001032 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001033 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001034 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001035
1036 /**
1037 * Helper function to compute the offset of the color in a vertex
1038 * @return offset of color in vertex layout or -1 if the
1039 * layout has no color.
1040 */
1041 static int VertexColorOffset(GrVertexLayout vertexLayout);
1042
1043 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001044 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001045 * coordinates of some index.
1046 *
1047 * @param coordIndex the tex coord index to query
1048 * @param vertexLayout layout to query
1049 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001050 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001051 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001052 */
bsalomon@google.com5782d712011-01-21 21:03:59 +00001053 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001054 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001055
reed@google.comac10a2d2010-12-22 21:39:39 +00001056 /**
1057 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001058 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001059 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001060 * @param stage the stage to query
1061 * @param vertexLayout layout to query
1062 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001063 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001064 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001065 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001066 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001067
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001068 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001069 * Helper function to compute the size of each vertex and the offsets of
1070 * texture coordinates and color. Determines tex coord offsets by tex coord
1071 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001072 * by StageTexCoordVertexLayoutBit.)
1073 *
1074 * @param vertexLayout the layout to query
1075 * @param texCoordOffsetsByIdx after return it is the offset of each
1076 * tex coord index in the vertex or -1 if
1077 * index isn't used.
1078 * @return size of a single vertex
1079 */
1080 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
1081 int texCoordOffsetsByIdx[kMaxTexCoords],
1082 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001083
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001084 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001085 * Helper function to compute the size of each vertex and the offsets of
1086 * texture coordinates and color. Determines tex coord offsets by stage
1087 * rather than by index. (Each stage can be mapped to any t.c. index
1088 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001089 * tex coords then that stage's offset will be 0 (positions are always at 0).
1090 *
1091 * @param vertexLayout the layout to query
1092 * @param texCoordOffsetsByStage after return it is the offset of each
1093 * tex coord index in the vertex or -1 if
1094 * index isn't used.
1095 * @return size of a single vertex
1096 */
1097 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1098 int texCoordOffsetsByStage[kNumStages],
1099 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001100
1101 /**
1102 * Accessing positions, texture coords, or colors, of a vertex within an
1103 * array is a hassle involving casts and simple math. These helpers exist
1104 * to keep GrDrawTarget clients' code a bit nicer looking.
1105 */
1106
1107 /**
1108 * Gets a pointer to a GrPoint of a vertex's position or texture
1109 * coordinate.
1110 * @param vertices the vetex array
1111 * @param vertexIndex the index of the vertex in the array
1112 * @param vertexSize the size of each vertex in the array
1113 * @param offset the offset in bytes of the vertex component.
1114 * Defaults to zero (corresponding to vertex position)
1115 * @return pointer to the vertex component as a GrPoint
1116 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001117 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001118 int vertexIndex,
1119 int vertexSize,
1120 int offset = 0) {
1121 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001122 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001123 vertexIndex * vertexSize);
1124 }
1125 static const GrPoint* GetVertexPoint(const void* vertices,
1126 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001127 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001128 int offset = 0) {
1129 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001130 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001131 vertexIndex * vertexSize);
1132 }
1133
1134 /**
1135 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1136 * @param vertices the vetex array
1137 * @param vertexIndex the index of the vertex in the array
1138 * @param vertexSize the size of each vertex in the array
1139 * @param offset the offset in bytes of the vertex color
1140 * @return pointer to the vertex component as a GrColor
1141 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001142 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001143 int vertexIndex,
1144 int vertexSize,
1145 int offset) {
1146 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001147 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001148 vertexIndex * vertexSize);
1149 }
1150 static const GrColor* GetVertexColor(const void* vertices,
1151 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001152 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001153 int offset) {
1154 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001155 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001156 vertexIndex * vertexSize);
1157 }
1158
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001159 static void VertexLayoutUnitTest();
1160
reed@google.comac10a2d2010-12-22 21:39:39 +00001161protected:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001162
1163 enum GeometrySrcType {
1164 kNone_GeometrySrcType, //<! src has not been specified
1165 kReserved_GeometrySrcType, //<! src was set using reserve*Space
1166 kArray_GeometrySrcType, //<! src was set using set*SourceToArray
1167 kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer
1168 };
1169
1170 struct GeometrySrcState {
1171 GeometrySrcType fVertexSrc;
1172 union {
1173 // valid if src type is buffer
1174 const GrVertexBuffer* fVertexBuffer;
1175 // valid if src type is reserved or array
1176 int fVertexCount;
1177 };
1178
1179 GeometrySrcType fIndexSrc;
1180 union {
1181 // valid if src type is buffer
1182 const GrIndexBuffer* fIndexBuffer;
1183 // valid if src type is reserved or array
1184 int fIndexCount;
1185 };
1186
1187 GrVertexLayout fVertexLayout;
1188 };
1189
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001190 // given a vertex layout and a draw state, will a stage be used?
1191 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1192 const DrState& state) {
1193 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1194 }
1195
1196 bool isStageEnabled(int stage) const {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001197 return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout,
1198 fCurrDrawState);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001199 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001200
reed@google.comac10a2d2010-12-22 21:39:39 +00001201 // Helpers for GrDrawTarget subclasses that won't have private access to
1202 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001203 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001204 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001205 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001206 { return sds.fState; }
1207
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001208 // implemented by subclass to allocate space for reserved geom
1209 virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
1210 int vertexCount,
1211 void** vertices) = 0;
1212 virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0;
1213 // implemented by subclass to handle release of reserved geom space
1214 virtual void releaseReservedVertexSpace() = 0;
1215 virtual void releaseReservedIndexSpace() = 0;
1216 // subclass must consume array contents when set
1217 virtual void onSetVertexSourceToArray(const void* vertexArray,
1218 int vertexCount) = 0;
1219 virtual void onSetIndexSourceToArray(const void* indexArray,
1220 int indexCount) = 0;
1221 // subclass is notified that geom source will be set away from an array
1222 virtual void releaseVertexArray() = 0;
1223 virtual void releaseIndexArray() = 0;
1224 // subclass overrides to be notified just before geo src state
1225 // is pushed/popped.
1226 virtual void geometrySourceWillPush() = 0;
1227 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
1228 // subclass called to perform drawing
1229 virtual void onDrawIndexed(GrPrimitiveType type,
1230 int startVertex,
1231 int startIndex,
1232 int vertexCount,
1233 int indexCount) = 0;
1234 virtual void onDrawNonIndexed(GrPrimitiveType type,
1235 int startVertex,
1236 int vertexCount) = 0;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001237 // subclass overrides to be notified when clip is set.
1238 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001239
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001240
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001241 // Helpers for drawRect, protected so subclasses that override drawRect
1242 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001243 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001244 const GrRect* srcRects[]);
1245
1246 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001247 const GrMatrix* matrix,
1248 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001249 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001250 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001251 void* vertices);
1252
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001253 // accessor for derived classes
1254 const GeometrySrcState& getGeomSrc() const {
1255 return fGeoSrcStateStack.back();
1256 }
reed@google.comac10a2d2010-12-22 21:39:39 +00001257
1258 GrClip fClip;
1259
reed@google.com8195f672011-01-12 18:14:28 +00001260 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001261
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001262private:
1263 // called when setting a new vert/idx source to unref prev vb/ib
1264 void releasePreviousVertexSource();
1265 void releasePreviousIndexSource();
1266
1267 enum {
1268 kPreallocGeoSrcStateStackCnt = 4,
reed@google.comac10a2d2010-12-22 21:39:39 +00001269 };
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001270 GrAlignedSTStorage<kPreallocGeoSrcStateStackCnt,
1271 GeometrySrcState>
1272 fGeoSrcStateStackStorage;
1273 GrTArray<GeometrySrcState, true> fGeoSrcStateStack;
1274
reed@google.comac10a2d2010-12-22 21:39:39 +00001275};
1276
1277#endif