blob: 88782f16478c9fcfda579cf035ba2d78638caec0 [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.com5782d712011-01-21 21:03:59 +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
40 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000041 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000042 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000043 * lookups are specified by a texture (setTexture), a texture matrix
bsalomon@google.com5782d712011-01-21 21:03:59 +000044 * (setTextureMatrix), and a sampler (setSamplerState). Texture coordinates
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000045 * 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.
bsalomon@google.com5782d712011-01-21 21:03:59 +000047 * The presence or absence of texture coordinates for each stage in the
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000048 * vertex layout indicates whether a stage is enabled or not.
49 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000050 enum {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +000051 kNumStages = 2,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000052 kMaxTexCoords = kNumStages
53 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000054
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000055 /**
reed@google.comac10a2d2010-12-22 21:39:39 +000056 * Geometric primitives used for drawing.
57 */
58 enum PrimitiveType {
59 kTriangles_PrimitiveType,
60 kTriangleStrip_PrimitiveType,
61 kTriangleFan_PrimitiveType,
62 kPoints_PrimitiveType,
63 kLines_PrimitiveType,
64 kLineStrip_PrimitiveType
65 };
66
67 /**
68 * Flags that affect rendering. Controlled using enable/disableState(). All
69 * default to disabled.
70 */
71 enum StateBits {
72 kDither_StateBit = 0x1,//<! Perform color dithering
73 kAntialias_StateBit = 0x2,//<! Perform anti-aliasing. The render-
74 // target must support some form of AA
75 // (msaa, coverage sampling, etc). For
76 // GrGpu-created rendertarget/textures
77 // this is controlled by parameters
78 // passed to createTexture.
79 kClip_StateBit = 0x4,//<! Controls whether drawing is clipped
80 // against the region specified by
81 // setClip.
82 };
83
84 /**
85 * Coeffecients for alpha-blending.
86 */
87 enum BlendCoeff {
88 kZero_BlendCoeff, //<! 0
89 kOne_BlendCoeff, //<! 1
90 kSC_BlendCoeff, //<! src color
91 kISC_BlendCoeff, //<! one minus src color
92 kDC_BlendCoeff, //<! dst color
93 kIDC_BlendCoeff, //<! one minus dst color
94 kSA_BlendCoeff, //<! src alpha
95 kISA_BlendCoeff, //<! one minus src alpha
96 kDA_BlendCoeff, //<! dst alpha
97 kIDA_BlendCoeff, //<! one minus dst alpha
98 };
99
100 /**
101 * StencilPass
102 *
103 * Sets the stencil state for subsequent draw calls. Used to fill paths.
104 *
105 * Winding requires two passes when the GPU/API doesn't support separate
106 * stencil.
107 *
108 * The color pass for path fill is used to zero out stencil bits used for
109 * path filling. Every pixel covere by a winding/EO stencil pass must get
110 * covered by the color pass in order to leave stencil buffer in the correct
111 * state for the next path draw.
112 *
113 * NOTE: Stencil-based Winding fill has alias-to-zero problems. (e.g. A
114 * winding count of 128,256,512,etc with a 8 bit stencil buffer
115 * will be unfilled)
116 */
117 enum StencilPass {
118 kNone_StencilPass, //<! Not drawing a path or clip.
119 kEvenOddStencil_StencilPass, //<! records in/out in stencil buffer
120 // using the Even/Odd fill rule.
121 kEvenOddColor_StencilPass, //<! writes colors to color target in
122 // pixels marked inside the fill by
123 // kEOFillStencil_StencilPass. Clears
124 // stencil in pixels covered by
125 // geometry.
126 kWindingStencil1_StencilPass, //<! records in/out in stencil buffer
127 // using the Winding fill rule.
128 kWindingStencil2_StencilPass, //<! records in/out in stencil buffer
129 // using the Winding fill rule.
130 // Run when single-stencil-pass winding
131 // not supported (i.e. no separate
132 // stencil support)
133 kWindingColor_StencilPass, //<! writes colors to color target in
134 // pixels marked inside the fill by
135 // kWindFillStencil_StencilPass. Clears
136 // stencil in pixels covered by
137 // geometry.
138 kDrawTargetCount_StencilPass //<! Subclass may extend this enum to use
139 // the stencil for other purposes (e.g.
140 // to do stencil-based clipping)
141 // This value is provided as basis for
142 // defining these extended enum values.
143 };
144
145protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000146
reed@google.com8195f672011-01-12 18:14:28 +0000147 struct DrState {
reed@google.comac10a2d2010-12-22 21:39:39 +0000148 uint32_t fFlagBits;
149 BlendCoeff fSrcBlend;
150 BlendCoeff fDstBlend;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000151 GrTexture* fTextures[kNumStages];
152 GrSamplerState fSamplerStates[kNumStages];
reed@google.comac10a2d2010-12-22 21:39:39 +0000153 GrRenderTarget* fRenderTarget;
154 GrColor fColor;
reed@google.comac10a2d2010-12-22 21:39:39 +0000155 StencilPass fStencilPass;
156 bool fReverseFill;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000157 GrMatrix fViewMatrix;
158 GrMatrix fTextureMatrices[kNumStages];
reed@google.com8195f672011-01-12 18:14:28 +0000159 bool operator ==(const DrState& s) const {
160 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000161 }
reed@google.com8195f672011-01-12 18:14:28 +0000162 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000163 };
164
165public:
166 ///////////////////////////////////////////////////////////////////////////
167
168 GrDrawTarget();
169
170 /**
171 * Sets the current clip to the region specified by clip. All draws will be
172 * clipped against this clip if kClip_StateBit is enabled.
173 *
174 * @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 /**
221 * Sets the sampler state for the next draw.
222 *
223 * The sampler state determines the address wrap modes and
224 * filtering
225 *
226 * @param samplerState Specifies the sampler state.
227 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000228 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000229
230 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000231 * Sets the matrix applied to texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000232 *
233 * The post-matrix texture coordinates in the square [0,1]^2 cover the
234 * entire area of the texture. This means the full POT width when a NPOT
235 * texture is embedded in a POT width texture to meet the 3D API
236 * requirements. The texture matrix is applied both when the texture
237 * coordinates are explicit and when vertex positions are used as texture
238 * coordinates. In the latter case the texture matrix is applied to the
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000239 * pre-view-matrix position values.
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000241 * @param stage the stage for which to set a matrix.
242 * @param m the matrix used to transform the texture coordinates.
reed@google.comac10a2d2010-12-22 21:39:39 +0000243 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000244 void setTextureMatrix(int stage, const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000245
246 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000247 * Multiplies the current texture matrix for a stage by a matrix
248 *
249 * After this call T' = T*m where T is the old tex matrix,
250 * m is the parameter to this function, and T' is the new tex matrix.
251 * (We consider positions to be column vectors so tex cood vector t is
252 * transformed by matrix X as t' = X*t.)
253 *
254 * @param m the matrix used to modify the texture matrix matrix.
255 */
256 void concatTextureMatrix(int stage, const GrMatrix& m);
257
258 /**
259 * Retrieves the current texture matrix for a stage
260 * @param stage index of stage
261 * @return the stage's current texture matrix.
262 */
263 const GrMatrix& getTextureMatrix(int stage) const;
264
265 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000266 * Sets the matrix applied to veretx positions.
267 *
268 * In the post-view-matrix space the rectangle [0,w]x[0,h]
269 * fully covers the render target. (w and h are the width and height of the
270 * the rendertarget.)
271 *
272 * @param m the matrix used to transform the vertex positions.
273 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000274 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000275
276 /**
277 * Multiplies the current view matrix by a matrix
278 *
279 * After this call V' = V*m where V is the old view matrix,
280 * m is the parameter to this function, and V' is the new view matrix.
281 * (We consider positions to be column vectors so position vector p is
282 * transformed by matrix X as p' = X*p.)
283 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000284 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000285 */
286 void concatViewMatrix(const GrMatrix& m);
287
288 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000289 * Retrieves the current view matrix
290 * @return the current view matrix.
291 */
292 const GrMatrix& getViewMatrix() const;
293
294 /**
295 * Retrieves the inverse of the current view matrix.
296 *
297 * If the current view matrix is invertible, return true, and if matrix
298 * is non-null, copy the inverse into it. If the current view matrix is
299 * non-invertible, return false and ignore the matrix parameter.
300 *
301 * @param matrix if not null, will receive a copy of the current inverse.
302 */
303 bool getViewInverse(GrMatrix* matrix) const;
304
305 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000306 * Sets color for next draw to a premultiplied-alpha color.
307 *
308 * @param the color to set.
309 */
310 void setColor(GrColor);
311
312 /**
313 * Sets the color to be used for the next draw to be
314 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
315 *
316 * @param alpha The alpha value to set as the color.
317 */
318 void setAlpha(uint8_t alpha);
319
320 /**
321 * Sets pass for path rendering
322 *
323 * @param pass of path rendering
324 */
325 void setStencilPass(StencilPass pass);
326
327 /**
328 * Reveses the in/out decision of the fill rule for path rendering.
329 * Only affects kEOFillColor_StencilPass and kWindingFillColor_StencilPass
330 *
331 * @param reverse true to reverse, false otherwise
332 */
333 void setReverseFill(bool reverse);
334
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 {
350 return fCurrDrawState.fFlagBits & kDither_StateBit;
351 }
352
353 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000354 * Sets the blending function coeffecients.
355 *
356 * The blend function will be:
357 * D' = sat(S*srcCoef + D*dstCoef)
358 *
359 * where D is the existing destination color, S is the incoming source
360 * color, and D' is the new destination color that will be written. sat()
361 * is the saturation function.
362 *
363 * @param srcCoef coeffecient applied to the src color.
364 * @param dstCoef coeffecient applied to the dst color.
365 */
366 void setBlendFunc(BlendCoeff srcCoef, BlendCoeff dstCoef);
367
368 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000369 * Used to save and restore the GrGpu's drawing state
370 */
371 struct SavedDrawState {
372 private:
reed@google.com8195f672011-01-12 18:14:28 +0000373 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000374 friend class GrDrawTarget;
375 };
376
377 /**
378 * Saves the current draw state. The state can be restored at a later time
379 * with restoreDrawState.
380 *
381 * See also AutoStateRestore class.
382 *
383 * @param state will hold the state after the function returns.
384 */
385 void saveCurrentDrawState(SavedDrawState* state) const;
386
387 /**
388 * Restores previously saved draw state. The client guarantees that state
389 * was previously passed to saveCurrentDrawState and that the rendertarget
390 * and texture set at save are still valid.
391 *
392 * See also AutoStateRestore class.
393 *
394 * @param state the previously saved state to restore.
395 */
396 void restoreDrawState(const SavedDrawState& state);
397
398 /**
399 * Copies the draw state from another target to this target.
400 *
401 * @param srcTarget draw target used as src of the draw state.
402 */
403 void copyDrawState(const GrDrawTarget& srcTarget);
404
405 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000406 * The format of vertices is represented as a bitfield of flags.
407 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000408 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000409 * coordinates and per-vertex colors. Each stage can use any of the texture
410 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000411 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000412 * If no texture coordinates are specified for a stage then the stage is
413 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000414 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000415 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000416 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000417 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000418 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000419 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000420 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000421 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000422 * the order would be (position, texture coordinate 1[, color]).
423 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000424
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000425 /**
426 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000427 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000428 * @param stage the stage that will use texture coordinates.
429 * @param texCoordIdx the index of the texture coordinates to use
430 *
431 * @return the bit to add to a GrVertexLayout bitfield.
432 */
433 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
434 GrAssert(stage < kNumStages);
435 GrAssert(texCoordIdx < kMaxTexCoords);
436 return 1 << (stage + (texCoordIdx * kNumStages));
437 }
438private:
439 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
440public:
441 /**
442 * Generates a bit indicating that a texture stage uses the position
443 * as its texture coordinate.
444 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000445 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000446 * coordinates.
447 *
448 * @return the bit to add to a GrVertexLayout bitfield.
449 */
450 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
451 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000452 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000453 }
454private:
455 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000456
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000457public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000458
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000459 /**
460 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000461 */
462 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000463
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000464 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
465 //<! vertices have colors
466 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
467 //<! use text vertices. (Pos
468 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000469 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000470 // text [GrGpuTextVertex vs
471 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000472 // for below assert
473 kDummy,
474 kHighVertexLayoutBit = kDummy - 1
475 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000476 // make sure we haven't exceeded the number of bits in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000477 GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
478
479 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000480 * There are three paths for specifying geometry (vertices and optionally
481 * indices) to the draw target. When indexed drawing the indices and vertices
482 * can be each use a different path.
483 *
484 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
485 * caller's client has already provided vertex data in a format
486 * the time compatible with a GrVertexLayout. The array must contain the
487 * data at set*SourceToArray is called. The source stays in effect for
488 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
489 * again or one of the other two paths is chosen.
490 *
491 * 2. Reserve and Lock. This is most useful when the caller has data it must
492 * transform before drawing and will not likely render it again. The
493 * caller requests that the draw target make room for some amount of
494 * vertex and/or index data. The target provides ptrs to hold the data
495 * data. The caller can write the data into the pts up until the first
496 * drawIndexed or drawNonIndexed call. At this point the data is frozen
497 * and the ptrs are no longer guaranteed to be valid. All subsequent
498 * drawIndexed & drawNonIndexed calls will use this data until
499 * releaseReserved geometry is called. This must be called before another
500 * source is set.
501 *
502 * 3. Vertex and Index Buffers. This is most useful for geometry that will
503 * be rendered multiple times. SetVertexSourceToBuffer &
504 * SetIndexSourceToBuffer are used to set the buffer and subsequent
505 * drawIndexed and drawNonIndexed calls use this source until another
506 * source is set.
507 */
508
509 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000510 * Reserves space for vertices and/or indices. Draw target will use
511 * reserved vertices / indices at next draw.
512 *
513 * If succeeds:
514 * if vertexCount is nonzero, *vertices will be the array
515 * of vertices to be filled by caller. The next draw will read
516 * these vertices.
517 *
518 * if indecCount is nonzero, *indices will be the array of indices
519 * to be filled by caller. The next indexed draw will read from
520 * these indices.
521 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000522 * If a client does not already have a vertex buffer then this is the
523 * preferred way to allocate vertex/index array. It allows the subclass of
524 * GrDrawTarget to decide whether to put data in buffers, to group vertex
525 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000526 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000527 * Following the first draw after reserveAndLockGeometry the ptrs returned
528 * by releaseReservedGeometry are no longer valid and the geometry data
529 * cannot be further modified. The contents that were put in the reserved
530 * space can be drawn by multiple draws, however.
531 *
532 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
533 * call after all draws that reference the reserved geometry data have
534 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000535 *
536 * AutoGeometryRelease can be used to automatically call the release.
537 *
538 * @param vertexCount the number of vertices to reserve space for. Can be 0.
539 * @param indexCount the number of indices to reserve space for. Can be 0.
540 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
541 * @param vertices will point to reserved vertex space if vertexCount is
542 * non-zero. Illegal to pass NULL if vertexCount > 0.
543 * @param indices will point to reserved index space if indexCount is
544 * non-zero. Illegal to pass NULL if indexCount > 0.
545 *
546 * @return true if succeeded in allocating space for the vertices and false
547 * if not.
548 */
549 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
550 uint32_t vertexCount,
551 uint32_t indexCount,
552 void** vertices,
553 void** indices);
554 /**
555 * Provides hints to caller about the number of vertices and indices
556 * that can be allocated cheaply. This can be useful if caller is reserving
557 * space but doesn't know exactly how much geometry is needed.
558 *
559 * Also may hint whether the draw target should be flushed first. This is
560 * useful for deferred targets.
561 *
562 * @param vertexLayout layout of vertices caller would like to reserve
563 * @param vertexCount in: hint about how many vertices the caller would
564 * like to allocate.
565 * out: a hint about the number of vertices that can be
566 * allocated cheaply. Negative means no hint.
567 * Ignored if NULL.
568 * @param indexCount in: hint about how many indices the caller would
569 * like to allocate.
570 * out: a hint about the number of indices that can be
571 * allocated cheaply. Negative means no hint.
572 * Ignored if NULL.
573 *
574 * @return true if target should be flushed based on the input values.
575 */
576 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000577 int* vertexCount,
578 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000579
580 /**
581 * Releases reserved vertex/index data from reserveAndLockGeometry().
582 */
583 void releaseReservedGeometry();
584
585 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000586 * Sets source of vertex data for the next draw. Array must contain
587 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000588 *
589 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000590 * @param size size of the vertex data.
591 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000592 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000593 void setVertexSourceToArray(GrVertexLayout vertexLayout,
594 const void* vertexArray,
595 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000596
597 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000598 * Sets source of index data for the next indexed draw. Array must contain
599 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000600 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000601 * @param array cpu array containing index data.
602 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000603 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000604 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000605
606 /**
607 * Sets source of vertex data for the next draw. Data does not have to be
608 * in the buffer until drawIndexed or drawNonIndexed.
609 *
610 * @param buffer vertex buffer containing vertex data. Must be
611 * unlocked before draw call.
612 * @param vertexLayout layout of the vertex data in the buffer.
613 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000614 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
615 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000616
617 /**
618 * Sets source of index data for the next indexed draw. Data does not have
619 * to be in the buffer until drawIndexed or drawNonIndexed.
620 *
621 * @param buffer index buffer containing indices. Must be unlocked
622 * before indexed draw call.
623 */
624 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
625
626 /**
627 * Draws indexed geometry using the current state and current vertex / index
628 * sources.
629 *
630 * @param type The type of primitives to draw.
631 * @param startVertex the vertex in the vertex array/buffer corresponding
632 * to index 0
633 * @param startIndex first index to read from index src.
634 * @param vertexCount one greater than the max index.
635 * @param indexCount the number of index elements to read. The index count
636 * is effectively trimmed to the last completely
637 * specified primitive.
638 */
639 virtual void drawIndexed(PrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000640 int startVertex,
641 int startIndex,
642 int vertexCount,
643 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000644
645 /**
646 * Draws non-indexed geometry using the current state and current vertex
647 * sources.
648 *
649 * @param type The type of primitives to draw.
650 * @param startVertex the vertex in the vertex array/buffer corresponding
651 * to index 0
652 * @param vertexCount one greater than the max index.
653 */
654 virtual void drawNonIndexed(PrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000655 int startVertex,
656 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000657
658 ///////////////////////////////////////////////////////////////////////////
659
660 class AutoStateRestore : ::GrNoncopyable {
661 public:
662 AutoStateRestore(GrDrawTarget* target);
663 ~AutoStateRestore();
664
665 private:
666 GrDrawTarget* fDrawTarget;
667 SavedDrawState fDrawState;
668 };
669
670 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000671
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000672 class AutoViewMatrixRestore : ::GrNoncopyable {
673 public:
674 AutoViewMatrixRestore() {
675 fDrawTarget = NULL;
676 }
677
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000678 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000679 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
680 GrAssert(NULL != target);
681 }
682
683 void set(GrDrawTarget* target) {
684 GrAssert(NULL != target);
685 if (NULL != fDrawTarget) {
686 fDrawTarget->setViewMatrix(fMatrix);
687 }
688 fDrawTarget = target;
689 fMatrix = target->getViewMatrix();
690 }
691
692 ~AutoViewMatrixRestore() {
693 if (NULL != fDrawTarget) {
694 fDrawTarget->setViewMatrix(fMatrix);
695 }
696 }
697
698 private:
699 GrDrawTarget* fDrawTarget;
700 GrMatrix fMatrix;
701 };
702
703 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000704
705 class AutoReleaseGeometry : ::GrNoncopyable {
706 public:
707 AutoReleaseGeometry(GrDrawTarget* target,
708 GrVertexLayout vertexLayout,
709 uint32_t vertexCount,
710 uint32_t indexCount) {
711 fTarget = target;
712 fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
713 vertexCount,
714 indexCount,
715 &fVertices,
716 &fIndices);
717 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000718
719 AutoReleaseGeometry() {
720 fSuccess = false;
721 }
722
reed@google.comac10a2d2010-12-22 21:39:39 +0000723 ~AutoReleaseGeometry() {
724 if (fSuccess) {
725 fTarget->releaseReservedGeometry();
726 }
727 }
728
bsalomon@google.com5782d712011-01-21 21:03:59 +0000729 bool set(GrDrawTarget* target,
730 GrVertexLayout vertexLayout,
731 uint32_t vertexCount,
732 uint32_t indexCount) {
733 if (fSuccess) {
734 fTarget->releaseReservedGeometry();
735 }
736 fTarget = target;
737 fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
738 vertexCount,
739 indexCount,
740 &fVertices,
741 &fIndices);
742 return fSuccess;
743 }
744
reed@google.comac10a2d2010-12-22 21:39:39 +0000745 bool succeeded() const { return fSuccess; }
746 void* vertices() const { return fVertices; }
747 void* indices() const { return fIndices; }
748
749 GrPoint* positions() const {
750 return static_cast<GrPoint*>(fVertices);
751 }
752
753 private:
754 GrDrawTarget* fTarget;
755 bool fSuccess;
756 void* fVertices;
757 void* fIndices;
758 };
759
760 ///////////////////////////////////////////////////////////////////////////
761
762 class AutoClipRestore : ::GrNoncopyable {
763 public:
764 AutoClipRestore(GrDrawTarget* target) {
765 fTarget = target;
766 fClip = fTarget->getClip();
767 }
768
769 ~AutoClipRestore() {
770 fTarget->setClip(fClip);
771 }
772 private:
773 GrDrawTarget* fTarget;
774 GrClip fClip;
775 };
776
777 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000778 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000779
reed@google.comac10a2d2010-12-22 21:39:39 +0000780 /**
781 * Helper function to compute the size of a vertex from a vertex layout
782 * @return size of a single vertex.
783 */
784 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000785
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000786 /**
787 * Helper function for determining the index of texture coordinates that
788 * is input for a texture stage. Note that a stage may instead use positions
789 * as texture coordinates, in which case the result of the function is
790 * indistinguishable from the case when the stage is disabled.
791 *
792 * @param stage the stage to query
793 * @param vertexLayout layout to query
794 *
795 * @return the texture coordinate index or -1 if the stage doesn't use
796 * separate (non-position) texture coordinates.
797 */
798 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000799
800 /**
801 * Helper function to compute the offset of texture coordinates in a vertex
802 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +0000803 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000804 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000805 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000806 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000807
808 /**
809 * Helper function to compute the offset of the color in a vertex
810 * @return offset of color in vertex layout or -1 if the
811 * layout has no color.
812 */
813 static int VertexColorOffset(GrVertexLayout vertexLayout);
814
815 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000816 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000817 * coordinates of some index.
818 *
819 * @param coordIndex the tex coord index to query
820 * @param vertexLayout layout to query
821 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000822 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000823 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000824 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000825 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000826 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000827
reed@google.comac10a2d2010-12-22 21:39:39 +0000828 /**
829 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000830 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000831 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000832 * @param stage the stage to query
833 * @param vertexLayout layout to query
834 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000835 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000836 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000837 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000838 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000839
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000840 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000841 * Helper function to compute the size of each vertex and the offsets of
842 * texture coordinates and color. Determines tex coord offsets by tex coord
843 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000844 * by StageTexCoordVertexLayoutBit.)
845 *
846 * @param vertexLayout the layout to query
847 * @param texCoordOffsetsByIdx after return it is the offset of each
848 * tex coord index in the vertex or -1 if
849 * index isn't used.
850 * @return size of a single vertex
851 */
852 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
853 int texCoordOffsetsByIdx[kMaxTexCoords],
854 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000855
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000856 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000857 * Helper function to compute the size of each vertex and the offsets of
858 * texture coordinates and color. Determines tex coord offsets by stage
859 * rather than by index. (Each stage can be mapped to any t.c. index
860 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000861 * tex coords then that stage's offset will be 0 (positions are always at 0).
862 *
863 * @param vertexLayout the layout to query
864 * @param texCoordOffsetsByStage after return it is the offset of each
865 * tex coord index in the vertex or -1 if
866 * index isn't used.
867 * @return size of a single vertex
868 */
869 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
870 int texCoordOffsetsByStage[kNumStages],
871 int *colorOffset);
reed@google.comac10a2d2010-12-22 21:39:39 +0000872protected:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000873
reed@google.comac10a2d2010-12-22 21:39:39 +0000874 // Helpers for GrDrawTarget subclasses that won't have private access to
875 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +0000876 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +0000877 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +0000878 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +0000879 { return sds.fState; }
880
881 // implemented by subclass
882 virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
883 void** vertices,
884 void** indices) = 0;
885
886 virtual void releaseGeometryHelper() = 0;
887
888 virtual void clipWillChange(const GrClip& clip) = 0;
889
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000890 virtual void setVertexSourceToArrayHelper(const void* vertexArray,
891 int vertexCount) = 0;
892
893 virtual void setIndexSourceToArrayHelper(const void* indexArray,
894 int indexCount) = 0;
895
reed@google.comac10a2d2010-12-22 21:39:39 +0000896 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000897 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
898 kArray_GeometrySrcType, // src was set using set*SourceToArray
899 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +0000900 };
901
902 struct {
903 bool fLocked;
904 uint32_t fVertexCount;
905 uint32_t fIndexCount;
906 } fReservedGeometry;
907
908 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000909 GeometrySrcType fVertexSrc;
910 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
911 GeometrySrcType fIndexSrc;
912 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
913 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +0000914 } fGeometrySrc;
915
916 GrClip fClip;
917
reed@google.com8195f672011-01-12 18:14:28 +0000918 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000919
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000920 // Not meant for external use. Only setVertexSourceToBuffer and
921 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
922 // support nested reserveAndLockGeometry (and cpu arrays internally use the
923 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +0000924 class AutoGeometrySrcRestore {
925 public:
926 AutoGeometrySrcRestore(GrDrawTarget* target) {
927 fTarget = target;
928 fGeometrySrc = fTarget->fGeometrySrc;
929 }
930 ~AutoGeometrySrcRestore() {
931 fTarget->fGeometrySrc = fGeometrySrc;
932 }
933 private:
934 GrDrawTarget *fTarget;
935 GeometrySrc fGeometrySrc;
936
937 AutoGeometrySrcRestore();
938 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
939 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
940 };
941
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000942private:
943 void VertexLayoutUnitTest();
reed@google.comac10a2d2010-12-22 21:39:39 +0000944};
945
946#endif