blob: e8f17937598009c4ed3edfd295d303531efa16dc [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
Scroggo97c88c22011-05-11 14:05:25 +000029#include "SkXfermode.h"
30
reed@google.comac10a2d2010-12-22 21:39:39 +000031class GrTexture;
reed@google.comac10a2d2010-12-22 21:39:39 +000032class GrClipIterator;
33class GrVertexBuffer;
34class GrIndexBuffer;
junov@google.comf93e7172011-03-31 21:26:24 +000035class GrEffect;
reed@google.comac10a2d2010-12-22 21:39:39 +000036
37class GrDrawTarget : public GrRefCnt {
38public:
39 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +000040 * Number of texture stages. Each stage takes as input a color and
41 * 2D texture coordinates. The color input to the first enabled stage is the
42 * per-vertex color or the constant color (setColor/setAlpha) if there are
43 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000044 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000045 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000046 * lookups are specified by a texture a sampler (setSamplerState). Texture
47 * coordinates for each stage come from the vertices based on a
48 * GrVertexLayout bitfield. The output fragment color is the output color of
49 * the last enabled stage. The presence or absence of texture coordinates
50 * for each stage in the vertex layout indicates whether a stage is enabled
51 * or not.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000052 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000053 enum {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +000054 kNumStages = 2,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000055 kMaxTexCoords = kNumStages
56 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000057
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000058 /**
bsalomon@google.comffca4002011-02-22 20:34:01 +000059 * Bitfield used to indicate which stages are in use.
reed@google.comac10a2d2010-12-22 21:39:39 +000060 */
bsalomon@google.comffca4002011-02-22 20:34:01 +000061 typedef int StageBitfield;
62 GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
reed@google.comac10a2d2010-12-22 21:39:39 +000063
64 /**
65 * Flags that affect rendering. Controlled using enable/disableState(). All
66 * default to disabled.
67 */
68 enum StateBits {
69 kDither_StateBit = 0x1,//<! Perform color dithering
70 kAntialias_StateBit = 0x2,//<! Perform anti-aliasing. The render-
71 // target must support some form of AA
72 // (msaa, coverage sampling, etc). For
73 // GrGpu-created rendertarget/textures
74 // this is controlled by parameters
75 // passed to createTexture.
76 kClip_StateBit = 0x4,//<! Controls whether drawing is clipped
77 // against the region specified by
78 // setClip.
bsalomon@google.comd302f142011-03-03 13:54:13 +000079 kNoColorWrites_StateBit = 0x8,//<! If set it disables writing colors.
80 // Useful while performing stencil ops.
81
82 // subclass may use additional bits internally
83 kDummyStateBit,
84 kLastPublicStateBit = kDummyStateBit-1
85 };
86
87 enum DrawFace {
88 kBoth_DrawFace,
89 kCCW_DrawFace,
90 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +000091 };
92
93 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +000094 * The DrawTarget may reserve some of the high bits of the stencil. The draw
95 * target will automatically trim reference and mask values so that the
96 * client doesn't overwrite these bits.
97 * The number of bits available is relative to the currently set render
98 *target.
99 * @return the number of bits usable by the draw target client.
reed@google.comac10a2d2010-12-22 21:39:39 +0000100 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000101 int getUsableStencilBits() const {
102 int bits = fCurrDrawState.fRenderTarget->stencilBits();
103 if (bits) {
104 return bits - 1;
105 } else {
106 return 0;
107 }
108 }
109
110 /**
111 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000112 * Changing the clip has the side-effect of possibly zeroing
113 * out the client settable stencil bits. So multipass algorithms
114 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000115 * @param settings the stencil settings to use.
116 */
117 void setStencil(const GrStencilSettings& settings) {
118 fCurrDrawState.fStencilSettings = settings;
119 }
120
121 /**
122 * Shortcut to disable stencil testing and ops.
123 */
124 void disableStencil() {
125 fCurrDrawState.fStencilSettings.setDisabled();
126 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000127
128protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000129
reed@google.com8195f672011-01-12 18:14:28 +0000130 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000131 DrState() {
132 // make sure any pad is zero for memcmp
133 // all DrState members should default to something
134 // valid by the memset
135 memset(this, 0, sizeof(DrState));
Scroggo97c88c22011-05-11 14:05:25 +0000136 // This is an exception to our memset, since it will
137 // result in no change.
138 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000139 GrAssert((intptr_t)(void*)NULL == 0LL);
140 GrAssert(fStencilSettings.isDisabled());
141 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000142 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000143 GrBlendCoeff fSrcBlend;
144 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000145 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000146 GrTexture* fTextures[kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000147 GrEffect* fEffects[kNumStages];
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000148 GrSamplerState fSamplerStates[kNumStages];
149 GrRenderTarget* fRenderTarget;
150 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000151 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000152 GrColor fColorFilterColor;
153 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000154
155 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000156 GrMatrix fViewMatrix;
reed@google.com8195f672011-01-12 18:14:28 +0000157 bool operator ==(const DrState& s) const {
158 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000159 }
reed@google.com8195f672011-01-12 18:14:28 +0000160 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000161 };
162
163public:
164 ///////////////////////////////////////////////////////////////////////////
165
166 GrDrawTarget();
167
168 /**
169 * Sets the current clip to the region specified by clip. All draws will be
170 * clipped against this clip if kClip_StateBit is enabled.
171 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000172 * Setting the clip may (or may not) zero out the client's stencil bits.
173 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000174 * @param description of the clipping region
175 */
176 void setClip(const GrClip& clip);
177
178 /**
179 * Gets the current clip.
180 *
181 * @return the clip.
182 */
183 const GrClip& getClip() const;
184
185 /**
186 * Sets the texture used at the next drawing call
187 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000188 * @param stage The texture stage for which the texture will be set
189 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000190 * @param texture The texture to set. Can be NULL though there is no advantage
191 * to settings a NULL texture if doing non-textured drawing
192 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000193 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000194
195 /**
196 * Retrieves the currently set texture.
197 *
198 * @return The currently set texture. The return value will be NULL if no
199 * texture has been set, NULL was most recently passed to
200 * setTexture, or the last setTexture was destroyed.
201 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000202 const GrTexture* getTexture(int stage) const;
203 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000204
205 /**
206 * Sets the rendertarget used at the next drawing call
207 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000208 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000209 */
210 void setRenderTarget(GrRenderTarget* target);
211
212 /**
213 * Retrieves the currently set rendertarget.
214 *
215 * @return The currently set render target.
216 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000217 const GrRenderTarget* getRenderTarget() const;
218 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000219
220 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000221 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000222 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000223 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000224 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000225 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000226 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000227 * @param samplerState Specifies the sampler state.
228 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000229 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000230
231 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000232 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000233 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000234 * @param stage the stage of the sampler to set
235 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000236 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000237 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
238 GrAssert(stage >= 0 && stage < kNumStages);
239 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000240 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000241
242 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000243 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000244 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000245 * @param stage the stage to of sampler to get
246 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000247 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000248 const GrMatrix& getSamplerMatrix(int stage) const {
249 return fCurrDrawState.fSamplerStates[stage].getMatrix();
250 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000251
252 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000253 * Sets the matrix of a stage's sampler
254 *
255 * @param stage the stage of sampler set
256 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000257 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000258 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000259 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
260 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000261
262 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000263 * Sets the matrix applied to veretx positions.
264 *
265 * In the post-view-matrix space the rectangle [0,w]x[0,h]
266 * fully covers the render target. (w and h are the width and height of the
267 * the rendertarget.)
268 *
269 * @param m the matrix used to transform the vertex positions.
270 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000271 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000272
273 /**
274 * Multiplies the current view matrix by a matrix
275 *
276 * After this call V' = V*m where V is the old view matrix,
277 * m is the parameter to this function, and V' is the new view matrix.
278 * (We consider positions to be column vectors so position vector p is
279 * transformed by matrix X as p' = X*p.)
280 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000281 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000282 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000283 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000284
285 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000286 * Multiplies the current view matrix by a matrix
287 *
288 * After this call V' = m*V where V is the old view matrix,
289 * m is the parameter to this function, and V' is the new view matrix.
290 * (We consider positions to be column vectors so position vector p is
291 * transformed by matrix X as p' = X*p.)
292 *
293 * @param m the matrix used to modify the view matrix.
294 */
295 void postConcatViewMatrix(const GrMatrix& m);
296
297 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000298 * Retrieves the current view matrix
299 * @return the current view matrix.
300 */
301 const GrMatrix& getViewMatrix() const;
302
303 /**
304 * Retrieves the inverse of the current view matrix.
305 *
306 * If the current view matrix is invertible, return true, and if matrix
307 * is non-null, copy the inverse into it. If the current view matrix is
308 * non-invertible, return false and ignore the matrix parameter.
309 *
310 * @param matrix if not null, will receive a copy of the current inverse.
311 */
312 bool getViewInverse(GrMatrix* matrix) const;
313
314 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000315 * Sets color for next draw to a premultiplied-alpha color.
316 *
317 * @param the color to set.
318 */
319 void setColor(GrColor);
320
321 /**
Scroggo97c88c22011-05-11 14:05:25 +0000322 * Add a color filter that can be represented by a color and a mode.
323 */
324 void setColorFilter(GrColor, SkXfermode::Mode);
325
326 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000327 * Sets the color to be used for the next draw to be
328 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
329 *
330 * @param alpha The alpha value to set as the color.
331 */
332 void setAlpha(uint8_t alpha);
333
334 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000335 * Controls whether clockwise, counterclockwise, or both faces are drawn.
336 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000337 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000338 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000339
340 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000341 * Gets whether the target is drawing clockwise, counterclockwise,
342 * or both faces.
343 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000344 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000345 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000346
347 /**
348 * Enable render state settings.
349 *
350 * @param flags bitfield of StateBits specifing the states to enable
351 */
352 void enableState(uint32_t stateBits);
353
354 /**
355 * Disable render state settings.
356 *
357 * @param flags bitfield of StateBits specifing the states to disable
358 */
359 void disableState(uint32_t stateBits);
360
361 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000362 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
363 }
364
365 bool isClipState() const {
366 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000367 }
368
bsalomon@google.comd302f142011-03-03 13:54:13 +0000369 bool isColorWriteDisabled() const {
370 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
371 }
372
reed@google.comac10a2d2010-12-22 21:39:39 +0000373 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000374 * Sets the blending function coeffecients.
375 *
376 * The blend function will be:
377 * D' = sat(S*srcCoef + D*dstCoef)
378 *
379 * where D is the existing destination color, S is the incoming source
380 * color, and D' is the new destination color that will be written. sat()
381 * is the saturation function.
382 *
383 * @param srcCoef coeffecient applied to the src color.
384 * @param dstCoef coeffecient applied to the dst color.
385 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000386 void setBlendFunc(GrBlendCoeff srcCoef, GrBlendCoeff dstCoef);
reed@google.comac10a2d2010-12-22 21:39:39 +0000387
388 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000389 * Sets the blending function constant referenced by the following blending
390 * coeffecients:
391 * kConstC_BlendCoeff
392 * kIConstC_BlendCoeff
393 * kConstA_BlendCoeff
394 * kIConstA_BlendCoeff
395 *
396 * @param constant the constant to set
397 */
398 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
399
400 /**
401 * Retrieves the last value set by setBlendConstant()
402 * @return the blending constant value
403 */
404 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
405
406 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000407 * Used to save and restore the GrGpu's drawing state
408 */
409 struct SavedDrawState {
410 private:
reed@google.com8195f672011-01-12 18:14:28 +0000411 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000412 friend class GrDrawTarget;
413 };
414
415 /**
416 * Saves the current draw state. The state can be restored at a later time
417 * with restoreDrawState.
418 *
419 * See also AutoStateRestore class.
420 *
421 * @param state will hold the state after the function returns.
422 */
423 void saveCurrentDrawState(SavedDrawState* state) const;
424
425 /**
426 * Restores previously saved draw state. The client guarantees that state
427 * was previously passed to saveCurrentDrawState and that the rendertarget
428 * and texture set at save are still valid.
429 *
430 * See also AutoStateRestore class.
431 *
432 * @param state the previously saved state to restore.
433 */
434 void restoreDrawState(const SavedDrawState& state);
435
436 /**
437 * Copies the draw state from another target to this target.
438 *
439 * @param srcTarget draw target used as src of the draw state.
440 */
441 void copyDrawState(const GrDrawTarget& srcTarget);
442
443 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000444 * The format of vertices is represented as a bitfield of flags.
445 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000446 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000447 * coordinates and per-vertex colors. Each stage can use any of the texture
448 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000449 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000450 * If no texture coordinates are specified for a stage then the stage is
451 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000452 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000453 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000454 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000455 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000456 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000457 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000458 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000459 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000460 * the order would be (position, texture coordinate 1[, color]).
461 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000462
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000463 /**
464 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000465 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000466 * @param stage the stage that will use texture coordinates.
467 * @param texCoordIdx the index of the texture coordinates to use
468 *
469 * @return the bit to add to a GrVertexLayout bitfield.
470 */
471 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
472 GrAssert(stage < kNumStages);
473 GrAssert(texCoordIdx < kMaxTexCoords);
474 return 1 << (stage + (texCoordIdx * kNumStages));
475 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000476
477 /**
478 * Determines if blend is effectively disabled.
479 *
480 * @return true if blend can be disabled without changing the rendering
481 * result given the current state including the vertex layout specified
482 * with the vertex source.
483 */
484 bool canDisableBlend() const;
485
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000486private:
487 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
488public:
489 /**
490 * Generates a bit indicating that a texture stage uses the position
491 * as its texture coordinate.
492 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000493 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000494 * coordinates.
495 *
496 * @return the bit to add to a GrVertexLayout bitfield.
497 */
498 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
499 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000500 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000501 }
502private:
503 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000504
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000505public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000506
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000507 /**
508 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000509 */
510 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000511
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000512 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
513 //<! vertices have colors
514 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
515 //<! use text vertices. (Pos
516 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000517 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000518 // text [GrGpuTextVertex vs
519 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000520 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000521 kDummyVertexLayoutBit,
522 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000523 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000524 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000525 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000526
527 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000528 * There are three paths for specifying geometry (vertices and optionally
529 * indices) to the draw target. When indexed drawing the indices and vertices
530 * can be each use a different path.
531 *
532 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
533 * caller's client has already provided vertex data in a format
534 * the time compatible with a GrVertexLayout. The array must contain the
535 * data at set*SourceToArray is called. The source stays in effect for
536 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
537 * again or one of the other two paths is chosen.
538 *
539 * 2. Reserve and Lock. This is most useful when the caller has data it must
540 * transform before drawing and will not likely render it again. The
541 * caller requests that the draw target make room for some amount of
542 * vertex and/or index data. The target provides ptrs to hold the data
543 * data. The caller can write the data into the pts up until the first
544 * drawIndexed or drawNonIndexed call. At this point the data is frozen
545 * and the ptrs are no longer guaranteed to be valid. All subsequent
546 * drawIndexed & drawNonIndexed calls will use this data until
547 * releaseReserved geometry is called. This must be called before another
548 * source is set.
549 *
550 * 3. Vertex and Index Buffers. This is most useful for geometry that will
551 * be rendered multiple times. SetVertexSourceToBuffer &
552 * SetIndexSourceToBuffer are used to set the buffer and subsequent
553 * drawIndexed and drawNonIndexed calls use this source until another
554 * source is set.
555 */
556
557 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000558 * Reserves space for vertices and/or indices. Draw target will use
559 * reserved vertices / indices at next draw.
560 *
561 * If succeeds:
562 * if vertexCount is nonzero, *vertices will be the array
563 * of vertices to be filled by caller. The next draw will read
564 * these vertices.
565 *
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000566 * if indexCount is nonzero, *indices will be the array of indices
reed@google.comac10a2d2010-12-22 21:39:39 +0000567 * to be filled by caller. The next indexed draw will read from
568 * these indices.
569 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000570 * If a client does not already have a vertex buffer then this is the
571 * preferred way to allocate vertex/index array. It allows the subclass of
572 * GrDrawTarget to decide whether to put data in buffers, to group vertex
573 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000574 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000575 * Following the first draw after reserveAndLockGeometry the ptrs returned
576 * by releaseReservedGeometry are no longer valid and the geometry data
577 * cannot be further modified. The contents that were put in the reserved
578 * space can be drawn by multiple draws, however.
579 *
580 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
581 * call after all draws that reference the reserved geometry data have
582 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000583 *
584 * AutoGeometryRelease can be used to automatically call the release.
585 *
586 * @param vertexCount the number of vertices to reserve space for. Can be 0.
587 * @param indexCount the number of indices to reserve space for. Can be 0.
588 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
589 * @param vertices will point to reserved vertex space if vertexCount is
590 * non-zero. Illegal to pass NULL if vertexCount > 0.
591 * @param indices will point to reserved index space if indexCount is
592 * non-zero. Illegal to pass NULL if indexCount > 0.
593 *
594 * @return true if succeeded in allocating space for the vertices and false
595 * if not.
596 */
597 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
598 uint32_t vertexCount,
599 uint32_t indexCount,
600 void** vertices,
601 void** indices);
602 /**
603 * Provides hints to caller about the number of vertices and indices
604 * that can be allocated cheaply. This can be useful if caller is reserving
605 * space but doesn't know exactly how much geometry is needed.
606 *
607 * Also may hint whether the draw target should be flushed first. This is
608 * useful for deferred targets.
609 *
610 * @param vertexLayout layout of vertices caller would like to reserve
611 * @param vertexCount in: hint about how many vertices the caller would
612 * like to allocate.
613 * out: a hint about the number of vertices that can be
614 * allocated cheaply. Negative means no hint.
615 * Ignored if NULL.
616 * @param indexCount in: hint about how many indices the caller would
617 * like to allocate.
618 * out: a hint about the number of indices that can be
619 * allocated cheaply. Negative means no hint.
620 * Ignored if NULL.
621 *
622 * @return true if target should be flushed based on the input values.
623 */
624 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000625 int* vertexCount,
626 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000627
628 /**
629 * Releases reserved vertex/index data from reserveAndLockGeometry().
630 */
631 void releaseReservedGeometry();
632
633 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000634 * Sets source of vertex data for the next draw. Array must contain
635 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000636 *
637 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000638 * @param size size of the vertex data.
639 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000640 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000641 void setVertexSourceToArray(GrVertexLayout vertexLayout,
642 const void* vertexArray,
643 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000644
645 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000646 * Sets source of index data for the next indexed draw. Array must contain
647 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000648 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000649 * @param array cpu array containing index data.
650 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000651 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000652 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000653
654 /**
655 * Sets source of vertex data for the next draw. Data does not have to be
656 * in the buffer until drawIndexed or drawNonIndexed.
657 *
658 * @param buffer vertex buffer containing vertex data. Must be
659 * unlocked before draw call.
660 * @param vertexLayout layout of the vertex data in the buffer.
661 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000662 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
663 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000664
665 /**
666 * Sets source of index data for the next indexed draw. Data does not have
667 * to be in the buffer until drawIndexed or drawNonIndexed.
668 *
669 * @param buffer index buffer containing indices. Must be unlocked
670 * before indexed draw call.
671 */
672 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
673
674 /**
675 * Draws indexed geometry using the current state and current vertex / index
676 * sources.
677 *
678 * @param type The type of primitives to draw.
679 * @param startVertex the vertex in the vertex array/buffer corresponding
680 * to index 0
681 * @param startIndex first index to read from index src.
682 * @param vertexCount one greater than the max index.
683 * @param indexCount the number of index elements to read. The index count
684 * is effectively trimmed to the last completely
685 * specified primitive.
686 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000687 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000688 int startVertex,
689 int startIndex,
690 int vertexCount,
691 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000692
693 /**
694 * Draws non-indexed geometry using the current state and current vertex
695 * sources.
696 *
697 * @param type The type of primitives to draw.
698 * @param startVertex the vertex in the vertex array/buffer corresponding
699 * to index 0
700 * @param vertexCount one greater than the max index.
701 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000702 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000703 int startVertex,
704 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000705
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000706 /**
707 * Helper function for drawing rects. This does not use the current index
708 * and vertex sources. After returning, the vertex and index sources may
709 * have changed. They should be reestablished before the next drawIndexed
710 * or drawNonIndexed. This cannot be called between reserving and releasing
711 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000712 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000713 * drawNonIndexed.
714 * @param rect the rect to draw
715 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000716 * @param stageEnableBitfield bitmask indicating which stages are enabled.
717 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000718 * @param srcRects specifies rects for stages enabled by stageEnableMask.
719 * if stageEnableMask bit i is 1, srcRects is not NULL,
720 * and srcRects[i] is not NULL, then srcRects[i] will be
721 * used as coordinates for stage i. Otherwise, if stage i
722 * is enabled then rect is used as the coordinates.
723 * @param srcMatrices optional matrices applied to srcRects. If
724 * srcRect[i] is non-NULL and srcMatrices[i] is
725 * non-NULL then srcRect[i] will be transformed by
726 * srcMatrix[i]. srcMatrices can be NULL when no
727 * srcMatrices are desired.
728 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000729 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000730 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000731 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000732 const GrRect* srcRects[],
733 const GrMatrix* srcMatrices[]);
734
735 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000736 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000737 * matrices.
738 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000739 void drawSimpleRect(const GrRect& rect,
740 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000741 StageBitfield stageEnableBitfield) {
742 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000743 }
744
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000745 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000746 * Clear the render target. Ignores the clip and all other draw state
747 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
748 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000749 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000750 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000751
reed@google.comac10a2d2010-12-22 21:39:39 +0000752 ///////////////////////////////////////////////////////////////////////////
753
754 class AutoStateRestore : ::GrNoncopyable {
755 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000756 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000757 AutoStateRestore(GrDrawTarget* target);
758 ~AutoStateRestore();
759
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000760 /**
761 * if this object is already saving state for param target then
762 * this does nothing. Otherise, it restores previously saved state on
763 * previous target (if any) and saves current state on param target.
764 */
765 void set(GrDrawTarget* target);
766
reed@google.comac10a2d2010-12-22 21:39:39 +0000767 private:
768 GrDrawTarget* fDrawTarget;
769 SavedDrawState fDrawState;
770 };
771
772 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000773
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000774 class AutoViewMatrixRestore : ::GrNoncopyable {
775 public:
776 AutoViewMatrixRestore() {
777 fDrawTarget = NULL;
778 }
779
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000780 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000781 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
782 GrAssert(NULL != target);
783 }
784
785 void set(GrDrawTarget* target) {
786 GrAssert(NULL != target);
787 if (NULL != fDrawTarget) {
788 fDrawTarget->setViewMatrix(fMatrix);
789 }
790 fDrawTarget = target;
791 fMatrix = target->getViewMatrix();
792 }
793
794 ~AutoViewMatrixRestore() {
795 if (NULL != fDrawTarget) {
796 fDrawTarget->setViewMatrix(fMatrix);
797 }
798 }
799
800 private:
801 GrDrawTarget* fDrawTarget;
802 GrMatrix fMatrix;
803 };
804
805 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000806
807 class AutoReleaseGeometry : ::GrNoncopyable {
808 public:
809 AutoReleaseGeometry(GrDrawTarget* target,
810 GrVertexLayout vertexLayout,
811 uint32_t vertexCount,
812 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000813 fTarget = NULL;
814 this->set(target, vertexLayout, vertexCount, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000815 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000816
817 AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000818 fTarget = NULL;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000819 }
820
reed@google.comac10a2d2010-12-22 21:39:39 +0000821 ~AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000822 if (NULL != fTarget) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000823 fTarget->releaseReservedGeometry();
824 }
825 }
826
bsalomon@google.com5782d712011-01-21 21:03:59 +0000827 bool set(GrDrawTarget* target,
828 GrVertexLayout vertexLayout,
829 uint32_t vertexCount,
830 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000831 if (NULL != fTarget) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000832 fTarget->releaseReservedGeometry();
833 }
834 fTarget = target;
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000835 if (NULL != fTarget) {
836 if (!fTarget->reserveAndLockGeometry(vertexLayout,
837 vertexCount,
838 indexCount,
839 &fVertices,
840 &fIndices)) {
841 fTarget = NULL;
842 }
843 }
844 return NULL != fTarget;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000845 }
846
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000847 bool succeeded() const { return NULL != fTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000848 void* vertices() const { return fVertices; }
849 void* indices() const { return fIndices; }
850
851 GrPoint* positions() const {
852 return static_cast<GrPoint*>(fVertices);
853 }
854
855 private:
856 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000857 void* fVertices;
858 void* fIndices;
859 };
860
861 ///////////////////////////////////////////////////////////////////////////
862
863 class AutoClipRestore : ::GrNoncopyable {
864 public:
865 AutoClipRestore(GrDrawTarget* target) {
866 fTarget = target;
867 fClip = fTarget->getClip();
868 }
869
870 ~AutoClipRestore() {
871 fTarget->setClip(fClip);
872 }
873 private:
874 GrDrawTarget* fTarget;
875 GrClip fClip;
876 };
877
878 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000879 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000880
reed@google.comac10a2d2010-12-22 21:39:39 +0000881 /**
882 * Helper function to compute the size of a vertex from a vertex layout
883 * @return size of a single vertex.
884 */
885 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000886
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000887 /**
888 * Helper function for determining the index of texture coordinates that
889 * is input for a texture stage. Note that a stage may instead use positions
890 * as texture coordinates, in which case the result of the function is
891 * indistinguishable from the case when the stage is disabled.
892 *
893 * @param stage the stage to query
894 * @param vertexLayout layout to query
895 *
896 * @return the texture coordinate index or -1 if the stage doesn't use
897 * separate (non-position) texture coordinates.
898 */
899 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000900
901 /**
902 * Helper function to compute the offset of texture coordinates in a vertex
903 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +0000904 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000905 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000906 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000907 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000908
909 /**
910 * Helper function to compute the offset of the color in a vertex
911 * @return offset of color in vertex layout or -1 if the
912 * layout has no color.
913 */
914 static int VertexColorOffset(GrVertexLayout vertexLayout);
915
916 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000917 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000918 * coordinates of some index.
919 *
920 * @param coordIndex the tex coord index to query
921 * @param vertexLayout layout to query
922 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000923 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000924 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000925 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000926 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000927 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000928
reed@google.comac10a2d2010-12-22 21:39:39 +0000929 /**
930 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000931 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000932 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000933 * @param stage the stage to query
934 * @param vertexLayout layout to query
935 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000936 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000937 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000938 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000939 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000940
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000941 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000942 * Helper function to compute the size of each vertex and the offsets of
943 * texture coordinates and color. Determines tex coord offsets by tex coord
944 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000945 * by StageTexCoordVertexLayoutBit.)
946 *
947 * @param vertexLayout the layout to query
948 * @param texCoordOffsetsByIdx after return it is the offset of each
949 * tex coord index in the vertex or -1 if
950 * index isn't used.
951 * @return size of a single vertex
952 */
953 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
954 int texCoordOffsetsByIdx[kMaxTexCoords],
955 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000956
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000957 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000958 * Helper function to compute the size of each vertex and the offsets of
959 * texture coordinates and color. Determines tex coord offsets by stage
960 * rather than by index. (Each stage can be mapped to any t.c. index
961 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000962 * tex coords then that stage's offset will be 0 (positions are always at 0).
963 *
964 * @param vertexLayout the layout to query
965 * @param texCoordOffsetsByStage after return it is the offset of each
966 * tex coord index in the vertex or -1 if
967 * index isn't used.
968 * @return size of a single vertex
969 */
970 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
971 int texCoordOffsetsByStage[kNumStages],
972 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000973
974 /**
975 * Accessing positions, texture coords, or colors, of a vertex within an
976 * array is a hassle involving casts and simple math. These helpers exist
977 * to keep GrDrawTarget clients' code a bit nicer looking.
978 */
979
980 /**
981 * Gets a pointer to a GrPoint of a vertex's position or texture
982 * coordinate.
983 * @param vertices the vetex array
984 * @param vertexIndex the index of the vertex in the array
985 * @param vertexSize the size of each vertex in the array
986 * @param offset the offset in bytes of the vertex component.
987 * Defaults to zero (corresponding to vertex position)
988 * @return pointer to the vertex component as a GrPoint
989 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000990 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000991 int vertexIndex,
992 int vertexSize,
993 int offset = 0) {
994 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000995 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000996 vertexIndex * vertexSize);
997 }
998 static const GrPoint* GetVertexPoint(const void* vertices,
999 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001000 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001001 int offset = 0) {
1002 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001003 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001004 vertexIndex * vertexSize);
1005 }
1006
1007 /**
1008 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1009 * @param vertices the vetex array
1010 * @param vertexIndex the index of the vertex in the array
1011 * @param vertexSize the size of each vertex in the array
1012 * @param offset the offset in bytes of the vertex color
1013 * @return pointer to the vertex component as a GrColor
1014 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001015 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001016 int vertexIndex,
1017 int vertexSize,
1018 int offset) {
1019 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001020 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001021 vertexIndex * vertexSize);
1022 }
1023 static const GrColor* GetVertexColor(const void* vertices,
1024 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001025 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001026 int offset) {
1027 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001028 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001029 vertexIndex * vertexSize);
1030 }
1031
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001032 static void VertexLayoutUnitTest();
1033
reed@google.comac10a2d2010-12-22 21:39:39 +00001034protected:
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001035 // given a vertex layout and a draw state, will a stage be used?
1036 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1037 const DrState& state) {
1038 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1039 }
1040
1041 bool isStageEnabled(int stage) const {
1042 return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
1043 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001044
reed@google.comac10a2d2010-12-22 21:39:39 +00001045 // Helpers for GrDrawTarget subclasses that won't have private access to
1046 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001047 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001048 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001049 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001050 { return sds.fState; }
1051
1052 // implemented by subclass
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001053 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
1054 void** vertices,
1055 void** indices) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001056
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001057 virtual void onReleaseGeometry() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001058
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001059 // subclass overrides to be notified when clip is set.
1060 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001061
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001062 virtual void onSetVertexSourceToArray(const void* vertexArray,
1063 int vertexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001064
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001065 virtual void onSetIndexSourceToArray(const void* indexArray,
1066 int indexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001067
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001068 // Helpers for drawRect, protected so subclasses that override drawRect
1069 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001070 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001071 const GrRect* srcRects[]);
1072
1073 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001074 const GrMatrix* matrix,
1075 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001076 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001077 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001078 void* vertices);
1079
reed@google.comac10a2d2010-12-22 21:39:39 +00001080 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001081 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
1082 kArray_GeometrySrcType, // src was set using set*SourceToArray
1083 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +00001084 };
1085
bsalomon@google.comd302f142011-03-03 13:54:13 +00001086 struct ReservedGeometry {
reed@google.comac10a2d2010-12-22 21:39:39 +00001087 bool fLocked;
1088 uint32_t fVertexCount;
1089 uint32_t fIndexCount;
1090 } fReservedGeometry;
1091
1092 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001093 GeometrySrcType fVertexSrc;
1094 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
1095 GeometrySrcType fIndexSrc;
1096 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
1097 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +00001098 } fGeometrySrc;
1099
1100 GrClip fClip;
1101
reed@google.com8195f672011-01-12 18:14:28 +00001102 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001103
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001104 // Not meant for external use. Only setVertexSourceToBuffer and
1105 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
1106 // support nested reserveAndLockGeometry (and cpu arrays internally use the
1107 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +00001108 class AutoGeometrySrcRestore {
1109 public:
1110 AutoGeometrySrcRestore(GrDrawTarget* target) {
1111 fTarget = target;
1112 fGeometrySrc = fTarget->fGeometrySrc;
1113 }
1114 ~AutoGeometrySrcRestore() {
1115 fTarget->fGeometrySrc = fGeometrySrc;
1116 }
1117 private:
1118 GrDrawTarget *fTarget;
1119 GeometrySrc fGeometrySrc;
1120
1121 AutoGeometrySrcRestore();
1122 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
1123 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
1124 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001125};
1126
1127#endif