blob: 3405bb50c57d2e090c97e7ff3aaaeeca8168ab54 [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
21#include "GrScalar.h"
22#include "GrMatrix.h"
23#include "GrColor.h"
24#include "GrRefCnt.h"
25#include "GrSamplerState.h"
26#include "GrClip.h"
27
28class GrTexture;
29class GrRenderTarget;
30class GrClipIterator;
31class GrVertexBuffer;
32class GrIndexBuffer;
33
34class GrDrawTarget : public GrRefCnt {
35public:
36 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000037 * Number of texture stages. Each stage takes as input a color and
38 * 2D texture coordinates. The color input to the first enabled stage is the
39 * per-vertex color or the constant color (setColor/setAlpha) if there are no
40 * per-vertex colors. For subsequent stages the input color is the output
41 * color from the previous enabled stage. The output color of each stage is
42 * the input color modulated with the result of a texture lookup. Texture
43 * lookups are specified by a texture (setTexture), a texture matrix
44 * (setTextureMatrix), and a sampler (setSamplerState). Texture coordinates
45 * for each stage come from the vertices based on a GrVertexLayout bitfield.
46 * The output fragment color is the output color of the last enabled stage.
47 * The presence or absence of texture coordinates for each stage in the
48 * vertex layout indicates whether a stage is enabled or not.
49 */
50
51 // Currently there is just one stage but this will be changed soon.
52 enum {
53 kNumStages = 1,
54 kMaxTexCoords = kNumStages
55 };
56
57 /**
reed@google.comac10a2d2010-12-22 21:39:39 +000058 * Geometric primitives used for drawing.
59 */
60 enum PrimitiveType {
61 kTriangles_PrimitiveType,
62 kTriangleStrip_PrimitiveType,
63 kTriangleFan_PrimitiveType,
64 kPoints_PrimitiveType,
65 kLines_PrimitiveType,
66 kLineStrip_PrimitiveType
67 };
68
69 /**
70 * Flags that affect rendering. Controlled using enable/disableState(). All
71 * default to disabled.
72 */
73 enum StateBits {
74 kDither_StateBit = 0x1,//<! Perform color dithering
75 kAntialias_StateBit = 0x2,//<! Perform anti-aliasing. The render-
76 // target must support some form of AA
77 // (msaa, coverage sampling, etc). For
78 // GrGpu-created rendertarget/textures
79 // this is controlled by parameters
80 // passed to createTexture.
81 kClip_StateBit = 0x4,//<! Controls whether drawing is clipped
82 // against the region specified by
83 // setClip.
84 };
85
86 /**
87 * Coeffecients for alpha-blending.
88 */
89 enum BlendCoeff {
90 kZero_BlendCoeff, //<! 0
91 kOne_BlendCoeff, //<! 1
92 kSC_BlendCoeff, //<! src color
93 kISC_BlendCoeff, //<! one minus src color
94 kDC_BlendCoeff, //<! dst color
95 kIDC_BlendCoeff, //<! one minus dst color
96 kSA_BlendCoeff, //<! src alpha
97 kISA_BlendCoeff, //<! one minus src alpha
98 kDA_BlendCoeff, //<! dst alpha
99 kIDA_BlendCoeff, //<! one minus dst alpha
100 };
101
102 /**
103 * StencilPass
104 *
105 * Sets the stencil state for subsequent draw calls. Used to fill paths.
106 *
107 * Winding requires two passes when the GPU/API doesn't support separate
108 * stencil.
109 *
110 * The color pass for path fill is used to zero out stencil bits used for
111 * path filling. Every pixel covere by a winding/EO stencil pass must get
112 * covered by the color pass in order to leave stencil buffer in the correct
113 * state for the next path draw.
114 *
115 * NOTE: Stencil-based Winding fill has alias-to-zero problems. (e.g. A
116 * winding count of 128,256,512,etc with a 8 bit stencil buffer
117 * will be unfilled)
118 */
119 enum StencilPass {
120 kNone_StencilPass, //<! Not drawing a path or clip.
121 kEvenOddStencil_StencilPass, //<! records in/out in stencil buffer
122 // using the Even/Odd fill rule.
123 kEvenOddColor_StencilPass, //<! writes colors to color target in
124 // pixels marked inside the fill by
125 // kEOFillStencil_StencilPass. Clears
126 // stencil in pixels covered by
127 // geometry.
128 kWindingStencil1_StencilPass, //<! records in/out in stencil buffer
129 // using the Winding fill rule.
130 kWindingStencil2_StencilPass, //<! records in/out in stencil buffer
131 // using the Winding fill rule.
132 // Run when single-stencil-pass winding
133 // not supported (i.e. no separate
134 // stencil support)
135 kWindingColor_StencilPass, //<! writes colors to color target in
136 // pixels marked inside the fill by
137 // kWindFillStencil_StencilPass. Clears
138 // stencil in pixels covered by
139 // geometry.
140 kDrawTargetCount_StencilPass //<! Subclass may extend this enum to use
141 // the stencil for other purposes (e.g.
142 // to do stencil-based clipping)
143 // This value is provided as basis for
144 // defining these extended enum values.
145 };
146
147protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000148
reed@google.com8195f672011-01-12 18:14:28 +0000149 struct DrState {
reed@google.comac10a2d2010-12-22 21:39:39 +0000150 uint32_t fFlagBits;
151 BlendCoeff fSrcBlend;
152 BlendCoeff fDstBlend;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000153 GrTexture* fTextures[kNumStages];
154 GrSamplerState fSamplerStates[kNumStages];
reed@google.comac10a2d2010-12-22 21:39:39 +0000155 GrRenderTarget* fRenderTarget;
156 GrColor fColor;
157 float fPointSize;
158 StencilPass fStencilPass;
159 bool fReverseFill;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000160 GrMatrix fViewMatrix;
161 GrMatrix fTextureMatrices[kNumStages];
reed@google.com8195f672011-01-12 18:14:28 +0000162 bool operator ==(const DrState& s) const {
163 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000164 }
reed@google.com8195f672011-01-12 18:14:28 +0000165 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000166 };
167
168public:
169 ///////////////////////////////////////////////////////////////////////////
170
171 GrDrawTarget();
172
173 /**
174 * Sets the current clip to the region specified by clip. All draws will be
175 * clipped against this clip if kClip_StateBit is enabled.
176 *
177 * @param description of the clipping region
178 */
179 void setClip(const GrClip& clip);
180
181 /**
182 * Gets the current clip.
183 *
184 * @return the clip.
185 */
186 const GrClip& getClip() const;
187
188 /**
189 * Sets the texture used at the next drawing call
190 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000191 * @param stage The texture stage for which the texture will be set
192 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000193 * @param texture The texture to set. Can be NULL though there is no advantage
194 * to settings a NULL texture if doing non-textured drawing
195 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000196 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000197
198 /**
199 * Retrieves the currently set texture.
200 *
201 * @return The currently set texture. The return value will be NULL if no
202 * texture has been set, NULL was most recently passed to
203 * setTexture, or the last setTexture was destroyed.
204 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000205 GrTexture* currentTexture(int stage) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000206
207 /**
208 * Sets the rendertarget used at the next drawing call
209 *
210 * @param target The render target to set. Must be a valid rendertarget.
211 * That is it is a value that was returned by
212 * currentRenderTarget() or GrTexture::asRenderTarget().
213 */
214 void setRenderTarget(GrRenderTarget* target);
215
216 /**
217 * Retrieves the currently set rendertarget.
218 *
219 * @return The currently set render target.
220 */
221 GrRenderTarget* currentRenderTarget() const;
222
223 /**
224 * Sets the sampler state for the next draw.
225 *
226 * The sampler state determines the address wrap modes and
227 * filtering
228 *
229 * @param samplerState Specifies the sampler state.
230 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000231 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000232
233 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000234 * Sets the matrix applied to texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000235 *
236 * The post-matrix texture coordinates in the square [0,1]^2 cover the
237 * entire area of the texture. This means the full POT width when a NPOT
238 * texture is embedded in a POT width texture to meet the 3D API
239 * requirements. The texture matrix is applied both when the texture
240 * coordinates are explicit and when vertex positions are used as texture
241 * coordinates. In the latter case the texture matrix is applied to the
242 * pre-modelview position values.
243 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000244 * @param stage the stage for which to set a matrix.
245 * @param m the matrix used to transform the texture coordinates.
reed@google.comac10a2d2010-12-22 21:39:39 +0000246 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000247 void setTextureMatrix(int stage, const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000248
249 /**
250 * Sets the matrix applied to veretx positions.
251 *
252 * In the post-view-matrix space the rectangle [0,w]x[0,h]
253 * fully covers the render target. (w and h are the width and height of the
254 * the rendertarget.)
255 *
256 * @param m the matrix used to transform the vertex positions.
257 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000258 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000259
260 /**
261 * Multiplies the current view matrix by a matrix
262 *
263 * After this call V' = V*m where V is the old view matrix,
264 * m is the parameter to this function, and V' is the new view matrix.
265 * (We consider positions to be column vectors so position vector p is
266 * transformed by matrix X as p' = X*p.)
267 *
268 * @param m the matrix used to modify the modelview matrix.
269 */
270 void concatViewMatrix(const GrMatrix& m);
271
272 /**
273 * Sets color for next draw to a premultiplied-alpha color.
274 *
275 * @param the color to set.
276 */
277 void setColor(GrColor);
278
279 /**
280 * Sets the color to be used for the next draw to be
281 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
282 *
283 * @param alpha The alpha value to set as the color.
284 */
285 void setAlpha(uint8_t alpha);
286
287 /**
288 * Sets pass for path rendering
289 *
290 * @param pass of path rendering
291 */
292 void setStencilPass(StencilPass pass);
293
294 /**
295 * Reveses the in/out decision of the fill rule for path rendering.
296 * Only affects kEOFillColor_StencilPass and kWindingFillColor_StencilPass
297 *
298 * @param reverse true to reverse, false otherwise
299 */
300 void setReverseFill(bool reverse);
301
302 /**
303 * Enable render state settings.
304 *
305 * @param flags bitfield of StateBits specifing the states to enable
306 */
307 void enableState(uint32_t stateBits);
308
309 /**
310 * Disable render state settings.
311 *
312 * @param flags bitfield of StateBits specifing the states to disable
313 */
314 void disableState(uint32_t stateBits);
315
316 bool isDitherState() const {
317 return fCurrDrawState.fFlagBits & kDither_StateBit;
318 }
319
320 /**
321 * Sets the size of points used the next time points are drawn.
322 *
323 * @param the point size
324 */
325 void setPointSize(float size);
326
327 /**
328 * Sets the blending function coeffecients.
329 *
330 * The blend function will be:
331 * D' = sat(S*srcCoef + D*dstCoef)
332 *
333 * where D is the existing destination color, S is the incoming source
334 * color, and D' is the new destination color that will be written. sat()
335 * is the saturation function.
336 *
337 * @param srcCoef coeffecient applied to the src color.
338 * @param dstCoef coeffecient applied to the dst color.
339 */
340 void setBlendFunc(BlendCoeff srcCoef, BlendCoeff dstCoef);
341
342 /**
343 * Retrieves the current view matrix
344 * @param matrix will be the current view matrix after return.
345 */
346 void getViewMatrix(GrMatrix* matrix) const;
347
348 /**
349 * Retrieves the inverse of the current view matrix.
350 *
351 * If the current view matrix is invertible, return true, and if matrix
352 * is non-null, copy the inverse into it. If the current view matrix is
353 * non-invertible, return false and ignore the matrix parameter.
354 *
355 * @param matrix if not null, will receive a copy of the current inverse.
356 */
357 bool getViewInverse(GrMatrix* matrix) const;
358
359 /**
360 * Used to save and restore the GrGpu's drawing state
361 */
362 struct SavedDrawState {
363 private:
reed@google.com8195f672011-01-12 18:14:28 +0000364 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000365 friend class GrDrawTarget;
366 };
367
368 /**
369 * Saves the current draw state. The state can be restored at a later time
370 * with restoreDrawState.
371 *
372 * See also AutoStateRestore class.
373 *
374 * @param state will hold the state after the function returns.
375 */
376 void saveCurrentDrawState(SavedDrawState* state) const;
377
378 /**
379 * Restores previously saved draw state. The client guarantees that state
380 * was previously passed to saveCurrentDrawState and that the rendertarget
381 * and texture set at save are still valid.
382 *
383 * See also AutoStateRestore class.
384 *
385 * @param state the previously saved state to restore.
386 */
387 void restoreDrawState(const SavedDrawState& state);
388
389 /**
390 * Copies the draw state from another target to this target.
391 *
392 * @param srcTarget draw target used as src of the draw state.
393 */
394 void copyDrawState(const GrDrawTarget& srcTarget);
395
396 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000397 * The format of vertices is represented as a bitfield of flags.
398 * Flags that indicate the layout of vertex data. Vertices always contain
399 * positions and may also contain up to kMaxTexCoords sets of 2D texture
400 * coordinates and per-vertex colors. Each stage can use any of the texture
401 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000402 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000403 * If no texture coordinates are specified for a stage then the stage is
404 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000405 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000406 * Only one type of texture coord can be specified per stage. For
407 * example StageTexCoordVertexLayoutBit(0, 2) and
408 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000409 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000410 * The order in memory is always (position, texture coord 0, ..., color)
411 * with any unused fields omitted. Note that this means that if only texture
412 * coordinates 1 is referenced then there is no texture coordinates 0 and
413 * the order would be (position, texture coordinate 1[, color]).
414 */
415
416 /**
417 * Generates a bit indicating that a texture stage uses texture coordinates
418 *
419 * @param stage the stage that will use texture coordinates.
420 * @param texCoordIdx the index of the texture coordinates to use
421 *
422 * @return the bit to add to a GrVertexLayout bitfield.
423 */
424 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
425 GrAssert(stage < kNumStages);
426 GrAssert(texCoordIdx < kMaxTexCoords);
427 return 1 << (stage + (texCoordIdx * kNumStages));
428 }
429private:
430 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
431public:
432 /**
433 * Generates a bit indicating that a texture stage uses the position
434 * as its texture coordinate.
435 *
436 * @param stage the stage that will use position as texture
437 * coordinates.
438 *
439 * @return the bit to add to a GrVertexLayout bitfield.
440 */
441 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
442 GrAssert(stage < kNumStages);
443 return (1 << (TEX_COORD_BIT_CNT + stage));
444 }
445private:
446 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
447
448public:
449
450 /**
451 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000452 */
453 enum VertexLayoutBits {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000454
455 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
456 //<! vertices have colors
457 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
458 //<! use text vertices. (Pos
459 // and tex coords may be
460 // a different type for
461 // text [GrGpuTextVertex vs
462 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000463 // for below assert
464 kDummy,
465 kHighVertexLayoutBit = kDummy - 1
466 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000467 // make sure we haven't exceeded the number of bits in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000468 GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
469
470 /**
471 * Reserves space for vertices and/or indices. Draw target will use
472 * reserved vertices / indices at next draw.
473 *
474 * If succeeds:
475 * if vertexCount is nonzero, *vertices will be the array
476 * of vertices to be filled by caller. The next draw will read
477 * these vertices.
478 *
479 * if indecCount is nonzero, *indices will be the array of indices
480 * to be filled by caller. The next indexed draw will read from
481 * these indices.
482 *
483 * If a client does not already have a vertex buffer or cpu arrays then this
484 * is the preferred way to allocate vertex/index array. It allows the
485 * subclass of GrDrawTarget to decide whether to put data in buffers, to
486 * group vertex data that uses the same state (e.g. for deferred rendering),
487 * etc.
488 *
489 * This must be matched with a releaseReservedGeometry call after all
490 * draws that reference the reserved geometry data have been called.
491 *
492 * AutoGeometryRelease can be used to automatically call the release.
493 *
494 * @param vertexCount the number of vertices to reserve space for. Can be 0.
495 * @param indexCount the number of indices to reserve space for. Can be 0.
496 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
497 * @param vertices will point to reserved vertex space if vertexCount is
498 * non-zero. Illegal to pass NULL if vertexCount > 0.
499 * @param indices will point to reserved index space if indexCount is
500 * non-zero. Illegal to pass NULL if indexCount > 0.
501 *
502 * @return true if succeeded in allocating space for the vertices and false
503 * if not.
504 */
505 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
506 uint32_t vertexCount,
507 uint32_t indexCount,
508 void** vertices,
509 void** indices);
510 /**
511 * Provides hints to caller about the number of vertices and indices
512 * that can be allocated cheaply. This can be useful if caller is reserving
513 * space but doesn't know exactly how much geometry is needed.
514 *
515 * Also may hint whether the draw target should be flushed first. This is
516 * useful for deferred targets.
517 *
518 * @param vertexLayout layout of vertices caller would like to reserve
519 * @param vertexCount in: hint about how many vertices the caller would
520 * like to allocate.
521 * out: a hint about the number of vertices that can be
522 * allocated cheaply. Negative means no hint.
523 * Ignored if NULL.
524 * @param indexCount in: hint about how many indices the caller would
525 * like to allocate.
526 * out: a hint about the number of indices that can be
527 * allocated cheaply. Negative means no hint.
528 * Ignored if NULL.
529 *
530 * @return true if target should be flushed based on the input values.
531 */
532 virtual bool geometryHints(GrVertexLayout vertexLayout,
533 int32_t* vertexCount,
534 int32_t* indexCount) const;
535
536 /**
537 * Releases reserved vertex/index data from reserveAndLockGeometry().
538 */
539 void releaseReservedGeometry();
540
541 /**
542 * Sets source of vertex data for the next draw. Data does not have to be
543 * in the array until drawIndexed or drawNonIndexed.
544 *
545 * @param array cpu array containing vertex data.
546 * @param vertexLayout layout of the vertex data in the array.
547 */
548 void setVertexSourceToArray(const void* array, GrVertexLayout vertexLayout);
549
550 /**
551 * Sets source of index data for the next indexed draw. Data does not have
552 * to be in the array until drawIndexed or drawNonIndexed.
553 *
554 * @param array cpu array containing index data.
555 */
556 void setIndexSourceToArray(const void* array);
557
558 /**
559 * Sets source of vertex data for the next draw. Data does not have to be
560 * in the buffer until drawIndexed or drawNonIndexed.
561 *
562 * @param buffer vertex buffer containing vertex data. Must be
563 * unlocked before draw call.
564 * @param vertexLayout layout of the vertex data in the buffer.
565 */
566 void setVertexSourceToBuffer(const GrVertexBuffer* buffer,
567 GrVertexLayout vertexLayout);
568
569 /**
570 * Sets source of index data for the next indexed draw. Data does not have
571 * to be in the buffer until drawIndexed or drawNonIndexed.
572 *
573 * @param buffer index buffer containing indices. Must be unlocked
574 * before indexed draw call.
575 */
576 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
577
578 /**
579 * Draws indexed geometry using the current state and current vertex / index
580 * sources.
581 *
582 * @param type The type of primitives to draw.
583 * @param startVertex the vertex in the vertex array/buffer corresponding
584 * to index 0
585 * @param startIndex first index to read from index src.
586 * @param vertexCount one greater than the max index.
587 * @param indexCount the number of index elements to read. The index count
588 * is effectively trimmed to the last completely
589 * specified primitive.
590 */
591 virtual void drawIndexed(PrimitiveType type,
592 uint32_t startVertex,
593 uint32_t startIndex,
594 uint32_t vertexCount,
595 uint32_t indexCount) = 0;
596
597 /**
598 * Draws non-indexed geometry using the current state and current vertex
599 * sources.
600 *
601 * @param type The type of primitives to draw.
602 * @param startVertex the vertex in the vertex array/buffer corresponding
603 * to index 0
604 * @param vertexCount one greater than the max index.
605 */
606 virtual void drawNonIndexed(PrimitiveType type,
607 uint32_t startVertex,
608 uint32_t vertexCount) = 0;
609
610 ///////////////////////////////////////////////////////////////////////////
611
612 class AutoStateRestore : ::GrNoncopyable {
613 public:
614 AutoStateRestore(GrDrawTarget* target);
615 ~AutoStateRestore();
616
617 private:
618 GrDrawTarget* fDrawTarget;
619 SavedDrawState fDrawState;
620 };
621
622 ///////////////////////////////////////////////////////////////////////////
623
624 class AutoReleaseGeometry : ::GrNoncopyable {
625 public:
626 AutoReleaseGeometry(GrDrawTarget* target,
627 GrVertexLayout vertexLayout,
628 uint32_t vertexCount,
629 uint32_t indexCount) {
630 fTarget = target;
631 fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
632 vertexCount,
633 indexCount,
634 &fVertices,
635 &fIndices);
636 }
637 ~AutoReleaseGeometry() {
638 if (fSuccess) {
639 fTarget->releaseReservedGeometry();
640 }
641 }
642
643 bool succeeded() const { return fSuccess; }
644 void* vertices() const { return fVertices; }
645 void* indices() const { return fIndices; }
646
647 GrPoint* positions() const {
648 return static_cast<GrPoint*>(fVertices);
649 }
650
651 private:
652 GrDrawTarget* fTarget;
653 bool fSuccess;
654 void* fVertices;
655 void* fIndices;
656 };
657
658 ///////////////////////////////////////////////////////////////////////////
659
660 class AutoClipRestore : ::GrNoncopyable {
661 public:
662 AutoClipRestore(GrDrawTarget* target) {
663 fTarget = target;
664 fClip = fTarget->getClip();
665 }
666
667 ~AutoClipRestore() {
668 fTarget->setClip(fClip);
669 }
670 private:
671 GrDrawTarget* fTarget;
672 GrClip fClip;
673 };
674
675 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000676 // Helpers for picking apart vertex layouts
677
reed@google.comac10a2d2010-12-22 21:39:39 +0000678 /**
679 * Helper function to compute the size of a vertex from a vertex layout
680 * @return size of a single vertex.
681 */
682 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000683
684 /**
685 * Helper function for determining the index of texture coordinates that
686 * is input for a texture stage. Note that a stage may instead use positions
687 * as texture coordinates, in which case the result of the function is
688 * indistinguishable from the case when the stage is disabled.
689 *
690 * @param stage the stage to query
691 * @param vertexLayout layout to query
692 *
693 * @return the texture coordinate index or -1 if the stage doesn't use
694 * separate (non-position) texture coordinates.
695 */
696 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000697
698 /**
699 * Helper function to compute the offset of texture coordinates in a vertex
700 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000701 * layout has no texture coordinates. Will be 0 if positions are
702 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000703 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000704 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000705
706 /**
707 * Helper function to compute the offset of the color in a vertex
708 * @return offset of color in vertex layout or -1 if the
709 * layout has no color.
710 */
711 static int VertexColorOffset(GrVertexLayout vertexLayout);
712
713 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000714 * Helper function to determine if vertex layout contains explicit texture
715 * coordinates of some index.
716 *
717 * @param coordIndex the tex coord index to query
718 * @param vertexLayout layout to query
719 *
720 * @return true if vertex specifies texture coordinates for the index,
721 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000722 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000723 static bool VertexUsesTexCoordIdx(int coordIndex,
724 GrVertexLayout vertexLayout);
725
reed@google.comac10a2d2010-12-22 21:39:39 +0000726 /**
727 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000728 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000729 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000730 * @param stage the stage to query
731 * @param vertexLayout layout to query
732 *
733 * @return true if vertex specifies texture coordinates for the stage,
734 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000735 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000736 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000737
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000738 /**
739 * Helper function to compute the size of each vertex and the offsets of
740 * texture coordinates and color. Determines tex coord offsets by tex coord
741 * index rather than by stage. (Each stage can be mapped to any t.c. index
742 * by StageTexCoordVertexLayoutBit.)
743 *
744 * @param vertexLayout the layout to query
745 * @param texCoordOffsetsByIdx after return it is the offset of each
746 * tex coord index in the vertex or -1 if
747 * index isn't used.
748 * @return size of a single vertex
749 */
750 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
751 int texCoordOffsetsByIdx[kMaxTexCoords],
752 int *colorOffset);
753
754 /**
755 * Helper function to compute the size of each vertex and the offsets of
756 * texture coordinates and color. Determines tex coord offsets by stage
757 * rather than by index. (Each stage can be mapped to any t.c. index
758 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
759 * tex coords then that stage's offset will be 0 (positions are always at 0).
760 *
761 * @param vertexLayout the layout to query
762 * @param texCoordOffsetsByStage after return it is the offset of each
763 * tex coord index in the vertex or -1 if
764 * index isn't used.
765 * @return size of a single vertex
766 */
767 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
768 int texCoordOffsetsByStage[kNumStages],
769 int *colorOffset);
reed@google.comac10a2d2010-12-22 21:39:39 +0000770protected:
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000771
reed@google.comac10a2d2010-12-22 21:39:39 +0000772 // Helpers for GrDrawTarget subclasses that won't have private access to
773 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +0000774 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +0000775 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +0000776 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +0000777 { return sds.fState; }
778
779 // implemented by subclass
780 virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
781 void** vertices,
782 void** indices) = 0;
783
784 virtual void releaseGeometryHelper() = 0;
785
786 virtual void clipWillChange(const GrClip& clip) = 0;
787
788 enum GeometrySrcType {
789 kArray_GeometrySrcType,
790 kReserved_GeometrySrcType,
791 kBuffer_GeometrySrcType
792 };
793
794 struct {
795 bool fLocked;
796 uint32_t fVertexCount;
797 uint32_t fIndexCount;
798 } fReservedGeometry;
799
800 struct GeometrySrc {
801 GeometrySrcType fVertexSrc;
802 union {
803 const GrVertexBuffer* fVertexBuffer;
804 const void* fVertexArray;
805 };
806 GeometrySrcType fIndexSrc;
807 union {
808 const GrIndexBuffer* fIndexBuffer;
809 const void* fIndexArray;
810 };
811 GrVertexLayout fVertexLayout;
812 } fGeometrySrc;
813
814 GrClip fClip;
815
reed@google.com8195f672011-01-12 18:14:28 +0000816 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000817
reed@google.comac10a2d2010-12-22 21:39:39 +0000818 // not meant for outside usage. Could cause problems if calls between
819 // the save and restore mess with reserved geometry state.
820 class AutoGeometrySrcRestore {
821 public:
822 AutoGeometrySrcRestore(GrDrawTarget* target) {
823 fTarget = target;
824 fGeometrySrc = fTarget->fGeometrySrc;
825 }
826 ~AutoGeometrySrcRestore() {
827 fTarget->fGeometrySrc = fGeometrySrc;
828 }
829 private:
830 GrDrawTarget *fTarget;
831 GeometrySrc fGeometrySrc;
832
833 AutoGeometrySrcRestore();
834 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
835 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
836 };
837
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000838private:
839 void VertexLayoutUnitTest();
reed@google.comac10a2d2010-12-22 21:39:39 +0000840};
841
842#endif