blob: d576d8043c9f70dbd3627192a913ed5342accd3b [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.
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +000092 kEdgeAAConcave_StateBit = 0x10,//<! If set, edge AA will test edge
93 // pairs for convexity while
94 // rasterizing. Set this if the
95 // source polygon is non-convex.
bsalomon@google.comd302f142011-03-03 13:54:13 +000096
97 // subclass may use additional bits internally
98 kDummyStateBit,
99 kLastPublicStateBit = kDummyStateBit-1
100 };
101
102 enum DrawFace {
103 kBoth_DrawFace,
104 kCCW_DrawFace,
105 kCW_DrawFace,
reed@google.comac10a2d2010-12-22 21:39:39 +0000106 };
107
108 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000109 * The DrawTarget may reserve some of the high bits of the stencil. The draw
110 * target will automatically trim reference and mask values so that the
111 * client doesn't overwrite these bits.
112 * The number of bits available is relative to the currently set render
113 *target.
114 * @return the number of bits usable by the draw target client.
reed@google.comac10a2d2010-12-22 21:39:39 +0000115 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000116 int getUsableStencilBits() const {
117 int bits = fCurrDrawState.fRenderTarget->stencilBits();
118 if (bits) {
119 return bits - 1;
120 } else {
121 return 0;
122 }
123 }
124
125 /**
126 * Sets the stencil settings to use for the next draw.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000127 * Changing the clip has the side-effect of possibly zeroing
128 * out the client settable stencil bits. So multipass algorithms
129 * using stencil should not change the clip between passes.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000130 * @param settings the stencil settings to use.
131 */
132 void setStencil(const GrStencilSettings& settings) {
133 fCurrDrawState.fStencilSettings = settings;
134 }
135
136 /**
137 * Shortcut to disable stencil testing and ops.
138 */
139 void disableStencil() {
140 fCurrDrawState.fStencilSettings.setDisabled();
141 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000142
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000143 class Edge {
144 public:
145 Edge() {}
146 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
147 GrPoint intersect(const Edge& other) {
148 return GrPoint::Make(
149 (fY * other.fZ - other.fY * fZ) /
150 (fX * other.fY - other.fX * fY),
151 (fX * other.fZ - other.fX * fZ) /
152 (other.fX * fY - fX * other.fY));
153 }
154 float fX, fY, fZ;
155 };
156
reed@google.comac10a2d2010-12-22 21:39:39 +0000157protected:
reed@google.comac10a2d2010-12-22 21:39:39 +0000158
reed@google.com8195f672011-01-12 18:14:28 +0000159 struct DrState {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000160 DrState() {
161 // make sure any pad is zero for memcmp
162 // all DrState members should default to something
163 // valid by the memset
164 memset(this, 0, sizeof(DrState));
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000165
166 // memset exceptions
Scroggo97c88c22011-05-11 14:05:25 +0000167 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000168 fFirstCoverageStage = kNumStages;
169
170 // pedantic assertion that our ptrs will
171 // be NULL (0 ptr is mem addr 0)
bsalomon@google.comd302f142011-03-03 13:54:13 +0000172 GrAssert((intptr_t)(void*)NULL == 0LL);
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000173
174 // default stencil setting should be disabled
bsalomon@google.comd302f142011-03-03 13:54:13 +0000175 GrAssert(fStencilSettings.isDisabled());
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000176 fFirstCoverageStage = kNumStages;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000177 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000178 uint32_t fFlagBits;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000179 GrBlendCoeff fSrcBlend;
180 GrBlendCoeff fDstBlend;
bsalomon@google.com080773c2011-03-15 19:09:25 +0000181 GrColor fBlendConstant;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000182 GrTexture* fTextures[kNumStages];
183 GrSamplerState fSamplerStates[kNumStages];
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000184 int fFirstCoverageStage;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000185 GrRenderTarget* fRenderTarget;
186 GrColor fColor;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000187 DrawFace fDrawFace;
Scroggo97c88c22011-05-11 14:05:25 +0000188 GrColor fColorFilterColor;
189 SkXfermode::Mode fColorFilterXfermode;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000190
191 GrStencilSettings fStencilSettings;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000192 GrMatrix fViewMatrix;
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000193 Edge fEdgeAAEdges[kMaxEdges];
194 int fEdgeAANumEdges;
reed@google.com8195f672011-01-12 18:14:28 +0000195 bool operator ==(const DrState& s) const {
196 return 0 == memcmp(this, &s, sizeof(DrState));
reed@google.comac10a2d2010-12-22 21:39:39 +0000197 }
reed@google.com8195f672011-01-12 18:14:28 +0000198 bool operator !=(const DrState& s) const { return !(*this == s); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000199 };
200
201public:
202 ///////////////////////////////////////////////////////////////////////////
203
204 GrDrawTarget();
205
206 /**
207 * Sets the current clip to the region specified by clip. All draws will be
208 * clipped against this clip if kClip_StateBit is enabled.
209 *
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000210 * Setting the clip may (or may not) zero out the client's stencil bits.
211 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000212 * @param description of the clipping region
213 */
214 void setClip(const GrClip& clip);
215
216 /**
217 * Gets the current clip.
218 *
219 * @return the clip.
220 */
221 const GrClip& getClip() const;
222
223 /**
224 * Sets the texture used at the next drawing call
225 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000226 * @param stage The texture stage for which the texture will be set
227 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000228 * @param texture The texture to set. Can be NULL though there is no advantage
229 * to settings a NULL texture if doing non-textured drawing
230 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000231 void setTexture(int stage, GrTexture* texture);
reed@google.comac10a2d2010-12-22 21:39:39 +0000232
233 /**
234 * Retrieves the currently set texture.
235 *
236 * @return The currently set texture. The return value will be NULL if no
237 * texture has been set, NULL was most recently passed to
238 * setTexture, or the last setTexture was destroyed.
239 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000240 const GrTexture* getTexture(int stage) const;
241 GrTexture* getTexture(int stage);
reed@google.comac10a2d2010-12-22 21:39:39 +0000242
243 /**
244 * Sets the rendertarget used at the next drawing call
245 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000246 * @param target The render target to set.
reed@google.comac10a2d2010-12-22 21:39:39 +0000247 */
248 void setRenderTarget(GrRenderTarget* target);
249
250 /**
251 * Retrieves the currently set rendertarget.
252 *
253 * @return The currently set render target.
254 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000255 const GrRenderTarget* getRenderTarget() const;
256 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000257
258 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000259 * Sets the sampler state for a stage used in subsequent draws.
reed@google.comac10a2d2010-12-22 21:39:39 +0000260 *
bsalomon@google.comd302f142011-03-03 13:54:13 +0000261 * The sampler state determines how texture coordinates are
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000262 * intepretted and used to sample the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000263 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000264 * @param stage the stage of the sampler to set
reed@google.comac10a2d2010-12-22 21:39:39 +0000265 * @param samplerState Specifies the sampler state.
266 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000267 void setSamplerState(int stage, const GrSamplerState& samplerState);
reed@google.comac10a2d2010-12-22 21:39:39 +0000268
269 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000270 * Concats the matrix of a stage's sampler.
reed@google.comac10a2d2010-12-22 21:39:39 +0000271 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000272 * @param stage the stage of the sampler to set
273 * @param matrix the matrix to concat
reed@google.comac10a2d2010-12-22 21:39:39 +0000274 */
bsalomon@google.com27847de2011-02-22 20:59:41 +0000275 void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
276 GrAssert(stage >= 0 && stage < kNumStages);
277 fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000278 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000279
280 /**
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000281 * Shortcut for preConcatSamplerMatrix on all stages in mask with same
282 * matrix
283 */
284 void preConcatSamplerMatrices(int stageMask, const GrMatrix& matrix) {
285 for (int i = 0; i < kNumStages; ++i) {
286 if ((1 << i) & stageMask) {
287 this->preConcatSamplerMatrix(i, matrix);
288 }
289 }
290 }
291
292 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000293 * Gets the matrix of a stage's sampler
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000294 *
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000295 * @param stage the stage to of sampler to get
296 * @return the sampler state's matrix
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000297 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000298 const GrMatrix& getSamplerMatrix(int stage) const {
299 return fCurrDrawState.fSamplerStates[stage].getMatrix();
300 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000301
302 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000303 * Sets the matrix of a stage's sampler
304 *
305 * @param stage the stage of sampler set
306 * @param matrix the matrix to set
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000307 */
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000308 void setSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000309 fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
310 }
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000311
312 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000313 * Sets the matrix applied to veretx positions.
314 *
315 * In the post-view-matrix space the rectangle [0,w]x[0,h]
316 * fully covers the render target. (w and h are the width and height of the
317 * the rendertarget.)
318 *
319 * @param m the matrix used to transform the vertex positions.
320 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000321 void setViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000322
323 /**
324 * Multiplies the current view matrix by a matrix
325 *
326 * After this call V' = V*m where V is the old view matrix,
327 * m is the parameter to this function, and V' is the new view matrix.
328 * (We consider positions to be column vectors so position vector p is
329 * transformed by matrix X as p' = X*p.)
330 *
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000331 * @param m the matrix used to modify the view matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +0000332 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000333 void preConcatViewMatrix(const GrMatrix& m);
reed@google.comac10a2d2010-12-22 21:39:39 +0000334
335 /**
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000336 * Multiplies the current view matrix by a matrix
337 *
338 * After this call V' = m*V where V is the old view matrix,
339 * m is the parameter to this function, and V' is the new view matrix.
340 * (We consider positions to be column vectors so position vector p is
341 * transformed by matrix X as p' = X*p.)
342 *
343 * @param m the matrix used to modify the view matrix.
344 */
345 void postConcatViewMatrix(const GrMatrix& m);
346
347 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000348 * Retrieves the current view matrix
349 * @return the current view matrix.
350 */
351 const GrMatrix& getViewMatrix() const;
352
353 /**
354 * Retrieves the inverse of the current view matrix.
355 *
356 * If the current view matrix is invertible, return true, and if matrix
357 * is non-null, copy the inverse into it. If the current view matrix is
358 * non-invertible, return false and ignore the matrix parameter.
359 *
360 * @param matrix if not null, will receive a copy of the current inverse.
361 */
362 bool getViewInverse(GrMatrix* matrix) const;
363
364 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000365 * Sets color for next draw to a premultiplied-alpha color.
366 *
367 * @param the color to set.
368 */
369 void setColor(GrColor);
370
371 /**
Scroggo97c88c22011-05-11 14:05:25 +0000372 * Add a color filter that can be represented by a color and a mode.
373 */
374 void setColorFilter(GrColor, SkXfermode::Mode);
375
376 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000377 * Sets the color to be used for the next draw to be
378 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
379 *
380 * @param alpha The alpha value to set as the color.
381 */
382 void setAlpha(uint8_t alpha);
383
384 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000385 * Controls whether clockwise, counterclockwise, or both faces are drawn.
386 * @param face the face(s) to draw.
reed@google.comac10a2d2010-12-22 21:39:39 +0000387 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000388 void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000389
390 /**
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000391 * A common pattern is to compute a color with the initial stages and then
392 * modulate that color by a coverage value in later stage(s) (AA, mask-
393 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
394 * computed based on the pre-coverage-modulated color. The division of
395 * stages between color-computing and coverage-computing is specified by
396 * this method. Initially this is kNumStages (all stages are color-
397 * computing).
398 */
399 void setFirstCoverageStage(int firstCoverageStage) {
400 fCurrDrawState.fFirstCoverageStage = firstCoverageStage;
401 }
402
403 /**
404 * Gets the index of the first coverage-computing stage.
405 */
406 int getFirstCoverageStage() const {
407 return fCurrDrawState.fFirstCoverageStage;
408 }
409
410 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000411 * Gets whether the target is drawing clockwise, counterclockwise,
412 * or both faces.
413 * @return the current draw face(s).
reed@google.comac10a2d2010-12-22 21:39:39 +0000414 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000415 DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000416
417 /**
418 * Enable render state settings.
419 *
420 * @param flags bitfield of StateBits specifing the states to enable
421 */
422 void enableState(uint32_t stateBits);
423
424 /**
425 * Disable render state settings.
426 *
427 * @param flags bitfield of StateBits specifing the states to disable
428 */
429 void disableState(uint32_t stateBits);
430
431 bool isDitherState() const {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000432 return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
433 }
434
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000435 bool isAntialiasState() const {
436 return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
437 }
438
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000439 bool isClipState() const {
440 return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000441 }
442
bsalomon@google.comd302f142011-03-03 13:54:13 +0000443 bool isColorWriteDisabled() const {
444 return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
445 }
446
reed@google.comac10a2d2010-12-22 21:39:39 +0000447 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000448 * Sets the blending function coeffecients.
449 *
450 * The blend function will be:
451 * D' = sat(S*srcCoef + D*dstCoef)
452 *
453 * where D is the existing destination color, S is the incoming source
454 * color, and D' is the new destination color that will be written. sat()
455 * is the saturation function.
456 *
457 * @param srcCoef coeffecient applied to the src color.
458 * @param dstCoef coeffecient applied to the dst color.
459 */
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000460 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
reed@google.comac10a2d2010-12-22 21:39:39 +0000461
462 /**
bsalomon@google.com080773c2011-03-15 19:09:25 +0000463 * Sets the blending function constant referenced by the following blending
464 * coeffecients:
465 * kConstC_BlendCoeff
466 * kIConstC_BlendCoeff
467 * kConstA_BlendCoeff
468 * kIConstA_BlendCoeff
469 *
470 * @param constant the constant to set
471 */
472 void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
473
474 /**
475 * Retrieves the last value set by setBlendConstant()
476 * @return the blending constant value
477 */
478 GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
479
480 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000481 * Used to save and restore the GrGpu's drawing state
482 */
483 struct SavedDrawState {
484 private:
reed@google.com8195f672011-01-12 18:14:28 +0000485 DrState fState;
reed@google.comac10a2d2010-12-22 21:39:39 +0000486 friend class GrDrawTarget;
487 };
488
489 /**
490 * Saves the current draw state. The state can be restored at a later time
491 * with restoreDrawState.
492 *
493 * See also AutoStateRestore class.
494 *
495 * @param state will hold the state after the function returns.
496 */
497 void saveCurrentDrawState(SavedDrawState* state) const;
498
499 /**
500 * Restores previously saved draw state. The client guarantees that state
501 * was previously passed to saveCurrentDrawState and that the rendertarget
502 * and texture set at save are still valid.
503 *
504 * See also AutoStateRestore class.
505 *
506 * @param state the previously saved state to restore.
507 */
508 void restoreDrawState(const SavedDrawState& state);
509
510 /**
511 * Copies the draw state from another target to this target.
512 *
513 * @param srcTarget draw target used as src of the draw state.
514 */
515 void copyDrawState(const GrDrawTarget& srcTarget);
516
517 /**
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000518 * The format of vertices is represented as a bitfield of flags.
519 * Flags that indicate the layout of vertex data. Vertices always contain
bsalomon@google.com5782d712011-01-21 21:03:59 +0000520 * positions and may also contain up to kMaxTexCoords sets of 2D texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000521 * coordinates and per-vertex colors. Each stage can use any of the texture
522 * coordinates as its input texture coordinates or it may use the positions.
reed@google.comac10a2d2010-12-22 21:39:39 +0000523 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000524 * If no texture coordinates are specified for a stage then the stage is
525 * disabled.
reed@google.comac10a2d2010-12-22 21:39:39 +0000526 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000527 * Only one type of texture coord can be specified per stage. For
bsalomon@google.com5782d712011-01-21 21:03:59 +0000528 * example StageTexCoordVertexLayoutBit(0, 2) and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000529 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
reed@google.comac10a2d2010-12-22 21:39:39 +0000530 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000531 * The order in memory is always (position, texture coord 0, ..., color)
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000532 * with any unused fields omitted. Note that this means that if only texture
bsalomon@google.com5782d712011-01-21 21:03:59 +0000533 * coordinates 1 is referenced then there is no texture coordinates 0 and
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000534 * the order would be (position, texture coordinate 1[, color]).
535 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000536
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000537 /**
538 * Generates a bit indicating that a texture stage uses texture coordinates
bsalomon@google.com5782d712011-01-21 21:03:59 +0000539 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000540 * @param stage the stage that will use texture coordinates.
541 * @param texCoordIdx the index of the texture coordinates to use
542 *
543 * @return the bit to add to a GrVertexLayout bitfield.
544 */
545 static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
546 GrAssert(stage < kNumStages);
547 GrAssert(texCoordIdx < kMaxTexCoords);
548 return 1 << (stage + (texCoordIdx * kNumStages));
549 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000550
551 /**
552 * Determines if blend is effectively disabled.
553 *
554 * @return true if blend can be disabled without changing the rendering
555 * result given the current state including the vertex layout specified
556 * with the vertex source.
557 */
558 bool canDisableBlend() const;
559
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000560 /**
561 * Sets the edge data required for edge antialiasing.
562 *
563 * @param edges 3 * 6 float values, representing the edge
564 * equations in Ax + By + C form
565 */
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000566 void setEdgeAAData(const Edge* edges, int numEdges);
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000567
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000568private:
569 static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
570public:
571 /**
572 * Generates a bit indicating that a texture stage uses the position
573 * as its texture coordinate.
574 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000575 * @param stage the stage that will use position as texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000576 * coordinates.
577 *
578 * @return the bit to add to a GrVertexLayout bitfield.
579 */
580 static int StagePosAsTexCoordVertexLayoutBit(int stage) {
581 GrAssert(stage < kNumStages);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000582 return (1 << (TEX_COORD_BIT_CNT + stage));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000583 }
584private:
585 static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000586
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000587public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000588
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000589 /**
590 * Additional Bits that can be specified in GrVertexLayout.
reed@google.comac10a2d2010-12-22 21:39:39 +0000591 */
592 enum VertexLayoutBits {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000593
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000594 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
595 //<! vertices have colors
596 kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
597 //<! use text vertices. (Pos
598 // and tex coords may be
bsalomon@google.com5782d712011-01-21 21:03:59 +0000599 // a different type for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000600 // text [GrGpuTextVertex vs
601 // GrPoint].)
reed@google.comac10a2d2010-12-22 21:39:39 +0000602 // for below assert
bsalomon@google.comd302f142011-03-03 13:54:13 +0000603 kDummyVertexLayoutBit,
604 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
reed@google.comac10a2d2010-12-22 21:39:39 +0000605 };
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000606 // make sure we haven't exceeded the number of bits in GrVertexLayout.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000607 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
reed@google.comac10a2d2010-12-22 21:39:39 +0000608
609 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000610 * There are three paths for specifying geometry (vertices and optionally
611 * indices) to the draw target. When indexed drawing the indices and vertices
612 * can be each use a different path.
613 *
614 * 1. Provide a cpu array (set*SourceToArray). This is useful when the
615 * caller's client has already provided vertex data in a format
616 * the time compatible with a GrVertexLayout. The array must contain the
617 * data at set*SourceToArray is called. The source stays in effect for
618 * drawIndexed & drawNonIndexed calls until set*SourceToArray is called
619 * again or one of the other two paths is chosen.
620 *
621 * 2. Reserve and Lock. This is most useful when the caller has data it must
622 * transform before drawing and will not likely render it again. The
623 * caller requests that the draw target make room for some amount of
624 * vertex and/or index data. The target provides ptrs to hold the data
625 * data. The caller can write the data into the pts up until the first
626 * drawIndexed or drawNonIndexed call. At this point the data is frozen
627 * and the ptrs are no longer guaranteed to be valid. All subsequent
628 * drawIndexed & drawNonIndexed calls will use this data until
629 * releaseReserved geometry is called. This must be called before another
630 * source is set.
631 *
632 * 3. Vertex and Index Buffers. This is most useful for geometry that will
633 * be rendered multiple times. SetVertexSourceToBuffer &
634 * SetIndexSourceToBuffer are used to set the buffer and subsequent
635 * drawIndexed and drawNonIndexed calls use this source until another
636 * source is set.
637 */
638
639 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000640 * Reserves space for vertices and/or indices. Draw target will use
641 * reserved vertices / indices at next draw.
642 *
643 * If succeeds:
644 * if vertexCount is nonzero, *vertices will be the array
645 * of vertices to be filled by caller. The next draw will read
646 * these vertices.
647 *
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000648 * if indexCount is nonzero, *indices will be the array of indices
reed@google.comac10a2d2010-12-22 21:39:39 +0000649 * to be filled by caller. The next indexed draw will read from
650 * these indices.
651 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000652 * If a client does not already have a vertex buffer then this is the
653 * preferred way to allocate vertex/index array. It allows the subclass of
654 * GrDrawTarget to decide whether to put data in buffers, to group vertex
655 * data that uses the same state (e.g. for deferred rendering), etc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000656 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000657 * Following the first draw after reserveAndLockGeometry the ptrs returned
658 * by releaseReservedGeometry are no longer valid and the geometry data
659 * cannot be further modified. The contents that were put in the reserved
660 * space can be drawn by multiple draws, however.
661 *
662 * reserveAndLockGeometry must be matched with a releaseReservedGeometry
663 * call after all draws that reference the reserved geometry data have
664 * been called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000665 *
666 * AutoGeometryRelease can be used to automatically call the release.
667 *
668 * @param vertexCount the number of vertices to reserve space for. Can be 0.
669 * @param indexCount the number of indices to reserve space for. Can be 0.
670 * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
671 * @param vertices will point to reserved vertex space if vertexCount is
672 * non-zero. Illegal to pass NULL if vertexCount > 0.
673 * @param indices will point to reserved index space if indexCount is
674 * non-zero. Illegal to pass NULL if indexCount > 0.
675 *
676 * @return true if succeeded in allocating space for the vertices and false
677 * if not.
678 */
679 bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
680 uint32_t vertexCount,
681 uint32_t indexCount,
682 void** vertices,
683 void** indices);
684 /**
685 * Provides hints to caller about the number of vertices and indices
686 * that can be allocated cheaply. This can be useful if caller is reserving
687 * space but doesn't know exactly how much geometry is needed.
688 *
689 * Also may hint whether the draw target should be flushed first. This is
690 * useful for deferred targets.
691 *
692 * @param vertexLayout layout of vertices caller would like to reserve
693 * @param vertexCount in: hint about how many vertices the caller would
694 * like to allocate.
695 * out: a hint about the number of vertices that can be
696 * allocated cheaply. Negative means no hint.
697 * Ignored if NULL.
698 * @param indexCount in: hint about how many indices the caller would
699 * like to allocate.
700 * out: a hint about the number of indices that can be
701 * allocated cheaply. Negative means no hint.
702 * Ignored if NULL.
703 *
704 * @return true if target should be flushed based on the input values.
705 */
706 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000707 int* vertexCount,
708 int* indexCount) const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000709
710 /**
711 * Releases reserved vertex/index data from reserveAndLockGeometry().
712 */
713 void releaseReservedGeometry();
714
715 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000716 * Sets source of vertex data for the next draw. Array must contain
717 * the vertex data when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000718 *
719 * @param array cpu array containing vertex data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000720 * @param size size of the vertex data.
721 * @param vertexCount the number of vertices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000722 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000723 void setVertexSourceToArray(GrVertexLayout vertexLayout,
724 const void* vertexArray,
725 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000726
727 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000728 * Sets source of index data for the next indexed draw. Array must contain
729 * the indices when this is called.
reed@google.comac10a2d2010-12-22 21:39:39 +0000730 *
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000731 * @param array cpu array containing index data.
732 * @param indexCount the number of indices in the array.
reed@google.comac10a2d2010-12-22 21:39:39 +0000733 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000734 void setIndexSourceToArray(const void* indexArray, int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000735
736 /**
737 * Sets source of vertex data for the next draw. Data does not have to be
738 * in the buffer until drawIndexed or drawNonIndexed.
739 *
740 * @param buffer vertex buffer containing vertex data. Must be
741 * unlocked before draw call.
742 * @param vertexLayout layout of the vertex data in the buffer.
743 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000744 void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
745 const GrVertexBuffer* buffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000746
747 /**
748 * Sets source of index data for the next indexed draw. Data does not have
749 * to be in the buffer until drawIndexed or drawNonIndexed.
750 *
751 * @param buffer index buffer containing indices. Must be unlocked
752 * before indexed draw call.
753 */
754 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
755
756 /**
757 * Draws indexed geometry using the current state and current vertex / index
758 * sources.
759 *
760 * @param type The type of primitives to draw.
761 * @param startVertex the vertex in the vertex array/buffer corresponding
762 * to index 0
763 * @param startIndex first index to read from index src.
764 * @param vertexCount one greater than the max index.
765 * @param indexCount the number of index elements to read. The index count
766 * is effectively trimmed to the last completely
767 * specified primitive.
768 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000769 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000770 int startVertex,
771 int startIndex,
772 int vertexCount,
773 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000774
775 /**
776 * Draws non-indexed geometry using the current state and current vertex
777 * sources.
778 *
779 * @param type The type of primitives to draw.
780 * @param startVertex the vertex in the vertex array/buffer corresponding
781 * to index 0
782 * @param vertexCount one greater than the max index.
783 */
bsalomon@google.comffca4002011-02-22 20:34:01 +0000784 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000785 int startVertex,
786 int vertexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000787
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000788 /**
789 * Helper function for drawing rects. This does not use the current index
790 * and vertex sources. After returning, the vertex and index sources may
791 * have changed. They should be reestablished before the next drawIndexed
792 * or drawNonIndexed. This cannot be called between reserving and releasing
793 * geometry. The GrDrawTarget subclass may be able to perform additional
bsalomon@google.comd302f142011-03-03 13:54:13 +0000794 * optimizations if drawRect is used rather than drawIndexed or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000795 * drawNonIndexed.
796 * @param rect the rect to draw
797 * @param matrix optional matrix applied to rect (before viewMatrix)
bsalomon@google.comffca4002011-02-22 20:34:01 +0000798 * @param stageEnableBitfield bitmask indicating which stages are enabled.
799 * Bit i indicates whether stage i is enabled.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000800 * @param srcRects specifies rects for stages enabled by stageEnableMask.
801 * if stageEnableMask bit i is 1, srcRects is not NULL,
802 * and srcRects[i] is not NULL, then srcRects[i] will be
803 * used as coordinates for stage i. Otherwise, if stage i
804 * is enabled then rect is used as the coordinates.
805 * @param srcMatrices optional matrices applied to srcRects. If
806 * srcRect[i] is non-NULL and srcMatrices[i] is
807 * non-NULL then srcRect[i] will be transformed by
808 * srcMatrix[i]. srcMatrices can be NULL when no
809 * srcMatrices are desired.
810 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000811 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000812 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000813 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000814 const GrRect* srcRects[],
815 const GrMatrix* srcMatrices[]);
816
817 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000818 * Helper for drawRect when the caller doesn't need separate src rects or
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000819 * matrices.
820 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000821 void drawSimpleRect(const GrRect& rect,
822 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000823 StageBitfield stageEnableBitfield) {
824 drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000825 }
826
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000827 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000828 * Clear the render target. Ignores the clip and all other draw state
829 * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
830 * otherwise just the rect.
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000831 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000832 virtual void clear(const GrIRect* rect, GrColor color) = 0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000833
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000834 /**
835 * Returns the maximum number of edges that may be specified in a single
836 * draw call when performing edge antialiasing. This is usually limited
837 * by the number of fragment uniforms which may be uploaded. Must be a
838 * minimum of six, since a triangle's vertices each belong to two boundary
839 * edges which may be distinct.
840 */
841 virtual int getMaxEdges() const { return 6; }
842
reed@google.comac10a2d2010-12-22 21:39:39 +0000843 ///////////////////////////////////////////////////////////////////////////
844
845 class AutoStateRestore : ::GrNoncopyable {
846 public:
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000847 AutoStateRestore();
reed@google.comac10a2d2010-12-22 21:39:39 +0000848 AutoStateRestore(GrDrawTarget* target);
849 ~AutoStateRestore();
850
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000851 /**
852 * if this object is already saving state for param target then
853 * this does nothing. Otherise, it restores previously saved state on
854 * previous target (if any) and saves current state on param target.
855 */
856 void set(GrDrawTarget* target);
857
reed@google.comac10a2d2010-12-22 21:39:39 +0000858 private:
859 GrDrawTarget* fDrawTarget;
860 SavedDrawState fDrawState;
861 };
862
863 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000864
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000865 class AutoViewMatrixRestore : ::GrNoncopyable {
866 public:
867 AutoViewMatrixRestore() {
868 fDrawTarget = NULL;
869 }
870
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000871 AutoViewMatrixRestore(GrDrawTarget* target)
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000872 : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
873 GrAssert(NULL != target);
874 }
875
876 void set(GrDrawTarget* target) {
877 GrAssert(NULL != target);
878 if (NULL != fDrawTarget) {
879 fDrawTarget->setViewMatrix(fMatrix);
880 }
881 fDrawTarget = target;
882 fMatrix = target->getViewMatrix();
883 }
884
885 ~AutoViewMatrixRestore() {
886 if (NULL != fDrawTarget) {
887 fDrawTarget->setViewMatrix(fMatrix);
888 }
889 }
890
891 private:
892 GrDrawTarget* fDrawTarget;
893 GrMatrix fMatrix;
894 };
895
896 ///////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000897
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000898 /**
899 * Sets the view matrix to I and preconcats all stage matrices enabled in
900 * mask by the view inverse. Destructor undoes these changes.
901 */
902 class AutoDeviceCoordDraw : ::GrNoncopyable {
903 public:
904 AutoDeviceCoordDraw(GrDrawTarget* target, int stageMask);
905 ~AutoDeviceCoordDraw();
906 private:
907 GrDrawTarget* fDrawTarget;
908 GrMatrix fViewMatrix;
909 GrMatrix fSamplerMatrices[kNumStages];
910 int fStageMask;
911 };
912
913 ///////////////////////////////////////////////////////////////////////////
914
reed@google.comac10a2d2010-12-22 21:39:39 +0000915 class AutoReleaseGeometry : ::GrNoncopyable {
916 public:
917 AutoReleaseGeometry(GrDrawTarget* target,
918 GrVertexLayout vertexLayout,
919 uint32_t vertexCount,
920 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000921 fTarget = NULL;
922 this->set(target, vertexLayout, vertexCount, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000923 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000924
925 AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000926 fTarget = NULL;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000927 }
928
reed@google.comac10a2d2010-12-22 21:39:39 +0000929 ~AutoReleaseGeometry() {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000930 if (NULL != fTarget) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000931 fTarget->releaseReservedGeometry();
932 }
933 }
934
bsalomon@google.com5782d712011-01-21 21:03:59 +0000935 bool set(GrDrawTarget* target,
936 GrVertexLayout vertexLayout,
937 uint32_t vertexCount,
938 uint32_t indexCount) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000939 if (NULL != fTarget) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000940 fTarget->releaseReservedGeometry();
941 }
942 fTarget = target;
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000943 if (NULL != fTarget) {
944 if (!fTarget->reserveAndLockGeometry(vertexLayout,
945 vertexCount,
946 indexCount,
947 &fVertices,
948 &fIndices)) {
949 fTarget = NULL;
950 }
951 }
952 return NULL != fTarget;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000953 }
954
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000955 bool succeeded() const { return NULL != fTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000956 void* vertices() const { return fVertices; }
957 void* indices() const { return fIndices; }
958
959 GrPoint* positions() const {
960 return static_cast<GrPoint*>(fVertices);
961 }
962
963 private:
964 GrDrawTarget* fTarget;
reed@google.comac10a2d2010-12-22 21:39:39 +0000965 void* fVertices;
966 void* fIndices;
967 };
968
969 ///////////////////////////////////////////////////////////////////////////
970
971 class AutoClipRestore : ::GrNoncopyable {
972 public:
973 AutoClipRestore(GrDrawTarget* target) {
974 fTarget = target;
975 fClip = fTarget->getClip();
976 }
977
978 ~AutoClipRestore() {
979 fTarget->setClip(fClip);
980 }
981 private:
982 GrDrawTarget* fTarget;
983 GrClip fClip;
984 };
985
986 ////////////////////////////////////////////////////////////////////////////
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000987 // Helpers for picking apart vertex layouts
bsalomon@google.com5782d712011-01-21 21:03:59 +0000988
reed@google.comac10a2d2010-12-22 21:39:39 +0000989 /**
990 * Helper function to compute the size of a vertex from a vertex layout
991 * @return size of a single vertex.
992 */
993 static size_t VertexSize(GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000994
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000995 /**
996 * Helper function for determining the index of texture coordinates that
997 * is input for a texture stage. Note that a stage may instead use positions
998 * as texture coordinates, in which case the result of the function is
999 * indistinguishable from the case when the stage is disabled.
1000 *
1001 * @param stage the stage to query
1002 * @param vertexLayout layout to query
1003 *
1004 * @return the texture coordinate index or -1 if the stage doesn't use
1005 * separate (non-position) texture coordinates.
1006 */
1007 static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001008
1009 /**
1010 * Helper function to compute the offset of texture coordinates in a vertex
1011 * @return offset of texture coordinates in vertex layout or -1 if the
bsalomon@google.com5782d712011-01-21 21:03:59 +00001012 * layout has no texture coordinates. Will be 0 if positions are
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001013 * used as texture coordinates for the stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001014 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001015 static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001016
1017 /**
1018 * Helper function to compute the offset of the color in a vertex
1019 * @return offset of color in vertex layout or -1 if the
1020 * layout has no color.
1021 */
1022 static int VertexColorOffset(GrVertexLayout vertexLayout);
1023
1024 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001025 * Helper function to determine if vertex layout contains explicit texture
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001026 * coordinates of some index.
1027 *
1028 * @param coordIndex the tex coord index to query
1029 * @param vertexLayout layout to query
1030 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001031 * @return true if vertex specifies texture coordinates for the index,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001032 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001033 */
bsalomon@google.com5782d712011-01-21 21:03:59 +00001034 static bool VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001035 GrVertexLayout vertexLayout);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001036
reed@google.comac10a2d2010-12-22 21:39:39 +00001037 /**
1038 * Helper function to determine if vertex layout contains either explicit or
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001039 * implicit texture coordinates for a stage.
reed@google.comac10a2d2010-12-22 21:39:39 +00001040 *
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001041 * @param stage the stage to query
1042 * @param vertexLayout layout to query
1043 *
bsalomon@google.com5782d712011-01-21 21:03:59 +00001044 * @return true if vertex specifies texture coordinates for the stage,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001045 * false otherwise.
reed@google.comac10a2d2010-12-22 21:39:39 +00001046 */
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001047 static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +00001048
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001049 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001050 * Helper function to compute the size of each vertex and the offsets of
1051 * texture coordinates and color. Determines tex coord offsets by tex coord
1052 * index rather than by stage. (Each stage can be mapped to any t.c. index
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001053 * by StageTexCoordVertexLayoutBit.)
1054 *
1055 * @param vertexLayout the layout to query
1056 * @param texCoordOffsetsByIdx after return it is the offset of each
1057 * tex coord index in the vertex or -1 if
1058 * index isn't used.
1059 * @return size of a single vertex
1060 */
1061 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
1062 int texCoordOffsetsByIdx[kMaxTexCoords],
1063 int *colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +00001064
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001065 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +00001066 * Helper function to compute the size of each vertex and the offsets of
1067 * texture coordinates and color. Determines tex coord offsets by stage
1068 * rather than by index. (Each stage can be mapped to any t.c. index
1069 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
bsalomon@google.com8531c1c2011-01-13 19:52:45 +00001070 * tex coords then that stage's offset will be 0 (positions are always at 0).
1071 *
1072 * @param vertexLayout the layout to query
1073 * @param texCoordOffsetsByStage after return it is the offset of each
1074 * tex coord index in the vertex or -1 if
1075 * index isn't used.
1076 * @return size of a single vertex
1077 */
1078 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1079 int texCoordOffsetsByStage[kNumStages],
1080 int *colorOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001081
1082 /**
1083 * Accessing positions, texture coords, or colors, of a vertex within an
1084 * array is a hassle involving casts and simple math. These helpers exist
1085 * to keep GrDrawTarget clients' code a bit nicer looking.
1086 */
1087
1088 /**
1089 * Gets a pointer to a GrPoint of a vertex's position or texture
1090 * coordinate.
1091 * @param vertices the vetex array
1092 * @param vertexIndex the index of the vertex in the array
1093 * @param vertexSize the size of each vertex in the array
1094 * @param offset the offset in bytes of the vertex component.
1095 * Defaults to zero (corresponding to vertex position)
1096 * @return pointer to the vertex component as a GrPoint
1097 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001098 static GrPoint* GetVertexPoint(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001099 int vertexIndex,
1100 int vertexSize,
1101 int offset = 0) {
1102 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001103 return GrTCast<GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001104 vertexIndex * vertexSize);
1105 }
1106 static const GrPoint* GetVertexPoint(const void* vertices,
1107 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001108 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001109 int offset = 0) {
1110 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001111 return GrTCast<const GrPoint*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001112 vertexIndex * vertexSize);
1113 }
1114
1115 /**
1116 * Gets a pointer to a GrColor inside a vertex within a vertex array.
1117 * @param vertices the vetex array
1118 * @param vertexIndex the index of the vertex in the array
1119 * @param vertexSize the size of each vertex in the array
1120 * @param offset the offset in bytes of the vertex color
1121 * @return pointer to the vertex component as a GrColor
1122 */
bsalomon@google.comd302f142011-03-03 13:54:13 +00001123 static GrColor* GetVertexColor(void* vertices,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001124 int vertexIndex,
1125 int vertexSize,
1126 int offset) {
1127 intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001128 return GrTCast<GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001129 vertexIndex * vertexSize);
1130 }
1131 static const GrColor* GetVertexColor(const void* vertices,
1132 int vertexIndex,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001133 int vertexSize,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001134 int offset) {
1135 const intptr_t start = GrTCast<intptr_t>(vertices);
bsalomon@google.comd302f142011-03-03 13:54:13 +00001136 return GrTCast<const GrColor*>(start + offset +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001137 vertexIndex * vertexSize);
1138 }
1139
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +00001140 static void VertexLayoutUnitTest();
1141
reed@google.comac10a2d2010-12-22 21:39:39 +00001142protected:
bsalomon@google.coma47a48d2011-04-26 20:22:11 +00001143 // given a vertex layout and a draw state, will a stage be used?
1144 static bool StageWillBeUsed(int stage, GrVertexLayout layout,
1145 const DrState& state) {
1146 return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
1147 }
1148
1149 bool isStageEnabled(int stage) const {
1150 return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
1151 }
bsalomon@google.com5782d712011-01-21 21:03:59 +00001152
reed@google.comac10a2d2010-12-22 21:39:39 +00001153 // Helpers for GrDrawTarget subclasses that won't have private access to
1154 // SavedDrawState but need to peek at the state values.
reed@google.com8195f672011-01-12 18:14:28 +00001155 static DrState& accessSavedDrawState(SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001156 { return sds.fState; }
reed@google.com8195f672011-01-12 18:14:28 +00001157 static const DrState& accessSavedDrawState(const SavedDrawState& sds)
reed@google.comac10a2d2010-12-22 21:39:39 +00001158 { return sds.fState; }
1159
1160 // implemented by subclass
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001161 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
1162 void** vertices,
1163 void** indices) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001164
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001165 virtual void onReleaseGeometry() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001166
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001167 // subclass overrides to be notified when clip is set.
1168 virtual void clipWillBeSet(const GrClip& clip) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +00001169
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001170 virtual void onSetVertexSourceToArray(const void* vertexArray,
1171 int vertexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001172
bsalomon@google.combcdbbe62011-04-12 15:40:00 +00001173 virtual void onSetIndexSourceToArray(const void* indexArray,
1174 int indexCount) = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001175
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001176 // Helpers for drawRect, protected so subclasses that override drawRect
1177 // can use them.
bsalomon@google.comffca4002011-02-22 20:34:01 +00001178 static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001179 const GrRect* srcRects[]);
1180
1181 static void SetRectVertices(const GrRect& rect,
bsalomon@google.comd302f142011-03-03 13:54:13 +00001182 const GrMatrix* matrix,
1183 const GrRect* srcRects[],
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001184 const GrMatrix* srcMatrices[],
bsalomon@google.comd302f142011-03-03 13:54:13 +00001185 GrVertexLayout layout,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +00001186 void* vertices);
1187
reed@google.comac10a2d2010-12-22 21:39:39 +00001188 enum GeometrySrcType {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001189 kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
1190 kArray_GeometrySrcType, // src was set using set*SourceToArray
1191 kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
reed@google.comac10a2d2010-12-22 21:39:39 +00001192 };
1193
bsalomon@google.comd302f142011-03-03 13:54:13 +00001194 struct ReservedGeometry {
reed@google.comac10a2d2010-12-22 21:39:39 +00001195 bool fLocked;
1196 uint32_t fVertexCount;
1197 uint32_t fIndexCount;
1198 } fReservedGeometry;
1199
1200 struct GeometrySrc {
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001201 GeometrySrcType fVertexSrc;
1202 const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
1203 GeometrySrcType fIndexSrc;
1204 const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
1205 GrVertexLayout fVertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +00001206 } fGeometrySrc;
1207
1208 GrClip fClip;
1209
reed@google.com8195f672011-01-12 18:14:28 +00001210 DrState fCurrDrawState;
reed@google.comac10a2d2010-12-22 21:39:39 +00001211
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001212 // Not meant for external use. Only setVertexSourceToBuffer and
1213 // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
1214 // support nested reserveAndLockGeometry (and cpu arrays internally use the
1215 // same path).
reed@google.comac10a2d2010-12-22 21:39:39 +00001216 class AutoGeometrySrcRestore {
1217 public:
1218 AutoGeometrySrcRestore(GrDrawTarget* target) {
1219 fTarget = target;
1220 fGeometrySrc = fTarget->fGeometrySrc;
1221 }
1222 ~AutoGeometrySrcRestore() {
1223 fTarget->fGeometrySrc = fGeometrySrc;
1224 }
1225 private:
1226 GrDrawTarget *fTarget;
1227 GeometrySrc fGeometrySrc;
1228
1229 AutoGeometrySrcRestore();
1230 AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
1231 AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
1232 };
reed@google.comac10a2d2010-12-22 21:39:39 +00001233};
1234
1235#endif