blob: 9a00b57386462c0f58c32093e11fefa8060fc101 [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;
35
36class GrDrawTarget : public GrRefCnt {
37public:
38 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +000039 * Number of texture stages. Each stage takes as input a color and
40 * 2D texture coordinates. The color input to the first enabled stage is the
41 * per-vertex color or the constant color (setColor/setAlpha) if there are
42 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000043 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000044 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000045 * lookups are specified by a texture a sampler (setSamplerState). Texture
46 * coordinates for each stage come from the vertices based on a
47 * GrVertexLayout bitfield. The output fragment color is the output color of
48 * the last enabled stage. The presence or absence of texture coordinates
49 * for each stage in the vertex layout indicates whether a stage is enabled
50 * or not.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000051 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000052 enum {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +000053 kNumStages = 2,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000054 kMaxTexCoords = kNumStages
55 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000056
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000057 /**
bsalomon@google.comffca4002011-02-22 20:34:01 +000058 * Bitfield used to indicate which stages are in use.
reed@google.comac10a2d2010-12-22 21:39:39 +000059 */
bsalomon@google.comffca4002011-02-22 20:34:01 +000060 typedef int StageBitfield;
61 GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
reed@google.comac10a2d2010-12-22 21:39:39 +000062
63 /**
64 * Flags that affect rendering. Controlled using enable/disableState(). All
65 * default to disabled.
66 */
67 enum StateBits {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000068 kDither_StateBit = 0x01, //<! Perform color dithering
69 kAntialias_StateBit = 0x02, //<! Perform anti-aliasing. The render-
reed@google.comac10a2d2010-12-22 21:39:39 +000070 // target must support some form of AA
71 // (msaa, coverage sampling, etc). For
72 // GrGpu-created rendertarget/textures
73 // this is controlled by parameters
74 // passed to createTexture.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000075 kClip_StateBit = 0x04, //<! Controls whether drawing is clipped
reed@google.comac10a2d2010-12-22 21:39:39 +000076 // against the region specified by
77 // setClip.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000078 kNoColorWrites_StateBit = 0x08, //<! If set it disables writing colors.
79 // Useful while performing stencil
80 // ops.
81 kEdgeAA_StateBit = 0x10, //<! Perform edge anti-aliasing.
82 // Requires the edges to be passed in
83 // setEdgeAAData().
bsalomon@google.comd302f142011-03-03 13:54:13 +000084
85 // subclass may use additional bits internally
86 kDummyStateBit,
87 kLastPublicStateBit = kDummyStateBit-1
88 };
89
90 enum DrawFace {
91 kBoth_DrawFace,
92 kCCW_DrawFace,
93 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +000094 };
95
96 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +000097 * The DrawTarget may reserve some of the high bits of the stencil. The draw
98 * target will automatically trim reference and mask values so that the
99 * client doesn't overwrite these bits.
100 * The number of bits available is relative to the currently set render
101 *target.
102 * @return the number of bits usable by the draw target client.
reed@google.comac10a2d2010-12-22 21:39:39 +0000103 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000104 int getUsableStencilBits() const {
105 int bits = fCurrDrawState.fRenderTarget->stencilBits();
106 if (bits) {
107 return bits - 1;
108 } else {
109 return 0;
110 }
111 }
112
113 /**
114 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000115 * Changing the clip has the side-effect of possibly zeroing
116 * out the client settable stencil bits. So multipass algorithms
117 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000118 * @param settings the stencil settings to use.
119 */
120 void setStencil(const GrStencilSettings& settings) {
121 fCurrDrawState.fStencilSettings = settings;
122 }
123
124 /**
125 * Shortcut to disable stencil testing and ops.
126 */
127 void disableStencil() {
128 fCurrDrawState.fStencilSettings.setDisabled();
129 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000130
131protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000132
reed@google.com8195f672011-01-12 18:14:28 +0000133 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000134 DrState() {
135 // make sure any pad is zero for memcmp
136 // all DrState members should default to something
137 // valid by the memset
138 memset(this, 0, sizeof(DrState));
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000139
140 // memset exceptions
Scroggo97c88c22011-05-11 14:05:25 +0000141 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000142 fFirstCoverageStage = kNumStages;
143
144 // pedantic assertion that our ptrs will
145 // be NULL (0 ptr is mem addr 0)
bsalomon@google.comd302f142011-03-03 13:54:13 +0000146 GrAssert((intptr_t)(void*)NULL == 0LL);
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000147
148 // default stencil setting should be disabled
bsalomon@google.comd302f142011-03-03 13:54:13 +0000149 GrAssert(fStencilSettings.isDisabled());
150 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000151 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000152 GrBlendCoeff fSrcBlend;
153 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000154 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000155 GrTexture* fTextures[kNumStages];
156 GrSamplerState fSamplerStates[kNumStages];
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000157 int fFirstCoverageStage;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000158 GrRenderTarget* fRenderTarget;
159 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000160 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000161 GrColor fColorFilterColor;
162 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000163
164 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000165 GrMatrix fViewMatrix;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000166 float fEdgeAAEdges[18];
reed@google.com8195f672011-01-12 18:14:28 +0000167 bool operator ==(const DrState& s) const {
168 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000169 }
reed@google.com8195f672011-01-12 18:14:28 +0000170 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000171 };
172
173public:
174 ///////////////////////////////////////////////////////////////////////////
175
176 GrDrawTarget();
177
178 /**
179 * Sets the current clip to the region specified by clip. All draws will be
180 * clipped against this clip if kClip_StateBit is enabled.
181 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000182 * Setting the clip may (or may not) zero out the client's stencil bits.
183 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000184 * @param description of the clipping region
185 */
186 void setClip(const GrClip& clip);
187
188 /**
189 * Gets the current clip.
190 *
191 * @return the clip.
192 */
193 const GrClip& getClip() const;
194
195 /**
196 * Sets the texture used at the next drawing call
197 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000198 * @param stage The texture stage for which the texture will be set
199 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000200 * @param texture The texture to set. Can be NULL though there is no advantage
201 * to settings a NULL texture if doing non-textured drawing
202 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000203 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000204
205 /**
206 * Retrieves the currently set texture.
207 *
208 * @return The currently set texture. The return value will be NULL if no
209 * texture has been set, NULL was most recently passed to
210 * setTexture, or the last setTexture was destroyed.
211 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000212 const GrTexture* getTexture(int stage) const;
213 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000214
215 /**
216 * Sets the rendertarget used at the next drawing call
217 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000218 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000219 */
220 void setRenderTarget(GrRenderTarget* target);
221
222 /**
223 * Retrieves the currently set rendertarget.
224 *
225 * @return The currently set render target.
226 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000227 const GrRenderTarget* getRenderTarget() const;
228 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000229
230 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000231 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000232 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000233 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000234 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000235 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000236 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000237 * @param samplerState Specifies the sampler state.
238 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000239 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000240
241 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000242 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000243 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000244 * @param stage the stage of the sampler to set
245 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000246 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000247 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
248 GrAssert(stage >= 0 && stage < kNumStages);
249 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000250 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000251
252 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000253 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000254 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000255 * @param stage the stage to of sampler to get
256 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000257 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000258 const GrMatrix& getSamplerMatrix(int stage) const {
259 return fCurrDrawState.fSamplerStates[stage].getMatrix();
260 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000261
262 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000263 * Sets the matrix of a stage's sampler
264 *
265 * @param stage the stage of sampler set
266 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000267 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000268 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000269 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
270 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000271
272 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000273 * Sets the matrix applied to veretx positions.
274 *
275 * In the post-view-matrix space the rectangle [0,w]x[0,h]
276 * fully covers the render target. (w and h are the width and height of the
277 * the rendertarget.)
278 *
279 * @param m the matrix used to transform the vertex positions.
280 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000281 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000282
283 /**
284 * Multiplies the current view matrix by a matrix
285 *
286 * After this call V' = V*m where V is the old view matrix,
287 * m is the parameter to this function, and V' is the new view matrix.
288 * (We consider positions to be column vectors so position vector p is
289 * transformed by matrix X as p' = X*p.)
290 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000291 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000292 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000293 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000294
295 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000296 * Multiplies the current view matrix by a matrix
297 *
298 * After this call V' = m*V where V is the old view matrix,
299 * m is the parameter to this function, and V' is the new view matrix.
300 * (We consider positions to be column vectors so position vector p is
301 * transformed by matrix X as p' = X*p.)
302 *
303 * @param m the matrix used to modify the view matrix.
304 */
305 void postConcatViewMatrix(const GrMatrix& m);
306
307 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000308 * Retrieves the current view matrix
309 * @return the current view matrix.
310 */
311 const GrMatrix& getViewMatrix() const;
312
313 /**
314 * Retrieves the inverse of the current view matrix.
315 *
316 * If the current view matrix is invertible, return true, and if matrix
317 * is non-null, copy the inverse into it. If the current view matrix is
318 * non-invertible, return false and ignore the matrix parameter.
319 *
320 * @param matrix if not null, will receive a copy of the current inverse.
321 */
322 bool getViewInverse(GrMatrix* matrix) const;
323
324 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000325 * Sets color for next draw to a premultiplied-alpha color.
326 *
327 * @param the color to set.
328 */
329 void setColor(GrColor);
330
331 /**
Scroggo97c88c22011-05-11 14:05:25 +0000332 * Add a color filter that can be represented by a color and a mode.
333 */
334 void setColorFilter(GrColor, SkXfermode::Mode);
335
336 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000337 * Sets the color to be used for the next draw to be
338 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
339 *
340 * @param alpha The alpha value to set as the color.
341 */
342 void setAlpha(uint8_t alpha);
343
344 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000345 * Controls whether clockwise, counterclockwise, or both faces are drawn.
346 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000347 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000348 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000349
350 /**
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000351 * A common pattern is to compute a color with the initial stages and then
352 * modulate that color by a coverage value in later stage(s) (AA, mask-
353 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
354 * computed based on the pre-coverage-modulated color. The division of
355 * stages between color-computing and coverage-computing is specified by
356 * this method. Initially this is kNumStages (all stages are color-
357 * computing).
358 */
359 void setFirstCoverageStage(int firstCoverageStage) {
360 fCurrDrawState.fFirstCoverageStage = firstCoverageStage;
361 }
362
363 /**
364 * Gets the index of the first coverage-computing stage.
365 */
366 int getFirstCoverageStage() const {
367 return fCurrDrawState.fFirstCoverageStage;
368 }
369
370 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000371 * Gets whether the target is drawing clockwise, counterclockwise,
372 * or both faces.
373 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000374 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000375 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000376
377 /**
378 * Enable render state settings.
379 *
380 * @param flags bitfield of StateBits specifing the states to enable
381 */
382 void enableState(uint32_t stateBits);
383
384 /**
385 * Disable render state settings.
386 *
387 * @param flags bitfield of StateBits specifing the states to disable
388 */
389 void disableState(uint32_t stateBits);
390
391 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000392 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
393 }
394
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000395 bool isAntialiasState() const {
396 return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
397 }
398
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000399 bool isClipState() const {
400 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000401 }
402
bsalomon@google.comd302f142011-03-03 13:54:13 +0000403 bool isColorWriteDisabled() const {
404 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
405 }
406
reed@google.comac10a2d2010-12-22 21:39:39 +0000407 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000408 * Sets the blending function coeffecients.
409 *
410 * The blend function will be:
411 * D' = sat(S*srcCoef + D*dstCoef)
412 *
413 * where D is the existing destination color, S is the incoming source
414 * color, and D' is the new destination color that will be written. sat()
415 * is the saturation function.
416 *
417 * @param srcCoef coeffecient applied to the src color.
418 * @param dstCoef coeffecient applied to the dst color.
419 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000420 void setBlendFunc(GrBlendCoeff srcCoef, GrBlendCoeff dstCoef);
reed@google.comac10a2d2010-12-22 21:39:39 +0000421
422 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000423 * Sets the blending function constant referenced by the following blending
424 * coeffecients:
425 * kConstC_BlendCoeff
426 * kIConstC_BlendCoeff
427 * kConstA_BlendCoeff
428 * kIConstA_BlendCoeff
429 *
430 * @param constant the constant to set
431 */
432 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
433
434 /**
435 * Retrieves the last value set by setBlendConstant()
436 * @return the blending constant value
437 */
438 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
439
440 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000441 * Used to save and restore the GrGpu's drawing state
442 */
443 struct SavedDrawState {
444 private:
reed@google.com8195f672011-01-12 18:14:28 +0000445 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000446 friend class GrDrawTarget;
447 };
448
449 /**
450 * Saves the current draw state. The state can be restored at a later time
451 * with restoreDrawState.
452 *
453 * See also AutoStateRestore class.
454 *
455 * @param state will hold the state after the function returns.
456 */
457 void saveCurrentDrawState(SavedDrawState* state) const;
458
459 /**
460 * Restores previously saved draw state. The client guarantees that state
461 * was previously passed to saveCurrentDrawState and that the rendertarget
462 * and texture set at save are still valid.
463 *
464 * See also AutoStateRestore class.
465 *
466 * @param state the previously saved state to restore.
467 */
468 void restoreDrawState(const SavedDrawState& state);
469
470 /**
471 * Copies the draw state from another target to this target.
472 *
473 * @param srcTarget draw target used as src of the draw state.
474 */
475 void copyDrawState(const GrDrawTarget& srcTarget);
476
477 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000478 * The format of vertices is represented as a bitfield of flags.
479 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000480 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000481 * coordinates and per-vertex colors. Each stage can use any of the texture
482 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000483 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000484 * If no texture coordinates are specified for a stage then the stage is
485 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000486 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000487 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000488 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000489 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000490 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000491 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000492 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000493 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000494 * the order would be (position, texture coordinate 1[, color]).
495 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000496
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000497 /**
498 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000499 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000500 * @param stage the stage that will use texture coordinates.
501 * @param texCoordIdx the index of the texture coordinates to use
502 *
503 * @return the bit to add to a GrVertexLayout bitfield.
504 */
505 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
506 GrAssert(stage < kNumStages);
507 GrAssert(texCoordIdx < kMaxTexCoords);
508 return 1 << (stage + (texCoordIdx * kNumStages));
509 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000510
511 /**
512 * Determines if blend is effectively disabled.
513 *
514 * @return true if blend can be disabled without changing the rendering
515 * result given the current state including the vertex layout specified
516 * with the vertex source.
517 */
518 bool canDisableBlend() const;
519
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000520 /**
521 * Sets the edge data required for edge antialiasing.
522 *
523 * @param edges 3 * 6 float values, representing the edge
524 * equations in Ax + By + C form
525 */
526 void setEdgeAAData(const float edges[18]);
527
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000528private:
529 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
530public:
531 /**
532 * Generates a bit indicating that a texture stage uses the position
533 * as its texture coordinate.
534 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000535 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000536 * coordinates.
537 *
538 * @return the bit to add to a GrVertexLayout bitfield.
539 */
540 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
541 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000542 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000543 }
544private:
545 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000546
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000547public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000548
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000549 /**
550 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000551 */
552 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000553
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000554 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
555 //<! vertices have colors
556 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
557 //<! use text vertices. (Pos
558 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000559 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000560 // text [GrGpuTextVertex vs
561 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000562 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000563 kDummyVertexLayoutBit,
564 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000565 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000566 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000567 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000568
569 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000570 * There are three paths for specifying geometry (vertices and optionally
571 * indices) to the draw target. When indexed drawing the indices and vertices
572 * can be each use a different path.
573 *
574 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
575 * caller's client has already provided vertex data in a format
576 * the time compatible with a GrVertexLayout. The array must contain the
577 * data at set*SourceToArray is called. The source stays in effect for
578 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
579 * again or one of the other two paths is chosen.
580 *
581 * 2. Reserve and Lock. This is most useful when the caller has data it must
582 * transform before drawing and will not likely render it again. The
583 * caller requests that the draw target make room for some amount of
584 * vertex and/or index data. The target provides ptrs to hold the data
585 * data. The caller can write the data into the pts up until the first
586 * drawIndexed or drawNonIndexed call. At this point the data is frozen
587 * and the ptrs are no longer guaranteed to be valid. All subsequent
588 * drawIndexed & drawNonIndexed calls will use this data until
589 * releaseReserved geometry is called. This must be called before another
590 * source is set.
591 *
592 * 3. Vertex and Index Buffers. This is most useful for geometry that will
593 * be rendered multiple times. SetVertexSourceToBuffer &
594 * SetIndexSourceToBuffer are used to set the buffer and subsequent
595 * drawIndexed and drawNonIndexed calls use this source until another
596 * source is set.
597 */
598
599 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000600 * Reserves space for vertices and/or indices. Draw target will use
601 * reserved vertices / indices at next draw.
602 *
603 * If succeeds:
604 * if vertexCount is nonzero, *vertices will be the array
605 * of vertices to be filled by caller. The next draw will read
606 * these vertices.
607 *
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000608 * if indexCount is nonzero, *indices will be the array of indices
reed@google.comac10a2d2010-12-22 21:39:39 +0000609 * to be filled by caller. The next indexed draw will read from
610 * these indices.
611 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000612 * If a client does not already have a vertex buffer then this is the
613 * preferred way to allocate vertex/index array. It allows the subclass of
614 * GrDrawTarget to decide whether to put data in buffers, to group vertex
615 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000616 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000617 * Following the first draw after reserveAndLockGeometry the ptrs returned
618 * by releaseReservedGeometry are no longer valid and the geometry data
619 * cannot be further modified. The contents that were put in the reserved
620 * space can be drawn by multiple draws, however.
621 *
622 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
623 * call after all draws that reference the reserved geometry data have
624 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000625 *
626 * AutoGeometryRelease can be used to automatically call the release.
627 *
628 * @param vertexCount the number of vertices to reserve space for. Can be 0.
629 * @param indexCount the number of indices to reserve space for. Can be 0.
630 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
631 * @param vertices will point to reserved vertex space if vertexCount is
632 * non-zero. Illegal to pass NULL if vertexCount > 0.
633 * @param indices will point to reserved index space if indexCount is
634 * non-zero. Illegal to pass NULL if indexCount > 0.
635 *
636 * @return true if succeeded in allocating space for the vertices and false
637 * if not.
638 */
639 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
640 uint32_t vertexCount,
641 uint32_t indexCount,
642 void** vertices,
643 void** indices);
644 /**
645 * Provides hints to caller about the number of vertices and indices
646 * that can be allocated cheaply. This can be useful if caller is reserving
647 * space but doesn't know exactly how much geometry is needed.
648 *
649 * Also may hint whether the draw target should be flushed first. This is
650 * useful for deferred targets.
651 *
652 * @param vertexLayout layout of vertices caller would like to reserve
653 * @param vertexCount in: hint about how many vertices the caller would
654 * like to allocate.
655 * out: a hint about the number of vertices that can be
656 * allocated cheaply. Negative means no hint.
657 * Ignored if NULL.
658 * @param indexCount in: hint about how many indices the caller would
659 * like to allocate.
660 * out: a hint about the number of indices that can be
661 * allocated cheaply. Negative means no hint.
662 * Ignored if NULL.
663 *
664 * @return true if target should be flushed based on the input values.
665 */
666 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000667 int* vertexCount,
668 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000669
670 /**
671 * Releases reserved vertex/index data from reserveAndLockGeometry().
672 */
673 void releaseReservedGeometry();
674
675 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000676 * Sets source of vertex data for the next draw. Array must contain
677 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000678 *
679 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000680 * @param size size of the vertex data.
681 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000682 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000683 void setVertexSourceToArray(GrVertexLayout vertexLayout,
684 const void* vertexArray,
685 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000686
687 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000688 * Sets source of index data for the next indexed draw. Array must contain
689 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000690 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000691 * @param array cpu array containing index data.
692 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000693 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000694 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000695
696 /**
697 * Sets source of vertex data for the next draw. Data does not have to be
698 * in the buffer until drawIndexed or drawNonIndexed.
699 *
700 * @param buffer vertex buffer containing vertex data. Must be
701 * unlocked before draw call.
702 * @param vertexLayout layout of the vertex data in the buffer.
703 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000704 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
705 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000706
707 /**
708 * Sets source of index data for the next indexed draw. Data does not have
709 * to be in the buffer until drawIndexed or drawNonIndexed.
710 *
711 * @param buffer index buffer containing indices. Must be unlocked
712 * before indexed draw call.
713 */
714 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
715
716 /**
717 * Draws indexed geometry using the current state and current vertex / index
718 * sources.
719 *
720 * @param type The type of primitives to draw.
721 * @param startVertex the vertex in the vertex array/buffer corresponding
722 * to index 0
723 * @param startIndex first index to read from index src.
724 * @param vertexCount one greater than the max index.
725 * @param indexCount the number of index elements to read. The index count
726 * is effectively trimmed to the last completely
727 * specified primitive.
728 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000729 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000730 int startVertex,
731 int startIndex,
732 int vertexCount,
733 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000734
735 /**
736 * Draws non-indexed geometry using the current state and current vertex
737 * sources.
738 *
739 * @param type The type of primitives to draw.
740 * @param startVertex the vertex in the vertex array/buffer corresponding
741 * to index 0
742 * @param vertexCount one greater than the max index.
743 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000744 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000745 int startVertex,
746 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000747
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000748 /**
749 * Helper function for drawing rects. This does not use the current index
750 * and vertex sources. After returning, the vertex and index sources may
751 * have changed. They should be reestablished before the next drawIndexed
752 * or drawNonIndexed. This cannot be called between reserving and releasing
753 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000754 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000755 * drawNonIndexed.
756 * @param rect the rect to draw
757 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000758 * @param stageEnableBitfield bitmask indicating which stages are enabled.
759 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000760 * @param srcRects specifies rects for stages enabled by stageEnableMask.
761 * if stageEnableMask bit i is 1, srcRects is not NULL,
762 * and srcRects[i] is not NULL, then srcRects[i] will be
763 * used as coordinates for stage i. Otherwise, if stage i
764 * is enabled then rect is used as the coordinates.
765 * @param srcMatrices optional matrices applied to srcRects. If
766 * srcRect[i] is non-NULL and srcMatrices[i] is
767 * non-NULL then srcRect[i] will be transformed by
768 * srcMatrix[i]. srcMatrices can be NULL when no
769 * srcMatrices are desired.
770 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000771 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000772 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000773 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000774 const GrRect* srcRects[],
775 const GrMatrix* srcMatrices[]);
776
777 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000778 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000779 * matrices.
780 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000781 void drawSimpleRect(const GrRect& rect,
782 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000783 StageBitfield stageEnableBitfield) {
784 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000785 }
786
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000787 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000788 * Clear the render target. Ignores the clip and all other draw state
789 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
790 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000791 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000792 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000793
reed@google.comac10a2d2010-12-22 21:39:39 +0000794 ///////////////////////////////////////////////////////////////////////////
795
796 class AutoStateRestore : ::GrNoncopyable {
797 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000798 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000799 AutoStateRestore(GrDrawTarget* target);
800 ~AutoStateRestore();
801
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000802 /**
803 * if this object is already saving state for param target then
804 * this does nothing. Otherise, it restores previously saved state on
805 * previous target (if any) and saves current state on param target.
806 */
807 void set(GrDrawTarget* target);
808
reed@google.comac10a2d2010-12-22 21:39:39 +0000809 private:
810 GrDrawTarget* fDrawTarget;
811 SavedDrawState fDrawState;
812 };
813
814 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000815
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000816 class AutoViewMatrixRestore : ::GrNoncopyable {
817 public:
818 AutoViewMatrixRestore() {
819 fDrawTarget = NULL;
820 }
821
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000822 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000823 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
824 GrAssert(NULL != target);
825 }
826
827 void set(GrDrawTarget* target) {
828 GrAssert(NULL != target);
829 if (NULL != fDrawTarget) {
830 fDrawTarget->setViewMatrix(fMatrix);
831 }
832 fDrawTarget = target;
833 fMatrix = target->getViewMatrix();
834 }
835
836 ~AutoViewMatrixRestore() {
837 if (NULL != fDrawTarget) {
838 fDrawTarget->setViewMatrix(fMatrix);
839 }
840 }
841
842 private:
843 GrDrawTarget* fDrawTarget;
844 GrMatrix fMatrix;
845 };
846
847 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000848
849 class AutoReleaseGeometry : ::GrNoncopyable {
850 public:
851 AutoReleaseGeometry(GrDrawTarget* target,
852 GrVertexLayout vertexLayout,
853 uint32_t vertexCount,
854 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000855 fTarget = NULL;
856 this->set(target, vertexLayout, vertexCount, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000857 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000858
859 AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000860 fTarget = NULL;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000861 }
862
reed@google.comac10a2d2010-12-22 21:39:39 +0000863 ~AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000864 if (NULL != fTarget) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000865 fTarget->releaseReservedGeometry();
866 }
867 }
868
bsalomon@google.com5782d712011-01-21 21:03:59 +0000869 bool set(GrDrawTarget* target,
870 GrVertexLayout vertexLayout,
871 uint32_t vertexCount,
872 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000873 if (NULL != fTarget) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000874 fTarget->releaseReservedGeometry();
875 }
876 fTarget = target;
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000877 if (NULL != fTarget) {
878 if (!fTarget->reserveAndLockGeometry(vertexLayout,
879 vertexCount,
880 indexCount,
881 &fVertices,
882 &fIndices)) {
883 fTarget = NULL;
884 }
885 }
886 return NULL != fTarget;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000887 }
888
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000889 bool succeeded() const { return NULL != fTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000890 void* vertices() const { return fVertices; }
891 void* indices() const { return fIndices; }
892
893 GrPoint* positions() const {
894 return static_cast<GrPoint*>(fVertices);
895 }
896
897 private:
898 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000899 void* fVertices;
900 void* fIndices;
901 };
902
903 ///////////////////////////////////////////////////////////////////////////
904
905 class AutoClipRestore : ::GrNoncopyable {
906 public:
907 AutoClipRestore(GrDrawTarget* target) {
908 fTarget = target;
909 fClip = fTarget->getClip();
910 }
911
912 ~AutoClipRestore() {
913 fTarget->setClip(fClip);
914 }
915 private:
916 GrDrawTarget* fTarget;
917 GrClip fClip;
918 };
919
920 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000921 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000922
reed@google.comac10a2d2010-12-22 21:39:39 +0000923 /**
924 * Helper function to compute the size of a vertex from a vertex layout
925 * @return size of a single vertex.
926 */
927 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000928
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000929 /**
930 * Helper function for determining the index of texture coordinates that
931 * is input for a texture stage. Note that a stage may instead use positions
932 * as texture coordinates, in which case the result of the function is
933 * indistinguishable from the case when the stage is disabled.
934 *
935 * @param stage the stage to query
936 * @param vertexLayout layout to query
937 *
938 * @return the texture coordinate index or -1 if the stage doesn't use
939 * separate (non-position) texture coordinates.
940 */
941 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000942
943 /**
944 * Helper function to compute the offset of texture coordinates in a vertex
945 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +0000946 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000947 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000948 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000949 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000950
951 /**
952 * Helper function to compute the offset of the color in a vertex
953 * @return offset of color in vertex layout or -1 if the
954 * layout has no color.
955 */
956 static int VertexColorOffset(GrVertexLayout vertexLayout);
957
958 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000959 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000960 * coordinates of some index.
961 *
962 * @param coordIndex the tex coord index to query
963 * @param vertexLayout layout to query
964 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000965 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000966 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000967 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000968 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000969 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000970
reed@google.comac10a2d2010-12-22 21:39:39 +0000971 /**
972 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000973 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000974 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000975 * @param stage the stage to query
976 * @param vertexLayout layout to query
977 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000978 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000979 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000980 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000981 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000982
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000983 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000984 * Helper function to compute the size of each vertex and the offsets of
985 * texture coordinates and color. Determines tex coord offsets by tex coord
986 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000987 * by StageTexCoordVertexLayoutBit.)
988 *
989 * @param vertexLayout the layout to query
990 * @param texCoordOffsetsByIdx after return it is the offset of each
991 * tex coord index in the vertex or -1 if
992 * index isn't used.
993 * @return size of a single vertex
994 */
995 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
996 int texCoordOffsetsByIdx[kMaxTexCoords],
997 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000998
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000999 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001000 * Helper function to compute the size of each vertex and the offsets of
1001 * texture coordinates and color. Determines tex coord offsets by stage
1002 * rather than by index. (Each stage can be mapped to any t.c. index
1003 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001004 * tex coords then that stage's offset will be 0 (positions are always at 0).
1005 *
1006 * @param vertexLayout the layout to query
1007 * @param texCoordOffsetsByStage after return it is the offset of each
1008 * tex coord index in the vertex or -1 if
1009 * index isn't used.
1010 * @return size of a single vertex
1011 */
1012 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1013 int texCoordOffsetsByStage[kNumStages],
1014 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001015
1016 /**
1017 * Accessing positions, texture coords, or colors, of a vertex within an
1018 * array is a hassle involving casts and simple math. These helpers exist
1019 * to keep GrDrawTarget clients' code a bit nicer looking.
1020 */
1021
1022 /**
1023 * Gets a pointer to a GrPoint of a vertex's position or texture
1024 * coordinate.
1025 * @param vertices the vetex array
1026 * @param vertexIndex the index of the vertex in the array
1027 * @param vertexSize the size of each vertex in the array
1028 * @param offset the offset in bytes of the vertex component.
1029 * Defaults to zero (corresponding to vertex position)
1030 * @return pointer to the vertex component as a GrPoint
1031 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001032 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001033 int vertexIndex,
1034 int vertexSize,
1035 int offset = 0) {
1036 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001037 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001038 vertexIndex * vertexSize);
1039 }
1040 static const GrPoint* GetVertexPoint(const void* vertices,
1041 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001042 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001043 int offset = 0) {
1044 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001045 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001046 vertexIndex * vertexSize);
1047 }
1048
1049 /**
1050 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1051 * @param vertices the vetex array
1052 * @param vertexIndex the index of the vertex in the array
1053 * @param vertexSize the size of each vertex in the array
1054 * @param offset the offset in bytes of the vertex color
1055 * @return pointer to the vertex component as a GrColor
1056 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001057 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001058 int vertexIndex,
1059 int vertexSize,
1060 int offset) {
1061 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001062 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001063 vertexIndex * vertexSize);
1064 }
1065 static const GrColor* GetVertexColor(const void* vertices,
1066 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001067 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001068 int offset) {
1069 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001070 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001071 vertexIndex * vertexSize);
1072 }
1073
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001074 static void VertexLayoutUnitTest();
1075
reed@google.comac10a2d2010-12-22 21:39:39 +00001076protected:
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001077 // given a vertex layout and a draw state, will a stage be used?
1078 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1079 const DrState& state) {
1080 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1081 }
1082
1083 bool isStageEnabled(int stage) const {
1084 return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
1085 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001086
reed@google.comac10a2d2010-12-22 21:39:39 +00001087 // Helpers for GrDrawTarget subclasses that won't have private access to
1088 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001089 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001090 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001091 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001092 { return sds.fState; }
1093
1094 // implemented by subclass
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001095 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
1096 void** vertices,
1097 void** indices) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001098
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001099 virtual void onReleaseGeometry() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001100
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001101 // subclass overrides to be notified when clip is set.
1102 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001103
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001104 virtual void onSetVertexSourceToArray(const void* vertexArray,
1105 int vertexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001106
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001107 virtual void onSetIndexSourceToArray(const void* indexArray,
1108 int indexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001109
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001110 // Helpers for drawRect, protected so subclasses that override drawRect
1111 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001112 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001113 const GrRect* srcRects[]);
1114
1115 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001116 const GrMatrix* matrix,
1117 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001118 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001119 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001120 void* vertices);
1121
reed@google.comac10a2d2010-12-22 21:39:39 +00001122 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001123 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
1124 kArray_GeometrySrcType, // src was set using set*SourceToArray
1125 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +00001126 };
1127
bsalomon@google.comd302f142011-03-03 13:54:13 +00001128 struct ReservedGeometry {
reed@google.comac10a2d2010-12-22 21:39:39 +00001129 bool fLocked;
1130 uint32_t fVertexCount;
1131 uint32_t fIndexCount;
1132 } fReservedGeometry;
1133
1134 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001135 GeometrySrcType fVertexSrc;
1136 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
1137 GeometrySrcType fIndexSrc;
1138 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
1139 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +00001140 } fGeometrySrc;
1141
1142 GrClip fClip;
1143
reed@google.com8195f672011-01-12 18:14:28 +00001144 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001145
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001146 // Not meant for external use. Only setVertexSourceToBuffer and
1147 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
1148 // support nested reserveAndLockGeometry (and cpu arrays internally use the
1149 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +00001150 class AutoGeometrySrcRestore {
1151 public:
1152 AutoGeometrySrcRestore(GrDrawTarget* target) {
1153 fTarget = target;
1154 fGeometrySrc = fTarget->fGeometrySrc;
1155 }
1156 ~AutoGeometrySrcRestore() {
1157 fTarget->fGeometrySrc = fGeometrySrc;
1158 }
1159 private:
1160 GrDrawTarget *fTarget;
1161 GeometrySrc fGeometrySrc;
1162
1163 AutoGeometrySrcRestore();
1164 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
1165 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
1166 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001167};
1168
1169#endif