blob: d16efa893c97aa5ed46b5e63b1ac6548799a8b40 [file] [log] [blame]
tomhudson@google.com93813632011-10-27 20:21:16 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrDrawState_DEFINED
9#define GrDrawState_DEFINED
10
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000011#include "GrBackendEffectFactory.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000012#include "GrColor.h"
bsalomon@google.com08283af2012-10-26 13:01:20 +000013#include "GrEffectStage.h"
bsalomon@google.com73818dc2013-03-28 13:23:29 +000014#include "GrPaint.h"
jvanverth@google.comcc782382013-01-28 20:39:48 +000015#include "GrRefCnt.h"
robertphillips@google.com9ec07532012-06-22 12:01:30 +000016#include "GrRenderTarget.h"
jvanverth@google.comcc782382013-01-28 20:39:48 +000017#include "GrStencil.h"
18#include "GrTemplates.h"
19#include "GrTexture.h"
bsalomon@google.com31ec7982013-03-27 18:14:57 +000020#include "GrTypesPriv.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000021#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000022
jvanverth@google.comcc782382013-01-28 20:39:48 +000023#include "SkMatrix.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000024#include "SkXfermode.h"
25
jvanverth@google.com9b855c72013-03-01 18:21:22 +000026/**
jvanverth@google.com9b855c72013-03-01 18:21:22 +000027 * Type used to describe how attributes bind to program usage
28 */
29typedef int GrAttribBindings;
30
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000031class GrDrawState : public GrRefCnt {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000032public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000033 SK_DECLARE_INST_COUNT(GrDrawState)
rmistry@google.comd6176b02012-08-23 18:14:13 +000034
tomhudson@google.com93813632011-10-27 20:21:16 +000035 /**
bsalomon@google.com13221342012-10-26 13:41:59 +000036 * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
37 * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
38 * output from the previous enabled stage and a position. The position is either derived from
39 * the interpolated vertex positions or explicit per-vertex coords, depending upon the
jvanverth@google.com9b855c72013-03-01 18:21:22 +000040 * GrAttribBindings used to draw.
robertphillips@google.combf5cad42012-05-10 12:40:40 +000041 *
bsalomon@google.com13221342012-10-26 13:41:59 +000042 * The stages are divided into two sets, color-computing and coverage-computing. The final color
43 * stage produces the final pixel color. The coverage-computing stages function exactly as the
44 * color-computing but the output of the final coverage stage is treated as a fractional pixel
45 * coverage rather than as input to the src/dst color blend step.
46 *
47 * The input color to the first enabled color-stage is either the constant color or interpolated
jvanverth@google.com9b855c72013-03-01 18:21:22 +000048 * per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
bsalomon@google.com4647f902013-03-26 14:45:27 +000049 * either a constant coverage (usually full-coverage) or interpolated per-vertex coverage.
bsalomon@google.com13221342012-10-26 13:41:59 +000050 *
bsalomon@google.comcf939ae2012-12-13 19:59:23 +000051 * See the documentation of kCoverageDrawing_StateBit for information about disabling the
52 * the color / coverage distinction.
53 *
bsalomon@google.com13221342012-10-26 13:41:59 +000054 * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
bsalomon@google.com73818dc2013-03-28 13:23:29 +000055 * GrPaint. Stage GrPaint::kTotalStages is earmarked for use by GrTextContext, GrPathRenderer-
56 * derived classes, and the rect/oval helper classes. GrPaint::kTotalStages+1 is earmarked for
57 * clipping by GrClipMaskManager. TODO: replace fixed size array of stages with variable size
58 * arrays of color and coverage stages.
tomhudson@google.com93813632011-10-27 20:21:16 +000059 */
60 enum {
bsalomon@google.com73818dc2013-03-28 13:23:29 +000061 kNumStages = GrPaint::kTotalStages + 2,
tomhudson@google.com93813632011-10-27 20:21:16 +000062 };
63
bsalomon@google.comca432082013-01-23 19:53:46 +000064 GrDrawState() {
reed@google.com75847192013-01-28 20:53:22 +000065#if GR_DEBUG
jvanverth@google.com9b855c72013-03-01 18:21:22 +000066 VertexAttributesUnitTest();
reed@google.com75847192013-01-28 20:53:22 +000067#endif
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000068 this->reset();
69 }
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000070
bsalomon@google.comca432082013-01-23 19:53:46 +000071 GrDrawState(const GrDrawState& state) {
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000072 *this = state;
73 }
74
robertphillips@google.com9ec07532012-06-22 12:01:30 +000075 virtual ~GrDrawState() {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000076 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000077 }
78
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000079 /**
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000080 * Resets to the default state.
bsalomon@google.com08283af2012-10-26 13:01:20 +000081 * GrEffects will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000082 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000083 void reset() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +000084
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000085 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000086
bsalomon@google.comca432082013-01-23 19:53:46 +000087 fRenderTarget.reset(NULL);
88
jvanverth@google.com9b855c72013-03-01 18:21:22 +000089 this->setDefaultVertexAttribs();
90
bsalomon@google.comca432082013-01-23 19:53:46 +000091 fCommon.fColor = 0xffffffff;
92 fCommon.fViewMatrix.reset();
93 fCommon.fSrcBlend = kOne_GrBlendCoeff;
94 fCommon.fDstBlend = kZero_GrBlendCoeff;
95 fCommon.fBlendConstant = 0x0;
96 fCommon.fFlagBits = 0x0;
bsalomon@google.comca432082013-01-23 19:53:46 +000097 fCommon.fStencilSettings.setDisabled();
98 fCommon.fFirstCoverageStage = kNumStages;
99 fCommon.fCoverage = 0xffffffff;
100 fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
101 fCommon.fColorFilterColor = 0x0;
102 fCommon.fDrawFace = kBoth_DrawFace;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000103 }
104
105 /**
106 * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000107 * encompasses more than GrPaint. Aspects of GrDrawState that have no
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000108 * GrPaint equivalents are not modified. GrPaint has fewer stages than
109 * GrDrawState. The extra GrDrawState stages are disabled.
110 */
111 void setFromPaint(const GrPaint& paint);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000112
113 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000114 /// @name Vertex Attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +0000115 ////
116
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000117 enum {
118 kVertexAttribCnt = 6,
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000119 };
120
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000121 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000122 * The format of vertices is represented as an array of vertex attribute
123 * pair, with each pair representing the type of the attribute and the
124 * offset in the vertex structure (see GrVertexAttrib, above).
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000125 *
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000126 * This will only set up the vertex geometry. To bind the attributes in
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000127 * the shaders, attribute indices and attribute bindings need to be set
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000128 * as well.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000129 */
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000130
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000131 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000132 * Sets vertex attributes for next draw.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000133 *
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000134 * @param attribs the array of vertex attributes to set.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000135 * @param count the number of attributes being set.
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000136 * limited to a count of kVertexAttribCnt.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000137 */
138 void setVertexAttribs(const GrVertexAttrib attribs[], int count);
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000139
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000140 const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
141 int getVertexAttribCount() const { return fVertexAttribs.count(); }
142
143 size_t getVertexSize() const;
144
145 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000146 * Sets default vertex attributes for next draw.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000147 *
148 * This will also set default vertex attribute indices and bindings
149 */
150 void setDefaultVertexAttribs();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000151
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000152 bool validateVertexAttribs() const;
153
jvanverth@google.comcc782382013-01-28 20:39:48 +0000154 ////////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000155 // Helpers for picking apart vertex attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +0000156
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000157 // helper array to let us check the expected so we know what bound attrib indices
158 // we care about
159 static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
jvanverth@google.comcc782382013-01-28 20:39:48 +0000160
161 /**
162 * Accessing positions, texture coords, or colors, of a vertex within an
163 * array is a hassle involving casts and simple math. These helpers exist
164 * to keep GrDrawTarget clients' code a bit nicer looking.
165 */
166
167 /**
168 * Gets a pointer to a GrPoint of a vertex's position or texture
169 * coordinate.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000170 * @param vertices the vertex array
jvanverth@google.comcc782382013-01-28 20:39:48 +0000171 * @param vertexIndex the index of the vertex in the array
172 * @param vertexSize the size of each vertex in the array
173 * @param offset the offset in bytes of the vertex component.
174 * Defaults to zero (corresponding to vertex position)
175 * @return pointer to the vertex component as a GrPoint
176 */
177 static GrPoint* GetVertexPoint(void* vertices,
178 int vertexIndex,
179 int vertexSize,
180 int offset = 0) {
181 intptr_t start = GrTCast<intptr_t>(vertices);
182 return GrTCast<GrPoint*>(start + offset +
183 vertexIndex * vertexSize);
184 }
185 static const GrPoint* GetVertexPoint(const void* vertices,
186 int vertexIndex,
187 int vertexSize,
188 int offset = 0) {
189 intptr_t start = GrTCast<intptr_t>(vertices);
190 return GrTCast<const GrPoint*>(start + offset +
191 vertexIndex * vertexSize);
192 }
193
194 /**
195 * Gets a pointer to a GrColor inside a vertex within a vertex array.
196 * @param vertices the vetex array
197 * @param vertexIndex the index of the vertex in the array
198 * @param vertexSize the size of each vertex in the array
199 * @param offset the offset in bytes of the vertex color
200 * @return pointer to the vertex component as a GrColor
201 */
202 static GrColor* GetVertexColor(void* vertices,
203 int vertexIndex,
204 int vertexSize,
205 int offset) {
206 intptr_t start = GrTCast<intptr_t>(vertices);
207 return GrTCast<GrColor*>(start + offset +
208 vertexIndex * vertexSize);
209 }
210 static const GrColor* GetVertexColor(const void* vertices,
211 int vertexIndex,
212 int vertexSize,
213 int offset) {
214 const intptr_t start = GrTCast<intptr_t>(vertices);
215 return GrTCast<const GrColor*>(start + offset +
216 vertexIndex * vertexSize);
217 }
218
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000219 /// @}
220
221 ///////////////////////////////////////////////////////////////////////////
222 /// @name Attribute Bindings
223 ////
224
225 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000226 * The vertex data used by the current program is represented as a bitfield
227 * of flags. Programs always use positions and may also use texture
bsalomon@google.comc7818882013-03-20 19:19:53 +0000228 * coordinates, per-vertex colors, per-vertex coverage and edge data. The
229 * local coords accessible by effects may either come from positions or
230 * be specified explicitly.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000231 */
232
233 /**
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000234 * Additional Bits that can be specified in GrAttribBindings.
235 */
236 enum AttribBindingsBits {
bsalomon@google.comc7818882013-03-20 19:19:53 +0000237 /** explicit local coords are provided (instead of using pre-view-matrix positions) */
238 kLocalCoords_AttribBindingsBit = 0x1,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000239 /* program uses colors (GrColor) */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000240 kColor_AttribBindingsBit = 0x2,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000241 /* program uses coverage (GrColor)
242 */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000243 kCoverage_AttribBindingsBit = 0x4,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000244 // for below assert
245 kDummyAttribBindingsBit,
246 kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
247 };
248 // make sure we haven't exceeded the number of bits in GrAttribBindings.
249 GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribBindings)));
250
251 enum AttribBindings {
252 kDefault_AttribBindings = 0
253 };
254
255 /**
256 * Sets attribute bindings for next draw.
257 *
258 * @param bindings the attribute bindings to set.
259 */
260 void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; }
261
262 GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; }
263
264 ////////////////////////////////////////////////////////////////////////////
265 // Helpers for picking apart attribute bindings
266
267 /**
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000268 * Determines whether src alpha is guaranteed to be one for all src pixels
269 */
270 bool srcAlphaWillBeOne(GrAttribBindings) const;
271
272 /**
273 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
274 */
275 bool hasSolidCoverage(GrAttribBindings) const;
276
277 static void VertexAttributesUnitTest();
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000278
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000279 /// @}
280
281 ///////////////////////////////////////////////////////////////////////////
282 /// @name Vertex Attribute Indices
283 ////
284
285 /**
286 * Vertex attribute indices map the data set in the vertex attribute array
287 * to the bindings specified in the attribute bindings. Each binding type
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000288 * has an associated index in the attribute array. This index is used to
289 * look up the vertex attribute data from the array, and potentially as the
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000290 * attribute index if we're binding attributes in GL.
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000291 *
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000292 * Indices which do not have active attribute bindings will be ignored.
293 */
294
295 enum AttribIndex {
296 kPosition_AttribIndex = 0,
297 kColor_AttribIndex,
298 kCoverage_AttribIndex,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000299 kLocalCoords_AttribIndex,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000300
bsalomon@google.comc7818882013-03-20 19:19:53 +0000301 kLast_AttribIndex = kLocalCoords_AttribIndex
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000302 };
303 static const int kAttribIndexCount = kLast_AttribIndex + 1;
304
305 // these are used when vertex color and coverage isn't set
306 enum {
307 kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt,
308 kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1,
309 };
310
311 ////////////////////////////////////////////////////////////////////////////
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000312 // Helpers to set attribute indices. These should match the index in the
313 // current attribute index array.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000314
315 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000316 * Sets index for next draw. This is used to look up the offset
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000317 * from the current vertex attribute array and to bind the attributes.
318 *
319 * @param index the attribute index we're setting
320 * @param value the value of the index
321 */
322 void setAttribIndex(AttribIndex index, int value) { fAttribIndices[index] = value; }
323
324 int getAttribIndex(AttribIndex index) const { return fAttribIndices[index]; }
jvanverth@google.comcc782382013-01-28 20:39:48 +0000325
326 /// @}
327
328 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000329 /// @name Color
330 ////
331
332 /**
333 * Sets color for next draw to a premultiplied-alpha color.
334 *
335 * @param color the color to set.
336 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000337 void setColor(GrColor color) { fCommon.fColor = color; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000338
bsalomon@google.comca432082013-01-23 19:53:46 +0000339 GrColor getColor() const { return fCommon.fColor; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000340
341 /**
342 * Sets the color to be used for the next draw to be
343 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
344 *
345 * @param alpha The alpha value to set as the color.
346 */
347 void setAlpha(uint8_t a) {
348 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
349 }
350
351 /**
352 * Add a color filter that can be represented by a color and a mode. Applied
bsalomon@google.comc7818882013-03-20 19:19:53 +0000353 * after color-computing effect stages.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000354 */
355 void setColorFilter(GrColor c, SkXfermode::Mode mode) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000356 fCommon.fColorFilterColor = c;
357 fCommon.fColorFilterMode = mode;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000358 }
359
bsalomon@google.comca432082013-01-23 19:53:46 +0000360 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
361 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000362
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000363 /**
364 * Constructor sets the color to be 'color' which is undone by the destructor.
365 */
366 class AutoColorRestore : public ::GrNoncopyable {
367 public:
sugoi@google.com66a58ac2013-03-05 20:40:52 +0000368 AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000369
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000370 AutoColorRestore(GrDrawState* drawState, GrColor color) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000371 fDrawState = NULL;
372 this->set(drawState, color);
373 }
374
375 void reset() {
376 if (NULL != fDrawState) {
377 fDrawState->setColor(fOldColor);
378 fDrawState = NULL;
379 }
380 }
381
382 void set(GrDrawState* drawState, GrColor color) {
383 this->reset();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000384 fDrawState = drawState;
385 fOldColor = fDrawState->getColor();
386 fDrawState->setColor(color);
387 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000388
389 ~AutoColorRestore() { this->reset(); }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000390 private:
391 GrDrawState* fDrawState;
392 GrColor fOldColor;
393 };
394
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000395 /// @}
396
397 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000398 /// @name Coverage
399 ////
400
401 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000402 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000403 * initial value (after construction or reset()) is 0xff. The constant
404 * coverage is ignored when per-vertex coverage is provided.
405 */
406 void setCoverage(uint8_t coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000407 fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000408 }
409
410 /**
411 * Version of above that specifies 4 channel per-vertex color. The value
412 * should be premultiplied.
413 */
414 void setCoverage4(GrColor coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000415 fCommon.fCoverage = coverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000416 }
417
418 GrColor getCoverage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000419 return fCommon.fCoverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000420 }
421
422 /// @}
423
424 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000425 /// @name Effect Stages
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000426 ////
427
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000428 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
429 fStages[stageIdx].setEffect(effect);
430 return effect;
431 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000432
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000433 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect,
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000434 int attr0, int attr1 = -1) {
435 fStages[stageIdx].setEffect(effect, attr0, attr1);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000436 return effect;
437 }
438
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000439 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000440 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000441 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000442 void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000443 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000444 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000445 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000446 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000447 void createTextureEffect(int stageIdx,
448 GrTexture* texture,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000449 const SkMatrix& matrix,
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000450 const GrTextureParams& params) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000451 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000452 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000453 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000454 }
455
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000456 bool stagesDisabled() {
457 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000458 if (NULL != fStages[i].getEffect()) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000459 return false;
460 }
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000461 }
tomhudson@google.com3eee8fb2012-06-25 12:30:34 +0000462 return true;
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000463 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000464
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000465 void disableStage(int stageIdx) {
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000466 this->setEffect(stageIdx, NULL);
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000467 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000468
robertphillips@google.com972265d2012-06-13 18:49:30 +0000469 /**
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000470 * Release all the GrEffects referred to by this draw state.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000471 */
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000472 void disableStages() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000473 for (int i = 0; i < kNumStages; ++i) {
tomhudson@google.com676e6602012-07-10 17:21:48 +0000474 this->disableStage(i);
robertphillips@google.com972265d2012-06-13 18:49:30 +0000475 }
476 }
477
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000478 class AutoStageDisable : public ::GrNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000479 public:
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000480 AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
481 ~AutoStageDisable() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000482 if (NULL != fDrawState) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000483 fDrawState->disableStages();
robertphillips@google.com972265d2012-06-13 18:49:30 +0000484 }
485 }
486 private:
487 GrDrawState* fDrawState;
488 };
489
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000490 /**
bsalomon@google.com08283af2012-10-26 13:01:20 +0000491 * Returns the current stage by index.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000492 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000493 const GrEffectStage& getStage(int stageIdx) const {
494 GrAssert((unsigned)stageIdx < kNumStages);
495 return fStages[stageIdx];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000496 }
497
498 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000499 * Called when the source coord system is changing. This ensures that effects will see the
500 * correct local coordinates. oldToNew gives the transformation from the old coord system in
501 * which the geometry was specified to the new coordinate system from which it will be rendered.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000502 */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000503 void localCoordChange(const SkMatrix& oldToNew) {
reed@google.com67e7cde2013-03-20 17:47:16 +0000504 for (int i = 0; i < kNumStages; ++i) {
505 if (this->isStageEnabled(i)) {
bsalomon@google.comc7818882013-03-20 19:19:53 +0000506 fStages[i].localCoordChange(oldToNew);
reed@google.com67e7cde2013-03-20 17:47:16 +0000507 }
508 }
reed@google.com67e7cde2013-03-20 17:47:16 +0000509 }
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +0000510
511 /**
512 * Checks whether any of the effects will read the dst pixel color.
513 */
514 bool willEffectReadDst() const {
515 for (int s = 0; s < kNumStages; ++s) {
516 if (this->isStageEnabled(s) && (*this->getStage(s).getEffect())->willReadDst()) {
517 return true;
518 }
519 }
520 return false;
521 }
reed@google.com67e7cde2013-03-20 17:47:16 +0000522
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000523 /// @}
524
525 ///////////////////////////////////////////////////////////////////////////
526 /// @name Coverage / Color Stages
527 ////
528
529 /**
530 * A common pattern is to compute a color with the initial stages and then
531 * modulate that color by a coverage value in later stage(s) (AA, mask-
rmistry@google.comd6176b02012-08-23 18:14:13 +0000532 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
533 * computed based on the pre-coverage-modulated color. The division of
534 * stages between color-computing and coverage-computing is specified by
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000535 * this method. Initially this is kNumStages (all stages
536 * are color-computing).
537 */
538 void setFirstCoverageStage(int firstCoverageStage) {
539 GrAssert((unsigned)firstCoverageStage <= kNumStages);
bsalomon@google.comca432082013-01-23 19:53:46 +0000540 fCommon.fFirstCoverageStage = firstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000541 }
542
543 /**
544 * Gets the index of the first coverage-computing stage.
545 */
546 int getFirstCoverageStage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000547 return fCommon.fFirstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000548 }
549
550 ///@}
551
552 ///////////////////////////////////////////////////////////////////////////
553 /// @name Blending
554 ////
555
556 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000557 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000558 *
559 * The blend function will be:
560 * D' = sat(S*srcCoef + D*dstCoef)
561 *
562 * where D is the existing destination color, S is the incoming source
563 * color, and D' is the new destination color that will be written. sat()
564 * is the saturation function.
565 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000566 * @param srcCoef coefficient applied to the src color.
567 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000568 */
569 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000570 fCommon.fSrcBlend = srcCoeff;
571 fCommon.fDstBlend = dstCoeff;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000572 #if GR_DEBUG
573 switch (dstCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000574 case kDC_GrBlendCoeff:
575 case kIDC_GrBlendCoeff:
576 case kDA_GrBlendCoeff:
577 case kIDA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000578 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
579 "coverage stages.\n");
580 break;
581 default:
582 break;
583 }
584 switch (srcCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000585 case kSC_GrBlendCoeff:
586 case kISC_GrBlendCoeff:
587 case kSA_GrBlendCoeff:
588 case kISA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000589 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
590 "coverage stages.\n");
591 break;
592 default:
593 break;
594 }
595 #endif
596 }
597
bsalomon@google.comca432082013-01-23 19:53:46 +0000598 GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
599 GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000600
601 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
602 GrBlendCoeff* dstBlendCoeff) const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000603 *srcBlendCoeff = fCommon.fSrcBlend;
604 *dstBlendCoeff = fCommon.fDstBlend;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000605 }
606
607 /**
608 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000609 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000610 * kConstC_GrBlendCoeff
611 * kIConstC_GrBlendCoeff
612 * kConstA_GrBlendCoeff
613 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000614 *
615 * @param constant the constant to set
616 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000617 void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000618
619 /**
620 * Retrieves the last value set by setBlendConstant()
621 * @return the blending constant value
622 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000623 GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000624
bsalomon@google.com2b446732013-02-12 16:47:41 +0000625 /**
626 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
627 * coverage before the blend will give the correct final destination color. In general it
628 * will not as coverage is applied after blending.
629 */
630 bool canTweakAlphaForCoverage() const;
631
632 /**
633 * Optimizations for blending / coverage to that can be applied based on the current state.
634 */
635 enum BlendOptFlags {
636 /**
637 * No optimization
638 */
639 kNone_BlendOpt = 0,
640 /**
641 * Don't draw at all
642 */
643 kSkipDraw_BlendOptFlag = 0x1,
644 /**
645 * Emit the src color, disable HW blending (replace dst with src)
646 */
647 kDisableBlend_BlendOptFlag = 0x2,
648 /**
649 * The coverage value does not have to be computed separately from alpha, the the output
650 * color can be the modulation of the two.
651 */
652 kCoverageAsAlpha_BlendOptFlag = 0x4,
653 /**
654 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
655 * "don't cares".
656 */
657 kEmitCoverage_BlendOptFlag = 0x8,
658 /**
659 * Emit transparent black instead of the src color, no need to compute coverage.
660 */
661 kEmitTransBlack_BlendOptFlag = 0x10,
662 };
663 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
664
665 /**
666 * Determines what optimizations can be applied based on the blend. The coefficients may have
667 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
668 * params that receive the tweaked coefficients. Normally the function looks at the current
669 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
670 * determine the blend optimizations that would be used if there was partial pixel coverage.
671 *
672 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
673 * playback) must call this function and respect the flags that replace the output color.
674 */
675 BlendOptFlags getBlendOpts(bool forceCoverage = false,
676 GrBlendCoeff* srcCoeff = NULL,
677 GrBlendCoeff* dstCoeff = NULL) const;
678
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000679 /// @}
680
681 ///////////////////////////////////////////////////////////////////////////
682 /// @name View Matrix
683 ////
684
685 /**
robertphillips@google.coma72eef32012-05-01 17:22:59 +0000686 * Sets the matrix applied to vertex positions.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000687 *
688 * In the post-view-matrix space the rectangle [0,w]x[0,h]
689 * fully covers the render target. (w and h are the width and height of the
bsalomon@google.comca432082013-01-23 19:53:46 +0000690 * the render-target.)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000691 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000692 void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000693
694 /**
695 * Gets a writable pointer to the view matrix.
696 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000697 SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000698
699 /**
700 * Multiplies the current view matrix by a matrix
701 *
702 * After this call V' = V*m where V is the old view matrix,
703 * m is the parameter to this function, and V' is the new view matrix.
704 * (We consider positions to be column vectors so position vector p is
705 * transformed by matrix X as p' = X*p.)
706 *
707 * @param m the matrix used to modify the view matrix.
708 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000709 void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000710
711 /**
712 * Multiplies the current view matrix by a matrix
713 *
714 * After this call V' = m*V where V is the old view matrix,
715 * m is the parameter to this function, and V' is the new view matrix.
716 * (We consider positions to be column vectors so position vector p is
717 * transformed by matrix X as p' = X*p.)
718 *
719 * @param m the matrix used to modify the view matrix.
720 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000721 void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000722
723 /**
724 * Retrieves the current view matrix
725 * @return the current view matrix.
726 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000727 const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000728
729 /**
730 * Retrieves the inverse of the current view matrix.
731 *
732 * If the current view matrix is invertible, return true, and if matrix
733 * is non-null, copy the inverse into it. If the current view matrix is
734 * non-invertible, return false and ignore the matrix parameter.
735 *
736 * @param matrix if not null, will receive a copy of the current inverse.
737 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000738 bool getViewInverse(SkMatrix* matrix) const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000739 // TODO: determine whether we really need to leave matrix unmodified
740 // at call sites when inversion fails.
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000741 SkMatrix inverse;
bsalomon@google.comca432082013-01-23 19:53:46 +0000742 if (fCommon.fViewMatrix.invert(&inverse)) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000743 if (matrix) {
744 *matrix = inverse;
745 }
746 return true;
747 }
748 return false;
749 }
750
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000751 ////////////////////////////////////////////////////////////////////////////
752
753 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000754 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.comc196b522012-10-25 21:52:43 +0000755 * Effect matrices are automatically adjusted to compensate.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000756 */
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000757 class AutoViewMatrixRestore : public ::GrNoncopyable {
758 public:
759 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000760
bsalomon@google.comc7818882013-03-20 19:19:53 +0000761 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000762 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000763 this->set(ds, preconcatMatrix);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000764 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000765
766 ~AutoViewMatrixRestore() { this->restore(); }
767
bsalomon@google.coma8347462012-10-08 18:59:39 +0000768 /**
769 * Can be called prior to destructor to restore the original matrix.
770 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000771 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000772
bsalomon@google.comc7818882013-03-20 19:19:53 +0000773 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000774
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000775 bool isSet() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000776
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000777 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000778 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000779 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000780 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000781 uint32_t fRestoreMask;
tomhudson@google.com93813632011-10-27 20:21:16 +0000782 };
783
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000784 ////////////////////////////////////////////////////////////////////////////
785
786 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000787 * This sets the view matrix to identity and adjusts stage matrices to compensate. The
788 * destructor undoes the changes, restoring the view matrix that was set before the
789 * constructor. It is similar to passing the inverse of the current view matrix to
790 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000791 */
792 class AutoDeviceCoordDraw : ::GrNoncopyable {
793 public:
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000794 AutoDeviceCoordDraw() : fDrawState(NULL) {}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000795 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000796 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
797 * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
798 * to specify such stages.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000799 */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000800 AutoDeviceCoordDraw(GrDrawState* drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000801 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000802 this->set(drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000803 }
804
bsalomon@google.coma8347462012-10-08 18:59:39 +0000805 ~AutoDeviceCoordDraw() { this->restore(); }
806
bsalomon@google.comc7818882013-03-20 19:19:53 +0000807 bool set(GrDrawState* drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000808
bsalomon@google.coma8347462012-10-08 18:59:39 +0000809 /**
810 * Returns true if this object was successfully initialized on to a GrDrawState. It may
811 * return false because a non-default constructor or set() were never called or because
812 * the view matrix was not invertible.
813 */
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000814 bool succeeded() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000815
bsalomon@google.coma8347462012-10-08 18:59:39 +0000816 /**
817 * Returns the matrix that was set previously set on the drawState. This is only valid
818 * if succeeded returns true.
819 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000820 const SkMatrix& getOriginalMatrix() const {
bsalomon@google.coma8347462012-10-08 18:59:39 +0000821 GrAssert(this->succeeded());
822 return fViewMatrix;
823 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000824
bsalomon@google.coma8347462012-10-08 18:59:39 +0000825 /**
826 * Can be called prior to destructor to restore the original matrix.
827 */
828 void restore();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000829
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000830 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000831 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000832 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000833 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000834 uint32_t fRestoreMask;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000835 };
836
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000837 /// @}
838
839 ///////////////////////////////////////////////////////////////////////////
840 /// @name Render Target
841 ////
842
843 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000844 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000845 *
846 * @param target The render target to set.
847 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000848 void setRenderTarget(GrRenderTarget* target) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000849 fRenderTarget.reset(SkSafeRef(target));
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000850 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000851
852 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000853 * Retrieves the currently set render-target.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000854 *
855 * @return The currently set render target.
856 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000857 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
858 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000859
860 class AutoRenderTargetRestore : public ::GrNoncopyable {
861 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000862 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000863 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
864 fDrawState = NULL;
robertphillips@google.com7460b372012-04-25 16:54:51 +0000865 fSavedTarget = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000866 this->set(ds, newTarget);
867 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000868 ~AutoRenderTargetRestore() { this->restore(); }
869
870 void restore() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000871 if (NULL != fDrawState) {
872 fDrawState->setRenderTarget(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000873 fDrawState = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000874 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000875 GrSafeSetNull(fSavedTarget);
876 }
877
878 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
879 this->restore();
880
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000881 if (NULL != ds) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000882 GrAssert(NULL == fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000883 fSavedTarget = ds->getRenderTarget();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000884 SkSafeRef(fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000885 ds->setRenderTarget(newTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000886 fDrawState = ds;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000887 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000888 }
889 private:
890 GrDrawState* fDrawState;
891 GrRenderTarget* fSavedTarget;
892 };
893
894 /// @}
895
896 ///////////////////////////////////////////////////////////////////////////
897 /// @name Stencil
898 ////
899
900 /**
901 * Sets the stencil settings to use for the next draw.
902 * Changing the clip has the side-effect of possibly zeroing
903 * out the client settable stencil bits. So multipass algorithms
904 * using stencil should not change the clip between passes.
905 * @param settings the stencil settings to use.
906 */
907 void setStencil(const GrStencilSettings& settings) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000908 fCommon.fStencilSettings = settings;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000909 }
910
911 /**
912 * Shortcut to disable stencil testing and ops.
913 */
914 void disableStencil() {
bsalomon@google.comca432082013-01-23 19:53:46 +0000915 fCommon.fStencilSettings.setDisabled();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000916 }
917
bsalomon@google.comca432082013-01-23 19:53:46 +0000918 const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000919
bsalomon@google.comca432082013-01-23 19:53:46 +0000920 GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000921
922 /// @}
923
924 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000925 /// @name State Flags
926 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000927
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000928 /**
929 * Flags that affect rendering. Controlled using enable/disableState(). All
930 * default to disabled.
931 */
932 enum StateBits {
933 /**
934 * Perform dithering. TODO: Re-evaluate whether we need this bit
935 */
936 kDither_StateBit = 0x01,
937 /**
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000938 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
939 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
940 * the 3D API.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000941 */
942 kHWAntialias_StateBit = 0x02,
943 /**
944 * Draws will respect the clip, otherwise the clip is ignored.
945 */
946 kClip_StateBit = 0x04,
947 /**
948 * Disables writing to the color buffer. Useful when performing stencil
949 * operations.
950 */
951 kNoColorWrites_StateBit = 0x08,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000952
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000953 /**
954 * Usually coverage is applied after color blending. The color is blended using the coeffs
955 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
956 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
957 * this case there is no distinction between coverage and color and the caller needs direct
958 * control over the blend coeffs. When set, there will be a single blend step controlled by
959 * setBlendFunc() which will use coverage*color as the src color.
960 */
961 kCoverageDrawing_StateBit = 0x10,
962
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000963 // Users of the class may add additional bits to the vector
964 kDummyStateBit,
965 kLastPublicStateBit = kDummyStateBit-1,
966 };
967
968 void resetStateFlags() {
bsalomon@google.comca432082013-01-23 19:53:46 +0000969 fCommon.fFlagBits = 0;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000970 }
971
972 /**
973 * Enable render state settings.
974 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000975 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000976 */
977 void enableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000978 fCommon.fFlagBits |= stateBits;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000979 }
980
981 /**
982 * Disable render state settings.
983 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000984 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000985 */
986 void disableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000987 fCommon.fFlagBits &= ~(stateBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000988 }
989
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000990 /**
991 * Enable or disable stateBits based on a boolean.
992 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000993 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000994 * @param enable if true enable stateBits, otherwise disable
995 */
996 void setState(uint32_t stateBits, bool enable) {
997 if (enable) {
998 this->enableState(stateBits);
999 } else {
1000 this->disableState(stateBits);
1001 }
1002 }
1003
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001004 bool isDitherState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001005 return 0 != (fCommon.fFlagBits & kDither_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001006 }
1007
1008 bool isHWAntialiasState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001009 return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001010 }
1011
1012 bool isClipState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001013 return 0 != (fCommon.fFlagBits & kClip_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001014 }
1015
1016 bool isColorWriteDisabled() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001017 return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001018 }
1019
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001020 bool isCoverageDrawing() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001021 return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001022 }
1023
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001024 bool isStateFlagEnabled(uint32_t stateBit) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001025 return 0 != (stateBit & fCommon.fFlagBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001026 }
1027
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001028 /// @}
1029
1030 ///////////////////////////////////////////////////////////////////////////
1031 /// @name Face Culling
1032 ////
1033
1034 enum DrawFace {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001035 kInvalid_DrawFace = -1,
1036
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001037 kBoth_DrawFace,
1038 kCCW_DrawFace,
1039 kCW_DrawFace,
1040 };
1041
1042 /**
1043 * Controls whether clockwise, counterclockwise, or both faces are drawn.
1044 * @param face the face(s) to draw.
1045 */
1046 void setDrawFace(DrawFace face) {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001047 GrAssert(kInvalid_DrawFace != face);
bsalomon@google.comca432082013-01-23 19:53:46 +00001048 fCommon.fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001049 }
1050
1051 /**
1052 * Gets whether the target is drawing clockwise, counterclockwise,
1053 * or both faces.
1054 * @return the current draw face(s).
1055 */
bsalomon@google.comca432082013-01-23 19:53:46 +00001056 DrawFace getDrawFace() const { return fCommon.fDrawFace; }
rmistry@google.comd6176b02012-08-23 18:14:13 +00001057
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001058 /// @}
1059
1060 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +00001061
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001062 bool isStageEnabled(int s) const {
1063 GrAssert((unsigned)s < kNumStages);
bsalomon@google.com08283af2012-10-26 13:01:20 +00001064 return (NULL != fStages[s].getEffect());
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001065 }
1066
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001067 bool operator ==(const GrDrawState& s) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001068 if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001069 return false;
1070 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +00001071 if (fVertexAttribs != s.fVertexAttribs) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001072 return false;
1073 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001074 for (int i = 0; i < kAttribIndexCount; ++i) {
bsalomon@google.comc7818882013-03-20 19:19:53 +00001075 if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001076 fAttribIndices[i] != s.fAttribIndices[i]) {
1077 return false;
1078 }
1079 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001080 for (int i = 0; i < kNumStages; i++) {
bsalomon@google.comf2f8fc32012-07-18 18:25:07 +00001081 bool enabled = this->isStageEnabled(i);
1082 if (enabled != s.isStageEnabled(i)) {
1083 return false;
1084 }
bsalomon@google.com08283af2012-10-26 13:01:20 +00001085 if (enabled && this->fStages[i] != s.fStages[i]) {
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001086 return false;
1087 }
1088 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001089 return true;
1090 }
1091 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
1092
bsalomon@google.comca432082013-01-23 19:53:46 +00001093 GrDrawState& operator= (const GrDrawState& s) {
1094 this->setRenderTarget(s.fRenderTarget.get());
1095 fCommon = s.fCommon;
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001096 fVertexAttribs = s.fVertexAttribs;
1097 for (int i = 0; i < kAttribIndexCount; i++) {
1098 fAttribIndices[i] = s.fAttribIndices[i];
1099 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001100 for (int i = 0; i < kNumStages; i++) {
tomhudson@google.come742bf02012-07-13 19:54:19 +00001101 if (s.isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +00001102 this->fStages[i] = s.fStages[i];
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001103 }
1104 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001105 return *this;
1106 }
1107
1108private:
bsalomon@google.com2e3d1442012-03-26 20:33:54 +00001109
bsalomon@google.comca432082013-01-23 19:53:46 +00001110 /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1111 struct CommonState {
1112 // These fields are roughly sorted by decreasing likelihood of being different in op==
1113 GrColor fColor;
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001114 GrAttribBindings fAttribBindings;
bsalomon@google.comca432082013-01-23 19:53:46 +00001115 SkMatrix fViewMatrix;
1116 GrBlendCoeff fSrcBlend;
1117 GrBlendCoeff fDstBlend;
1118 GrColor fBlendConstant;
1119 uint32_t fFlagBits;
bsalomon@google.comca432082013-01-23 19:53:46 +00001120 GrStencilSettings fStencilSettings;
1121 int fFirstCoverageStage;
1122 GrColor fCoverage;
1123 SkXfermode::Mode fColorFilterMode;
1124 GrColor fColorFilterColor;
1125 DrawFace fDrawFace;
1126 bool operator== (const CommonState& other) const {
1127 return fColor == other.fColor &&
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001128 fAttribBindings == other.fAttribBindings &&
bsalomon@google.comca432082013-01-23 19:53:46 +00001129 fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1130 fSrcBlend == other.fSrcBlend &&
1131 fDstBlend == other.fDstBlend &&
1132 fBlendConstant == other.fBlendConstant &&
1133 fFlagBits == other.fFlagBits &&
bsalomon@google.comca432082013-01-23 19:53:46 +00001134 fStencilSettings == other.fStencilSettings &&
1135 fFirstCoverageStage == other.fFirstCoverageStage &&
1136 fCoverage == other.fCoverage &&
1137 fColorFilterMode == other.fColorFilterMode &&
1138 fColorFilterColor == other.fColorFilterColor &&
1139 fDrawFace == other.fDrawFace;
1140 }
1141 bool operator!= (const CommonState& other) const { return !(*this == other); }
1142 };
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001143
bsalomon@google.comca432082013-01-23 19:53:46 +00001144 /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1145 DeferredState must directly reference GrEffects, however. */
1146 struct SavedEffectStage {
1147 SavedEffectStage() : fEffect(NULL) {}
1148 const GrEffect* fEffect;
1149 GrEffectStage::SavedCoordChange fCoordChange;
1150 };
1151
1152public:
1153 /**
1154 * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1155 * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1156 * dispose mechanism returns them to the cache. This allows recycling resources through the
1157 * the cache while they are in a deferred draw queue.
1158 */
1159 class DeferredState {
1160 public:
1161 DeferredState() : fRenderTarget(NULL) {
1162 GR_DEBUGCODE(fInitialized = false;)
1163 }
1164 // TODO: Remove this when DeferredState no longer holds a ref to the RT
1165 ~DeferredState() { SkSafeUnref(fRenderTarget); }
1166
1167 void saveFrom(const GrDrawState& drawState) {
1168 fCommon = drawState.fCommon;
1169 // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1170 fRenderTarget = drawState.fRenderTarget.get();
1171 SkSafeRef(fRenderTarget);
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001172 fVertexAttribs = drawState.fVertexAttribs;
1173 for (int i = 0; i < kAttribIndexCount; i++) {
1174 fAttribIndices[i] = drawState.fAttribIndices[i];
1175 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001176 // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1177 // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1178 // and recycle them to the cache (if no one else is holding a ref to the resources).
1179 for (int i = 0; i < kNumStages; ++i) {
1180 fStages[i].saveFrom(drawState.fStages[i]);
1181 }
1182 GR_DEBUGCODE(fInitialized = true;)
1183 }
1184
1185 void restoreTo(GrDrawState* drawState) {
1186 GrAssert(fInitialized);
1187 drawState->fCommon = fCommon;
1188 drawState->setRenderTarget(fRenderTarget);
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001189 drawState->fVertexAttribs = fVertexAttribs;
1190 for (int i = 0; i < kAttribIndexCount; i++) {
1191 drawState->fAttribIndices[i] = fAttribIndices[i];
1192 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001193 for (int i = 0; i < kNumStages; ++i) {
1194 fStages[i].restoreTo(&drawState->fStages[i]);
1195 }
1196 }
1197
1198 bool isEqual(const GrDrawState& state) const {
1199 if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1200 return false;
1201 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001202 for (int i = 0; i < kAttribIndexCount; ++i) {
skia.committer@gmail.comf140f182013-03-02 07:01:56 +00001203 if ((i == kPosition_AttribIndex ||
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001204 state.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
1205 fAttribIndices[i] != state.fAttribIndices[i]) {
1206 return false;
1207 }
1208 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +00001209 if (fVertexAttribs != state.fVertexAttribs) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001210 return false;
1211 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001212 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.comdcd69bf2013-01-24 18:28:51 +00001213 if (!fStages[i].isEqual(state.fStages[i])) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001214 return false;
1215 }
1216 }
1217 return true;
1218 }
1219
1220 private:
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001221 GrRenderTarget* fRenderTarget;
1222 CommonState fCommon;
1223 int fAttribIndices[kAttribIndexCount];
1224 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
1225 GrEffectStage::DeferredStage fStages[kNumStages];
bsalomon@google.comca432082013-01-23 19:53:46 +00001226
1227 GR_DEBUGCODE(bool fInitialized;)
1228 };
1229
1230private:
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001231 // helper array to let us check the current bindings so we know what bound attrib indices
1232 // we care about
1233 static const GrAttribBindings kAttribIndexMasks[kAttribIndexCount];
1234
1235 SkAutoTUnref<GrRenderTarget> fRenderTarget;
1236 CommonState fCommon;
1237 int fAttribIndices[kAttribIndexCount];
1238 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
1239 GrEffectStage fStages[kNumStages];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001240
reed@google.comfa35e3d2012-06-26 20:16:17 +00001241 typedef GrRefCnt INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +00001242};
1243
bsalomon@google.com2b446732013-02-12 16:47:41 +00001244GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
1245
tomhudson@google.com93813632011-10-27 20:21:16 +00001246#endif