blob: fed89dbefcd9eb4164cc2eeab7261109dd36a909 [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"
jvanverth@google.comcc782382013-01-28 20:39:48 +000014#include "GrRefCnt.h"
robertphillips@google.com9ec07532012-06-22 12:01:30 +000015#include "GrRenderTarget.h"
jvanverth@google.comcc782382013-01-28 20:39:48 +000016#include "GrStencil.h"
17#include "GrTemplates.h"
18#include "GrTexture.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000019#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000020
jvanverth@google.comcc782382013-01-28 20:39:48 +000021#include "SkMatrix.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000022#include "SkXfermode.h"
23
bsalomon@google.comaf84e742012-10-05 13:23:24 +000024class GrPaint;
tomhudson@google.com93813632011-10-27 20:21:16 +000025
jvanverth@google.com9b855c72013-03-01 18:21:22 +000026/**
27 * Types used to describe format of vertices in arrays
28 */
29enum GrVertexAttribType {
30 kFloat_GrVertexAttribType = 0,
31 kVec2f_GrVertexAttribType,
32 kVec3f_GrVertexAttribType,
33 kVec4f_GrVertexAttribType,
34 kVec4ub_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors
35
36 kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
37};
38static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
39
40struct GrVertexAttrib {
skia.committer@gmail.comf140f182013-03-02 07:01:56 +000041 inline void set(GrVertexAttribType type, size_t offset) {
jvanverth@google.com3b0d6312013-03-01 20:30:01 +000042 fType = type; fOffset = offset;
43 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +000044 bool operator==(const GrVertexAttrib& other) const {
45 return fType == other.fType && fOffset == other.fOffset;
46 };
47 bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
48
49 GrVertexAttribType fType;
50 size_t fOffset;
51};
52
53template <int N>
54class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
55
56/**
57 * Type used to describe how attributes bind to program usage
58 */
59typedef int GrAttribBindings;
60
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000061class GrDrawState : public GrRefCnt {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000062public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000063 SK_DECLARE_INST_COUNT(GrDrawState)
rmistry@google.comd6176b02012-08-23 18:14:13 +000064
tomhudson@google.com93813632011-10-27 20:21:16 +000065 /**
bsalomon@google.com13221342012-10-26 13:41:59 +000066 * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
67 * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
68 * output from the previous enabled stage and a position. The position is either derived from
69 * the interpolated vertex positions or explicit per-vertex coords, depending upon the
jvanverth@google.com9b855c72013-03-01 18:21:22 +000070 * GrAttribBindings used to draw.
robertphillips@google.combf5cad42012-05-10 12:40:40 +000071 *
bsalomon@google.com13221342012-10-26 13:41:59 +000072 * The stages are divided into two sets, color-computing and coverage-computing. The final color
73 * stage produces the final pixel color. The coverage-computing stages function exactly as the
74 * color-computing but the output of the final coverage stage is treated as a fractional pixel
75 * coverage rather than as input to the src/dst color blend step.
76 *
77 * The input color to the first enabled color-stage is either the constant color or interpolated
jvanverth@google.com9b855c72013-03-01 18:21:22 +000078 * per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
bsalomon@google.com4647f902013-03-26 14:45:27 +000079 * either a constant coverage (usually full-coverage) or interpolated per-vertex coverage.
bsalomon@google.com13221342012-10-26 13:41:59 +000080 *
bsalomon@google.comcf939ae2012-12-13 19:59:23 +000081 * See the documentation of kCoverageDrawing_StateBit for information about disabling the
82 * the color / coverage distinction.
83 *
bsalomon@google.com13221342012-10-26 13:41:59 +000084 * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
85 * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
86 * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +000087 * by GrClipMaskManager.
tomhudson@google.com93813632011-10-27 20:21:16 +000088 */
89 enum {
twiz@google.com58071162012-07-18 21:41:50 +000090 kNumStages = 5,
tomhudson@google.com93813632011-10-27 20:21:16 +000091 };
92
bsalomon@google.comca432082013-01-23 19:53:46 +000093 GrDrawState() {
reed@google.com75847192013-01-28 20:53:22 +000094#if GR_DEBUG
jvanverth@google.com9b855c72013-03-01 18:21:22 +000095 VertexAttributesUnitTest();
reed@google.com75847192013-01-28 20:53:22 +000096#endif
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000097 this->reset();
98 }
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000099
bsalomon@google.comca432082013-01-23 19:53:46 +0000100 GrDrawState(const GrDrawState& state) {
bsalomon@google.com46f7afb2012-01-18 19:51:55 +0000101 *this = state;
102 }
103
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000104 virtual ~GrDrawState() {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000105 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000106 }
107
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000108 /**
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000109 * Resets to the default state.
bsalomon@google.com08283af2012-10-26 13:01:20 +0000110 * GrEffects will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +0000111 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000112 void reset() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000113
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000114 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000115
bsalomon@google.comca432082013-01-23 19:53:46 +0000116 fRenderTarget.reset(NULL);
117
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000118 this->setDefaultVertexAttribs();
119
bsalomon@google.comca432082013-01-23 19:53:46 +0000120 fCommon.fColor = 0xffffffff;
121 fCommon.fViewMatrix.reset();
122 fCommon.fSrcBlend = kOne_GrBlendCoeff;
123 fCommon.fDstBlend = kZero_GrBlendCoeff;
124 fCommon.fBlendConstant = 0x0;
125 fCommon.fFlagBits = 0x0;
bsalomon@google.comca432082013-01-23 19:53:46 +0000126 fCommon.fStencilSettings.setDisabled();
127 fCommon.fFirstCoverageStage = kNumStages;
128 fCommon.fCoverage = 0xffffffff;
129 fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
130 fCommon.fColorFilterColor = 0x0;
131 fCommon.fDrawFace = kBoth_DrawFace;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000132 }
133
134 /**
135 * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000136 * encompasses more than GrPaint. Aspects of GrDrawState that have no
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000137 * GrPaint equivalents are not modified. GrPaint has fewer stages than
138 * GrDrawState. The extra GrDrawState stages are disabled.
139 */
140 void setFromPaint(const GrPaint& paint);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000141
142 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000143 /// @name Vertex Attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +0000144 ////
145
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000146 enum {
147 kVertexAttribCnt = 6,
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000148 };
149
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000150 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000151 * The format of vertices is represented as an array of vertex attribute
152 * pair, with each pair representing the type of the attribute and the
153 * offset in the vertex structure (see GrVertexAttrib, above).
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000154 *
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000155 * This will only set up the vertex geometry. To bind the attributes in
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000156 * the shaders, attribute indices and attribute bindings need to be set
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000157 * as well.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000158 */
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000159
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000160 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000161 * Sets vertex attributes for next draw.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000162 *
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000163 * @param attribs the array of vertex attributes to set.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000164 * @param count the number of attributes being set.
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000165 * limited to a count of kVertexAttribCnt.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000166 */
167 void setVertexAttribs(const GrVertexAttrib attribs[], int count);
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000168
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000169 const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
170 int getVertexAttribCount() const { return fVertexAttribs.count(); }
171
172 size_t getVertexSize() const;
173
174 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000175 * Sets default vertex attributes for next draw.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000176 *
177 * This will also set default vertex attribute indices and bindings
178 */
179 void setDefaultVertexAttribs();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000180
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000181 bool validateVertexAttribs() const;
182
jvanverth@google.comcc782382013-01-28 20:39:48 +0000183 ////////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000184 // Helpers for picking apart vertex attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +0000185
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000186 // helper array to let us check the expected so we know what bound attrib indices
187 // we care about
188 static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
jvanverth@google.comcc782382013-01-28 20:39:48 +0000189
190 /**
191 * Accessing positions, texture coords, or colors, of a vertex within an
192 * array is a hassle involving casts and simple math. These helpers exist
193 * to keep GrDrawTarget clients' code a bit nicer looking.
194 */
195
196 /**
197 * Gets a pointer to a GrPoint of a vertex's position or texture
198 * coordinate.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000199 * @param vertices the vertex array
jvanverth@google.comcc782382013-01-28 20:39:48 +0000200 * @param vertexIndex the index of the vertex in the array
201 * @param vertexSize the size of each vertex in the array
202 * @param offset the offset in bytes of the vertex component.
203 * Defaults to zero (corresponding to vertex position)
204 * @return pointer to the vertex component as a GrPoint
205 */
206 static GrPoint* GetVertexPoint(void* vertices,
207 int vertexIndex,
208 int vertexSize,
209 int offset = 0) {
210 intptr_t start = GrTCast<intptr_t>(vertices);
211 return GrTCast<GrPoint*>(start + offset +
212 vertexIndex * vertexSize);
213 }
214 static const GrPoint* GetVertexPoint(const void* vertices,
215 int vertexIndex,
216 int vertexSize,
217 int offset = 0) {
218 intptr_t start = GrTCast<intptr_t>(vertices);
219 return GrTCast<const GrPoint*>(start + offset +
220 vertexIndex * vertexSize);
221 }
222
223 /**
224 * Gets a pointer to a GrColor inside a vertex within a vertex array.
225 * @param vertices the vetex array
226 * @param vertexIndex the index of the vertex in the array
227 * @param vertexSize the size of each vertex in the array
228 * @param offset the offset in bytes of the vertex color
229 * @return pointer to the vertex component as a GrColor
230 */
231 static GrColor* GetVertexColor(void* vertices,
232 int vertexIndex,
233 int vertexSize,
234 int offset) {
235 intptr_t start = GrTCast<intptr_t>(vertices);
236 return GrTCast<GrColor*>(start + offset +
237 vertexIndex * vertexSize);
238 }
239 static const GrColor* GetVertexColor(const void* vertices,
240 int vertexIndex,
241 int vertexSize,
242 int offset) {
243 const intptr_t start = GrTCast<intptr_t>(vertices);
244 return GrTCast<const GrColor*>(start + offset +
245 vertexIndex * vertexSize);
246 }
247
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000248 /// @}
249
250 ///////////////////////////////////////////////////////////////////////////
251 /// @name Attribute Bindings
252 ////
253
254 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000255 * The vertex data used by the current program is represented as a bitfield
256 * of flags. Programs always use positions and may also use texture
bsalomon@google.comc7818882013-03-20 19:19:53 +0000257 * coordinates, per-vertex colors, per-vertex coverage and edge data. The
258 * local coords accessible by effects may either come from positions or
259 * be specified explicitly.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000260 */
261
262 /**
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000263 * Additional Bits that can be specified in GrAttribBindings.
264 */
265 enum AttribBindingsBits {
bsalomon@google.comc7818882013-03-20 19:19:53 +0000266 /** explicit local coords are provided (instead of using pre-view-matrix positions) */
267 kLocalCoords_AttribBindingsBit = 0x1,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000268 /* program uses colors (GrColor) */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000269 kColor_AttribBindingsBit = 0x2,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000270 /* program uses coverage (GrColor)
271 */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000272 kCoverage_AttribBindingsBit = 0x4,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000273 // for below assert
274 kDummyAttribBindingsBit,
275 kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
276 };
277 // make sure we haven't exceeded the number of bits in GrAttribBindings.
278 GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribBindings)));
279
280 enum AttribBindings {
281 kDefault_AttribBindings = 0
282 };
283
284 /**
285 * Sets attribute bindings for next draw.
286 *
287 * @param bindings the attribute bindings to set.
288 */
289 void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; }
290
291 GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; }
292
293 ////////////////////////////////////////////////////////////////////////////
294 // Helpers for picking apart attribute bindings
295
296 /**
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000297 * Determines whether src alpha is guaranteed to be one for all src pixels
298 */
299 bool srcAlphaWillBeOne(GrAttribBindings) const;
300
301 /**
302 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
303 */
304 bool hasSolidCoverage(GrAttribBindings) const;
305
306 static void VertexAttributesUnitTest();
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000307
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000308 /// @}
309
310 ///////////////////////////////////////////////////////////////////////////
311 /// @name Vertex Attribute Indices
312 ////
313
314 /**
315 * Vertex attribute indices map the data set in the vertex attribute array
316 * to the bindings specified in the attribute bindings. Each binding type
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000317 * has an associated index in the attribute array. This index is used to
318 * look up the vertex attribute data from the array, and potentially as the
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000319 * attribute index if we're binding attributes in GL.
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000320 *
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000321 * Indices which do not have active attribute bindings will be ignored.
322 */
323
324 enum AttribIndex {
325 kPosition_AttribIndex = 0,
326 kColor_AttribIndex,
327 kCoverage_AttribIndex,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000328 kLocalCoords_AttribIndex,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000329
bsalomon@google.comc7818882013-03-20 19:19:53 +0000330 kLast_AttribIndex = kLocalCoords_AttribIndex
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000331 };
332 static const int kAttribIndexCount = kLast_AttribIndex + 1;
333
334 // these are used when vertex color and coverage isn't set
335 enum {
336 kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt,
337 kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1,
338 };
339
340 ////////////////////////////////////////////////////////////////////////////
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000341 // Helpers to set attribute indices. These should match the index in the
342 // current attribute index array.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000343
344 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000345 * Sets index for next draw. This is used to look up the offset
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000346 * from the current vertex attribute array and to bind the attributes.
347 *
348 * @param index the attribute index we're setting
349 * @param value the value of the index
350 */
351 void setAttribIndex(AttribIndex index, int value) { fAttribIndices[index] = value; }
352
353 int getAttribIndex(AttribIndex index) const { return fAttribIndices[index]; }
jvanverth@google.comcc782382013-01-28 20:39:48 +0000354
355 /// @}
356
357 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000358 /// @name Color
359 ////
360
361 /**
362 * Sets color for next draw to a premultiplied-alpha color.
363 *
364 * @param color the color to set.
365 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000366 void setColor(GrColor color) { fCommon.fColor = color; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000367
bsalomon@google.comca432082013-01-23 19:53:46 +0000368 GrColor getColor() const { return fCommon.fColor; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000369
370 /**
371 * Sets the color to be used for the next draw to be
372 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
373 *
374 * @param alpha The alpha value to set as the color.
375 */
376 void setAlpha(uint8_t a) {
377 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
378 }
379
380 /**
381 * Add a color filter that can be represented by a color and a mode. Applied
bsalomon@google.comc7818882013-03-20 19:19:53 +0000382 * after color-computing effect stages.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000383 */
384 void setColorFilter(GrColor c, SkXfermode::Mode mode) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000385 fCommon.fColorFilterColor = c;
386 fCommon.fColorFilterMode = mode;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000387 }
388
bsalomon@google.comca432082013-01-23 19:53:46 +0000389 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
390 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000391
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000392 /**
393 * Constructor sets the color to be 'color' which is undone by the destructor.
394 */
395 class AutoColorRestore : public ::GrNoncopyable {
396 public:
sugoi@google.com66a58ac2013-03-05 20:40:52 +0000397 AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000398
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000399 AutoColorRestore(GrDrawState* drawState, GrColor color) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000400 fDrawState = NULL;
401 this->set(drawState, color);
402 }
403
404 void reset() {
405 if (NULL != fDrawState) {
406 fDrawState->setColor(fOldColor);
407 fDrawState = NULL;
408 }
409 }
410
411 void set(GrDrawState* drawState, GrColor color) {
412 this->reset();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000413 fDrawState = drawState;
414 fOldColor = fDrawState->getColor();
415 fDrawState->setColor(color);
416 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000417
418 ~AutoColorRestore() { this->reset(); }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000419 private:
420 GrDrawState* fDrawState;
421 GrColor fOldColor;
422 };
423
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000424 /// @}
425
426 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000427 /// @name Coverage
428 ////
429
430 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000431 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000432 * initial value (after construction or reset()) is 0xff. The constant
433 * coverage is ignored when per-vertex coverage is provided.
434 */
435 void setCoverage(uint8_t coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000436 fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000437 }
438
439 /**
440 * Version of above that specifies 4 channel per-vertex color. The value
441 * should be premultiplied.
442 */
443 void setCoverage4(GrColor coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000444 fCommon.fCoverage = coverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000445 }
446
447 GrColor getCoverage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000448 return fCommon.fCoverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000449 }
450
451 /// @}
452
453 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000454 /// @name Effect Stages
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000455 ////
456
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000457 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
458 fStages[stageIdx].setEffect(effect);
459 return effect;
460 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000461
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000462 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect,
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000463 int attr0, int attr1 = -1) {
464 fStages[stageIdx].setEffect(effect, attr0, attr1);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000465 return effect;
466 }
467
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000468 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000469 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000470 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000471 void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000472 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000473 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000474 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000475 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000476 void createTextureEffect(int stageIdx,
477 GrTexture* texture,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000478 const SkMatrix& matrix,
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000479 const GrTextureParams& params) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000480 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000481 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000482 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000483 }
484
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000485 bool stagesDisabled() {
486 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000487 if (NULL != fStages[i].getEffect()) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000488 return false;
489 }
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000490 }
tomhudson@google.com3eee8fb2012-06-25 12:30:34 +0000491 return true;
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000492 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000493
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000494 void disableStage(int stageIdx) {
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000495 this->setEffect(stageIdx, NULL);
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000496 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000497
robertphillips@google.com972265d2012-06-13 18:49:30 +0000498 /**
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000499 * Release all the GrEffects referred to by this draw state.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000500 */
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000501 void disableStages() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000502 for (int i = 0; i < kNumStages; ++i) {
tomhudson@google.com676e6602012-07-10 17:21:48 +0000503 this->disableStage(i);
robertphillips@google.com972265d2012-06-13 18:49:30 +0000504 }
505 }
506
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000507 class AutoStageDisable : public ::GrNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000508 public:
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000509 AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
510 ~AutoStageDisable() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000511 if (NULL != fDrawState) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000512 fDrawState->disableStages();
robertphillips@google.com972265d2012-06-13 18:49:30 +0000513 }
514 }
515 private:
516 GrDrawState* fDrawState;
517 };
518
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000519 /**
bsalomon@google.com08283af2012-10-26 13:01:20 +0000520 * Returns the current stage by index.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000521 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000522 const GrEffectStage& getStage(int stageIdx) const {
523 GrAssert((unsigned)stageIdx < kNumStages);
524 return fStages[stageIdx];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000525 }
526
527 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000528 * Called when the source coord system is changing. This ensures that effects will see the
529 * correct local coordinates. oldToNew gives the transformation from the old coord system in
530 * which the geometry was specified to the new coordinate system from which it will be rendered.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000531 */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000532 void localCoordChange(const SkMatrix& oldToNew) {
reed@google.com67e7cde2013-03-20 17:47:16 +0000533 for (int i = 0; i < kNumStages; ++i) {
534 if (this->isStageEnabled(i)) {
bsalomon@google.comc7818882013-03-20 19:19:53 +0000535 fStages[i].localCoordChange(oldToNew);
reed@google.com67e7cde2013-03-20 17:47:16 +0000536 }
537 }
reed@google.com67e7cde2013-03-20 17:47:16 +0000538 }
539
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000540 /// @}
541
542 ///////////////////////////////////////////////////////////////////////////
543 /// @name Coverage / Color Stages
544 ////
545
546 /**
547 * A common pattern is to compute a color with the initial stages and then
548 * modulate that color by a coverage value in later stage(s) (AA, mask-
rmistry@google.comd6176b02012-08-23 18:14:13 +0000549 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
550 * computed based on the pre-coverage-modulated color. The division of
551 * stages between color-computing and coverage-computing is specified by
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000552 * this method. Initially this is kNumStages (all stages
553 * are color-computing).
554 */
555 void setFirstCoverageStage(int firstCoverageStage) {
556 GrAssert((unsigned)firstCoverageStage <= kNumStages);
bsalomon@google.comca432082013-01-23 19:53:46 +0000557 fCommon.fFirstCoverageStage = firstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000558 }
559
560 /**
561 * Gets the index of the first coverage-computing stage.
562 */
563 int getFirstCoverageStage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000564 return fCommon.fFirstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000565 }
566
567 ///@}
568
569 ///////////////////////////////////////////////////////////////////////////
570 /// @name Blending
571 ////
572
573 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000574 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000575 *
576 * The blend function will be:
577 * D' = sat(S*srcCoef + D*dstCoef)
578 *
579 * where D is the existing destination color, S is the incoming source
580 * color, and D' is the new destination color that will be written. sat()
581 * is the saturation function.
582 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000583 * @param srcCoef coefficient applied to the src color.
584 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000585 */
586 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000587 fCommon.fSrcBlend = srcCoeff;
588 fCommon.fDstBlend = dstCoeff;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000589 #if GR_DEBUG
590 switch (dstCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000591 case kDC_GrBlendCoeff:
592 case kIDC_GrBlendCoeff:
593 case kDA_GrBlendCoeff:
594 case kIDA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000595 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
596 "coverage stages.\n");
597 break;
598 default:
599 break;
600 }
601 switch (srcCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000602 case kSC_GrBlendCoeff:
603 case kISC_GrBlendCoeff:
604 case kSA_GrBlendCoeff:
605 case kISA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000606 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
607 "coverage stages.\n");
608 break;
609 default:
610 break;
611 }
612 #endif
613 }
614
bsalomon@google.comca432082013-01-23 19:53:46 +0000615 GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
616 GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000617
618 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
619 GrBlendCoeff* dstBlendCoeff) const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000620 *srcBlendCoeff = fCommon.fSrcBlend;
621 *dstBlendCoeff = fCommon.fDstBlend;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000622 }
623
624 /**
625 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000626 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000627 * kConstC_GrBlendCoeff
628 * kIConstC_GrBlendCoeff
629 * kConstA_GrBlendCoeff
630 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000631 *
632 * @param constant the constant to set
633 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000634 void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000635
636 /**
637 * Retrieves the last value set by setBlendConstant()
638 * @return the blending constant value
639 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000640 GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000641
bsalomon@google.com2b446732013-02-12 16:47:41 +0000642 /**
643 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
644 * coverage before the blend will give the correct final destination color. In general it
645 * will not as coverage is applied after blending.
646 */
647 bool canTweakAlphaForCoverage() const;
648
649 /**
650 * Optimizations for blending / coverage to that can be applied based on the current state.
651 */
652 enum BlendOptFlags {
653 /**
654 * No optimization
655 */
656 kNone_BlendOpt = 0,
657 /**
658 * Don't draw at all
659 */
660 kSkipDraw_BlendOptFlag = 0x1,
661 /**
662 * Emit the src color, disable HW blending (replace dst with src)
663 */
664 kDisableBlend_BlendOptFlag = 0x2,
665 /**
666 * The coverage value does not have to be computed separately from alpha, the the output
667 * color can be the modulation of the two.
668 */
669 kCoverageAsAlpha_BlendOptFlag = 0x4,
670 /**
671 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
672 * "don't cares".
673 */
674 kEmitCoverage_BlendOptFlag = 0x8,
675 /**
676 * Emit transparent black instead of the src color, no need to compute coverage.
677 */
678 kEmitTransBlack_BlendOptFlag = 0x10,
679 };
680 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
681
682 /**
683 * Determines what optimizations can be applied based on the blend. The coefficients may have
684 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
685 * params that receive the tweaked coefficients. Normally the function looks at the current
686 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
687 * determine the blend optimizations that would be used if there was partial pixel coverage.
688 *
689 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
690 * playback) must call this function and respect the flags that replace the output color.
691 */
692 BlendOptFlags getBlendOpts(bool forceCoverage = false,
693 GrBlendCoeff* srcCoeff = NULL,
694 GrBlendCoeff* dstCoeff = NULL) const;
695
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000696 /// @}
697
698 ///////////////////////////////////////////////////////////////////////////
699 /// @name View Matrix
700 ////
701
702 /**
robertphillips@google.coma72eef32012-05-01 17:22:59 +0000703 * Sets the matrix applied to vertex positions.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000704 *
705 * In the post-view-matrix space the rectangle [0,w]x[0,h]
706 * fully covers the render target. (w and h are the width and height of the
bsalomon@google.comca432082013-01-23 19:53:46 +0000707 * the render-target.)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000708 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000709 void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000710
711 /**
712 * Gets a writable pointer to the view matrix.
713 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000714 SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000715
716 /**
717 * Multiplies the current view matrix by a matrix
718 *
719 * After this call V' = V*m where V is the old view matrix,
720 * m is the parameter to this function, and V' is the new view matrix.
721 * (We consider positions to be column vectors so position vector p is
722 * transformed by matrix X as p' = X*p.)
723 *
724 * @param m the matrix used to modify the view matrix.
725 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000726 void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000727
728 /**
729 * Multiplies the current view matrix by a matrix
730 *
731 * After this call V' = m*V where V is the old view matrix,
732 * m is the parameter to this function, and V' is the new view matrix.
733 * (We consider positions to be column vectors so position vector p is
734 * transformed by matrix X as p' = X*p.)
735 *
736 * @param m the matrix used to modify the view matrix.
737 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000738 void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000739
740 /**
741 * Retrieves the current view matrix
742 * @return the current view matrix.
743 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000744 const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000745
746 /**
747 * Retrieves the inverse of the current view matrix.
748 *
749 * If the current view matrix is invertible, return true, and if matrix
750 * is non-null, copy the inverse into it. If the current view matrix is
751 * non-invertible, return false and ignore the matrix parameter.
752 *
753 * @param matrix if not null, will receive a copy of the current inverse.
754 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000755 bool getViewInverse(SkMatrix* matrix) const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000756 // TODO: determine whether we really need to leave matrix unmodified
757 // at call sites when inversion fails.
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000758 SkMatrix inverse;
bsalomon@google.comca432082013-01-23 19:53:46 +0000759 if (fCommon.fViewMatrix.invert(&inverse)) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000760 if (matrix) {
761 *matrix = inverse;
762 }
763 return true;
764 }
765 return false;
766 }
767
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000768 ////////////////////////////////////////////////////////////////////////////
769
770 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000771 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.comc196b522012-10-25 21:52:43 +0000772 * Effect matrices are automatically adjusted to compensate.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000773 */
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000774 class AutoViewMatrixRestore : public ::GrNoncopyable {
775 public:
776 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000777
bsalomon@google.comc7818882013-03-20 19:19:53 +0000778 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000779 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000780 this->set(ds, preconcatMatrix);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000781 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000782
783 ~AutoViewMatrixRestore() { this->restore(); }
784
bsalomon@google.coma8347462012-10-08 18:59:39 +0000785 /**
786 * Can be called prior to destructor to restore the original matrix.
787 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000788 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000789
bsalomon@google.comc7818882013-03-20 19:19:53 +0000790 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000791
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000792 bool isSet() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000793
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000794 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000795 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000796 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000797 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000798 uint32_t fRestoreMask;
tomhudson@google.com93813632011-10-27 20:21:16 +0000799 };
800
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000801 ////////////////////////////////////////////////////////////////////////////
802
803 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000804 * This sets the view matrix to identity and adjusts stage matrices to compensate. The
805 * destructor undoes the changes, restoring the view matrix that was set before the
806 * constructor. It is similar to passing the inverse of the current view matrix to
807 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000808 */
809 class AutoDeviceCoordDraw : ::GrNoncopyable {
810 public:
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000811 AutoDeviceCoordDraw() : fDrawState(NULL) {}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000812 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000813 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
814 * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
815 * to specify such stages.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000816 */
bsalomon@google.comc7818882013-03-20 19:19:53 +0000817 AutoDeviceCoordDraw(GrDrawState* drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000818 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000819 this->set(drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000820 }
821
bsalomon@google.coma8347462012-10-08 18:59:39 +0000822 ~AutoDeviceCoordDraw() { this->restore(); }
823
bsalomon@google.comc7818882013-03-20 19:19:53 +0000824 bool set(GrDrawState* drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000825
bsalomon@google.coma8347462012-10-08 18:59:39 +0000826 /**
827 * Returns true if this object was successfully initialized on to a GrDrawState. It may
828 * return false because a non-default constructor or set() were never called or because
829 * the view matrix was not invertible.
830 */
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000831 bool succeeded() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000832
bsalomon@google.coma8347462012-10-08 18:59:39 +0000833 /**
834 * Returns the matrix that was set previously set on the drawState. This is only valid
835 * if succeeded returns true.
836 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000837 const SkMatrix& getOriginalMatrix() const {
bsalomon@google.coma8347462012-10-08 18:59:39 +0000838 GrAssert(this->succeeded());
839 return fViewMatrix;
840 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000841
bsalomon@google.coma8347462012-10-08 18:59:39 +0000842 /**
843 * Can be called prior to destructor to restore the original matrix.
844 */
845 void restore();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000846
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000847 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000848 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000849 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000850 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000851 uint32_t fRestoreMask;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000852 };
853
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000854 /// @}
855
856 ///////////////////////////////////////////////////////////////////////////
857 /// @name Render Target
858 ////
859
860 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000861 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000862 *
863 * @param target The render target to set.
864 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000865 void setRenderTarget(GrRenderTarget* target) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000866 fRenderTarget.reset(SkSafeRef(target));
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000867 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000868
869 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000870 * Retrieves the currently set render-target.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000871 *
872 * @return The currently set render target.
873 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000874 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
875 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000876
877 class AutoRenderTargetRestore : public ::GrNoncopyable {
878 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000879 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000880 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
881 fDrawState = NULL;
robertphillips@google.com7460b372012-04-25 16:54:51 +0000882 fSavedTarget = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000883 this->set(ds, newTarget);
884 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000885 ~AutoRenderTargetRestore() { this->restore(); }
886
887 void restore() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000888 if (NULL != fDrawState) {
889 fDrawState->setRenderTarget(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000890 fDrawState = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000891 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000892 GrSafeSetNull(fSavedTarget);
893 }
894
895 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
896 this->restore();
897
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000898 if (NULL != ds) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000899 GrAssert(NULL == fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000900 fSavedTarget = ds->getRenderTarget();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000901 SkSafeRef(fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000902 ds->setRenderTarget(newTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000903 fDrawState = ds;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000904 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000905 }
906 private:
907 GrDrawState* fDrawState;
908 GrRenderTarget* fSavedTarget;
909 };
910
911 /// @}
912
913 ///////////////////////////////////////////////////////////////////////////
914 /// @name Stencil
915 ////
916
917 /**
918 * Sets the stencil settings to use for the next draw.
919 * Changing the clip has the side-effect of possibly zeroing
920 * out the client settable stencil bits. So multipass algorithms
921 * using stencil should not change the clip between passes.
922 * @param settings the stencil settings to use.
923 */
924 void setStencil(const GrStencilSettings& settings) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000925 fCommon.fStencilSettings = settings;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000926 }
927
928 /**
929 * Shortcut to disable stencil testing and ops.
930 */
931 void disableStencil() {
bsalomon@google.comca432082013-01-23 19:53:46 +0000932 fCommon.fStencilSettings.setDisabled();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000933 }
934
bsalomon@google.comca432082013-01-23 19:53:46 +0000935 const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000936
bsalomon@google.comca432082013-01-23 19:53:46 +0000937 GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000938
939 /// @}
940
941 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000942 /// @name State Flags
943 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000944
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000945 /**
946 * Flags that affect rendering. Controlled using enable/disableState(). All
947 * default to disabled.
948 */
949 enum StateBits {
950 /**
951 * Perform dithering. TODO: Re-evaluate whether we need this bit
952 */
953 kDither_StateBit = 0x01,
954 /**
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000955 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
956 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
957 * the 3D API.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000958 */
959 kHWAntialias_StateBit = 0x02,
960 /**
961 * Draws will respect the clip, otherwise the clip is ignored.
962 */
963 kClip_StateBit = 0x04,
964 /**
965 * Disables writing to the color buffer. Useful when performing stencil
966 * operations.
967 */
968 kNoColorWrites_StateBit = 0x08,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000969
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000970 /**
971 * Usually coverage is applied after color blending. The color is blended using the coeffs
972 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
973 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
974 * this case there is no distinction between coverage and color and the caller needs direct
975 * control over the blend coeffs. When set, there will be a single blend step controlled by
976 * setBlendFunc() which will use coverage*color as the src color.
977 */
978 kCoverageDrawing_StateBit = 0x10,
979
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000980 // Users of the class may add additional bits to the vector
981 kDummyStateBit,
982 kLastPublicStateBit = kDummyStateBit-1,
983 };
984
985 void resetStateFlags() {
bsalomon@google.comca432082013-01-23 19:53:46 +0000986 fCommon.fFlagBits = 0;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000987 }
988
989 /**
990 * Enable render state settings.
991 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000992 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000993 */
994 void enableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000995 fCommon.fFlagBits |= stateBits;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000996 }
997
998 /**
999 * Disable render state settings.
1000 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001001 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001002 */
1003 void disableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001004 fCommon.fFlagBits &= ~(stateBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001005 }
1006
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +00001007 /**
1008 * Enable or disable stateBits based on a boolean.
1009 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001010 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +00001011 * @param enable if true enable stateBits, otherwise disable
1012 */
1013 void setState(uint32_t stateBits, bool enable) {
1014 if (enable) {
1015 this->enableState(stateBits);
1016 } else {
1017 this->disableState(stateBits);
1018 }
1019 }
1020
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001021 bool isDitherState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001022 return 0 != (fCommon.fFlagBits & kDither_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001023 }
1024
1025 bool isHWAntialiasState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001026 return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001027 }
1028
1029 bool isClipState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001030 return 0 != (fCommon.fFlagBits & kClip_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001031 }
1032
1033 bool isColorWriteDisabled() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001034 return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001035 }
1036
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001037 bool isCoverageDrawing() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001038 return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001039 }
1040
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001041 bool isStateFlagEnabled(uint32_t stateBit) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001042 return 0 != (stateBit & fCommon.fFlagBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001043 }
1044
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001045 /// @}
1046
1047 ///////////////////////////////////////////////////////////////////////////
1048 /// @name Face Culling
1049 ////
1050
1051 enum DrawFace {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001052 kInvalid_DrawFace = -1,
1053
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001054 kBoth_DrawFace,
1055 kCCW_DrawFace,
1056 kCW_DrawFace,
1057 };
1058
1059 /**
1060 * Controls whether clockwise, counterclockwise, or both faces are drawn.
1061 * @param face the face(s) to draw.
1062 */
1063 void setDrawFace(DrawFace face) {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001064 GrAssert(kInvalid_DrawFace != face);
bsalomon@google.comca432082013-01-23 19:53:46 +00001065 fCommon.fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001066 }
1067
1068 /**
1069 * Gets whether the target is drawing clockwise, counterclockwise,
1070 * or both faces.
1071 * @return the current draw face(s).
1072 */
bsalomon@google.comca432082013-01-23 19:53:46 +00001073 DrawFace getDrawFace() const { return fCommon.fDrawFace; }
rmistry@google.comd6176b02012-08-23 18:14:13 +00001074
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001075 /// @}
1076
1077 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +00001078
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001079 bool isStageEnabled(int s) const {
1080 GrAssert((unsigned)s < kNumStages);
bsalomon@google.com08283af2012-10-26 13:01:20 +00001081 return (NULL != fStages[s].getEffect());
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001082 }
1083
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001084 bool operator ==(const GrDrawState& s) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001085 if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001086 return false;
1087 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +00001088 if (fVertexAttribs != s.fVertexAttribs) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001089 return false;
1090 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001091 for (int i = 0; i < kAttribIndexCount; ++i) {
bsalomon@google.comc7818882013-03-20 19:19:53 +00001092 if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001093 fAttribIndices[i] != s.fAttribIndices[i]) {
1094 return false;
1095 }
1096 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001097 for (int i = 0; i < kNumStages; i++) {
bsalomon@google.comf2f8fc32012-07-18 18:25:07 +00001098 bool enabled = this->isStageEnabled(i);
1099 if (enabled != s.isStageEnabled(i)) {
1100 return false;
1101 }
bsalomon@google.com08283af2012-10-26 13:01:20 +00001102 if (enabled && this->fStages[i] != s.fStages[i]) {
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001103 return false;
1104 }
1105 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001106 return true;
1107 }
1108 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
1109
bsalomon@google.comca432082013-01-23 19:53:46 +00001110 GrDrawState& operator= (const GrDrawState& s) {
1111 this->setRenderTarget(s.fRenderTarget.get());
1112 fCommon = s.fCommon;
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001113 fVertexAttribs = s.fVertexAttribs;
1114 for (int i = 0; i < kAttribIndexCount; i++) {
1115 fAttribIndices[i] = s.fAttribIndices[i];
1116 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001117 for (int i = 0; i < kNumStages; i++) {
tomhudson@google.come742bf02012-07-13 19:54:19 +00001118 if (s.isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +00001119 this->fStages[i] = s.fStages[i];
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001120 }
1121 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001122 return *this;
1123 }
1124
1125private:
bsalomon@google.com2e3d1442012-03-26 20:33:54 +00001126
bsalomon@google.comca432082013-01-23 19:53:46 +00001127 /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1128 struct CommonState {
1129 // These fields are roughly sorted by decreasing likelihood of being different in op==
1130 GrColor fColor;
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001131 GrAttribBindings fAttribBindings;
bsalomon@google.comca432082013-01-23 19:53:46 +00001132 SkMatrix fViewMatrix;
1133 GrBlendCoeff fSrcBlend;
1134 GrBlendCoeff fDstBlend;
1135 GrColor fBlendConstant;
1136 uint32_t fFlagBits;
bsalomon@google.comca432082013-01-23 19:53:46 +00001137 GrStencilSettings fStencilSettings;
1138 int fFirstCoverageStage;
1139 GrColor fCoverage;
1140 SkXfermode::Mode fColorFilterMode;
1141 GrColor fColorFilterColor;
1142 DrawFace fDrawFace;
1143 bool operator== (const CommonState& other) const {
1144 return fColor == other.fColor &&
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001145 fAttribBindings == other.fAttribBindings &&
bsalomon@google.comca432082013-01-23 19:53:46 +00001146 fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1147 fSrcBlend == other.fSrcBlend &&
1148 fDstBlend == other.fDstBlend &&
1149 fBlendConstant == other.fBlendConstant &&
1150 fFlagBits == other.fFlagBits &&
bsalomon@google.comca432082013-01-23 19:53:46 +00001151 fStencilSettings == other.fStencilSettings &&
1152 fFirstCoverageStage == other.fFirstCoverageStage &&
1153 fCoverage == other.fCoverage &&
1154 fColorFilterMode == other.fColorFilterMode &&
1155 fColorFilterColor == other.fColorFilterColor &&
1156 fDrawFace == other.fDrawFace;
1157 }
1158 bool operator!= (const CommonState& other) const { return !(*this == other); }
1159 };
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001160
bsalomon@google.comca432082013-01-23 19:53:46 +00001161 /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1162 DeferredState must directly reference GrEffects, however. */
1163 struct SavedEffectStage {
1164 SavedEffectStage() : fEffect(NULL) {}
1165 const GrEffect* fEffect;
1166 GrEffectStage::SavedCoordChange fCoordChange;
1167 };
1168
1169public:
1170 /**
1171 * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1172 * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1173 * dispose mechanism returns them to the cache. This allows recycling resources through the
1174 * the cache while they are in a deferred draw queue.
1175 */
1176 class DeferredState {
1177 public:
1178 DeferredState() : fRenderTarget(NULL) {
1179 GR_DEBUGCODE(fInitialized = false;)
1180 }
1181 // TODO: Remove this when DeferredState no longer holds a ref to the RT
1182 ~DeferredState() { SkSafeUnref(fRenderTarget); }
1183
1184 void saveFrom(const GrDrawState& drawState) {
1185 fCommon = drawState.fCommon;
1186 // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1187 fRenderTarget = drawState.fRenderTarget.get();
1188 SkSafeRef(fRenderTarget);
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001189 fVertexAttribs = drawState.fVertexAttribs;
1190 for (int i = 0; i < kAttribIndexCount; i++) {
1191 fAttribIndices[i] = drawState.fAttribIndices[i];
1192 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001193 // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1194 // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1195 // and recycle them to the cache (if no one else is holding a ref to the resources).
1196 for (int i = 0; i < kNumStages; ++i) {
1197 fStages[i].saveFrom(drawState.fStages[i]);
1198 }
1199 GR_DEBUGCODE(fInitialized = true;)
1200 }
1201
1202 void restoreTo(GrDrawState* drawState) {
1203 GrAssert(fInitialized);
1204 drawState->fCommon = fCommon;
1205 drawState->setRenderTarget(fRenderTarget);
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001206 drawState->fVertexAttribs = fVertexAttribs;
1207 for (int i = 0; i < kAttribIndexCount; i++) {
1208 drawState->fAttribIndices[i] = fAttribIndices[i];
1209 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001210 for (int i = 0; i < kNumStages; ++i) {
1211 fStages[i].restoreTo(&drawState->fStages[i]);
1212 }
1213 }
1214
1215 bool isEqual(const GrDrawState& state) const {
1216 if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1217 return false;
1218 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001219 for (int i = 0; i < kAttribIndexCount; ++i) {
skia.committer@gmail.comf140f182013-03-02 07:01:56 +00001220 if ((i == kPosition_AttribIndex ||
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001221 state.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
1222 fAttribIndices[i] != state.fAttribIndices[i]) {
1223 return false;
1224 }
1225 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +00001226 if (fVertexAttribs != state.fVertexAttribs) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001227 return false;
1228 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001229 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.comdcd69bf2013-01-24 18:28:51 +00001230 if (!fStages[i].isEqual(state.fStages[i])) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001231 return false;
1232 }
1233 }
1234 return true;
1235 }
1236
1237 private:
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001238 GrRenderTarget* fRenderTarget;
1239 CommonState fCommon;
1240 int fAttribIndices[kAttribIndexCount];
1241 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
1242 GrEffectStage::DeferredStage fStages[kNumStages];
bsalomon@google.comca432082013-01-23 19:53:46 +00001243
1244 GR_DEBUGCODE(bool fInitialized;)
1245 };
1246
1247private:
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001248 // helper array to let us check the current bindings so we know what bound attrib indices
1249 // we care about
1250 static const GrAttribBindings kAttribIndexMasks[kAttribIndexCount];
1251
1252 SkAutoTUnref<GrRenderTarget> fRenderTarget;
1253 CommonState fCommon;
1254 int fAttribIndices[kAttribIndexCount];
1255 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
1256 GrEffectStage fStages[kNumStages];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001257
reed@google.comfa35e3d2012-06-26 20:16:17 +00001258 typedef GrRefCnt INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +00001259};
1260
bsalomon@google.com2b446732013-02-12 16:47:41 +00001261GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
1262
tomhudson@google.com93813632011-10-27 20:21:16 +00001263#endif