blob: 038e776c5bc7318b23164a11256250a1d2999648 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#ifndef GrDrawTarget_DEFINED
19#define GrDrawTarget_DEFINED
20
reed@google.comac10a2d2010-12-22 21:39:39 +000021#include "GrMatrix.h"
22#include "GrColor.h"
23#include "GrRefCnt.h"
24#include "GrSamplerState.h"
25#include "GrClip.h"
bsalomon@google.comd302f142011-03-03 13:54:13 +000026#include "GrTexture.h"
27#include "GrStencil.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000028
29class GrTexture;
reed@google.comac10a2d2010-12-22 21:39:39 +000030class GrClipIterator;
31class GrVertexBuffer;
32class GrIndexBuffer;
junov@google.comf93e7172011-03-31 21:26:24 +000033class GrEffect;
reed@google.comac10a2d2010-12-22 21:39:39 +000034
35class GrDrawTarget : public GrRefCnt {
36public:
37 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +000038 * Number of texture stages. Each stage takes as input a color and
39 * 2D texture coordinates. The color input to the first enabled stage is the
40 * per-vertex color or the constant color (setColor/setAlpha) if there are
41 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000042 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000043 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000044 * lookups are specified by a texture a sampler (setSamplerState). Texture
45 * coordinates for each stage come from the vertices based on a
46 * GrVertexLayout bitfield. The output fragment color is the output color of
47 * the last enabled stage. The presence or absence of texture coordinates
48 * for each stage in the vertex layout indicates whether a stage is enabled
49 * or not.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000050 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000051 enum {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +000052 kNumStages = 2,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000053 kMaxTexCoords = kNumStages
54 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000055
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000056 /**
bsalomon@google.comffca4002011-02-22 20:34:01 +000057 * Bitfield used to indicate which stages are in use.
reed@google.comac10a2d2010-12-22 21:39:39 +000058 */
bsalomon@google.comffca4002011-02-22 20:34:01 +000059 typedef int StageBitfield;
60 GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
reed@google.comac10a2d2010-12-22 21:39:39 +000061
62 /**
63 * Flags that affect rendering. Controlled using enable/disableState(). All
64 * default to disabled.
65 */
66 enum StateBits {
67 kDither_StateBit = 0x1,//<! Perform color dithering
68 kAntialias_StateBit = 0x2,//<! Perform anti-aliasing. The render-
69 // target must support some form of AA
70 // (msaa, coverage sampling, etc). For
71 // GrGpu-created rendertarget/textures
72 // this is controlled by parameters
73 // passed to createTexture.
74 kClip_StateBit = 0x4,//<! Controls whether drawing is clipped
75 // against the region specified by
76 // setClip.
bsalomon@google.comd302f142011-03-03 13:54:13 +000077 kNoColorWrites_StateBit = 0x8,//<! If set it disables writing colors.
78 // Useful while performing stencil ops.
79
80 // subclass may use additional bits internally
81 kDummyStateBit,
82 kLastPublicStateBit = kDummyStateBit-1
83 };
84
85 enum DrawFace {
86 kBoth_DrawFace,
87 kCCW_DrawFace,
88 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +000089 };
90
91 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +000092 * The DrawTarget may reserve some of the high bits of the stencil. The draw
93 * target will automatically trim reference and mask values so that the
94 * client doesn't overwrite these bits.
95 * The number of bits available is relative to the currently set render
96 *target.
97 * @return the number of bits usable by the draw target client.
reed@google.comac10a2d2010-12-22 21:39:39 +000098 */
bsalomon@google.comd302f142011-03-03 13:54:13 +000099 int getUsableStencilBits() const {
100 int bits = fCurrDrawState.fRenderTarget->stencilBits();
101 if (bits) {
102 return bits - 1;
103 } else {
104 return 0;
105 }
106 }
107
108 /**
109 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000110 * Changing the clip has the side-effect of possibly zeroing
111 * out the client settable stencil bits. So multipass algorithms
112 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000113 * @param settings the stencil settings to use.
114 */
115 void setStencil(const GrStencilSettings& settings) {
116 fCurrDrawState.fStencilSettings = settings;
117 }
118
119 /**
120 * Shortcut to disable stencil testing and ops.
121 */
122 void disableStencil() {
123 fCurrDrawState.fStencilSettings.setDisabled();
124 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000125
126protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000127
reed@google.com8195f672011-01-12 18:14:28 +0000128 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000129 DrState() {
130 // make sure any pad is zero for memcmp
131 // all DrState members should default to something
132 // valid by the memset
133 memset(this, 0, sizeof(DrState));
134 GrAssert((intptr_t)(void*)NULL == 0LL);
135 GrAssert(fStencilSettings.isDisabled());
136 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000137 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000138 GrBlendCoeff fSrcBlend;
139 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000140 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000141 GrTexture* fTextures[kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000142 GrEffect* fEffects[kNumStages];
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000143 GrSamplerState fSamplerStates[kNumStages];
144 GrRenderTarget* fRenderTarget;
145 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000146 DrawFace fDrawFace;
147
148 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000149 GrMatrix fViewMatrix;
reed@google.com8195f672011-01-12 18:14:28 +0000150 bool operator ==(const DrState& s) const {
151 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000152 }
reed@google.com8195f672011-01-12 18:14:28 +0000153 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000154 };
155
156public:
157 ///////////////////////////////////////////////////////////////////////////
158
159 GrDrawTarget();
160
161 /**
162 * Sets the current clip to the region specified by clip. All draws will be
163 * clipped against this clip if kClip_StateBit is enabled.
164 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000165 * Setting the clip may (or may not) zero out the client's stencil bits.
166 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000167 * @param description of the clipping region
168 */
169 void setClip(const GrClip& clip);
170
171 /**
172 * Gets the current clip.
173 *
174 * @return the clip.
175 */
176 const GrClip& getClip() const;
177
178 /**
179 * Sets the texture used at the next drawing call
180 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000181 * @param stage The texture stage for which the texture will be set
182 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000183 * @param texture The texture to set. Can be NULL though there is no advantage
184 * to settings a NULL texture if doing non-textured drawing
185 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000186 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000187
188 /**
189 * Retrieves the currently set texture.
190 *
191 * @return The currently set texture. The return value will be NULL if no
192 * texture has been set, NULL was most recently passed to
193 * setTexture, or the last setTexture was destroyed.
194 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000195 const GrTexture* getTexture(int stage) const;
196 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000197
198 /**
199 * Sets the rendertarget used at the next drawing call
200 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000201 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000202 */
203 void setRenderTarget(GrRenderTarget* target);
204
205 /**
206 * Retrieves the currently set rendertarget.
207 *
208 * @return The currently set render target.
209 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000210 const GrRenderTarget* getRenderTarget() const;
211 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000212
213 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000214 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000215 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000216 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000217 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000218 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000219 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000220 * @param samplerState Specifies the sampler state.
221 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000222 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000223
224 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000225 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000227 * @param stage the stage of the sampler to set
228 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000229 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000230 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
231 GrAssert(stage >= 0 && stage < kNumStages);
232 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000233 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000234
235 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000236 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000237 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000238 * @param stage the stage to of sampler to get
239 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000240 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000241 const GrMatrix& getSamplerMatrix(int stage) const {
242 return fCurrDrawState.fSamplerStates[stage].getMatrix();
243 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000244
245 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000246 * Sets the matrix of a stage's sampler
247 *
248 * @param stage the stage of sampler set
249 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000250 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000251 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000252 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
253 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000254
255 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000256 * Sets the matrix applied to veretx positions.
257 *
258 * In the post-view-matrix space the rectangle [0,w]x[0,h]
259 * fully covers the render target. (w and h are the width and height of the
260 * the rendertarget.)
261 *
262 * @param m the matrix used to transform the vertex positions.
263 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000264 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000265
266 /**
267 * Multiplies the current view matrix by a matrix
268 *
269 * After this call V' = V*m where V is the old view matrix,
270 * m is the parameter to this function, and V' is the new view matrix.
271 * (We consider positions to be column vectors so position vector p is
272 * transformed by matrix X as p' = X*p.)
273 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000274 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000275 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000276 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000277
278 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000279 * Retrieves the current view matrix
280 * @return the current view matrix.
281 */
282 const GrMatrix& getViewMatrix() const;
283
284 /**
285 * Retrieves the inverse of the current view matrix.
286 *
287 * If the current view matrix is invertible, return true, and if matrix
288 * is non-null, copy the inverse into it. If the current view matrix is
289 * non-invertible, return false and ignore the matrix parameter.
290 *
291 * @param matrix if not null, will receive a copy of the current inverse.
292 */
293 bool getViewInverse(GrMatrix* matrix) const;
294
295 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000296 * Sets color for next draw to a premultiplied-alpha color.
297 *
298 * @param the color to set.
299 */
300 void setColor(GrColor);
301
302 /**
303 * Sets the color to be used for the next draw to be
304 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
305 *
306 * @param alpha The alpha value to set as the color.
307 */
308 void setAlpha(uint8_t alpha);
309
310 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000311 * Controls whether clockwise, counterclockwise, or both faces are drawn.
312 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000313 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000314 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000315
316 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000317 * Gets whether the target is drawing clockwise, counterclockwise,
318 * or both faces.
319 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000320 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000321 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000322
323 /**
324 * Enable render state settings.
325 *
326 * @param flags bitfield of StateBits specifing the states to enable
327 */
328 void enableState(uint32_t stateBits);
329
330 /**
331 * Disable render state settings.
332 *
333 * @param flags bitfield of StateBits specifing the states to disable
334 */
335 void disableState(uint32_t stateBits);
336
337 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000338 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
339 }
340
341 bool isClipState() const {
342 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000343 }
344
bsalomon@google.comd302f142011-03-03 13:54:13 +0000345 bool isColorWriteDisabled() const {
346 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
347 }
348
reed@google.comac10a2d2010-12-22 21:39:39 +0000349 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000350 * Sets the blending function coeffecients.
351 *
352 * The blend function will be:
353 * D' = sat(S*srcCoef + D*dstCoef)
354 *
355 * where D is the existing destination color, S is the incoming source
356 * color, and D' is the new destination color that will be written. sat()
357 * is the saturation function.
358 *
359 * @param srcCoef coeffecient applied to the src color.
360 * @param dstCoef coeffecient applied to the dst color.
361 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000362 void setBlendFunc(GrBlendCoeff srcCoef, GrBlendCoeff dstCoef);
reed@google.comac10a2d2010-12-22 21:39:39 +0000363
364 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000365 * Sets the blending function constant referenced by the following blending
366 * coeffecients:
367 * kConstC_BlendCoeff
368 * kIConstC_BlendCoeff
369 * kConstA_BlendCoeff
370 * kIConstA_BlendCoeff
371 *
372 * @param constant the constant to set
373 */
374 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
375
376 /**
377 * Retrieves the last value set by setBlendConstant()
378 * @return the blending constant value
379 */
380 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
381
382 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000383 * Used to save and restore the GrGpu's drawing state
384 */
385 struct SavedDrawState {
386 private:
reed@google.com8195f672011-01-12 18:14:28 +0000387 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000388 friend class GrDrawTarget;
389 };
390
391 /**
392 * Saves the current draw state. The state can be restored at a later time
393 * with restoreDrawState.
394 *
395 * See also AutoStateRestore class.
396 *
397 * @param state will hold the state after the function returns.
398 */
399 void saveCurrentDrawState(SavedDrawState* state) const;
400
401 /**
402 * Restores previously saved draw state. The client guarantees that state
403 * was previously passed to saveCurrentDrawState and that the rendertarget
404 * and texture set at save are still valid.
405 *
406 * See also AutoStateRestore class.
407 *
408 * @param state the previously saved state to restore.
409 */
410 void restoreDrawState(const SavedDrawState& state);
411
412 /**
413 * Copies the draw state from another target to this target.
414 *
415 * @param srcTarget draw target used as src of the draw state.
416 */
417 void copyDrawState(const GrDrawTarget& srcTarget);
418
419 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000420 * The format of vertices is represented as a bitfield of flags.
421 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000422 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000423 * coordinates and per-vertex colors. Each stage can use any of the texture
424 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000425 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000426 * If no texture coordinates are specified for a stage then the stage is
427 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000428 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000429 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000430 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000431 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000432 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000433 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000434 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000435 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000436 * the order would be (position, texture coordinate 1[, color]).
437 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000438
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000439 /**
440 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000441 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000442 * @param stage the stage that will use texture coordinates.
443 * @param texCoordIdx the index of the texture coordinates to use
444 *
445 * @return the bit to add to a GrVertexLayout bitfield.
446 */
447 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
448 GrAssert(stage < kNumStages);
449 GrAssert(texCoordIdx < kMaxTexCoords);
450 return 1 << (stage + (texCoordIdx * kNumStages));
451 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000452
453 /**
454 * Determines if blend is effectively disabled.
455 *
456 * @return true if blend can be disabled without changing the rendering
457 * result given the current state including the vertex layout specified
458 * with the vertex source.
459 */
460 bool canDisableBlend() const;
461
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000462private:
463 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
464public:
465 /**
466 * Generates a bit indicating that a texture stage uses the position
467 * as its texture coordinate.
468 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000469 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000470 * coordinates.
471 *
472 * @return the bit to add to a GrVertexLayout bitfield.
473 */
474 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
475 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000476 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000477 }
478private:
479 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000480
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000481public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000482
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000483 /**
484 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000485 */
486 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000487
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000488 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
489 //<! vertices have colors
490 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
491 //<! use text vertices. (Pos
492 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000493 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000494 // text [GrGpuTextVertex vs
495 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000496 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000497 kDummyVertexLayoutBit,
498 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000499 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000500 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000501 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000502
503 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000504 * There are three paths for specifying geometry (vertices and optionally
505 * indices) to the draw target. When indexed drawing the indices and vertices
506 * can be each use a different path.
507 *
508 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
509 * caller's client has already provided vertex data in a format
510 * the time compatible with a GrVertexLayout. The array must contain the
511 * data at set*SourceToArray is called. The source stays in effect for
512 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
513 * again or one of the other two paths is chosen.
514 *
515 * 2. Reserve and Lock. This is most useful when the caller has data it must
516 * transform before drawing and will not likely render it again. The
517 * caller requests that the draw target make room for some amount of
518 * vertex and/or index data. The target provides ptrs to hold the data
519 * data. The caller can write the data into the pts up until the first
520 * drawIndexed or drawNonIndexed call. At this point the data is frozen
521 * and the ptrs are no longer guaranteed to be valid. All subsequent
522 * drawIndexed & drawNonIndexed calls will use this data until
523 * releaseReserved geometry is called. This must be called before another
524 * source is set.
525 *
526 * 3. Vertex and Index Buffers. This is most useful for geometry that will
527 * be rendered multiple times. SetVertexSourceToBuffer &
528 * SetIndexSourceToBuffer are used to set the buffer and subsequent
529 * drawIndexed and drawNonIndexed calls use this source until another
530 * source is set.
531 */
532
533 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000534 * Reserves space for vertices and/or indices. Draw target will use
535 * reserved vertices / indices at next draw.
536 *
537 * If succeeds:
538 * if vertexCount is nonzero, *vertices will be the array
539 * of vertices to be filled by caller. The next draw will read
540 * these vertices.
541 *
542 * if indecCount is nonzero, *indices will be the array of indices
543 * to be filled by caller. The next indexed draw will read from
544 * these indices.
545 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000546 * If a client does not already have a vertex buffer then this is the
547 * preferred way to allocate vertex/index array. It allows the subclass of
548 * GrDrawTarget to decide whether to put data in buffers, to group vertex
549 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000550 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000551 * Following the first draw after reserveAndLockGeometry the ptrs returned
552 * by releaseReservedGeometry are no longer valid and the geometry data
553 * cannot be further modified. The contents that were put in the reserved
554 * space can be drawn by multiple draws, however.
555 *
556 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
557 * call after all draws that reference the reserved geometry data have
558 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000559 *
560 * AutoGeometryRelease can be used to automatically call the release.
561 *
562 * @param vertexCount the number of vertices to reserve space for. Can be 0.
563 * @param indexCount the number of indices to reserve space for. Can be 0.
564 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
565 * @param vertices will point to reserved vertex space if vertexCount is
566 * non-zero. Illegal to pass NULL if vertexCount > 0.
567 * @param indices will point to reserved index space if indexCount is
568 * non-zero. Illegal to pass NULL if indexCount > 0.
569 *
570 * @return true if succeeded in allocating space for the vertices and false
571 * if not.
572 */
573 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
574 uint32_t vertexCount,
575 uint32_t indexCount,
576 void** vertices,
577 void** indices);
578 /**
579 * Provides hints to caller about the number of vertices and indices
580 * that can be allocated cheaply. This can be useful if caller is reserving
581 * space but doesn't know exactly how much geometry is needed.
582 *
583 * Also may hint whether the draw target should be flushed first. This is
584 * useful for deferred targets.
585 *
586 * @param vertexLayout layout of vertices caller would like to reserve
587 * @param vertexCount in: hint about how many vertices the caller would
588 * like to allocate.
589 * out: a hint about the number of vertices that can be
590 * allocated cheaply. Negative means no hint.
591 * Ignored if NULL.
592 * @param indexCount in: hint about how many indices the caller would
593 * like to allocate.
594 * out: a hint about the number of indices that can be
595 * allocated cheaply. Negative means no hint.
596 * Ignored if NULL.
597 *
598 * @return true if target should be flushed based on the input values.
599 */
600 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000601 int* vertexCount,
602 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000603
604 /**
605 * Releases reserved vertex/index data from reserveAndLockGeometry().
606 */
607 void releaseReservedGeometry();
608
609 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000610 * Sets source of vertex data for the next draw. Array must contain
611 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000612 *
613 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000614 * @param size size of the vertex data.
615 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000616 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000617 void setVertexSourceToArray(GrVertexLayout vertexLayout,
618 const void* vertexArray,
619 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000620
621 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000622 * Sets source of index data for the next indexed draw. Array must contain
623 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000624 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000625 * @param array cpu array containing index data.
626 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000627 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000628 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000629
630 /**
631 * Sets source of vertex data for the next draw. Data does not have to be
632 * in the buffer until drawIndexed or drawNonIndexed.
633 *
634 * @param buffer vertex buffer containing vertex data. Must be
635 * unlocked before draw call.
636 * @param vertexLayout layout of the vertex data in the buffer.
637 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000638 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
639 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000640
641 /**
642 * Sets source of index data for the next indexed draw. Data does not have
643 * to be in the buffer until drawIndexed or drawNonIndexed.
644 *
645 * @param buffer index buffer containing indices. Must be unlocked
646 * before indexed draw call.
647 */
648 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
649
650 /**
651 * Draws indexed geometry using the current state and current vertex / index
652 * sources.
653 *
654 * @param type The type of primitives to draw.
655 * @param startVertex the vertex in the vertex array/buffer corresponding
656 * to index 0
657 * @param startIndex first index to read from index src.
658 * @param vertexCount one greater than the max index.
659 * @param indexCount the number of index elements to read. The index count
660 * is effectively trimmed to the last completely
661 * specified primitive.
662 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000663 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000664 int startVertex,
665 int startIndex,
666 int vertexCount,
667 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000668
669 /**
670 * Draws non-indexed geometry using the current state and current vertex
671 * sources.
672 *
673 * @param type The type of primitives to draw.
674 * @param startVertex the vertex in the vertex array/buffer corresponding
675 * to index 0
676 * @param vertexCount one greater than the max index.
677 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000678 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000679 int startVertex,
680 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000681
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000682 /**
683 * Helper function for drawing rects. This does not use the current index
684 * and vertex sources. After returning, the vertex and index sources may
685 * have changed. They should be reestablished before the next drawIndexed
686 * or drawNonIndexed. This cannot be called between reserving and releasing
687 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000688 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000689 * drawNonIndexed.
690 * @param rect the rect to draw
691 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000692 * @param stageEnableBitfield bitmask indicating which stages are enabled.
693 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000694 * @param srcRects specifies rects for stages enabled by stageEnableMask.
695 * if stageEnableMask bit i is 1, srcRects is not NULL,
696 * and srcRects[i] is not NULL, then srcRects[i] will be
697 * used as coordinates for stage i. Otherwise, if stage i
698 * is enabled then rect is used as the coordinates.
699 * @param srcMatrices optional matrices applied to srcRects. If
700 * srcRect[i] is non-NULL and srcMatrices[i] is
701 * non-NULL then srcRect[i] will be transformed by
702 * srcMatrix[i]. srcMatrices can be NULL when no
703 * srcMatrices are desired.
704 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000705 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000706 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000707 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000708 const GrRect* srcRects[],
709 const GrMatrix* srcMatrices[]);
710
711 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000712 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000713 * matrices.
714 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000715 void drawSimpleRect(const GrRect& rect,
716 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000717 StageBitfield stageEnableBitfield) {
718 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000719 }
720
reed@google.comac10a2d2010-12-22 21:39:39 +0000721 ///////////////////////////////////////////////////////////////////////////
722
723 class AutoStateRestore : ::GrNoncopyable {
724 public:
725 AutoStateRestore(GrDrawTarget* target);
726 ~AutoStateRestore();
727
728 private:
729 GrDrawTarget* fDrawTarget;
730 SavedDrawState fDrawState;
731 };
732
733 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000734
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000735 class AutoViewMatrixRestore : ::GrNoncopyable {
736 public:
737 AutoViewMatrixRestore() {
738 fDrawTarget = NULL;
739 }
740
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000741 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000742 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
743 GrAssert(NULL != target);
744 }
745
746 void set(GrDrawTarget* target) {
747 GrAssert(NULL != target);
748 if (NULL != fDrawTarget) {
749 fDrawTarget->setViewMatrix(fMatrix);
750 }
751 fDrawTarget = target;
752 fMatrix = target->getViewMatrix();
753 }
754
755 ~AutoViewMatrixRestore() {
756 if (NULL != fDrawTarget) {
757 fDrawTarget->setViewMatrix(fMatrix);
758 }
759 }
760
761 private:
762 GrDrawTarget* fDrawTarget;
763 GrMatrix fMatrix;
764 };
765
766 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000767
768 class AutoReleaseGeometry : ::GrNoncopyable {
769 public:
770 AutoReleaseGeometry(GrDrawTarget* target,
771 GrVertexLayout vertexLayout,
772 uint32_t vertexCount,
773 uint32_t indexCount) {
774 fTarget = target;
775 fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
776 vertexCount,
777 indexCount,
778 &fVertices,
779 &fIndices);
780 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000781
782 AutoReleaseGeometry() {
783 fSuccess = false;
784 }
785
reed@google.comac10a2d2010-12-22 21:39:39 +0000786 ~AutoReleaseGeometry() {
787 if (fSuccess) {
788 fTarget->releaseReservedGeometry();
789 }
790 }
791
bsalomon@google.com5782d712011-01-21 21:03:59 +0000792 bool set(GrDrawTarget* target,
793 GrVertexLayout vertexLayout,
794 uint32_t vertexCount,
795 uint32_t indexCount) {
796 if (fSuccess) {
797 fTarget->releaseReservedGeometry();
798 }
799 fTarget = target;
800 fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
801 vertexCount,
802 indexCount,
803 &fVertices,
804 &fIndices);
805 return fSuccess;
806 }
807
reed@google.comac10a2d2010-12-22 21:39:39 +0000808 bool succeeded() const { return fSuccess; }
809 void* vertices() const { return fVertices; }
810 void* indices() const { return fIndices; }
811
812 GrPoint* positions() const {
813 return static_cast<GrPoint*>(fVertices);
814 }
815
816 private:
817 GrDrawTarget* fTarget;
818 bool fSuccess;
819 void* fVertices;
820 void* fIndices;
821 };
822
823 ///////////////////////////////////////////////////////////////////////////
824
825 class AutoClipRestore : ::GrNoncopyable {
826 public:
827 AutoClipRestore(GrDrawTarget* target) {
828 fTarget = target;
829 fClip = fTarget->getClip();
830 }
831
832 ~AutoClipRestore() {
833 fTarget->setClip(fClip);
834 }
835 private:
836 GrDrawTarget* fTarget;
837 GrClip fClip;
838 };
839
840 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000841 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000842
reed@google.comac10a2d2010-12-22 21:39:39 +0000843 /**
844 * Helper function to compute the size of a vertex from a vertex layout
845 * @return size of a single vertex.
846 */
847 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000848
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000849 /**
850 * Helper function for determining the index of texture coordinates that
851 * is input for a texture stage. Note that a stage may instead use positions
852 * as texture coordinates, in which case the result of the function is
853 * indistinguishable from the case when the stage is disabled.
854 *
855 * @param stage the stage to query
856 * @param vertexLayout layout to query
857 *
858 * @return the texture coordinate index or -1 if the stage doesn't use
859 * separate (non-position) texture coordinates.
860 */
861 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000862
863 /**
864 * Helper function to compute the offset of texture coordinates in a vertex
865 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +0000866 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000867 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000868 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000869 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000870
871 /**
872 * Helper function to compute the offset of the color in a vertex
873 * @return offset of color in vertex layout or -1 if the
874 * layout has no color.
875 */
876 static int VertexColorOffset(GrVertexLayout vertexLayout);
877
878 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000879 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000880 * coordinates of some index.
881 *
882 * @param coordIndex the tex coord index to query
883 * @param vertexLayout layout to query
884 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000885 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000886 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000887 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000888 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000889 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000890
reed@google.comac10a2d2010-12-22 21:39:39 +0000891 /**
892 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000893 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000894 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000895 * @param stage the stage to query
896 * @param vertexLayout layout to query
897 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000898 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000899 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000900 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000901 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000902
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000903 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000904 * Helper function to compute the size of each vertex and the offsets of
905 * texture coordinates and color. Determines tex coord offsets by tex coord
906 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000907 * by StageTexCoordVertexLayoutBit.)
908 *
909 * @param vertexLayout the layout to query
910 * @param texCoordOffsetsByIdx after return it is the offset of each
911 * tex coord index in the vertex or -1 if
912 * index isn't used.
913 * @return size of a single vertex
914 */
915 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
916 int texCoordOffsetsByIdx[kMaxTexCoords],
917 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000918
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000919 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000920 * Helper function to compute the size of each vertex and the offsets of
921 * texture coordinates and color. Determines tex coord offsets by stage
922 * rather than by index. (Each stage can be mapped to any t.c. index
923 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000924 * tex coords then that stage's offset will be 0 (positions are always at 0).
925 *
926 * @param vertexLayout the layout to query
927 * @param texCoordOffsetsByStage after return it is the offset of each
928 * tex coord index in the vertex or -1 if
929 * index isn't used.
930 * @return size of a single vertex
931 */
932 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
933 int texCoordOffsetsByStage[kNumStages],
934 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000935
936 /**
937 * Accessing positions, texture coords, or colors, of a vertex within an
938 * array is a hassle involving casts and simple math. These helpers exist
939 * to keep GrDrawTarget clients' code a bit nicer looking.
940 */
941
942 /**
943 * Gets a pointer to a GrPoint of a vertex's position or texture
944 * coordinate.
945 * @param vertices the vetex array
946 * @param vertexIndex the index of the vertex in the array
947 * @param vertexSize the size of each vertex in the array
948 * @param offset the offset in bytes of the vertex component.
949 * Defaults to zero (corresponding to vertex position)
950 * @return pointer to the vertex component as a GrPoint
951 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000952 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000953 int vertexIndex,
954 int vertexSize,
955 int offset = 0) {
956 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000957 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000958 vertexIndex * vertexSize);
959 }
960 static const GrPoint* GetVertexPoint(const void* vertices,
961 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000962 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000963 int offset = 0) {
964 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000965 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000966 vertexIndex * vertexSize);
967 }
968
969 /**
970 * Gets a pointer to a GrColor inside a vertex within a vertex array.
971 * @param vertices the vetex array
972 * @param vertexIndex the index of the vertex in the array
973 * @param vertexSize the size of each vertex in the array
974 * @param offset the offset in bytes of the vertex color
975 * @return pointer to the vertex component as a GrColor
976 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000977 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000978 int vertexIndex,
979 int vertexSize,
980 int offset) {
981 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000982 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000983 vertexIndex * vertexSize);
984 }
985 static const GrColor* GetVertexColor(const void* vertices,
986 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000987 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000988 int offset) {
989 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000990 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000991 vertexIndex * vertexSize);
992 }
993
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000994 static void VertexLayoutUnitTest();
995
reed@google.comac10a2d2010-12-22 21:39:39 +0000996protected:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000997
reed@google.comac10a2d2010-12-22 21:39:39 +0000998 // Helpers for GrDrawTarget subclasses that won't have private access to
999 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001000 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001001 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001002 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001003 { return sds.fState; }
1004
1005 // implemented by subclass
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001006 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
1007 void** vertices,
1008 void** indices) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001009
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001010 virtual void onReleaseGeometry() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001011
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001012 // subclass overrides to be notified when clip is set.
1013 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001014
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001015 virtual void onSetVertexSourceToArray(const void* vertexArray,
1016 int vertexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001017
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001018 virtual void onSetIndexSourceToArray(const void* indexArray,
1019 int indexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001020
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001021 // Helpers for drawRect, protected so subclasses that override drawRect
1022 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001023 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001024 const GrRect* srcRects[]);
1025
1026 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001027 const GrMatrix* matrix,
1028 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001029 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001030 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001031 void* vertices);
1032
reed@google.comac10a2d2010-12-22 21:39:39 +00001033 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001034 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
1035 kArray_GeometrySrcType, // src was set using set*SourceToArray
1036 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +00001037 };
1038
bsalomon@google.comd302f142011-03-03 13:54:13 +00001039 struct ReservedGeometry {
reed@google.comac10a2d2010-12-22 21:39:39 +00001040 bool fLocked;
1041 uint32_t fVertexCount;
1042 uint32_t fIndexCount;
1043 } fReservedGeometry;
1044
1045 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001046 GeometrySrcType fVertexSrc;
1047 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
1048 GeometrySrcType fIndexSrc;
1049 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
1050 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +00001051 } fGeometrySrc;
1052
1053 GrClip fClip;
1054
reed@google.com8195f672011-01-12 18:14:28 +00001055 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001056
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001057 // Not meant for external use. Only setVertexSourceToBuffer and
1058 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
1059 // support nested reserveAndLockGeometry (and cpu arrays internally use the
1060 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +00001061 class AutoGeometrySrcRestore {
1062 public:
1063 AutoGeometrySrcRestore(GrDrawTarget* target) {
1064 fTarget = target;
1065 fGeometrySrc = fTarget->fGeometrySrc;
1066 }
1067 ~AutoGeometrySrcRestore() {
1068 fTarget->fGeometrySrc = fGeometrySrc;
1069 }
1070 private:
1071 GrDrawTarget *fTarget;
1072 GeometrySrc fGeometrySrc;
1073
1074 AutoGeometrySrcRestore();
1075 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
1076 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
1077 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001078};
1079
1080#endif