blob: 93b381dd9f2a92054d093be8b42176acdabe6dec [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#ifndef GrDrawTarget_DEFINED
19#define GrDrawTarget_DEFINED
20
reed@google.comac10a2d2010-12-22 21:39:39 +000021#include "GrMatrix.h"
22#include "GrColor.h"
23#include "GrRefCnt.h"
24#include "GrSamplerState.h"
25#include "GrClip.h"
bsalomon@google.comd302f142011-03-03 13:54:13 +000026#include "GrTexture.h"
27#include "GrStencil.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000028
Scroggo97c88c22011-05-11 14:05:25 +000029#include "SkXfermode.h"
30
reed@google.comac10a2d2010-12-22 21:39:39 +000031class GrTexture;
reed@google.comac10a2d2010-12-22 21:39:39 +000032class GrClipIterator;
33class GrVertexBuffer;
34class GrIndexBuffer;
junov@google.comf93e7172011-03-31 21:26:24 +000035class GrEffect;
reed@google.comac10a2d2010-12-22 21:39:39 +000036
37class GrDrawTarget : public GrRefCnt {
38public:
39 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +000040 * Number of texture stages. Each stage takes as input a color and
41 * 2D texture coordinates. The color input to the first enabled stage is the
42 * per-vertex color or the constant color (setColor/setAlpha) if there are
43 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000044 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000045 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000046 * lookups are specified by a texture a sampler (setSamplerState). Texture
47 * coordinates for each stage come from the vertices based on a
48 * GrVertexLayout bitfield. The output fragment color is the output color of
49 * the last enabled stage. The presence or absence of texture coordinates
50 * for each stage in the vertex layout indicates whether a stage is enabled
51 * or not.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000052 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000053 enum {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +000054 kNumStages = 2,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000055 kMaxTexCoords = kNumStages
56 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000057
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000058 /**
bsalomon@google.comffca4002011-02-22 20:34:01 +000059 * Bitfield used to indicate which stages are in use.
reed@google.comac10a2d2010-12-22 21:39:39 +000060 */
bsalomon@google.comffca4002011-02-22 20:34:01 +000061 typedef int StageBitfield;
62 GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
reed@google.comac10a2d2010-12-22 21:39:39 +000063
64 /**
65 * Flags that affect rendering. Controlled using enable/disableState(). All
66 * default to disabled.
67 */
68 enum StateBits {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000069 kDither_StateBit = 0x01, //<! Perform color dithering
70 kAntialias_StateBit = 0x02, //<! Perform anti-aliasing. The render-
reed@google.comac10a2d2010-12-22 21:39:39 +000071 // target must support some form of AA
72 // (msaa, coverage sampling, etc). For
73 // GrGpu-created rendertarget/textures
74 // this is controlled by parameters
75 // passed to createTexture.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000076 kClip_StateBit = 0x04, //<! Controls whether drawing is clipped
reed@google.comac10a2d2010-12-22 21:39:39 +000077 // against the region specified by
78 // setClip.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000079 kNoColorWrites_StateBit = 0x08, //<! If set it disables writing colors.
80 // Useful while performing stencil
81 // ops.
82 kEdgeAA_StateBit = 0x10, //<! Perform edge anti-aliasing.
83 // Requires the edges to be passed in
84 // setEdgeAAData().
bsalomon@google.comd302f142011-03-03 13:54:13 +000085
86 // subclass may use additional bits internally
87 kDummyStateBit,
88 kLastPublicStateBit = kDummyStateBit-1
89 };
90
91 enum DrawFace {
92 kBoth_DrawFace,
93 kCCW_DrawFace,
94 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +000095 };
96
97 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +000098 * The DrawTarget may reserve some of the high bits of the stencil. The draw
99 * target will automatically trim reference and mask values so that the
100 * client doesn't overwrite these bits.
101 * The number of bits available is relative to the currently set render
102 *target.
103 * @return the number of bits usable by the draw target client.
reed@google.comac10a2d2010-12-22 21:39:39 +0000104 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000105 int getUsableStencilBits() const {
106 int bits = fCurrDrawState.fRenderTarget->stencilBits();
107 if (bits) {
108 return bits - 1;
109 } else {
110 return 0;
111 }
112 }
113
114 /**
115 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000116 * Changing the clip has the side-effect of possibly zeroing
117 * out the client settable stencil bits. So multipass algorithms
118 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000119 * @param settings the stencil settings to use.
120 */
121 void setStencil(const GrStencilSettings& settings) {
122 fCurrDrawState.fStencilSettings = settings;
123 }
124
125 /**
126 * Shortcut to disable stencil testing and ops.
127 */
128 void disableStencil() {
129 fCurrDrawState.fStencilSettings.setDisabled();
130 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000131
132protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000133
reed@google.com8195f672011-01-12 18:14:28 +0000134 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000135 DrState() {
136 // make sure any pad is zero for memcmp
137 // all DrState members should default to something
138 // valid by the memset
139 memset(this, 0, sizeof(DrState));
Scroggo97c88c22011-05-11 14:05:25 +0000140 // This is an exception to our memset, since it will
141 // result in no change.
142 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000143 GrAssert((intptr_t)(void*)NULL == 0LL);
144 GrAssert(fStencilSettings.isDisabled());
145 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000146 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000147 GrBlendCoeff fSrcBlend;
148 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000149 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000150 GrTexture* fTextures[kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000151 GrEffect* fEffects[kNumStages];
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000152 GrSamplerState fSamplerStates[kNumStages];
153 GrRenderTarget* fRenderTarget;
154 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000155 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000156 GrColor fColorFilterColor;
157 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000158
159 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000160 GrMatrix fViewMatrix;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000161 float fEdgeAAEdges[18];
reed@google.com8195f672011-01-12 18:14:28 +0000162 bool operator ==(const DrState& s) const {
163 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000164 }
reed@google.com8195f672011-01-12 18:14:28 +0000165 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000166 };
167
168public:
169 ///////////////////////////////////////////////////////////////////////////
170
171 GrDrawTarget();
172
173 /**
174 * Sets the current clip to the region specified by clip. All draws will be
175 * clipped against this clip if kClip_StateBit is enabled.
176 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000177 * Setting the clip may (or may not) zero out the client's stencil bits.
178 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000179 * @param description of the clipping region
180 */
181 void setClip(const GrClip& clip);
182
183 /**
184 * Gets the current clip.
185 *
186 * @return the clip.
187 */
188 const GrClip& getClip() const;
189
190 /**
191 * Sets the texture used at the next drawing call
192 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000193 * @param stage The texture stage for which the texture will be set
194 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000195 * @param texture The texture to set. Can be NULL though there is no advantage
196 * to settings a NULL texture if doing non-textured drawing
197 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000198 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000199
200 /**
201 * Retrieves the currently set texture.
202 *
203 * @return The currently set texture. The return value will be NULL if no
204 * texture has been set, NULL was most recently passed to
205 * setTexture, or the last setTexture was destroyed.
206 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000207 const GrTexture* getTexture(int stage) const;
208 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000209
210 /**
211 * Sets the rendertarget used at the next drawing call
212 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000213 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000214 */
215 void setRenderTarget(GrRenderTarget* target);
216
217 /**
218 * Retrieves the currently set rendertarget.
219 *
220 * @return The currently set render target.
221 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000222 const GrRenderTarget* getRenderTarget() const;
223 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000224
225 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000226 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000227 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000228 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000229 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000230 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000231 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000232 * @param samplerState Specifies the sampler state.
233 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000234 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000235
236 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000237 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000238 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000239 * @param stage the stage of the sampler to set
240 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000241 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000242 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
243 GrAssert(stage >= 0 && stage < kNumStages);
244 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000245 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000246
247 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000248 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000249 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000250 * @param stage the stage to of sampler to get
251 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000252 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000253 const GrMatrix& getSamplerMatrix(int stage) const {
254 return fCurrDrawState.fSamplerStates[stage].getMatrix();
255 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000256
257 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000258 * Sets the matrix of a stage's sampler
259 *
260 * @param stage the stage of sampler set
261 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000262 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000263 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000264 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
265 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000266
267 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000268 * Sets the matrix applied to veretx positions.
269 *
270 * In the post-view-matrix space the rectangle [0,w]x[0,h]
271 * fully covers the render target. (w and h are the width and height of the
272 * the rendertarget.)
273 *
274 * @param m the matrix used to transform the vertex positions.
275 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000276 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000277
278 /**
279 * Multiplies the current view matrix by a matrix
280 *
281 * After this call V' = V*m where V is the old view matrix,
282 * m is the parameter to this function, and V' is the new view matrix.
283 * (We consider positions to be column vectors so position vector p is
284 * transformed by matrix X as p' = X*p.)
285 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000286 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000287 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000288 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000289
290 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000291 * Multiplies the current view matrix by a matrix
292 *
293 * After this call V' = m*V where V is the old view matrix,
294 * m is the parameter to this function, and V' is the new view matrix.
295 * (We consider positions to be column vectors so position vector p is
296 * transformed by matrix X as p' = X*p.)
297 *
298 * @param m the matrix used to modify the view matrix.
299 */
300 void postConcatViewMatrix(const GrMatrix& m);
301
302 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000303 * Retrieves the current view matrix
304 * @return the current view matrix.
305 */
306 const GrMatrix& getViewMatrix() const;
307
308 /**
309 * Retrieves the inverse of the current view matrix.
310 *
311 * If the current view matrix is invertible, return true, and if matrix
312 * is non-null, copy the inverse into it. If the current view matrix is
313 * non-invertible, return false and ignore the matrix parameter.
314 *
315 * @param matrix if not null, will receive a copy of the current inverse.
316 */
317 bool getViewInverse(GrMatrix* matrix) const;
318
319 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000320 * Sets color for next draw to a premultiplied-alpha color.
321 *
322 * @param the color to set.
323 */
324 void setColor(GrColor);
325
326 /**
Scroggo97c88c22011-05-11 14:05:25 +0000327 * Add a color filter that can be represented by a color and a mode.
328 */
329 void setColorFilter(GrColor, SkXfermode::Mode);
330
331 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000332 * Sets the color to be used for the next draw to be
333 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
334 *
335 * @param alpha The alpha value to set as the color.
336 */
337 void setAlpha(uint8_t alpha);
338
339 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000340 * Controls whether clockwise, counterclockwise, or both faces are drawn.
341 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000342 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000343 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000344
345 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000346 * Gets whether the target is drawing clockwise, counterclockwise,
347 * or both faces.
348 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000349 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000350 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000351
352 /**
353 * Enable render state settings.
354 *
355 * @param flags bitfield of StateBits specifing the states to enable
356 */
357 void enableState(uint32_t stateBits);
358
359 /**
360 * Disable render state settings.
361 *
362 * @param flags bitfield of StateBits specifing the states to disable
363 */
364 void disableState(uint32_t stateBits);
365
366 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000367 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
368 }
369
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000370 bool isAntialiasState() const {
371 return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
372 }
373
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000374 bool isClipState() const {
375 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000376 }
377
bsalomon@google.comd302f142011-03-03 13:54:13 +0000378 bool isColorWriteDisabled() const {
379 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
380 }
381
reed@google.comac10a2d2010-12-22 21:39:39 +0000382 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000383 * Sets the blending function coeffecients.
384 *
385 * The blend function will be:
386 * D' = sat(S*srcCoef + D*dstCoef)
387 *
388 * where D is the existing destination color, S is the incoming source
389 * color, and D' is the new destination color that will be written. sat()
390 * is the saturation function.
391 *
392 * @param srcCoef coeffecient applied to the src color.
393 * @param dstCoef coeffecient applied to the dst color.
394 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000395 void setBlendFunc(GrBlendCoeff srcCoef, GrBlendCoeff dstCoef);
reed@google.comac10a2d2010-12-22 21:39:39 +0000396
397 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000398 * Sets the blending function constant referenced by the following blending
399 * coeffecients:
400 * kConstC_BlendCoeff
401 * kIConstC_BlendCoeff
402 * kConstA_BlendCoeff
403 * kIConstA_BlendCoeff
404 *
405 * @param constant the constant to set
406 */
407 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
408
409 /**
410 * Retrieves the last value set by setBlendConstant()
411 * @return the blending constant value
412 */
413 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
414
415 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000416 * Used to save and restore the GrGpu's drawing state
417 */
418 struct SavedDrawState {
419 private:
reed@google.com8195f672011-01-12 18:14:28 +0000420 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000421 friend class GrDrawTarget;
422 };
423
424 /**
425 * Saves the current draw state. The state can be restored at a later time
426 * with restoreDrawState.
427 *
428 * See also AutoStateRestore class.
429 *
430 * @param state will hold the state after the function returns.
431 */
432 void saveCurrentDrawState(SavedDrawState* state) const;
433
434 /**
435 * Restores previously saved draw state. The client guarantees that state
436 * was previously passed to saveCurrentDrawState and that the rendertarget
437 * and texture set at save are still valid.
438 *
439 * See also AutoStateRestore class.
440 *
441 * @param state the previously saved state to restore.
442 */
443 void restoreDrawState(const SavedDrawState& state);
444
445 /**
446 * Copies the draw state from another target to this target.
447 *
448 * @param srcTarget draw target used as src of the draw state.
449 */
450 void copyDrawState(const GrDrawTarget& srcTarget);
451
452 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000453 * The format of vertices is represented as a bitfield of flags.
454 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000455 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000456 * coordinates and per-vertex colors. Each stage can use any of the texture
457 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000458 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000459 * If no texture coordinates are specified for a stage then the stage is
460 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000461 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000462 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000463 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000464 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000465 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000466 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000467 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000468 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000469 * the order would be (position, texture coordinate 1[, color]).
470 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000471
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000472 /**
473 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000474 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000475 * @param stage the stage that will use texture coordinates.
476 * @param texCoordIdx the index of the texture coordinates to use
477 *
478 * @return the bit to add to a GrVertexLayout bitfield.
479 */
480 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
481 GrAssert(stage < kNumStages);
482 GrAssert(texCoordIdx < kMaxTexCoords);
483 return 1 << (stage + (texCoordIdx * kNumStages));
484 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000485
486 /**
487 * Determines if blend is effectively disabled.
488 *
489 * @return true if blend can be disabled without changing the rendering
490 * result given the current state including the vertex layout specified
491 * with the vertex source.
492 */
493 bool canDisableBlend() const;
494
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000495 /**
496 * Sets the edge data required for edge antialiasing.
497 *
498 * @param edges 3 * 6 float values, representing the edge
499 * equations in Ax + By + C form
500 */
501 void setEdgeAAData(const float edges[18]);
502
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000503private:
504 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
505public:
506 /**
507 * Generates a bit indicating that a texture stage uses the position
508 * as its texture coordinate.
509 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000510 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000511 * coordinates.
512 *
513 * @return the bit to add to a GrVertexLayout bitfield.
514 */
515 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
516 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000517 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000518 }
519private:
520 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000521
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000522public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000523
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000524 /**
525 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000526 */
527 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000528
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000529 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
530 //<! vertices have colors
531 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
532 //<! use text vertices. (Pos
533 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000534 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000535 // text [GrGpuTextVertex vs
536 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000537 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000538 kDummyVertexLayoutBit,
539 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000540 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000541 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000542 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000543
544 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000545 * There are three paths for specifying geometry (vertices and optionally
546 * indices) to the draw target. When indexed drawing the indices and vertices
547 * can be each use a different path.
548 *
549 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
550 * caller's client has already provided vertex data in a format
551 * the time compatible with a GrVertexLayout. The array must contain the
552 * data at set*SourceToArray is called. The source stays in effect for
553 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
554 * again or one of the other two paths is chosen.
555 *
556 * 2. Reserve and Lock. This is most useful when the caller has data it must
557 * transform before drawing and will not likely render it again. The
558 * caller requests that the draw target make room for some amount of
559 * vertex and/or index data. The target provides ptrs to hold the data
560 * data. The caller can write the data into the pts up until the first
561 * drawIndexed or drawNonIndexed call. At this point the data is frozen
562 * and the ptrs are no longer guaranteed to be valid. All subsequent
563 * drawIndexed & drawNonIndexed calls will use this data until
564 * releaseReserved geometry is called. This must be called before another
565 * source is set.
566 *
567 * 3. Vertex and Index Buffers. This is most useful for geometry that will
568 * be rendered multiple times. SetVertexSourceToBuffer &
569 * SetIndexSourceToBuffer are used to set the buffer and subsequent
570 * drawIndexed and drawNonIndexed calls use this source until another
571 * source is set.
572 */
573
574 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000575 * Reserves space for vertices and/or indices. Draw target will use
576 * reserved vertices / indices at next draw.
577 *
578 * If succeeds:
579 * if vertexCount is nonzero, *vertices will be the array
580 * of vertices to be filled by caller. The next draw will read
581 * these vertices.
582 *
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000583 * if indexCount is nonzero, *indices will be the array of indices
reed@google.comac10a2d2010-12-22 21:39:39 +0000584 * to be filled by caller. The next indexed draw will read from
585 * these indices.
586 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000587 * If a client does not already have a vertex buffer then this is the
588 * preferred way to allocate vertex/index array. It allows the subclass of
589 * GrDrawTarget to decide whether to put data in buffers, to group vertex
590 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000591 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000592 * Following the first draw after reserveAndLockGeometry the ptrs returned
593 * by releaseReservedGeometry are no longer valid and the geometry data
594 * cannot be further modified. The contents that were put in the reserved
595 * space can be drawn by multiple draws, however.
596 *
597 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
598 * call after all draws that reference the reserved geometry data have
599 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000600 *
601 * AutoGeometryRelease can be used to automatically call the release.
602 *
603 * @param vertexCount the number of vertices to reserve space for. Can be 0.
604 * @param indexCount the number of indices to reserve space for. Can be 0.
605 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
606 * @param vertices will point to reserved vertex space if vertexCount is
607 * non-zero. Illegal to pass NULL if vertexCount > 0.
608 * @param indices will point to reserved index space if indexCount is
609 * non-zero. Illegal to pass NULL if indexCount > 0.
610 *
611 * @return true if succeeded in allocating space for the vertices and false
612 * if not.
613 */
614 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
615 uint32_t vertexCount,
616 uint32_t indexCount,
617 void** vertices,
618 void** indices);
619 /**
620 * Provides hints to caller about the number of vertices and indices
621 * that can be allocated cheaply. This can be useful if caller is reserving
622 * space but doesn't know exactly how much geometry is needed.
623 *
624 * Also may hint whether the draw target should be flushed first. This is
625 * useful for deferred targets.
626 *
627 * @param vertexLayout layout of vertices caller would like to reserve
628 * @param vertexCount in: hint about how many vertices the caller would
629 * like to allocate.
630 * out: a hint about the number of vertices that can be
631 * allocated cheaply. Negative means no hint.
632 * Ignored if NULL.
633 * @param indexCount in: hint about how many indices the caller would
634 * like to allocate.
635 * out: a hint about the number of indices that can be
636 * allocated cheaply. Negative means no hint.
637 * Ignored if NULL.
638 *
639 * @return true if target should be flushed based on the input values.
640 */
641 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000642 int* vertexCount,
643 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000644
645 /**
646 * Releases reserved vertex/index data from reserveAndLockGeometry().
647 */
648 void releaseReservedGeometry();
649
650 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000651 * Sets source of vertex data for the next draw. Array must contain
652 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000653 *
654 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000655 * @param size size of the vertex data.
656 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000657 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000658 void setVertexSourceToArray(GrVertexLayout vertexLayout,
659 const void* vertexArray,
660 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000661
662 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000663 * Sets source of index data for the next indexed draw. Array must contain
664 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000665 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000666 * @param array cpu array containing index data.
667 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000668 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000669 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000670
671 /**
672 * Sets source of vertex data for the next draw. Data does not have to be
673 * in the buffer until drawIndexed or drawNonIndexed.
674 *
675 * @param buffer vertex buffer containing vertex data. Must be
676 * unlocked before draw call.
677 * @param vertexLayout layout of the vertex data in the buffer.
678 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000679 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
680 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000681
682 /**
683 * Sets source of index data for the next indexed draw. Data does not have
684 * to be in the buffer until drawIndexed or drawNonIndexed.
685 *
686 * @param buffer index buffer containing indices. Must be unlocked
687 * before indexed draw call.
688 */
689 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
690
691 /**
692 * Draws indexed geometry using the current state and current vertex / index
693 * sources.
694 *
695 * @param type The type of primitives to draw.
696 * @param startVertex the vertex in the vertex array/buffer corresponding
697 * to index 0
698 * @param startIndex first index to read from index src.
699 * @param vertexCount one greater than the max index.
700 * @param indexCount the number of index elements to read. The index count
701 * is effectively trimmed to the last completely
702 * specified primitive.
703 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000704 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000705 int startVertex,
706 int startIndex,
707 int vertexCount,
708 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000709
710 /**
711 * Draws non-indexed geometry using the current state and current vertex
712 * sources.
713 *
714 * @param type The type of primitives to draw.
715 * @param startVertex the vertex in the vertex array/buffer corresponding
716 * to index 0
717 * @param vertexCount one greater than the max index.
718 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000719 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000720 int startVertex,
721 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000722
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000723 /**
724 * Helper function for drawing rects. This does not use the current index
725 * and vertex sources. After returning, the vertex and index sources may
726 * have changed. They should be reestablished before the next drawIndexed
727 * or drawNonIndexed. This cannot be called between reserving and releasing
728 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000729 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000730 * drawNonIndexed.
731 * @param rect the rect to draw
732 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000733 * @param stageEnableBitfield bitmask indicating which stages are enabled.
734 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000735 * @param srcRects specifies rects for stages enabled by stageEnableMask.
736 * if stageEnableMask bit i is 1, srcRects is not NULL,
737 * and srcRects[i] is not NULL, then srcRects[i] will be
738 * used as coordinates for stage i. Otherwise, if stage i
739 * is enabled then rect is used as the coordinates.
740 * @param srcMatrices optional matrices applied to srcRects. If
741 * srcRect[i] is non-NULL and srcMatrices[i] is
742 * non-NULL then srcRect[i] will be transformed by
743 * srcMatrix[i]. srcMatrices can be NULL when no
744 * srcMatrices are desired.
745 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000746 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000747 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000748 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000749 const GrRect* srcRects[],
750 const GrMatrix* srcMatrices[]);
751
752 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000753 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000754 * matrices.
755 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000756 void drawSimpleRect(const GrRect& rect,
757 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000758 StageBitfield stageEnableBitfield) {
759 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000760 }
761
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000762 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000763 * Clear the render target. Ignores the clip and all other draw state
764 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
765 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000766 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000767 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000768
reed@google.comac10a2d2010-12-22 21:39:39 +0000769 ///////////////////////////////////////////////////////////////////////////
770
771 class AutoStateRestore : ::GrNoncopyable {
772 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000773 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000774 AutoStateRestore(GrDrawTarget* target);
775 ~AutoStateRestore();
776
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000777 /**
778 * if this object is already saving state for param target then
779 * this does nothing. Otherise, it restores previously saved state on
780 * previous target (if any) and saves current state on param target.
781 */
782 void set(GrDrawTarget* target);
783
reed@google.comac10a2d2010-12-22 21:39:39 +0000784 private:
785 GrDrawTarget* fDrawTarget;
786 SavedDrawState fDrawState;
787 };
788
789 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000790
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000791 class AutoViewMatrixRestore : ::GrNoncopyable {
792 public:
793 AutoViewMatrixRestore() {
794 fDrawTarget = NULL;
795 }
796
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000797 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000798 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
799 GrAssert(NULL != target);
800 }
801
802 void set(GrDrawTarget* target) {
803 GrAssert(NULL != target);
804 if (NULL != fDrawTarget) {
805 fDrawTarget->setViewMatrix(fMatrix);
806 }
807 fDrawTarget = target;
808 fMatrix = target->getViewMatrix();
809 }
810
811 ~AutoViewMatrixRestore() {
812 if (NULL != fDrawTarget) {
813 fDrawTarget->setViewMatrix(fMatrix);
814 }
815 }
816
817 private:
818 GrDrawTarget* fDrawTarget;
819 GrMatrix fMatrix;
820 };
821
822 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000823
824 class AutoReleaseGeometry : ::GrNoncopyable {
825 public:
826 AutoReleaseGeometry(GrDrawTarget* target,
827 GrVertexLayout vertexLayout,
828 uint32_t vertexCount,
829 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000830 fTarget = NULL;
831 this->set(target, vertexLayout, vertexCount, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000832 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000833
834 AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000835 fTarget = NULL;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000836 }
837
reed@google.comac10a2d2010-12-22 21:39:39 +0000838 ~AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000839 if (NULL != fTarget) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000840 fTarget->releaseReservedGeometry();
841 }
842 }
843
bsalomon@google.com5782d712011-01-21 21:03:59 +0000844 bool set(GrDrawTarget* target,
845 GrVertexLayout vertexLayout,
846 uint32_t vertexCount,
847 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000848 if (NULL != fTarget) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000849 fTarget->releaseReservedGeometry();
850 }
851 fTarget = target;
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000852 if (NULL != fTarget) {
853 if (!fTarget->reserveAndLockGeometry(vertexLayout,
854 vertexCount,
855 indexCount,
856 &fVertices,
857 &fIndices)) {
858 fTarget = NULL;
859 }
860 }
861 return NULL != fTarget;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000862 }
863
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000864 bool succeeded() const { return NULL != fTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000865 void* vertices() const { return fVertices; }
866 void* indices() const { return fIndices; }
867
868 GrPoint* positions() const {
869 return static_cast<GrPoint*>(fVertices);
870 }
871
872 private:
873 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000874 void* fVertices;
875 void* fIndices;
876 };
877
878 ///////////////////////////////////////////////////////////////////////////
879
880 class AutoClipRestore : ::GrNoncopyable {
881 public:
882 AutoClipRestore(GrDrawTarget* target) {
883 fTarget = target;
884 fClip = fTarget->getClip();
885 }
886
887 ~AutoClipRestore() {
888 fTarget->setClip(fClip);
889 }
890 private:
891 GrDrawTarget* fTarget;
892 GrClip fClip;
893 };
894
895 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000896 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000897
reed@google.comac10a2d2010-12-22 21:39:39 +0000898 /**
899 * Helper function to compute the size of a vertex from a vertex layout
900 * @return size of a single vertex.
901 */
902 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000903
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000904 /**
905 * Helper function for determining the index of texture coordinates that
906 * is input for a texture stage. Note that a stage may instead use positions
907 * as texture coordinates, in which case the result of the function is
908 * indistinguishable from the case when the stage is disabled.
909 *
910 * @param stage the stage to query
911 * @param vertexLayout layout to query
912 *
913 * @return the texture coordinate index or -1 if the stage doesn't use
914 * separate (non-position) texture coordinates.
915 */
916 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000917
918 /**
919 * Helper function to compute the offset of texture coordinates in a vertex
920 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +0000921 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000922 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000923 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000924 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000925
926 /**
927 * Helper function to compute the offset of the color in a vertex
928 * @return offset of color in vertex layout or -1 if the
929 * layout has no color.
930 */
931 static int VertexColorOffset(GrVertexLayout vertexLayout);
932
933 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000934 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000935 * coordinates of some index.
936 *
937 * @param coordIndex the tex coord index to query
938 * @param vertexLayout layout to query
939 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000940 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000941 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000942 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000943 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000944 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000945
reed@google.comac10a2d2010-12-22 21:39:39 +0000946 /**
947 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000948 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +0000949 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000950 * @param stage the stage to query
951 * @param vertexLayout layout to query
952 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000953 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000954 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +0000955 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000956 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000957
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000958 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000959 * Helper function to compute the size of each vertex and the offsets of
960 * texture coordinates and color. Determines tex coord offsets by tex coord
961 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000962 * by StageTexCoordVertexLayoutBit.)
963 *
964 * @param vertexLayout the layout to query
965 * @param texCoordOffsetsByIdx after return it is the offset of each
966 * tex coord index in the vertex or -1 if
967 * index isn't used.
968 * @return size of a single vertex
969 */
970 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
971 int texCoordOffsetsByIdx[kMaxTexCoords],
972 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000973
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000974 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000975 * Helper function to compute the size of each vertex and the offsets of
976 * texture coordinates and color. Determines tex coord offsets by stage
977 * rather than by index. (Each stage can be mapped to any t.c. index
978 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000979 * tex coords then that stage's offset will be 0 (positions are always at 0).
980 *
981 * @param vertexLayout the layout to query
982 * @param texCoordOffsetsByStage after return it is the offset of each
983 * tex coord index in the vertex or -1 if
984 * index isn't used.
985 * @return size of a single vertex
986 */
987 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
988 int texCoordOffsetsByStage[kNumStages],
989 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000990
991 /**
992 * Accessing positions, texture coords, or colors, of a vertex within an
993 * array is a hassle involving casts and simple math. These helpers exist
994 * to keep GrDrawTarget clients' code a bit nicer looking.
995 */
996
997 /**
998 * Gets a pointer to a GrPoint of a vertex's position or texture
999 * coordinate.
1000 * @param vertices the vetex array
1001 * @param vertexIndex the index of the vertex in the array
1002 * @param vertexSize the size of each vertex in the array
1003 * @param offset the offset in bytes of the vertex component.
1004 * Defaults to zero (corresponding to vertex position)
1005 * @return pointer to the vertex component as a GrPoint
1006 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001007 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001008 int vertexIndex,
1009 int vertexSize,
1010 int offset = 0) {
1011 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001012 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001013 vertexIndex * vertexSize);
1014 }
1015 static const GrPoint* GetVertexPoint(const void* vertices,
1016 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001017 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001018 int offset = 0) {
1019 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001020 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001021 vertexIndex * vertexSize);
1022 }
1023
1024 /**
1025 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1026 * @param vertices the vetex array
1027 * @param vertexIndex the index of the vertex in the array
1028 * @param vertexSize the size of each vertex in the array
1029 * @param offset the offset in bytes of the vertex color
1030 * @return pointer to the vertex component as a GrColor
1031 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001032 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001033 int vertexIndex,
1034 int vertexSize,
1035 int offset) {
1036 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001037 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001038 vertexIndex * vertexSize);
1039 }
1040 static const GrColor* GetVertexColor(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) {
1044 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001045 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001046 vertexIndex * vertexSize);
1047 }
1048
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001049 static void VertexLayoutUnitTest();
1050
reed@google.comac10a2d2010-12-22 21:39:39 +00001051protected:
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001052 // given a vertex layout and a draw state, will a stage be used?
1053 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1054 const DrState& state) {
1055 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1056 }
1057
1058 bool isStageEnabled(int stage) const {
1059 return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
1060 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001061
reed@google.comac10a2d2010-12-22 21:39:39 +00001062 // Helpers for GrDrawTarget subclasses that won't have private access to
1063 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001064 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001065 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001066 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001067 { return sds.fState; }
1068
1069 // implemented by subclass
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001070 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
1071 void** vertices,
1072 void** indices) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001073
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001074 virtual void onReleaseGeometry() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001075
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001076 // subclass overrides to be notified when clip is set.
1077 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001078
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001079 virtual void onSetVertexSourceToArray(const void* vertexArray,
1080 int vertexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001081
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001082 virtual void onSetIndexSourceToArray(const void* indexArray,
1083 int indexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001084
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001085 // Helpers for drawRect, protected so subclasses that override drawRect
1086 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001087 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001088 const GrRect* srcRects[]);
1089
1090 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001091 const GrMatrix* matrix,
1092 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001093 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001094 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001095 void* vertices);
1096
reed@google.comac10a2d2010-12-22 21:39:39 +00001097 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001098 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
1099 kArray_GeometrySrcType, // src was set using set*SourceToArray
1100 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +00001101 };
1102
bsalomon@google.comd302f142011-03-03 13:54:13 +00001103 struct ReservedGeometry {
reed@google.comac10a2d2010-12-22 21:39:39 +00001104 bool fLocked;
1105 uint32_t fVertexCount;
1106 uint32_t fIndexCount;
1107 } fReservedGeometry;
1108
1109 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001110 GeometrySrcType fVertexSrc;
1111 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
1112 GeometrySrcType fIndexSrc;
1113 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
1114 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +00001115 } fGeometrySrc;
1116
1117 GrClip fClip;
1118
reed@google.com8195f672011-01-12 18:14:28 +00001119 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001120
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001121 // Not meant for external use. Only setVertexSourceToBuffer and
1122 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
1123 // support nested reserveAndLockGeometry (and cpu arrays internally use the
1124 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +00001125 class AutoGeometrySrcRestore {
1126 public:
1127 AutoGeometrySrcRestore(GrDrawTarget* target) {
1128 fTarget = target;
1129 fGeometrySrc = fTarget->fGeometrySrc;
1130 }
1131 ~AutoGeometrySrcRestore() {
1132 fTarget->fGeometrySrc = fGeometrySrc;
1133 }
1134 private:
1135 GrDrawTarget *fTarget;
1136 GeometrySrc fGeometrySrc;
1137
1138 AutoGeometrySrcRestore();
1139 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
1140 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
1141 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001142};
1143
1144#endif