blob: c971e717b7e7bc30d3e4a01adf4775b3c583db0a [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.com06afe7b2011-04-26 15:31:40 +0000279 * Multiplies the current view matrix by a matrix
280 *
281 * After this call V' = m*V where V is the old view matrix,
282 * m is the parameter to this function, and V' is the new view matrix.
283 * (We consider positions to be column vectors so position vector p is
284 * transformed by matrix X as p' = X*p.)
285 *
286 * @param m the matrix used to modify the view matrix.
287 */
288 void postConcatViewMatrix(const GrMatrix& m);
289
290 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000291 * Retrieves the current view matrix
292 * @return the current view matrix.
293 */
294 const GrMatrix& getViewMatrix() const;
295
296 /**
297 * Retrieves the inverse of the current view matrix.
298 *
299 * If the current view matrix is invertible, return true, and if matrix
300 * is non-null, copy the inverse into it. If the current view matrix is
301 * non-invertible, return false and ignore the matrix parameter.
302 *
303 * @param matrix if not null, will receive a copy of the current inverse.
304 */
305 bool getViewInverse(GrMatrix* matrix) const;
306
307 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000308 * Sets color for next draw to a premultiplied-alpha color.
309 *
310 * @param the color to set.
311 */
312 void setColor(GrColor);
313
314 /**
315 * Sets the color to be used for the next draw to be
316 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
317 *
318 * @param alpha The alpha value to set as the color.
319 */
320 void setAlpha(uint8_t alpha);
321
322 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000323 * Controls whether clockwise, counterclockwise, or both faces are drawn.
324 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000325 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000326 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000327
328 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000329 * Gets whether the target is drawing clockwise, counterclockwise,
330 * or both faces.
331 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000332 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000333 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000334
335 /**
336 * Enable render state settings.
337 *
338 * @param flags bitfield of StateBits specifing the states to enable
339 */
340 void enableState(uint32_t stateBits);
341
342 /**
343 * Disable render state settings.
344 *
345 * @param flags bitfield of StateBits specifing the states to disable
346 */
347 void disableState(uint32_t stateBits);
348
349 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000350 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
351 }
352
353 bool isClipState() const {
354 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000355 }
356
bsalomon@google.comd302f142011-03-03 13:54:13 +0000357 bool isColorWriteDisabled() const {
358 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
359 }
360
reed@google.comac10a2d2010-12-22 21:39:39 +0000361 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000362 * Sets the blending function coeffecients.
363 *
364 * The blend function will be:
365 * D' = sat(S*srcCoef + D*dstCoef)
366 *
367 * where D is the existing destination color, S is the incoming source
368 * color, and D' is the new destination color that will be written. sat()
369 * is the saturation function.
370 *
371 * @param srcCoef coeffecient applied to the src color.
372 * @param dstCoef coeffecient applied to the dst color.
373 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000374 void setBlendFunc(GrBlendCoeff srcCoef, GrBlendCoeff dstCoef);
reed@google.comac10a2d2010-12-22 21:39:39 +0000375
376 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000377 * Sets the blending function constant referenced by the following blending
378 * coeffecients:
379 * kConstC_BlendCoeff
380 * kIConstC_BlendCoeff
381 * kConstA_BlendCoeff
382 * kIConstA_BlendCoeff
383 *
384 * @param constant the constant to set
385 */
386 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
387
388 /**
389 * Retrieves the last value set by setBlendConstant()
390 * @return the blending constant value
391 */
392 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
393
394 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000395 * Used to save and restore the GrGpu's drawing state
396 */
397 struct SavedDrawState {
398 private:
reed@google.com8195f672011-01-12 18:14:28 +0000399 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000400 friend class GrDrawTarget;
401 };
402
403 /**
404 * Saves the current draw state. The state can be restored at a later time
405 * with restoreDrawState.
406 *
407 * See also AutoStateRestore class.
408 *
409 * @param state will hold the state after the function returns.
410 */
411 void saveCurrentDrawState(SavedDrawState* state) const;
412
413 /**
414 * Restores previously saved draw state. The client guarantees that state
415 * was previously passed to saveCurrentDrawState and that the rendertarget
416 * and texture set at save are still valid.
417 *
418 * See also AutoStateRestore class.
419 *
420 * @param state the previously saved state to restore.
421 */
422 void restoreDrawState(const SavedDrawState& state);
423
424 /**
425 * Copies the draw state from another target to this target.
426 *
427 * @param srcTarget draw target used as src of the draw state.
428 */
429 void copyDrawState(const GrDrawTarget& srcTarget);
430
431 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000432 * The format of vertices is represented as a bitfield of flags.
433 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000434 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000435 * coordinates and per-vertex colors. Each stage can use any of the texture
436 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000437 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000438 * If no texture coordinates are specified for a stage then the stage is
439 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000440 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000441 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000442 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000443 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000444 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000445 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000446 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000447 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000448 * the order would be (position, texture coordinate 1[, color]).
449 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000450
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000451 /**
452 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000453 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000454 * @param stage the stage that will use texture coordinates.
455 * @param texCoordIdx the index of the texture coordinates to use
456 *
457 * @return the bit to add to a GrVertexLayout bitfield.
458 */
459 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
460 GrAssert(stage < kNumStages);
461 GrAssert(texCoordIdx < kMaxTexCoords);
462 return 1 << (stage + (texCoordIdx * kNumStages));
463 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000464
465 /**
466 * Determines if blend is effectively disabled.
467 *
468 * @return true if blend can be disabled without changing the rendering
469 * result given the current state including the vertex layout specified
470 * with the vertex source.
471 */
472 bool canDisableBlend() const;
473
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000474private:
475 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
476public:
477 /**
478 * Generates a bit indicating that a texture stage uses the position
479 * as its texture coordinate.
480 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000481 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000482 * coordinates.
483 *
484 * @return the bit to add to a GrVertexLayout bitfield.
485 */
486 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
487 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000488 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000489 }
490private:
491 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000492
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000493public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000494
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000495 /**
496 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000497 */
498 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000499
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000500 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
501 //<! vertices have colors
502 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
503 //<! use text vertices. (Pos
504 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000505 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000506 // text [GrGpuTextVertex vs
507 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000508 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000509 kDummyVertexLayoutBit,
510 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000511 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000512 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000513 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000514
515 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000516 * There are three paths for specifying geometry (vertices and optionally
517 * indices) to the draw target. When indexed drawing the indices and vertices
518 * can be each use a different path.
519 *
520 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
521 * caller's client has already provided vertex data in a format
522 * the time compatible with a GrVertexLayout. The array must contain the
523 * data at set*SourceToArray is called. The source stays in effect for
524 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
525 * again or one of the other two paths is chosen.
526 *
527 * 2. Reserve and Lock. This is most useful when the caller has data it must
528 * transform before drawing and will not likely render it again. The
529 * caller requests that the draw target make room for some amount of
530 * vertex and/or index data. The target provides ptrs to hold the data
531 * data. The caller can write the data into the pts up until the first
532 * drawIndexed or drawNonIndexed call. At this point the data is frozen
533 * and the ptrs are no longer guaranteed to be valid. All subsequent
534 * drawIndexed & drawNonIndexed calls will use this data until
535 * releaseReserved geometry is called. This must be called before another
536 * source is set.
537 *
538 * 3. Vertex and Index Buffers. This is most useful for geometry that will
539 * be rendered multiple times. SetVertexSourceToBuffer &
540 * SetIndexSourceToBuffer are used to set the buffer and subsequent
541 * drawIndexed and drawNonIndexed calls use this source until another
542 * source is set.
543 */
544
545 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000546 * Reserves space for vertices and/or indices. Draw target will use
547 * reserved vertices / indices at next draw.
548 *
549 * If succeeds:
550 * if vertexCount is nonzero, *vertices will be the array
551 * of vertices to be filled by caller. The next draw will read
552 * these vertices.
553 *
554 * if indecCount is nonzero, *indices will be the array of indices
555 * to be filled by caller. The next indexed draw will read from
556 * these indices.
557 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000558 * If a client does not already have a vertex buffer then this is the
559 * preferred way to allocate vertex/index array. It allows the subclass of
560 * GrDrawTarget to decide whether to put data in buffers, to group vertex
561 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000562 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000563 * Following the first draw after reserveAndLockGeometry the ptrs returned
564 * by releaseReservedGeometry are no longer valid and the geometry data
565 * cannot be further modified. The contents that were put in the reserved
566 * space can be drawn by multiple draws, however.
567 *
568 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
569 * call after all draws that reference the reserved geometry data have
570 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000571 *
572 * AutoGeometryRelease can be used to automatically call the release.
573 *
574 * @param vertexCount the number of vertices to reserve space for. Can be 0.
575 * @param indexCount the number of indices to reserve space for. Can be 0.
576 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
577 * @param vertices will point to reserved vertex space if vertexCount is
578 * non-zero. Illegal to pass NULL if vertexCount > 0.
579 * @param indices will point to reserved index space if indexCount is
580 * non-zero. Illegal to pass NULL if indexCount > 0.
581 *
582 * @return true if succeeded in allocating space for the vertices and false
583 * if not.
584 */
585 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
586 uint32_t vertexCount,
587 uint32_t indexCount,
588 void** vertices,
589 void** indices);
590 /**
591 * Provides hints to caller about the number of vertices and indices
592 * that can be allocated cheaply. This can be useful if caller is reserving
593 * space but doesn't know exactly how much geometry is needed.
594 *
595 * Also may hint whether the draw target should be flushed first. This is
596 * useful for deferred targets.
597 *
598 * @param vertexLayout layout of vertices caller would like to reserve
599 * @param vertexCount in: hint about how many vertices the caller would
600 * like to allocate.
601 * out: a hint about the number of vertices that can be
602 * allocated cheaply. Negative means no hint.
603 * Ignored if NULL.
604 * @param indexCount in: hint about how many indices the caller would
605 * like to allocate.
606 * out: a hint about the number of indices that can be
607 * allocated cheaply. Negative means no hint.
608 * Ignored if NULL.
609 *
610 * @return true if target should be flushed based on the input values.
611 */
612 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000613 int* vertexCount,
614 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000615
616 /**
617 * Releases reserved vertex/index data from reserveAndLockGeometry().
618 */
619 void releaseReservedGeometry();
620
621 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000622 * Sets source of vertex data for the next draw. Array must contain
623 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000624 *
625 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000626 * @param size size of the vertex data.
627 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000628 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000629 void setVertexSourceToArray(GrVertexLayout vertexLayout,
630 const void* vertexArray,
631 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000632
633 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000634 * Sets source of index data for the next indexed draw. Array must contain
635 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000636 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000637 * @param array cpu array containing index data.
638 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000639 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000640 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000641
642 /**
643 * Sets source of vertex data for the next draw. Data does not have to be
644 * in the buffer until drawIndexed or drawNonIndexed.
645 *
646 * @param buffer vertex buffer containing vertex data. Must be
647 * unlocked before draw call.
648 * @param vertexLayout layout of the vertex data in the buffer.
649 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000650 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
651 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000652
653 /**
654 * Sets source of index data for the next indexed draw. Data does not have
655 * to be in the buffer until drawIndexed or drawNonIndexed.
656 *
657 * @param buffer index buffer containing indices. Must be unlocked
658 * before indexed draw call.
659 */
660 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
661
662 /**
663 * Draws indexed geometry using the current state and current vertex / index
664 * sources.
665 *
666 * @param type The type of primitives to draw.
667 * @param startVertex the vertex in the vertex array/buffer corresponding
668 * to index 0
669 * @param startIndex first index to read from index src.
670 * @param vertexCount one greater than the max index.
671 * @param indexCount the number of index elements to read. The index count
672 * is effectively trimmed to the last completely
673 * specified primitive.
674 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000675 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000676 int startVertex,
677 int startIndex,
678 int vertexCount,
679 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000680
681 /**
682 * Draws non-indexed geometry using the current state and current vertex
683 * sources.
684 *
685 * @param type The type of primitives to draw.
686 * @param startVertex the vertex in the vertex array/buffer corresponding
687 * to index 0
688 * @param vertexCount one greater than the max index.
689 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000690 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000691 int startVertex,
692 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000693
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000694 /**
695 * Helper function for drawing rects. This does not use the current index
696 * and vertex sources. After returning, the vertex and index sources may
697 * have changed. They should be reestablished before the next drawIndexed
698 * or drawNonIndexed. This cannot be called between reserving and releasing
699 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000700 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000701 * drawNonIndexed.
702 * @param rect the rect to draw
703 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000704 * @param stageEnableBitfield bitmask indicating which stages are enabled.
705 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000706 * @param srcRects specifies rects for stages enabled by stageEnableMask.
707 * if stageEnableMask bit i is 1, srcRects is not NULL,
708 * and srcRects[i] is not NULL, then srcRects[i] will be
709 * used as coordinates for stage i. Otherwise, if stage i
710 * is enabled then rect is used as the coordinates.
711 * @param srcMatrices optional matrices applied to srcRects. If
712 * srcRect[i] is non-NULL and srcMatrices[i] is
713 * non-NULL then srcRect[i] will be transformed by
714 * srcMatrix[i]. srcMatrices can be NULL when no
715 * srcMatrices are desired.
716 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000717 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000718 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000719 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000720 const GrRect* srcRects[],
721 const GrMatrix* srcMatrices[]);
722
723 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000724 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000725 * matrices.
726 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000727 void drawSimpleRect(const GrRect& rect,
728 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000729 StageBitfield stageEnableBitfield) {
730 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000731 }
732
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000733 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000734 * Clear the render target. Ignores the clip and all other draw state
735 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
736 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000737 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000738 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000739
reed@google.comac10a2d2010-12-22 21:39:39 +0000740 ///////////////////////////////////////////////////////////////////////////
741
742 class AutoStateRestore : ::GrNoncopyable {
743 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000744 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000745 AutoStateRestore(GrDrawTarget* target);
746 ~AutoStateRestore();
747
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000748 /**
749 * if this object is already saving state for param target then
750 * this does nothing. Otherise, it restores previously saved state on
751 * previous target (if any) and saves current state on param target.
752 */
753 void set(GrDrawTarget* target);
754
reed@google.comac10a2d2010-12-22 21:39:39 +0000755 private:
756 GrDrawTarget* fDrawTarget;
757 SavedDrawState fDrawState;
758 };
759
760 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000761
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000762 class AutoViewMatrixRestore : ::GrNoncopyable {
763 public:
764 AutoViewMatrixRestore() {
765 fDrawTarget = NULL;
766 }
767
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000768 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000769 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
770 GrAssert(NULL != target);
771 }
772
773 void set(GrDrawTarget* target) {
774 GrAssert(NULL != target);
775 if (NULL != fDrawTarget) {
776 fDrawTarget->setViewMatrix(fMatrix);
777 }
778 fDrawTarget = target;
779 fMatrix = target->getViewMatrix();
780 }
781
782 ~AutoViewMatrixRestore() {
783 if (NULL != fDrawTarget) {
784 fDrawTarget->setViewMatrix(fMatrix);
785 }
786 }
787
788 private:
789 GrDrawTarget* fDrawTarget;
790 GrMatrix fMatrix;
791 };
792
793 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000794
795 class AutoReleaseGeometry : ::GrNoncopyable {
796 public:
797 AutoReleaseGeometry(GrDrawTarget* target,
798 GrVertexLayout vertexLayout,
799 uint32_t vertexCount,
800 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000801 fTarget = NULL;
802 this->set(target, vertexLayout, vertexCount, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000803 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000804
805 AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000806 fTarget = NULL;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000807 }
808
reed@google.comac10a2d2010-12-22 21:39:39 +0000809 ~AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000810 if (NULL != fTarget) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000811 fTarget->releaseReservedGeometry();
812 }
813 }
814
bsalomon@google.com5782d712011-01-21 21:03:59 +0000815 bool set(GrDrawTarget* target,
816 GrVertexLayout vertexLayout,
817 uint32_t vertexCount,
818 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000819 if (NULL != fTarget) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000820 fTarget->releaseReservedGeometry();
821 }
822 fTarget = target;
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000823 if (NULL != fTarget) {
824 if (!fTarget->reserveAndLockGeometry(vertexLayout,
825 vertexCount,
826 indexCount,
827 &fVertices,
828 &fIndices)) {
829 fTarget = NULL;
830 }
831 }
832 return NULL != fTarget;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000833 }
834
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000835 bool succeeded() const { return NULL != fTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000836 void* vertices() const { return fVertices; }
837 void* indices() const { return fIndices; }
838
839 GrPoint* positions() const {
840 return static_cast<GrPoint*>(fVertices);
841 }
842
843 private:
844 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000845 void* fVertices;
846 void* fIndices;
847 };
848
849 ///////////////////////////////////////////////////////////////////////////
850
851 class AutoClipRestore : ::GrNoncopyable {
852 public:
853 AutoClipRestore(GrDrawTarget* target) {
854 fTarget = target;
855 fClip = fTarget->getClip();
856 }
857
858 ~AutoClipRestore() {
859 fTarget->setClip(fClip);
860 }
861 private:
862 GrDrawTarget* fTarget;
863 GrClip fClip;
864 };
865
866 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000867 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000868
reed@google.comac10a2d2010-12-22 21:39:39 +0000869 /**
870 * Helper function to compute the size of a vertex from a vertex layout
871 * @return size of a single vertex.
872 */
873 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000874
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000875 /**
876 * Helper function for determining the index of texture coordinates that
877 * is input for a texture stage. Note that a stage may instead use positions
878 * as texture coordinates, in which case the result of the function is
879 * indistinguishable from the case when the stage is disabled.
880 *
881 * @param stage the stage to query
882 * @param vertexLayout layout to query
883 *
884 * @return the texture coordinate index or -1 if the stage doesn't use
885 * separate (non-position) texture coordinates.
886 */
887 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000888
889 /**
890 * Helper function to compute the offset of texture coordinates in a vertex
891 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +0000892 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000893 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000894 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000895 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000896
897 /**
898 * Helper function to compute the offset of the color in a vertex
899 * @return offset of color in vertex layout or -1 if the
900 * layout has no color.
901 */
902 static int VertexColorOffset(GrVertexLayout vertexLayout);
903
904 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000905 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000906 * coordinates of some index.
907 *
908 * @param coordIndex the tex coord index to query
909 * @param vertexLayout layout to query
910 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000911 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000912 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000913 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000914 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000915 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000916
reed@google.comac10a2d2010-12-22 21:39:39 +0000917 /**
918 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000919 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000920 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000921 * @param stage the stage to query
922 * @param vertexLayout layout to query
923 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000924 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000925 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000926 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000927 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000928
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000929 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000930 * Helper function to compute the size of each vertex and the offsets of
931 * texture coordinates and color. Determines tex coord offsets by tex coord
932 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000933 * by StageTexCoordVertexLayoutBit.)
934 *
935 * @param vertexLayout the layout to query
936 * @param texCoordOffsetsByIdx after return it is the offset of each
937 * tex coord index in the vertex or -1 if
938 * index isn't used.
939 * @return size of a single vertex
940 */
941 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
942 int texCoordOffsetsByIdx[kMaxTexCoords],
943 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000944
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000945 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000946 * Helper function to compute the size of each vertex and the offsets of
947 * texture coordinates and color. Determines tex coord offsets by stage
948 * rather than by index. (Each stage can be mapped to any t.c. index
949 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000950 * tex coords then that stage's offset will be 0 (positions are always at 0).
951 *
952 * @param vertexLayout the layout to query
953 * @param texCoordOffsetsByStage after return it is the offset of each
954 * tex coord index in the vertex or -1 if
955 * index isn't used.
956 * @return size of a single vertex
957 */
958 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
959 int texCoordOffsetsByStage[kNumStages],
960 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000961
962 /**
963 * Accessing positions, texture coords, or colors, of a vertex within an
964 * array is a hassle involving casts and simple math. These helpers exist
965 * to keep GrDrawTarget clients' code a bit nicer looking.
966 */
967
968 /**
969 * Gets a pointer to a GrPoint of a vertex's position or texture
970 * coordinate.
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 component.
975 * Defaults to zero (corresponding to vertex position)
976 * @return pointer to the vertex component as a GrPoint
977 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000978 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000979 int vertexIndex,
980 int vertexSize,
981 int offset = 0) {
982 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000983 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000984 vertexIndex * vertexSize);
985 }
986 static const GrPoint* GetVertexPoint(const void* vertices,
987 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000988 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000989 int offset = 0) {
990 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000991 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000992 vertexIndex * vertexSize);
993 }
994
995 /**
996 * Gets a pointer to a GrColor inside a vertex within a vertex array.
997 * @param vertices the vetex array
998 * @param vertexIndex the index of the vertex in the array
999 * @param vertexSize the size of each vertex in the array
1000 * @param offset the offset in bytes of the vertex color
1001 * @return pointer to the vertex component as a GrColor
1002 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001003 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001004 int vertexIndex,
1005 int vertexSize,
1006 int offset) {
1007 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001008 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001009 vertexIndex * vertexSize);
1010 }
1011 static const GrColor* GetVertexColor(const void* vertices,
1012 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001013 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001014 int offset) {
1015 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001016 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001017 vertexIndex * vertexSize);
1018 }
1019
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001020 static void VertexLayoutUnitTest();
1021
reed@google.comac10a2d2010-12-22 21:39:39 +00001022protected:
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001023 // given a vertex layout and a draw state, will a stage be used?
1024 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1025 const DrState& state) {
1026 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1027 }
1028
1029 bool isStageEnabled(int stage) const {
1030 return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
1031 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001032
reed@google.comac10a2d2010-12-22 21:39:39 +00001033 // Helpers for GrDrawTarget subclasses that won't have private access to
1034 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001035 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001036 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001037 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001038 { return sds.fState; }
1039
1040 // implemented by subclass
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001041 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
1042 void** vertices,
1043 void** indices) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001044
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001045 virtual void onReleaseGeometry() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001046
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001047 // subclass overrides to be notified when clip is set.
1048 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001049
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001050 virtual void onSetVertexSourceToArray(const void* vertexArray,
1051 int vertexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001052
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001053 virtual void onSetIndexSourceToArray(const void* indexArray,
1054 int indexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001055
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001056 // Helpers for drawRect, protected so subclasses that override drawRect
1057 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001058 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001059 const GrRect* srcRects[]);
1060
1061 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001062 const GrMatrix* matrix,
1063 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001064 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001065 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001066 void* vertices);
1067
reed@google.comac10a2d2010-12-22 21:39:39 +00001068 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001069 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
1070 kArray_GeometrySrcType, // src was set using set*SourceToArray
1071 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +00001072 };
1073
bsalomon@google.comd302f142011-03-03 13:54:13 +00001074 struct ReservedGeometry {
reed@google.comac10a2d2010-12-22 21:39:39 +00001075 bool fLocked;
1076 uint32_t fVertexCount;
1077 uint32_t fIndexCount;
1078 } fReservedGeometry;
1079
1080 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001081 GeometrySrcType fVertexSrc;
1082 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
1083 GeometrySrcType fIndexSrc;
1084 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
1085 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +00001086 } fGeometrySrc;
1087
1088 GrClip fClip;
1089
reed@google.com8195f672011-01-12 18:14:28 +00001090 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001091
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001092 // Not meant for external use. Only setVertexSourceToBuffer and
1093 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
1094 // support nested reserveAndLockGeometry (and cpu arrays internally use the
1095 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +00001096 class AutoGeometrySrcRestore {
1097 public:
1098 AutoGeometrySrcRestore(GrDrawTarget* target) {
1099 fTarget = target;
1100 fGeometrySrc = fTarget->fGeometrySrc;
1101 }
1102 ~AutoGeometrySrcRestore() {
1103 fTarget->fGeometrySrc = fGeometrySrc;
1104 }
1105 private:
1106 GrDrawTarget *fTarget;
1107 GeometrySrc fGeometrySrc;
1108
1109 AutoGeometrySrcRestore();
1110 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
1111 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
1112 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001113};
1114
1115#endif