blob: 42723f6da3d106388368df4a5601c73682de40b6 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#ifndef GrDrawTarget_DEFINED
12#define GrDrawTarget_DEFINED
13
reed@google.comac10a2d2010-12-22 21:39:39 +000014#include "GrClip.h"
bsalomon@google.comaa5b6732011-07-29 15:13:20 +000015#include "GrColor.h"
16#include "GrMatrix.h"
17#include "GrRefCnt.h"
18#include "GrRenderTarget.h"
19#include "GrSamplerState.h"
bsalomon@google.comd302f142011-03-03 13:54:13 +000020#include "GrStencil.h"
bsalomon@google.comaa5b6732011-07-29 15:13:20 +000021#include "GrTexture.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000022
Scroggo97c88c22011-05-11 14:05:25 +000023#include "SkXfermode.h"
24
reed@google.comac10a2d2010-12-22 21:39:39 +000025class GrTexture;
reed@google.comac10a2d2010-12-22 21:39:39 +000026class GrClipIterator;
27class GrVertexBuffer;
28class GrIndexBuffer;
29
30class GrDrawTarget : public GrRefCnt {
31public:
32 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +000033 * Number of texture stages. Each stage takes as input a color and
34 * 2D texture coordinates. The color input to the first enabled stage is the
35 * per-vertex color or the constant color (setColor/setAlpha) if there are
36 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000037 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000038 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000039 * lookups are specified by a texture a sampler (setSamplerState). Texture
40 * coordinates for each stage come from the vertices based on a
41 * GrVertexLayout bitfield. The output fragment color is the output color of
42 * the last enabled stage. The presence or absence of texture coordinates
43 * for each stage in the vertex layout indicates whether a stage is enabled
44 * or not.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000045 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000046 enum {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000047 kNumStages = 3,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000048 kMaxTexCoords = kNumStages
49 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000050
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +000051
52 /**
53 * The absolute maximum number of edges that may be specified for
54 * a single draw call when performing edge antialiasing. This is used for
55 * the size of several static buffers, so implementations of getMaxEdges()
56 * (below) should clamp to this value.
57 */
58 enum {
59 kMaxEdges = 32
60 };
61
bsalomon@google.comaeb21602011-08-30 18:13:44 +000062 /**
63 * When specifying edges as vertex data this enum specifies what type of
64 * edges are in use. The edges are always 4 GrScalars in memory, even when
65 * the edge type requires fewer than 4.
66 */
67 enum VertexEdgeType {
68 /* 1-pixel wide line
69 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
70 kHairLine_EdgeType,
71 /* 1-pixel wide quadratic
72 u^2-v canonical coords (only 2 components used) */
73 kHairQuad_EdgeType
74 };
75
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000076 /**
bsalomon@google.comffca4002011-02-22 20:34:01 +000077 * Bitfield used to indicate which stages are in use.
reed@google.comac10a2d2010-12-22 21:39:39 +000078 */
bsalomon@google.comffca4002011-02-22 20:34:01 +000079 typedef int StageBitfield;
80 GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
reed@google.comac10a2d2010-12-22 21:39:39 +000081
82 /**
83 * Flags that affect rendering. Controlled using enable/disableState(). All
84 * default to disabled.
85 */
86 enum StateBits {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000087 kDither_StateBit = 0x01, //<! Perform color dithering
88 kAntialias_StateBit = 0x02, //<! Perform anti-aliasing. The render-
reed@google.comac10a2d2010-12-22 21:39:39 +000089 // target must support some form of AA
90 // (msaa, coverage sampling, etc). For
91 // GrGpu-created rendertarget/textures
92 // this is controlled by parameters
93 // passed to createTexture.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000094 kClip_StateBit = 0x04, //<! Controls whether drawing is clipped
reed@google.comac10a2d2010-12-22 21:39:39 +000095 // against the region specified by
96 // setClip.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000097 kNoColorWrites_StateBit = 0x08, //<! If set it disables writing colors.
98 // Useful while performing stencil
99 // ops.
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000100 kEdgeAAConcave_StateBit = 0x10,//<! If set, edge AA will test edge
101 // pairs for convexity while
102 // rasterizing. Set this if the
103 // source polygon is non-convex.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000104
105 // subclass may use additional bits internally
106 kDummyStateBit,
107 kLastPublicStateBit = kDummyStateBit-1
108 };
109
110 enum DrawFace {
111 kBoth_DrawFace,
112 kCCW_DrawFace,
113 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +0000114 };
115
116 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000117 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000118 * Changing the clip has the side-effect of possibly zeroing
119 * out the client settable stencil bits. So multipass algorithms
120 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000121 * @param settings the stencil settings to use.
122 */
123 void setStencil(const GrStencilSettings& settings) {
124 fCurrDrawState.fStencilSettings = settings;
125 }
126
127 /**
128 * Shortcut to disable stencil testing and ops.
129 */
130 void disableStencil() {
131 fCurrDrawState.fStencilSettings.setDisabled();
132 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000133
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000134 class Edge {
135 public:
136 Edge() {}
137 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
138 GrPoint intersect(const Edge& other) {
139 return GrPoint::Make(
140 (fY * other.fZ - other.fY * fZ) /
141 (fX * other.fY - other.fX * fY),
142 (fX * other.fZ - other.fX * fZ) /
143 (other.fX * fY - fX * other.fY));
144 }
145 float fX, fY, fZ;
146 };
147
reed@google.comac10a2d2010-12-22 21:39:39 +0000148protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000149
reed@google.com8195f672011-01-12 18:14:28 +0000150 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000151 DrState() {
152 // make sure any pad is zero for memcmp
153 // all DrState members should default to something
154 // valid by the memset
155 memset(this, 0, sizeof(DrState));
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000156
157 // memset exceptions
Scroggo97c88c22011-05-11 14:05:25 +0000158 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000159 fFirstCoverageStage = kNumStages;
160
161 // pedantic assertion that our ptrs will
162 // be NULL (0 ptr is mem addr 0)
bsalomon@google.comd302f142011-03-03 13:54:13 +0000163 GrAssert((intptr_t)(void*)NULL == 0LL);
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000164
165 // default stencil setting should be disabled
bsalomon@google.comd302f142011-03-03 13:54:13 +0000166 GrAssert(fStencilSettings.isDisabled());
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000167 fFirstCoverageStage = kNumStages;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000168 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000169 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000170 GrBlendCoeff fSrcBlend;
171 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000172 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000173 GrTexture* fTextures[kNumStages];
174 GrSamplerState fSamplerStates[kNumStages];
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000175 int fFirstCoverageStage;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000176 GrRenderTarget* fRenderTarget;
177 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000178 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000179 GrColor fColorFilterColor;
180 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000181
182 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000183 GrMatrix fViewMatrix;
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000184 VertexEdgeType fVertexEdgeType;
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000185 Edge fEdgeAAEdges[kMaxEdges];
186 int fEdgeAANumEdges;
reed@google.com8195f672011-01-12 18:14:28 +0000187 bool operator ==(const DrState& s) const {
188 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000189 }
reed@google.com8195f672011-01-12 18:14:28 +0000190 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000191 };
192
193public:
194 ///////////////////////////////////////////////////////////////////////////
195
196 GrDrawTarget();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000197 virtual ~GrDrawTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000198
199 /**
200 * Sets the current clip to the region specified by clip. All draws will be
201 * clipped against this clip if kClip_StateBit is enabled.
202 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000203 * Setting the clip may (or may not) zero out the client's stencil bits.
204 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000205 * @param description of the clipping region
206 */
207 void setClip(const GrClip& clip);
208
209 /**
210 * Gets the current clip.
211 *
212 * @return the clip.
213 */
214 const GrClip& getClip() const;
215
216 /**
217 * Sets the texture used at the next drawing call
218 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000219 * @param stage The texture stage for which the texture will be set
220 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000221 * @param texture The texture to set. Can be NULL though there is no advantage
222 * to settings a NULL texture if doing non-textured drawing
223 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000224 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000225
226 /**
227 * Retrieves the currently set texture.
228 *
229 * @return The currently set texture. The return value will be NULL if no
230 * texture has been set, NULL was most recently passed to
231 * setTexture, or the last setTexture was destroyed.
232 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000233 const GrTexture* getTexture(int stage) const;
234 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000235
236 /**
237 * Sets the rendertarget used at the next drawing call
238 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000239 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 */
241 void setRenderTarget(GrRenderTarget* target);
242
243 /**
244 * Retrieves the currently set rendertarget.
245 *
246 * @return The currently set render target.
247 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000248 const GrRenderTarget* getRenderTarget() const;
249 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000250
251 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000252 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000253 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000254 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000255 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000256 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000257 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000258 * @param samplerState Specifies the sampler state.
259 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000260 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000261
262 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000263 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000264 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000265 * @param stage the stage of the sampler to set
266 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000267 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000268 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
269 GrAssert(stage >= 0 && stage < kNumStages);
270 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000271 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000272
273 /**
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000274 * Shortcut for preConcatSamplerMatrix on all stages in mask with same
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000275 * matrix
276 */
277 void preConcatSamplerMatrices(int stageMask, const GrMatrix& matrix) {
278 for (int i = 0; i < kNumStages; ++i) {
279 if ((1 << i) & stageMask) {
280 this->preConcatSamplerMatrix(i, matrix);
281 }
282 }
283 }
284
285 /**
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000286 * Shortcut for preConcatSamplerMatrix on all enabled stages in mask with
287 * same matrix
288 *
289 * @param stage the stage of the sampler to set
290 * @param matrix the matrix to concat
291 */
292 void preConcatEnabledSamplerMatrices(const GrMatrix& matrix) {
293 StageBitfield stageMask = this->enabledStages();
294 this->preConcatSamplerMatrices(stageMask, matrix);
295 }
296
297 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000298 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000299 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000300 * @param stage the stage to of sampler to get
301 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000302 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000303 const GrMatrix& getSamplerMatrix(int stage) const {
304 return fCurrDrawState.fSamplerStates[stage].getMatrix();
305 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000306
307 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000308 * Sets the matrix of a stage's sampler
309 *
310 * @param stage the stage of sampler set
311 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000312 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000313 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000314 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
315 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000316
317 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000318 * Sets the matrix applied to veretx positions.
319 *
320 * In the post-view-matrix space the rectangle [0,w]x[0,h]
321 * fully covers the render target. (w and h are the width and height of the
322 * the rendertarget.)
323 *
324 * @param m the matrix used to transform the vertex positions.
325 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000326 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000327
328 /**
329 * Multiplies the current view matrix by a matrix
330 *
331 * After this call V' = V*m where V is the old view matrix,
332 * m is the parameter to this function, and V' is the new view matrix.
333 * (We consider positions to be column vectors so position vector p is
334 * transformed by matrix X as p' = X*p.)
335 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000336 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000337 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000338 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000339
340 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000341 * Multiplies the current view matrix by a matrix
342 *
343 * After this call V' = m*V where V is the old view matrix,
344 * m is the parameter to this function, and V' is the new view matrix.
345 * (We consider positions to be column vectors so position vector p is
346 * transformed by matrix X as p' = X*p.)
347 *
348 * @param m the matrix used to modify the view matrix.
349 */
350 void postConcatViewMatrix(const GrMatrix& m);
351
352 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000353 * Retrieves the current view matrix
354 * @return the current view matrix.
355 */
356 const GrMatrix& getViewMatrix() const;
357
358 /**
359 * Retrieves the inverse of the current view matrix.
360 *
361 * If the current view matrix is invertible, return true, and if matrix
362 * is non-null, copy the inverse into it. If the current view matrix is
363 * non-invertible, return false and ignore the matrix parameter.
364 *
365 * @param matrix if not null, will receive a copy of the current inverse.
366 */
367 bool getViewInverse(GrMatrix* matrix) const;
368
369 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000370 * Sets color for next draw to a premultiplied-alpha color.
371 *
372 * @param the color to set.
373 */
374 void setColor(GrColor);
375
376 /**
Scroggo97c88c22011-05-11 14:05:25 +0000377 * Add a color filter that can be represented by a color and a mode.
378 */
379 void setColorFilter(GrColor, SkXfermode::Mode);
380
381 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000382 * Sets the color to be used for the next draw to be
383 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
384 *
385 * @param alpha The alpha value to set as the color.
386 */
387 void setAlpha(uint8_t alpha);
388
389 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000390 * Controls whether clockwise, counterclockwise, or both faces are drawn.
391 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000392 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000393 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000394
395 /**
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000396 * A common pattern is to compute a color with the initial stages and then
397 * modulate that color by a coverage value in later stage(s) (AA, mask-
398 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
399 * computed based on the pre-coverage-modulated color. The division of
400 * stages between color-computing and coverage-computing is specified by
401 * this method. Initially this is kNumStages (all stages are color-
402 * computing).
403 */
404 void setFirstCoverageStage(int firstCoverageStage) {
405 fCurrDrawState.fFirstCoverageStage = firstCoverageStage;
406 }
407
408 /**
409 * Gets the index of the first coverage-computing stage.
410 */
411 int getFirstCoverageStage() const {
412 return fCurrDrawState.fFirstCoverageStage;
413 }
414
415 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000416 * Gets whether the target is drawing clockwise, counterclockwise,
417 * or both faces.
418 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000419 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000420 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000421
422 /**
423 * Enable render state settings.
424 *
425 * @param flags bitfield of StateBits specifing the states to enable
426 */
427 void enableState(uint32_t stateBits);
428
429 /**
430 * Disable render state settings.
431 *
432 * @param flags bitfield of StateBits specifing the states to disable
433 */
434 void disableState(uint32_t stateBits);
435
436 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000437 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
438 }
439
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000440 bool isAntialiasState() const {
441 return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
442 }
443
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000444 bool isClipState() const {
445 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000446 }
447
bsalomon@google.comd302f142011-03-03 13:54:13 +0000448 bool isColorWriteDisabled() const {
449 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
450 }
451
reed@google.comac10a2d2010-12-22 21:39:39 +0000452 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000453 * Sets the blending function coeffecients.
454 *
455 * The blend function will be:
456 * D' = sat(S*srcCoef + D*dstCoef)
457 *
458 * where D is the existing destination color, S is the incoming source
459 * color, and D' is the new destination color that will be written. sat()
460 * is the saturation function.
461 *
462 * @param srcCoef coeffecient applied to the src color.
463 * @param dstCoef coeffecient applied to the dst color.
464 */
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000465 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
reed@google.comac10a2d2010-12-22 21:39:39 +0000466
467 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000468 * Sets the blending function constant referenced by the following blending
469 * coeffecients:
470 * kConstC_BlendCoeff
471 * kIConstC_BlendCoeff
472 * kConstA_BlendCoeff
473 * kIConstA_BlendCoeff
474 *
475 * @param constant the constant to set
476 */
477 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
478
479 /**
480 * Retrieves the last value set by setBlendConstant()
481 * @return the blending constant value
482 */
483 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
484
485 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000486 * Used to save and restore the GrGpu's drawing state
487 */
488 struct SavedDrawState {
489 private:
reed@google.com8195f672011-01-12 18:14:28 +0000490 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000491 friend class GrDrawTarget;
492 };
493
494 /**
495 * Saves the current draw state. The state can be restored at a later time
496 * with restoreDrawState.
497 *
498 * See also AutoStateRestore class.
499 *
500 * @param state will hold the state after the function returns.
501 */
502 void saveCurrentDrawState(SavedDrawState* state) const;
503
504 /**
505 * Restores previously saved draw state. The client guarantees that state
506 * was previously passed to saveCurrentDrawState and that the rendertarget
507 * and texture set at save are still valid.
508 *
509 * See also AutoStateRestore class.
510 *
511 * @param state the previously saved state to restore.
512 */
513 void restoreDrawState(const SavedDrawState& state);
514
515 /**
516 * Copies the draw state from another target to this target.
517 *
518 * @param srcTarget draw target used as src of the draw state.
519 */
520 void copyDrawState(const GrDrawTarget& srcTarget);
521
522 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000523 * The format of vertices is represented as a bitfield of flags.
524 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000525 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000526 * coordinates and per-vertex colors. Each stage can use any of the texture
527 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000528 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000529 * If no texture coordinates are specified for a stage then the stage is
530 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000531 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000532 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000533 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000534 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000535 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000536 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000537 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000538 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000539 * the order would be (position, texture coordinate 1[, color]).
540 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000541
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000542 /**
543 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000544 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000545 * @param stage the stage that will use texture coordinates.
546 * @param texCoordIdx the index of the texture coordinates to use
547 *
548 * @return the bit to add to a GrVertexLayout bitfield.
549 */
550 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
551 GrAssert(stage < kNumStages);
552 GrAssert(texCoordIdx < kMaxTexCoords);
553 return 1 << (stage + (texCoordIdx * kNumStages));
554 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000555
556 /**
557 * Determines if blend is effectively disabled.
558 *
559 * @return true if blend can be disabled without changing the rendering
560 * result given the current state including the vertex layout specified
561 * with the vertex source.
562 */
563 bool canDisableBlend() const;
564
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000565 /**
566 * Determines the interpretation per-vertex edge data when the
567 * kEdge_VertexLayoutBit is set (see below). When per-vertex edges are not
568 * specified the value of this setting has no effect.
569 */
570 void setVertexEdgeType(VertexEdgeType type) {
571 fCurrDrawState.fVertexEdgeType = type;
572 }
573
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000574 /**
bsalomon@google.com471d4712011-08-23 15:45:25 +0000575 * Given the current draw state, vertex layout, and hw support, will HW AA
576 * lines be used (if line primitive type is drawn)? (Note that lines are
577 * always 1 pixel wide)
578 */
579 virtual bool willUseHWAALines() const = 0;
580
581 /**
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000582 * Sets the edge data required for edge antialiasing.
583 *
584 * @param edges 3 * 6 float values, representing the edge
585 * equations in Ax + By + C form
586 */
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000587 void setEdgeAAData(const Edge* edges, int numEdges);
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000588
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000589private:
590 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
591public:
592 /**
593 * Generates a bit indicating that a texture stage uses the position
594 * as its texture coordinate.
595 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000596 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000597 * coordinates.
598 *
599 * @return the bit to add to a GrVertexLayout bitfield.
600 */
601 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
602 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000603 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000604 }
605private:
606 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000607
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000608public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000609
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000610 /**
611 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000612 */
613 enum VertexLayoutBits {
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000614 /* vertices have colors */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000615 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000616
617 /* Use text vertices. (Pos and tex coords may be a different type for
618 text [GrGpuTextVertex vs GrPoint].) */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000619 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000620
621 kEdge_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 2),
reed@google.comac10a2d2010-12-22 21:39:39 +0000622 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000623 kDummyVertexLayoutBit,
624 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000625 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000626 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000627 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000628
629 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000630 * There are three methods for specifying geometry (vertices and optionally
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000631 * indices) to the draw target. When indexed drawing the indices and vertices
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000632 * can use a different method. Once geometry is specified it can be used for
633 * multiple drawIndexed and drawNonIndexed calls.
634 *
635 * Sometimes it is necessary to perform a draw while upstack code has
636 * already specified geometry that it isn't finished with. There are push
637 * pop methods
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000638 *
639 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
640 * caller's client has already provided vertex data in a format
641 * the time compatible with a GrVertexLayout. The array must contain the
642 * data at set*SourceToArray is called. The source stays in effect for
643 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
644 * again or one of the other two paths is chosen.
645 *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000646 * 2. Reserve. This is most useful when the caller has data it must
647 * transform before drawing and is not long-lived. The caller requests
648 * that the draw target make room for some amount of vertex and/or index
649 * data. The target provides ptrs to hold the vertex and/or index data.
650 *
651 * The data is writable up until the next drawIndexed, drawNonIndexed,
652 * or pushGeometrySource At this point the data is frozen and the ptrs
653 * are no longer valid.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000654 *
655 * 3. Vertex and Index Buffers. This is most useful for geometry that will
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000656 * is long-lived. SetVertexSourceToBuffer and SetIndexSourceToBuffer are
657 * used to set the buffer and subsequent drawIndexed and drawNonIndexed
658 * calls use this source until another source is set.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000659 */
660
661 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000662 * Reserves space for vertices. Draw target will use reserved vertices at
663 * at the next draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000664 *
665 * If succeeds:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000666 * if vertexCount > 0, *vertices will be the array
reed@google.comac10a2d2010-12-22 21:39:39 +0000667 * of vertices to be filled by caller. The next draw will read
668 * these vertices.
669 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000670 * If a client does not already have a vertex buffer then this is the
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000671 * preferred way to allocate vertex data. It allows the subclass of
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000672 * GrDrawTarget to decide whether to put data in buffers, to group vertex
673 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000674 *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000675 * After the next draw or pushGeometrySource the vertices ptr is no longer
676 * valid and the geometry data cannot be further modified. The contents
677 * that were put in the reserved space can be drawn by multiple draws,
678 * however.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000679 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000680 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000681 * @param vertexCount the number of vertices to reserve space for. Can be 0.
reed@google.comac10a2d2010-12-22 21:39:39 +0000682 * @param vertices will point to reserved vertex space if vertexCount is
683 * non-zero. Illegal to pass NULL if vertexCount > 0.
reed@google.comac10a2d2010-12-22 21:39:39 +0000684 *
685 * @return true if succeeded in allocating space for the vertices and false
686 * if not.
687 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000688 bool reserveVertexSpace(GrVertexLayout vertexLayout,
689 int vertexCount,
690 void** vertices);
691 /**
692 * Reserves space for indices. Draw target will use the reserved indices at
693 * the next indexed draw.
694 *
695 * If succeeds:
696 * if indexCount > 0, *indices will be the array
697 * of indices to be filled by caller. The next draw will read
698 * these indices.
699 *
700 * If a client does not already have a index buffer then this is the
701 * preferred way to allocate index data. It allows the subclass of
702 * GrDrawTarget to decide whether to put data in buffers, to group index
703 * data that uses the same state (e.g. for deferred rendering), etc.
704 *
705 * After the next indexed draw or pushGeometrySource the indices ptr is no
706 * longer valid and the geometry data cannot be further modified. The
707 * contents that were put in the reserved space can be drawn by multiple
708 * draws, however.
709 *
710 * @param indexCount the number of indices to reserve space for. Can be 0.
711 * @param indices will point to reserved index space if indexCount is
712 * non-zero. Illegal to pass NULL if indexCount > 0.
713 */
714
715 bool reserveIndexSpace(int indexCount, void** indices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000716 /**
717 * Provides hints to caller about the number of vertices and indices
718 * that can be allocated cheaply. This can be useful if caller is reserving
719 * space but doesn't know exactly how much geometry is needed.
720 *
721 * Also may hint whether the draw target should be flushed first. This is
722 * useful for deferred targets.
723 *
724 * @param vertexLayout layout of vertices caller would like to reserve
725 * @param vertexCount in: hint about how many vertices the caller would
726 * like to allocate.
727 * out: a hint about the number of vertices that can be
728 * allocated cheaply. Negative means no hint.
729 * Ignored if NULL.
730 * @param indexCount in: hint about how many indices the caller would
731 * like to allocate.
732 * out: a hint about the number of indices that can be
733 * allocated cheaply. Negative means no hint.
734 * Ignored if NULL.
735 *
736 * @return true if target should be flushed based on the input values.
737 */
738 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000739 int* vertexCount,
740 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000741
742 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000743 * Sets source of vertex data for the next draw. Array must contain
744 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000745 *
746 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000747 * @param size size of the vertex data.
748 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000749 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000750 void setVertexSourceToArray(GrVertexLayout vertexLayout,
751 const void* vertexArray,
752 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000753
754 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000755 * Sets source of index data for the next indexed draw. Array must contain
756 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000757 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000758 * @param array cpu array containing index data.
759 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000760 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000761 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000762
763 /**
764 * Sets source of vertex data for the next draw. Data does not have to be
765 * in the buffer until drawIndexed or drawNonIndexed.
766 *
767 * @param buffer vertex buffer containing vertex data. Must be
768 * unlocked before draw call.
769 * @param vertexLayout layout of the vertex data in the buffer.
770 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000771 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
772 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000773
774 /**
775 * Sets source of index data for the next indexed draw. Data does not have
776 * to be in the buffer until drawIndexed or drawNonIndexed.
777 *
778 * @param buffer index buffer containing indices. Must be unlocked
779 * before indexed draw call.
780 */
781 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000782
783 /**
784 * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
785 * source to reserved, array, or buffer before next draw. May be able to free
786 * up temporary storage allocated by setVertexSourceToArray or
787 * reserveVertexSpace.
788 */
789 void resetVertexSource();
790
791 /**
792 * Resets index source. Indexed Drawing from reset indices is illegal. Set
793 * index source to reserved, array, or buffer before next indexed draw. May
794 * be able to free up temporary storage allocated by setIndexSourceToArray
795 * or reserveIndexSpace.
796 */
797 void resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000798
799 /**
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000800 * Pushes and resets the vertex/index sources. Any reserved vertex / index
801 * data is finalized (i.e. cannot be updated after the matching pop but can
802 * be drawn from). Must be balanced by a pop.
803 */
804 void pushGeometrySource();
805
806 /**
807 * Pops the vertex / index sources from the matching push.
808 */
809 void popGeometrySource();
810
811 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000812 * Draws indexed geometry using the current state and current vertex / index
813 * sources.
814 *
815 * @param type The type of primitives to draw.
816 * @param startVertex the vertex in the vertex array/buffer corresponding
817 * to index 0
818 * @param startIndex first index to read from index src.
819 * @param vertexCount one greater than the max index.
820 * @param indexCount the number of index elements to read. The index count
821 * is effectively trimmed to the last completely
822 * specified primitive.
823 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000824 void drawIndexed(GrPrimitiveType type,
825 int startVertex,
826 int startIndex,
827 int vertexCount,
828 int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000829
830 /**
831 * Draws non-indexed geometry using the current state and current vertex
832 * sources.
833 *
834 * @param type The type of primitives to draw.
835 * @param startVertex the vertex in the vertex array/buffer corresponding
836 * to index 0
837 * @param vertexCount one greater than the max index.
838 */
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000839 void drawNonIndexed(GrPrimitiveType type,
840 int startVertex,
841 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000842
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000843 /**
844 * Helper function for drawing rects. This does not use the current index
845 * and vertex sources. After returning, the vertex and index sources may
846 * have changed. They should be reestablished before the next drawIndexed
847 * or drawNonIndexed. This cannot be called between reserving and releasing
848 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000849 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000850 * drawNonIndexed.
851 * @param rect the rect to draw
852 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000853 * @param stageEnableBitfield bitmask indicating which stages are enabled.
854 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000855 * @param srcRects specifies rects for stages enabled by stageEnableMask.
856 * if stageEnableMask bit i is 1, srcRects is not NULL,
857 * and srcRects[i] is not NULL, then srcRects[i] will be
858 * used as coordinates for stage i. Otherwise, if stage i
859 * is enabled then rect is used as the coordinates.
860 * @param srcMatrices optional matrices applied to srcRects. If
861 * srcRect[i] is non-NULL and srcMatrices[i] is
862 * non-NULL then srcRect[i] will be transformed by
863 * srcMatrix[i]. srcMatrices can be NULL when no
864 * srcMatrices are desired.
865 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000866 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000867 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000868 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000869 const GrRect* srcRects[],
870 const GrMatrix* srcMatrices[]);
871
872 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000873 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000874 * matrices.
875 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000876 void drawSimpleRect(const GrRect& rect,
877 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000878 StageBitfield stageEnableBitfield) {
879 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000880 }
881
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000882 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000883 * Clear the render target. Ignores the clip and all other draw state
884 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
885 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000886 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000887 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000888
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000889 /**
890 * Returns the maximum number of edges that may be specified in a single
891 * draw call when performing edge antialiasing. This is usually limited
892 * by the number of fragment uniforms which may be uploaded. Must be a
893 * minimum of six, since a triangle's vertices each belong to two boundary
894 * edges which may be distinct.
895 */
896 virtual int getMaxEdges() const { return 6; }
897
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000898 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000899
900 class AutoStateRestore : ::GrNoncopyable {
901 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000902 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000903 AutoStateRestore(GrDrawTarget* target);
904 ~AutoStateRestore();
905
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000906 /**
907 * if this object is already saving state for param target then
908 * this does nothing. Otherise, it restores previously saved state on
909 * previous target (if any) and saves current state on param target.
910 */
911 void set(GrDrawTarget* target);
912
reed@google.comac10a2d2010-12-22 21:39:39 +0000913 private:
914 GrDrawTarget* fDrawTarget;
915 SavedDrawState fDrawState;
916 };
917
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000918 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000919
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000920 class AutoViewMatrixRestore : ::GrNoncopyable {
921 public:
922 AutoViewMatrixRestore() {
923 fDrawTarget = NULL;
924 }
925
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000926 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000927 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
928 GrAssert(NULL != target);
929 }
930
931 void set(GrDrawTarget* target) {
932 GrAssert(NULL != target);
933 if (NULL != fDrawTarget) {
934 fDrawTarget->setViewMatrix(fMatrix);
935 }
936 fDrawTarget = target;
937 fMatrix = target->getViewMatrix();
938 }
939
940 ~AutoViewMatrixRestore() {
941 if (NULL != fDrawTarget) {
942 fDrawTarget->setViewMatrix(fMatrix);
943 }
944 }
945
946 private:
947 GrDrawTarget* fDrawTarget;
948 GrMatrix fMatrix;
949 };
950
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000951 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000952
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000953 /**
954 * Sets the view matrix to I and preconcats all stage matrices enabled in
955 * mask by the view inverse. Destructor undoes these changes.
956 */
957 class AutoDeviceCoordDraw : ::GrNoncopyable {
958 public:
959 AutoDeviceCoordDraw(GrDrawTarget* target, int stageMask);
960 ~AutoDeviceCoordDraw();
961 private:
962 GrDrawTarget* fDrawTarget;
963 GrMatrix fViewMatrix;
964 GrMatrix fSamplerMatrices[kNumStages];
965 int fStageMask;
966 };
967
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000968 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000969
reed@google.comac10a2d2010-12-22 21:39:39 +0000970 class AutoReleaseGeometry : ::GrNoncopyable {
971 public:
972 AutoReleaseGeometry(GrDrawTarget* target,
973 GrVertexLayout vertexLayout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000974 int vertexCount,
975 int indexCount);
976 AutoReleaseGeometry();
977 ~AutoReleaseGeometry();
bsalomon@google.com5782d712011-01-21 21:03:59 +0000978 bool set(GrDrawTarget* target,
979 GrVertexLayout vertexLayout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000980 int vertexCount,
981 int indexCount);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000982 bool succeeded() const { return NULL != fTarget; }
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000983 void* vertices() const { GrAssert(this->succeeded()); return fVertices; }
984 void* indices() const { GrAssert(this->succeeded()); return fIndices; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000985 GrPoint* positions() const {
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000986 return static_cast<GrPoint*>(this->vertices());
reed@google.comac10a2d2010-12-22 21:39:39 +0000987 }
988
989 private:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000990 void reset();
991
reed@google.comac10a2d2010-12-22 21:39:39 +0000992 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000993 void* fVertices;
994 void* fIndices;
995 };
996
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000997 ////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000998
999 class AutoClipRestore : ::GrNoncopyable {
1000 public:
1001 AutoClipRestore(GrDrawTarget* target) {
1002 fTarget = target;
1003 fClip = fTarget->getClip();
1004 }
1005
1006 ~AutoClipRestore() {
1007 fTarget->setClip(fClip);
1008 }
1009 private:
1010 GrDrawTarget* fTarget;
1011 GrClip fClip;
1012 };
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001013
1014 ////////////////////////////////////////////////////////////////////////////
1015
1016 class AutoGeometryPush : ::GrNoncopyable {
1017 public:
1018 AutoGeometryPush(GrDrawTarget* target) {
1019 GrAssert(NULL != target);
1020 fTarget = target;
1021 target->pushGeometrySource();
1022 }
1023 ~AutoGeometryPush() {
1024 fTarget->popGeometrySource();
1025 }
1026 private:
1027 GrDrawTarget* fTarget;
1028 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001029
1030 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001031 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +00001032
reed@google.comac10a2d2010-12-22 21:39:39 +00001033 /**
1034 * Helper function to compute the size of a vertex from a vertex layout
1035 * @return size of a single vertex.
1036 */
1037 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001038
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001039 /**
1040 * Helper function for determining the index of texture coordinates that
1041 * is input for a texture stage. Note that a stage may instead use positions
1042 * as texture coordinates, in which case the result of the function is
1043 * indistinguishable from the case when the stage is disabled.
1044 *
1045 * @param stage the stage to query
1046 * @param vertexLayout layout to query
1047 *
1048 * @return the texture coordinate index or -1 if the stage doesn't use
1049 * separate (non-position) texture coordinates.
1050 */
1051 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001052
1053 /**
1054 * Helper function to compute the offset of texture coordinates in a vertex
1055 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +00001056 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001057 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001058 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001059 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001060
1061 /**
1062 * Helper function to compute the offset of the color in a vertex
1063 * @return offset of color in vertex layout or -1 if the
1064 * layout has no color.
1065 */
1066 static int VertexColorOffset(GrVertexLayout vertexLayout);
1067
bsalomon@google.comaeb21602011-08-30 18:13:44 +00001068 /**
1069 * Helper function to compute the offset of the edge pts in a vertex
1070 * @return offset of edge in vertex layout or -1 if the
1071 * layout has no edge.
1072 */
1073 static int VertexEdgeOffset(GrVertexLayout vertexLayout);
1074
reed@google.comac10a2d2010-12-22 21:39:39 +00001075 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001076 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001077 * coordinates of some index.
1078 *
1079 * @param coordIndex the tex coord index to query
1080 * @param vertexLayout layout to query
1081 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001082 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001083 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001084 */
bsalomon@google.com5782d712011-01-21 21:03:59 +00001085 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001086 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001087
reed@google.comac10a2d2010-12-22 21:39:39 +00001088 /**
1089 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001090 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001091 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001092 * @param stage the stage to query
1093 * @param vertexLayout layout to query
1094 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001095 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001096 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001097 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001098 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001099
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001100 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001101 * Helper function to compute the size of each vertex and the offsets of
1102 * texture coordinates and color. Determines tex coord offsets by tex coord
1103 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001104 * by StageTexCoordVertexLayoutBit.)
1105 *
1106 * @param vertexLayout the layout to query
1107 * @param texCoordOffsetsByIdx after return it is the offset of each
1108 * tex coord index in the vertex or -1 if
1109 * index isn't used.
1110 * @return size of a single vertex
1111 */
1112 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
1113 int texCoordOffsetsByIdx[kMaxTexCoords],
bsalomon@google.comaeb21602011-08-30 18:13:44 +00001114 int *colorOffset,
1115 int* edgeOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001116
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001117 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001118 * Helper function to compute the size of each vertex and the offsets of
1119 * texture coordinates and color. Determines tex coord offsets by stage
1120 * rather than by index. (Each stage can be mapped to any t.c. index
1121 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001122 * tex coords then that stage's offset will be 0 (positions are always at 0).
1123 *
1124 * @param vertexLayout the layout to query
1125 * @param texCoordOffsetsByStage after return it is the offset of each
1126 * tex coord index in the vertex or -1 if
1127 * index isn't used.
1128 * @return size of a single vertex
1129 */
1130 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1131 int texCoordOffsetsByStage[kNumStages],
bsalomon@google.comaeb21602011-08-30 18:13:44 +00001132 int *colorOffset,
1133 int* edgeOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001134
1135 /**
1136 * Accessing positions, texture coords, or colors, of a vertex within an
1137 * array is a hassle involving casts and simple math. These helpers exist
1138 * to keep GrDrawTarget clients' code a bit nicer looking.
1139 */
1140
1141 /**
1142 * Gets a pointer to a GrPoint of a vertex's position or texture
1143 * coordinate.
1144 * @param vertices the vetex array
1145 * @param vertexIndex the index of the vertex in the array
1146 * @param vertexSize the size of each vertex in the array
1147 * @param offset the offset in bytes of the vertex component.
1148 * Defaults to zero (corresponding to vertex position)
1149 * @return pointer to the vertex component as a GrPoint
1150 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001151 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001152 int vertexIndex,
1153 int vertexSize,
1154 int offset = 0) {
1155 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001156 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001157 vertexIndex * vertexSize);
1158 }
1159 static const GrPoint* GetVertexPoint(const void* vertices,
1160 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001161 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001162 int offset = 0) {
1163 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001164 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001165 vertexIndex * vertexSize);
1166 }
1167
1168 /**
1169 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1170 * @param vertices the vetex array
1171 * @param vertexIndex the index of the vertex in the array
1172 * @param vertexSize the size of each vertex in the array
1173 * @param offset the offset in bytes of the vertex color
1174 * @return pointer to the vertex component as a GrColor
1175 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001176 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001177 int vertexIndex,
1178 int vertexSize,
1179 int offset) {
1180 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001181 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001182 vertexIndex * vertexSize);
1183 }
1184 static const GrColor* GetVertexColor(const void* vertices,
1185 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001186 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001187 int offset) {
1188 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001189 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001190 vertexIndex * vertexSize);
1191 }
1192
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001193 static void VertexLayoutUnitTest();
1194
reed@google.comac10a2d2010-12-22 21:39:39 +00001195protected:
bsalomon@google.com471d4712011-08-23 15:45:25 +00001196
1197 // determines whether HW blending can be disabled or not
1198 static bool CanDisableBlend(GrVertexLayout layout, const DrState& state);
1199
1200 // determines whether HW AA lines can be used or not
1201 static bool CanUseHWAALines(GrVertexLayout layout, const DrState& state);
1202
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001203 enum GeometrySrcType {
1204 kNone_GeometrySrcType, //<! src has not been specified
1205 kReserved_GeometrySrcType, //<! src was set using reserve*Space
1206 kArray_GeometrySrcType, //<! src was set using set*SourceToArray
1207 kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer
1208 };
1209
1210 struct GeometrySrcState {
1211 GeometrySrcType fVertexSrc;
1212 union {
1213 // valid if src type is buffer
1214 const GrVertexBuffer* fVertexBuffer;
1215 // valid if src type is reserved or array
1216 int fVertexCount;
1217 };
1218
1219 GeometrySrcType fIndexSrc;
1220 union {
1221 // valid if src type is buffer
1222 const GrIndexBuffer* fIndexBuffer;
1223 // valid if src type is reserved or array
1224 int fIndexCount;
1225 };
1226
1227 GrVertexLayout fVertexLayout;
1228 };
1229
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001230 // given a vertex layout and a draw state, will a stage be used?
1231 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
bsalomon@google.comaeb21602011-08-30 18:13:44 +00001232 const DrState& state) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001233 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1234 }
1235
1236 bool isStageEnabled(int stage) const {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001237 return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout,
1238 fCurrDrawState);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001239 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001240
bsalomon@google.comaeb21602011-08-30 18:13:44 +00001241 StageBitfield enabledStages() const {
1242 StageBitfield mask = 0;
1243 for (int s = 0; s < kNumStages; ++s) {
1244 mask |= this->isStageEnabled(s) ? 1 : 0;
1245 }
1246 return mask;
1247 }
1248
reed@google.comac10a2d2010-12-22 21:39:39 +00001249 // Helpers for GrDrawTarget subclasses that won't have private access to
1250 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001251 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001252 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001253 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001254 { return sds.fState; }
1255
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001256 // implemented by subclass to allocate space for reserved geom
1257 virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
1258 int vertexCount,
1259 void** vertices) = 0;
1260 virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0;
1261 // implemented by subclass to handle release of reserved geom space
1262 virtual void releaseReservedVertexSpace() = 0;
1263 virtual void releaseReservedIndexSpace() = 0;
1264 // subclass must consume array contents when set
1265 virtual void onSetVertexSourceToArray(const void* vertexArray,
1266 int vertexCount) = 0;
1267 virtual void onSetIndexSourceToArray(const void* indexArray,
1268 int indexCount) = 0;
1269 // subclass is notified that geom source will be set away from an array
1270 virtual void releaseVertexArray() = 0;
1271 virtual void releaseIndexArray() = 0;
1272 // subclass overrides to be notified just before geo src state
1273 // is pushed/popped.
1274 virtual void geometrySourceWillPush() = 0;
1275 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
1276 // subclass called to perform drawing
1277 virtual void onDrawIndexed(GrPrimitiveType type,
1278 int startVertex,
1279 int startIndex,
1280 int vertexCount,
1281 int indexCount) = 0;
1282 virtual void onDrawNonIndexed(GrPrimitiveType type,
1283 int startVertex,
1284 int vertexCount) = 0;
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +00001285 // subclass overrides to be notified when clip is set. Must call
1286 // INHERITED::clipwillBeSet
1287 virtual void clipWillBeSet(const GrClip& clip);
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001288
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001289 // Helpers for drawRect, protected so subclasses that override drawRect
1290 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001291 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001292 const GrRect* srcRects[]);
1293
1294 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001295 const GrMatrix* matrix,
1296 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001297 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001298 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001299 void* vertices);
1300
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001301 // accessor for derived classes
1302 const GeometrySrcState& getGeomSrc() const {
1303 return fGeoSrcStateStack.back();
1304 }
reed@google.comac10a2d2010-12-22 21:39:39 +00001305
1306 GrClip fClip;
1307
reed@google.com8195f672011-01-12 18:14:28 +00001308 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001309
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001310private:
1311 // called when setting a new vert/idx source to unref prev vb/ib
1312 void releasePreviousVertexSource();
1313 void releasePreviousIndexSource();
1314
1315 enum {
1316 kPreallocGeoSrcStateStackCnt = 4,
reed@google.comac10a2d2010-12-22 21:39:39 +00001317 };
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001318 GrAlignedSTStorage<kPreallocGeoSrcStateStackCnt,
1319 GeometrySrcState>
1320 fGeoSrcStateStackStorage;
1321 GrTArray<GeometrySrcState, true> fGeoSrcStateStack;
1322
reed@google.comac10a2d2010-12-22 21:39:39 +00001323};
1324
1325#endif