blob: d8d0498ae3b5021a35d853b74c7fea33becdfd58 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#ifndef GrDrawTarget_DEFINED
19#define GrDrawTarget_DEFINED
20
reed@google.comac10a2d2010-12-22 21:39:39 +000021#include "GrMatrix.h"
22#include "GrColor.h"
23#include "GrRefCnt.h"
24#include "GrSamplerState.h"
25#include "GrClip.h"
bsalomon@google.comd302f142011-03-03 13:54:13 +000026#include "GrTexture.h"
27#include "GrStencil.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000028
Scroggo97c88c22011-05-11 14:05:25 +000029#include "SkXfermode.h"
30
reed@google.comac10a2d2010-12-22 21:39:39 +000031class GrTexture;
reed@google.comac10a2d2010-12-22 21:39:39 +000032class GrClipIterator;
33class GrVertexBuffer;
34class GrIndexBuffer;
35
36class GrDrawTarget : public GrRefCnt {
37public:
38 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +000039 * Number of texture stages. Each stage takes as input a color and
40 * 2D texture coordinates. The color input to the first enabled stage is the
41 * per-vertex color or the constant color (setColor/setAlpha) if there are
42 * no per-vertex colors. For subsequent stages the input color is the output
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000043 * color from the previous enabled stage. The output color of each stage is
bsalomon@google.com5782d712011-01-21 21:03:59 +000044 * the input color modulated with the result of a texture lookup. Texture
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000045 * lookups are specified by a texture a sampler (setSamplerState). Texture
46 * coordinates for each stage come from the vertices based on a
47 * GrVertexLayout bitfield. The output fragment color is the output color of
48 * the last enabled stage. The presence or absence of texture coordinates
49 * for each stage in the vertex layout indicates whether a stage is enabled
50 * or not.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000051 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000052 enum {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000053 kNumStages = 3,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000054 kMaxTexCoords = kNumStages
55 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000056
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +000057
58 /**
59 * The absolute maximum number of edges that may be specified for
60 * a single draw call when performing edge antialiasing. This is used for
61 * the size of several static buffers, so implementations of getMaxEdges()
62 * (below) should clamp to this value.
63 */
64 enum {
65 kMaxEdges = 32
66 };
67
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000068 /**
bsalomon@google.comffca4002011-02-22 20:34:01 +000069 * Bitfield used to indicate which stages are in use.
reed@google.comac10a2d2010-12-22 21:39:39 +000070 */
bsalomon@google.comffca4002011-02-22 20:34:01 +000071 typedef int StageBitfield;
72 GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
reed@google.comac10a2d2010-12-22 21:39:39 +000073
74 /**
75 * Flags that affect rendering. Controlled using enable/disableState(). All
76 * default to disabled.
77 */
78 enum StateBits {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000079 kDither_StateBit = 0x01, //<! Perform color dithering
80 kAntialias_StateBit = 0x02, //<! Perform anti-aliasing. The render-
reed@google.comac10a2d2010-12-22 21:39:39 +000081 // target must support some form of AA
82 // (msaa, coverage sampling, etc). For
83 // GrGpu-created rendertarget/textures
84 // this is controlled by parameters
85 // passed to createTexture.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000086 kClip_StateBit = 0x04, //<! Controls whether drawing is clipped
reed@google.comac10a2d2010-12-22 21:39:39 +000087 // against the region specified by
88 // setClip.
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000089 kNoColorWrites_StateBit = 0x08, //<! If set it disables writing colors.
90 // Useful while performing stencil
91 // ops.
bsalomon@google.comd302f142011-03-03 13:54:13 +000092
93 // subclass may use additional bits internally
94 kDummyStateBit,
95 kLastPublicStateBit = kDummyStateBit-1
96 };
97
98 enum DrawFace {
99 kBoth_DrawFace,
100 kCCW_DrawFace,
101 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +0000102 };
103
104 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000105 * The DrawTarget may reserve some of the high bits of the stencil. The draw
106 * target will automatically trim reference and mask values so that the
107 * client doesn't overwrite these bits.
108 * The number of bits available is relative to the currently set render
109 *target.
110 * @return the number of bits usable by the draw target client.
reed@google.comac10a2d2010-12-22 21:39:39 +0000111 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000112 int getUsableStencilBits() const {
113 int bits = fCurrDrawState.fRenderTarget->stencilBits();
114 if (bits) {
115 return bits - 1;
116 } else {
117 return 0;
118 }
119 }
120
121 /**
122 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000123 * Changing the clip has the side-effect of possibly zeroing
124 * out the client settable stencil bits. So multipass algorithms
125 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000126 * @param settings the stencil settings to use.
127 */
128 void setStencil(const GrStencilSettings& settings) {
129 fCurrDrawState.fStencilSettings = settings;
130 }
131
132 /**
133 * Shortcut to disable stencil testing and ops.
134 */
135 void disableStencil() {
136 fCurrDrawState.fStencilSettings.setDisabled();
137 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000138
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000139 class Edge {
140 public:
141 Edge() {}
142 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
143 GrPoint intersect(const Edge& other) {
144 return GrPoint::Make(
145 (fY * other.fZ - other.fY * fZ) /
146 (fX * other.fY - other.fX * fY),
147 (fX * other.fZ - other.fX * fZ) /
148 (other.fX * fY - fX * other.fY));
149 }
150 float fX, fY, fZ;
151 };
152
reed@google.comac10a2d2010-12-22 21:39:39 +0000153protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000154
reed@google.com8195f672011-01-12 18:14:28 +0000155 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000156 DrState() {
157 // make sure any pad is zero for memcmp
158 // all DrState members should default to something
159 // valid by the memset
160 memset(this, 0, sizeof(DrState));
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000161
162 // memset exceptions
Scroggo97c88c22011-05-11 14:05:25 +0000163 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000164 fFirstCoverageStage = kNumStages;
165
166 // pedantic assertion that our ptrs will
167 // be NULL (0 ptr is mem addr 0)
bsalomon@google.comd302f142011-03-03 13:54:13 +0000168 GrAssert((intptr_t)(void*)NULL == 0LL);
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000169
170 // default stencil setting should be disabled
bsalomon@google.comd302f142011-03-03 13:54:13 +0000171 GrAssert(fStencilSettings.isDisabled());
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000172 fFirstCoverageStage = kNumStages;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000173 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000174 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000175 GrBlendCoeff fSrcBlend;
176 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000177 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000178 GrTexture* fTextures[kNumStages];
179 GrSamplerState fSamplerStates[kNumStages];
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000180 int fFirstCoverageStage;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000181 GrRenderTarget* fRenderTarget;
182 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000183 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000184 GrColor fColorFilterColor;
185 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000186
187 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000188 GrMatrix fViewMatrix;
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000189 Edge fEdgeAAEdges[kMaxEdges];
190 int fEdgeAANumEdges;
reed@google.com8195f672011-01-12 18:14:28 +0000191 bool operator ==(const DrState& s) const {
192 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000193 }
reed@google.com8195f672011-01-12 18:14:28 +0000194 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000195 };
196
197public:
198 ///////////////////////////////////////////////////////////////////////////
199
200 GrDrawTarget();
201
202 /**
203 * Sets the current clip to the region specified by clip. All draws will be
204 * clipped against this clip if kClip_StateBit is enabled.
205 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000206 * Setting the clip may (or may not) zero out the client's stencil bits.
207 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000208 * @param description of the clipping region
209 */
210 void setClip(const GrClip& clip);
211
212 /**
213 * Gets the current clip.
214 *
215 * @return the clip.
216 */
217 const GrClip& getClip() const;
218
219 /**
220 * Sets the texture used at the next drawing call
221 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000222 * @param stage The texture stage for which the texture will be set
223 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000224 * @param texture The texture to set. Can be NULL though there is no advantage
225 * to settings a NULL texture if doing non-textured drawing
226 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000227 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000228
229 /**
230 * Retrieves the currently set texture.
231 *
232 * @return The currently set texture. The return value will be NULL if no
233 * texture has been set, NULL was most recently passed to
234 * setTexture, or the last setTexture was destroyed.
235 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000236 const GrTexture* getTexture(int stage) const;
237 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000238
239 /**
240 * Sets the rendertarget used at the next drawing call
241 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000242 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000243 */
244 void setRenderTarget(GrRenderTarget* target);
245
246 /**
247 * Retrieves the currently set rendertarget.
248 *
249 * @return The currently set render target.
250 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000251 const GrRenderTarget* getRenderTarget() const;
252 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000253
254 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000255 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000256 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000257 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000258 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000259 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000260 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000261 * @param samplerState Specifies the sampler state.
262 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000263 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000264
265 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000266 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000267 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000268 * @param stage the stage of the sampler to set
269 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000270 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000271 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
272 GrAssert(stage >= 0 && stage < kNumStages);
273 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000274 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000275
276 /**
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000277 * Shortcut for preConcatSamplerMatrix on all stages in mask with same
278 * matrix
279 */
280 void preConcatSamplerMatrices(int stageMask, const GrMatrix& matrix) {
281 for (int i = 0; i < kNumStages; ++i) {
282 if ((1 << i) & stageMask) {
283 this->preConcatSamplerMatrix(i, matrix);
284 }
285 }
286 }
287
288 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000289 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000290 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000291 * @param stage the stage to of sampler to get
292 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000293 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000294 const GrMatrix& getSamplerMatrix(int stage) const {
295 return fCurrDrawState.fSamplerStates[stage].getMatrix();
296 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000297
298 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000299 * Sets the matrix of a stage's sampler
300 *
301 * @param stage the stage of sampler set
302 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000303 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000304 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000305 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
306 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000307
308 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000309 * Sets the matrix applied to veretx positions.
310 *
311 * In the post-view-matrix space the rectangle [0,w]x[0,h]
312 * fully covers the render target. (w and h are the width and height of the
313 * the rendertarget.)
314 *
315 * @param m the matrix used to transform the vertex positions.
316 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000317 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000318
319 /**
320 * Multiplies the current view matrix by a matrix
321 *
322 * After this call V' = V*m where V is the old view matrix,
323 * m is the parameter to this function, and V' is the new view matrix.
324 * (We consider positions to be column vectors so position vector p is
325 * transformed by matrix X as p' = X*p.)
326 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000327 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000328 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000329 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000330
331 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000332 * Multiplies the current view matrix by a matrix
333 *
334 * After this call V' = m*V where V is the old view matrix,
335 * m is the parameter to this function, and V' is the new view matrix.
336 * (We consider positions to be column vectors so position vector p is
337 * transformed by matrix X as p' = X*p.)
338 *
339 * @param m the matrix used to modify the view matrix.
340 */
341 void postConcatViewMatrix(const GrMatrix& m);
342
343 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000344 * Retrieves the current view matrix
345 * @return the current view matrix.
346 */
347 const GrMatrix& getViewMatrix() const;
348
349 /**
350 * Retrieves the inverse of the current view matrix.
351 *
352 * If the current view matrix is invertible, return true, and if matrix
353 * is non-null, copy the inverse into it. If the current view matrix is
354 * non-invertible, return false and ignore the matrix parameter.
355 *
356 * @param matrix if not null, will receive a copy of the current inverse.
357 */
358 bool getViewInverse(GrMatrix* matrix) const;
359
360 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000361 * Sets color for next draw to a premultiplied-alpha color.
362 *
363 * @param the color to set.
364 */
365 void setColor(GrColor);
366
367 /**
Scroggo97c88c22011-05-11 14:05:25 +0000368 * Add a color filter that can be represented by a color and a mode.
369 */
370 void setColorFilter(GrColor, SkXfermode::Mode);
371
372 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000373 * Sets the color to be used for the next draw to be
374 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
375 *
376 * @param alpha The alpha value to set as the color.
377 */
378 void setAlpha(uint8_t alpha);
379
380 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000381 * Controls whether clockwise, counterclockwise, or both faces are drawn.
382 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000383 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000384 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000385
386 /**
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000387 * A common pattern is to compute a color with the initial stages and then
388 * modulate that color by a coverage value in later stage(s) (AA, mask-
389 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
390 * computed based on the pre-coverage-modulated color. The division of
391 * stages between color-computing and coverage-computing is specified by
392 * this method. Initially this is kNumStages (all stages are color-
393 * computing).
394 */
395 void setFirstCoverageStage(int firstCoverageStage) {
396 fCurrDrawState.fFirstCoverageStage = firstCoverageStage;
397 }
398
399 /**
400 * Gets the index of the first coverage-computing stage.
401 */
402 int getFirstCoverageStage() const {
403 return fCurrDrawState.fFirstCoverageStage;
404 }
405
406 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000407 * Gets whether the target is drawing clockwise, counterclockwise,
408 * or both faces.
409 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000410 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000411 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000412
413 /**
414 * Enable render state settings.
415 *
416 * @param flags bitfield of StateBits specifing the states to enable
417 */
418 void enableState(uint32_t stateBits);
419
420 /**
421 * Disable render state settings.
422 *
423 * @param flags bitfield of StateBits specifing the states to disable
424 */
425 void disableState(uint32_t stateBits);
426
427 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000428 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
429 }
430
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000431 bool isAntialiasState() const {
432 return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
433 }
434
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000435 bool isClipState() const {
436 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000437 }
438
bsalomon@google.comd302f142011-03-03 13:54:13 +0000439 bool isColorWriteDisabled() const {
440 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
441 }
442
reed@google.comac10a2d2010-12-22 21:39:39 +0000443 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000444 * Sets the blending function coeffecients.
445 *
446 * The blend function will be:
447 * D' = sat(S*srcCoef + D*dstCoef)
448 *
449 * where D is the existing destination color, S is the incoming source
450 * color, and D' is the new destination color that will be written. sat()
451 * is the saturation function.
452 *
453 * @param srcCoef coeffecient applied to the src color.
454 * @param dstCoef coeffecient applied to the dst color.
455 */
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000456 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
reed@google.comac10a2d2010-12-22 21:39:39 +0000457
458 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000459 * Sets the blending function constant referenced by the following blending
460 * coeffecients:
461 * kConstC_BlendCoeff
462 * kIConstC_BlendCoeff
463 * kConstA_BlendCoeff
464 * kIConstA_BlendCoeff
465 *
466 * @param constant the constant to set
467 */
468 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
469
470 /**
471 * Retrieves the last value set by setBlendConstant()
472 * @return the blending constant value
473 */
474 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
475
476 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000477 * Used to save and restore the GrGpu's drawing state
478 */
479 struct SavedDrawState {
480 private:
reed@google.com8195f672011-01-12 18:14:28 +0000481 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000482 friend class GrDrawTarget;
483 };
484
485 /**
486 * Saves the current draw state. The state can be restored at a later time
487 * with restoreDrawState.
488 *
489 * See also AutoStateRestore class.
490 *
491 * @param state will hold the state after the function returns.
492 */
493 void saveCurrentDrawState(SavedDrawState* state) const;
494
495 /**
496 * Restores previously saved draw state. The client guarantees that state
497 * was previously passed to saveCurrentDrawState and that the rendertarget
498 * and texture set at save are still valid.
499 *
500 * See also AutoStateRestore class.
501 *
502 * @param state the previously saved state to restore.
503 */
504 void restoreDrawState(const SavedDrawState& state);
505
506 /**
507 * Copies the draw state from another target to this target.
508 *
509 * @param srcTarget draw target used as src of the draw state.
510 */
511 void copyDrawState(const GrDrawTarget& srcTarget);
512
513 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000514 * The format of vertices is represented as a bitfield of flags.
515 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000516 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000517 * coordinates and per-vertex colors. Each stage can use any of the texture
518 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000519 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000520 * If no texture coordinates are specified for a stage then the stage is
521 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000522 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000523 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000524 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000525 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000526 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000527 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000528 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000529 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000530 * the order would be (position, texture coordinate 1[, color]).
531 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000532
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000533 /**
534 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000535 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000536 * @param stage the stage that will use texture coordinates.
537 * @param texCoordIdx the index of the texture coordinates to use
538 *
539 * @return the bit to add to a GrVertexLayout bitfield.
540 */
541 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
542 GrAssert(stage < kNumStages);
543 GrAssert(texCoordIdx < kMaxTexCoords);
544 return 1 << (stage + (texCoordIdx * kNumStages));
545 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000546
547 /**
548 * Determines if blend is effectively disabled.
549 *
550 * @return true if blend can be disabled without changing the rendering
551 * result given the current state including the vertex layout specified
552 * with the vertex source.
553 */
554 bool canDisableBlend() const;
555
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000556 /**
557 * Sets the edge data required for edge antialiasing.
558 *
559 * @param edges 3 * 6 float values, representing the edge
560 * equations in Ax + By + C form
561 */
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000562 void setEdgeAAData(const Edge* edges, int numEdges);
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000563
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000564private:
565 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
566public:
567 /**
568 * Generates a bit indicating that a texture stage uses the position
569 * as its texture coordinate.
570 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000571 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000572 * coordinates.
573 *
574 * @return the bit to add to a GrVertexLayout bitfield.
575 */
576 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
577 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000578 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000579 }
580private:
581 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000582
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000583public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000584
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000585 /**
586 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000587 */
588 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000589
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000590 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
591 //<! vertices have colors
592 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
593 //<! use text vertices. (Pos
594 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000595 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000596 // text [GrGpuTextVertex vs
597 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000598 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000599 kDummyVertexLayoutBit,
600 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000601 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000602 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000603 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000604
605 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000606 * There are three paths for specifying geometry (vertices and optionally
607 * indices) to the draw target. When indexed drawing the indices and vertices
608 * can be each use a different path.
609 *
610 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
611 * caller's client has already provided vertex data in a format
612 * the time compatible with a GrVertexLayout. The array must contain the
613 * data at set*SourceToArray is called. The source stays in effect for
614 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
615 * again or one of the other two paths is chosen.
616 *
617 * 2. Reserve and Lock. This is most useful when the caller has data it must
618 * transform before drawing and will not likely render it again. The
619 * caller requests that the draw target make room for some amount of
620 * vertex and/or index data. The target provides ptrs to hold the data
621 * data. The caller can write the data into the pts up until the first
622 * drawIndexed or drawNonIndexed call. At this point the data is frozen
623 * and the ptrs are no longer guaranteed to be valid. All subsequent
624 * drawIndexed & drawNonIndexed calls will use this data until
625 * releaseReserved geometry is called. This must be called before another
626 * source is set.
627 *
628 * 3. Vertex and Index Buffers. This is most useful for geometry that will
629 * be rendered multiple times. SetVertexSourceToBuffer &
630 * SetIndexSourceToBuffer are used to set the buffer and subsequent
631 * drawIndexed and drawNonIndexed calls use this source until another
632 * source is set.
633 */
634
635 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000636 * Reserves space for vertices and/or indices. Draw target will use
637 * reserved vertices / indices at next draw.
638 *
639 * If succeeds:
640 * if vertexCount is nonzero, *vertices will be the array
641 * of vertices to be filled by caller. The next draw will read
642 * these vertices.
643 *
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000644 * if indexCount is nonzero, *indices will be the array of indices
reed@google.comac10a2d2010-12-22 21:39:39 +0000645 * to be filled by caller. The next indexed draw will read from
646 * these indices.
647 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000648 * If a client does not already have a vertex buffer then this is the
649 * preferred way to allocate vertex/index array. It allows the subclass of
650 * GrDrawTarget to decide whether to put data in buffers, to group vertex
651 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000652 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000653 * Following the first draw after reserveAndLockGeometry the ptrs returned
654 * by releaseReservedGeometry are no longer valid and the geometry data
655 * cannot be further modified. The contents that were put in the reserved
656 * space can be drawn by multiple draws, however.
657 *
658 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
659 * call after all draws that reference the reserved geometry data have
660 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000661 *
662 * AutoGeometryRelease can be used to automatically call the release.
663 *
664 * @param vertexCount the number of vertices to reserve space for. Can be 0.
665 * @param indexCount the number of indices to reserve space for. Can be 0.
666 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
667 * @param vertices will point to reserved vertex space if vertexCount is
668 * non-zero. Illegal to pass NULL if vertexCount > 0.
669 * @param indices will point to reserved index space if indexCount is
670 * non-zero. Illegal to pass NULL if indexCount > 0.
671 *
672 * @return true if succeeded in allocating space for the vertices and false
673 * if not.
674 */
675 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
676 uint32_t vertexCount,
677 uint32_t indexCount,
678 void** vertices,
679 void** indices);
680 /**
681 * Provides hints to caller about the number of vertices and indices
682 * that can be allocated cheaply. This can be useful if caller is reserving
683 * space but doesn't know exactly how much geometry is needed.
684 *
685 * Also may hint whether the draw target should be flushed first. This is
686 * useful for deferred targets.
687 *
688 * @param vertexLayout layout of vertices caller would like to reserve
689 * @param vertexCount in: hint about how many vertices the caller would
690 * like to allocate.
691 * out: a hint about the number of vertices that can be
692 * allocated cheaply. Negative means no hint.
693 * Ignored if NULL.
694 * @param indexCount in: hint about how many indices the caller would
695 * like to allocate.
696 * out: a hint about the number of indices that can be
697 * allocated cheaply. Negative means no hint.
698 * Ignored if NULL.
699 *
700 * @return true if target should be flushed based on the input values.
701 */
702 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000703 int* vertexCount,
704 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000705
706 /**
707 * Releases reserved vertex/index data from reserveAndLockGeometry().
708 */
709 void releaseReservedGeometry();
710
711 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000712 * Sets source of vertex data for the next draw. Array must contain
713 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000714 *
715 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000716 * @param size size of the vertex data.
717 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000718 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000719 void setVertexSourceToArray(GrVertexLayout vertexLayout,
720 const void* vertexArray,
721 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000722
723 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000724 * Sets source of index data for the next indexed draw. Array must contain
725 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000726 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000727 * @param array cpu array containing index data.
728 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000729 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000730 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000731
732 /**
733 * Sets source of vertex data for the next draw. Data does not have to be
734 * in the buffer until drawIndexed or drawNonIndexed.
735 *
736 * @param buffer vertex buffer containing vertex data. Must be
737 * unlocked before draw call.
738 * @param vertexLayout layout of the vertex data in the buffer.
739 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000740 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
741 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000742
743 /**
744 * Sets source of index data for the next indexed draw. Data does not have
745 * to be in the buffer until drawIndexed or drawNonIndexed.
746 *
747 * @param buffer index buffer containing indices. Must be unlocked
748 * before indexed draw call.
749 */
750 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
751
752 /**
753 * Draws indexed geometry using the current state and current vertex / index
754 * sources.
755 *
756 * @param type The type of primitives to draw.
757 * @param startVertex the vertex in the vertex array/buffer corresponding
758 * to index 0
759 * @param startIndex first index to read from index src.
760 * @param vertexCount one greater than the max index.
761 * @param indexCount the number of index elements to read. The index count
762 * is effectively trimmed to the last completely
763 * specified primitive.
764 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000765 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000766 int startVertex,
767 int startIndex,
768 int vertexCount,
769 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000770
771 /**
772 * Draws non-indexed geometry using the current state and current vertex
773 * sources.
774 *
775 * @param type The type of primitives to draw.
776 * @param startVertex the vertex in the vertex array/buffer corresponding
777 * to index 0
778 * @param vertexCount one greater than the max index.
779 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000780 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000781 int startVertex,
782 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000783
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000784 /**
785 * Helper function for drawing rects. This does not use the current index
786 * and vertex sources. After returning, the vertex and index sources may
787 * have changed. They should be reestablished before the next drawIndexed
788 * or drawNonIndexed. This cannot be called between reserving and releasing
789 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000790 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000791 * drawNonIndexed.
792 * @param rect the rect to draw
793 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000794 * @param stageEnableBitfield bitmask indicating which stages are enabled.
795 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000796 * @param srcRects specifies rects for stages enabled by stageEnableMask.
797 * if stageEnableMask bit i is 1, srcRects is not NULL,
798 * and srcRects[i] is not NULL, then srcRects[i] will be
799 * used as coordinates for stage i. Otherwise, if stage i
800 * is enabled then rect is used as the coordinates.
801 * @param srcMatrices optional matrices applied to srcRects. If
802 * srcRect[i] is non-NULL and srcMatrices[i] is
803 * non-NULL then srcRect[i] will be transformed by
804 * srcMatrix[i]. srcMatrices can be NULL when no
805 * srcMatrices are desired.
806 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000807 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000808 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000809 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000810 const GrRect* srcRects[],
811 const GrMatrix* srcMatrices[]);
812
813 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000814 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000815 * matrices.
816 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000817 void drawSimpleRect(const GrRect& rect,
818 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000819 StageBitfield stageEnableBitfield) {
820 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000821 }
822
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000823 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000824 * Clear the render target. Ignores the clip and all other draw state
825 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
826 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000827 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000828 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000829
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000830 /**
831 * Returns the maximum number of edges that may be specified in a single
832 * draw call when performing edge antialiasing. This is usually limited
833 * by the number of fragment uniforms which may be uploaded. Must be a
834 * minimum of six, since a triangle's vertices each belong to two boundary
835 * edges which may be distinct.
836 */
837 virtual int getMaxEdges() const { return 6; }
838
reed@google.comac10a2d2010-12-22 21:39:39 +0000839 ///////////////////////////////////////////////////////////////////////////
840
841 class AutoStateRestore : ::GrNoncopyable {
842 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000843 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000844 AutoStateRestore(GrDrawTarget* target);
845 ~AutoStateRestore();
846
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000847 /**
848 * if this object is already saving state for param target then
849 * this does nothing. Otherise, it restores previously saved state on
850 * previous target (if any) and saves current state on param target.
851 */
852 void set(GrDrawTarget* target);
853
reed@google.comac10a2d2010-12-22 21:39:39 +0000854 private:
855 GrDrawTarget* fDrawTarget;
856 SavedDrawState fDrawState;
857 };
858
859 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000860
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000861 class AutoViewMatrixRestore : ::GrNoncopyable {
862 public:
863 AutoViewMatrixRestore() {
864 fDrawTarget = NULL;
865 }
866
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000867 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000868 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
869 GrAssert(NULL != target);
870 }
871
872 void set(GrDrawTarget* target) {
873 GrAssert(NULL != target);
874 if (NULL != fDrawTarget) {
875 fDrawTarget->setViewMatrix(fMatrix);
876 }
877 fDrawTarget = target;
878 fMatrix = target->getViewMatrix();
879 }
880
881 ~AutoViewMatrixRestore() {
882 if (NULL != fDrawTarget) {
883 fDrawTarget->setViewMatrix(fMatrix);
884 }
885 }
886
887 private:
888 GrDrawTarget* fDrawTarget;
889 GrMatrix fMatrix;
890 };
891
892 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000893
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000894 /**
895 * Sets the view matrix to I and preconcats all stage matrices enabled in
896 * mask by the view inverse. Destructor undoes these changes.
897 */
898 class AutoDeviceCoordDraw : ::GrNoncopyable {
899 public:
900 AutoDeviceCoordDraw(GrDrawTarget* target, int stageMask);
901 ~AutoDeviceCoordDraw();
902 private:
903 GrDrawTarget* fDrawTarget;
904 GrMatrix fViewMatrix;
905 GrMatrix fSamplerMatrices[kNumStages];
906 int fStageMask;
907 };
908
909 ///////////////////////////////////////////////////////////////////////////
910
reed@google.comac10a2d2010-12-22 21:39:39 +0000911 class AutoReleaseGeometry : ::GrNoncopyable {
912 public:
913 AutoReleaseGeometry(GrDrawTarget* target,
914 GrVertexLayout vertexLayout,
915 uint32_t vertexCount,
916 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000917 fTarget = NULL;
918 this->set(target, vertexLayout, vertexCount, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000919 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000920
921 AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000922 fTarget = NULL;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000923 }
924
reed@google.comac10a2d2010-12-22 21:39:39 +0000925 ~AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000926 if (NULL != fTarget) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000927 fTarget->releaseReservedGeometry();
928 }
929 }
930
bsalomon@google.com5782d712011-01-21 21:03:59 +0000931 bool set(GrDrawTarget* target,
932 GrVertexLayout vertexLayout,
933 uint32_t vertexCount,
934 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000935 if (NULL != fTarget) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000936 fTarget->releaseReservedGeometry();
937 }
938 fTarget = target;
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000939 if (NULL != fTarget) {
940 if (!fTarget->reserveAndLockGeometry(vertexLayout,
941 vertexCount,
942 indexCount,
943 &fVertices,
944 &fIndices)) {
945 fTarget = NULL;
946 }
947 }
948 return NULL != fTarget;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000949 }
950
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000951 bool succeeded() const { return NULL != fTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000952 void* vertices() const { return fVertices; }
953 void* indices() const { return fIndices; }
954
955 GrPoint* positions() const {
956 return static_cast<GrPoint*>(fVertices);
957 }
958
959 private:
960 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000961 void* fVertices;
962 void* fIndices;
963 };
964
965 ///////////////////////////////////////////////////////////////////////////
966
967 class AutoClipRestore : ::GrNoncopyable {
968 public:
969 AutoClipRestore(GrDrawTarget* target) {
970 fTarget = target;
971 fClip = fTarget->getClip();
972 }
973
974 ~AutoClipRestore() {
975 fTarget->setClip(fClip);
976 }
977 private:
978 GrDrawTarget* fTarget;
979 GrClip fClip;
980 };
981
982 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000983 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000984
reed@google.comac10a2d2010-12-22 21:39:39 +0000985 /**
986 * Helper function to compute the size of a vertex from a vertex layout
987 * @return size of a single vertex.
988 */
989 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000990
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000991 /**
992 * Helper function for determining the index of texture coordinates that
993 * is input for a texture stage. Note that a stage may instead use positions
994 * as texture coordinates, in which case the result of the function is
995 * indistinguishable from the case when the stage is disabled.
996 *
997 * @param stage the stage to query
998 * @param vertexLayout layout to query
999 *
1000 * @return the texture coordinate index or -1 if the stage doesn't use
1001 * separate (non-position) texture coordinates.
1002 */
1003 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001004
1005 /**
1006 * Helper function to compute the offset of texture coordinates in a vertex
1007 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +00001008 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001009 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001010 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001011 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001012
1013 /**
1014 * Helper function to compute the offset of the color in a vertex
1015 * @return offset of color in vertex layout or -1 if the
1016 * layout has no color.
1017 */
1018 static int VertexColorOffset(GrVertexLayout vertexLayout);
1019
1020 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001021 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001022 * coordinates of some index.
1023 *
1024 * @param coordIndex the tex coord index to query
1025 * @param vertexLayout layout to query
1026 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001027 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001028 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001029 */
bsalomon@google.com5782d712011-01-21 21:03:59 +00001030 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001031 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001032
reed@google.comac10a2d2010-12-22 21:39:39 +00001033 /**
1034 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001035 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001036 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001037 * @param stage the stage to query
1038 * @param vertexLayout layout to query
1039 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001040 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001041 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001042 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001043 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001044
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001045 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001046 * Helper function to compute the size of each vertex and the offsets of
1047 * texture coordinates and color. Determines tex coord offsets by tex coord
1048 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001049 * by StageTexCoordVertexLayoutBit.)
1050 *
1051 * @param vertexLayout the layout to query
1052 * @param texCoordOffsetsByIdx after return it is the offset of each
1053 * tex coord index in the vertex or -1 if
1054 * index isn't used.
1055 * @return size of a single vertex
1056 */
1057 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
1058 int texCoordOffsetsByIdx[kMaxTexCoords],
1059 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001060
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001061 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001062 * Helper function to compute the size of each vertex and the offsets of
1063 * texture coordinates and color. Determines tex coord offsets by stage
1064 * rather than by index. (Each stage can be mapped to any t.c. index
1065 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001066 * tex coords then that stage's offset will be 0 (positions are always at 0).
1067 *
1068 * @param vertexLayout the layout to query
1069 * @param texCoordOffsetsByStage after return it is the offset of each
1070 * tex coord index in the vertex or -1 if
1071 * index isn't used.
1072 * @return size of a single vertex
1073 */
1074 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1075 int texCoordOffsetsByStage[kNumStages],
1076 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001077
1078 /**
1079 * Accessing positions, texture coords, or colors, of a vertex within an
1080 * array is a hassle involving casts and simple math. These helpers exist
1081 * to keep GrDrawTarget clients' code a bit nicer looking.
1082 */
1083
1084 /**
1085 * Gets a pointer to a GrPoint of a vertex's position or texture
1086 * coordinate.
1087 * @param vertices the vetex array
1088 * @param vertexIndex the index of the vertex in the array
1089 * @param vertexSize the size of each vertex in the array
1090 * @param offset the offset in bytes of the vertex component.
1091 * Defaults to zero (corresponding to vertex position)
1092 * @return pointer to the vertex component as a GrPoint
1093 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001094 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001095 int vertexIndex,
1096 int vertexSize,
1097 int offset = 0) {
1098 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001099 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001100 vertexIndex * vertexSize);
1101 }
1102 static const GrPoint* GetVertexPoint(const void* vertices,
1103 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001104 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001105 int offset = 0) {
1106 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001107 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001108 vertexIndex * vertexSize);
1109 }
1110
1111 /**
1112 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1113 * @param vertices the vetex array
1114 * @param vertexIndex the index of the vertex in the array
1115 * @param vertexSize the size of each vertex in the array
1116 * @param offset the offset in bytes of the vertex color
1117 * @return pointer to the vertex component as a GrColor
1118 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001119 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001120 int vertexIndex,
1121 int vertexSize,
1122 int offset) {
1123 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001124 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001125 vertexIndex * vertexSize);
1126 }
1127 static const GrColor* GetVertexColor(const void* vertices,
1128 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001129 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001130 int offset) {
1131 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001132 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001133 vertexIndex * vertexSize);
1134 }
1135
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001136 static void VertexLayoutUnitTest();
1137
reed@google.comac10a2d2010-12-22 21:39:39 +00001138protected:
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001139 // given a vertex layout and a draw state, will a stage be used?
1140 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1141 const DrState& state) {
1142 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1143 }
1144
1145 bool isStageEnabled(int stage) const {
1146 return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
1147 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001148
reed@google.comac10a2d2010-12-22 21:39:39 +00001149 // Helpers for GrDrawTarget subclasses that won't have private access to
1150 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001151 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001152 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001153 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001154 { return sds.fState; }
1155
1156 // implemented by subclass
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001157 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
1158 void** vertices,
1159 void** indices) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001160
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001161 virtual void onReleaseGeometry() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001162
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001163 // subclass overrides to be notified when clip is set.
1164 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001165
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001166 virtual void onSetVertexSourceToArray(const void* vertexArray,
1167 int vertexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001168
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001169 virtual void onSetIndexSourceToArray(const void* indexArray,
1170 int indexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001171
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001172 // Helpers for drawRect, protected so subclasses that override drawRect
1173 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001174 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001175 const GrRect* srcRects[]);
1176
1177 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001178 const GrMatrix* matrix,
1179 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001180 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001181 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001182 void* vertices);
1183
reed@google.comac10a2d2010-12-22 21:39:39 +00001184 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001185 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
1186 kArray_GeometrySrcType, // src was set using set*SourceToArray
1187 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +00001188 };
1189
bsalomon@google.comd302f142011-03-03 13:54:13 +00001190 struct ReservedGeometry {
reed@google.comac10a2d2010-12-22 21:39:39 +00001191 bool fLocked;
1192 uint32_t fVertexCount;
1193 uint32_t fIndexCount;
1194 } fReservedGeometry;
1195
1196 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001197 GeometrySrcType fVertexSrc;
1198 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
1199 GeometrySrcType fIndexSrc;
1200 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
1201 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +00001202 } fGeometrySrc;
1203
1204 GrClip fClip;
1205
reed@google.com8195f672011-01-12 18:14:28 +00001206 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001207
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001208 // Not meant for external use. Only setVertexSourceToBuffer and
1209 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
1210 // support nested reserveAndLockGeometry (and cpu arrays internally use the
1211 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +00001212 class AutoGeometrySrcRestore {
1213 public:
1214 AutoGeometrySrcRestore(GrDrawTarget* target) {
1215 fTarget = target;
1216 fGeometrySrc = fTarget->fGeometrySrc;
1217 }
1218 ~AutoGeometrySrcRestore() {
1219 fTarget->fGeometrySrc = fGeometrySrc;
1220 }
1221 private:
1222 GrDrawTarget *fTarget;
1223 GeometrySrc fGeometrySrc;
1224
1225 AutoGeometrySrcRestore();
1226 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
1227 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
1228 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001229};
1230
1231#endif