blob: 1124ebb368c64a52ac4587a8e72d5d8b08a8081b [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
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000026class GrDrawState : public GrRefCnt {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000027public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000028 SK_DECLARE_INST_COUNT(GrDrawState)
rmistry@google.comd6176b02012-08-23 18:14:13 +000029
tomhudson@google.com93813632011-10-27 20:21:16 +000030 /**
bsalomon@google.com13221342012-10-26 13:41:59 +000031 * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
32 * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
33 * output from the previous enabled stage and a position. The position is either derived from
34 * the interpolated vertex positions or explicit per-vertex coords, depending upon the
35 * GrVertexLayout used to draw.
robertphillips@google.combf5cad42012-05-10 12:40:40 +000036 *
bsalomon@google.com13221342012-10-26 13:41:59 +000037 * The stages are divided into two sets, color-computing and coverage-computing. The final color
38 * stage produces the final pixel color. The coverage-computing stages function exactly as the
39 * color-computing but the output of the final coverage stage is treated as a fractional pixel
40 * coverage rather than as input to the src/dst color blend step.
41 *
42 * The input color to the first enabled color-stage is either the constant color or interpolated
43 * per-vertex colors, depending upon GrVertexLayout. The input to the first coverage stage is
44 * either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or
45 * edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a
46 * GrEffect).
47 *
bsalomon@google.comcf939ae2012-12-13 19:59:23 +000048 * See the documentation of kCoverageDrawing_StateBit for information about disabling the
49 * the color / coverage distinction.
50 *
bsalomon@google.com13221342012-10-26 13:41:59 +000051 * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
52 * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
53 * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +000054 * by GrClipMaskManager.
tomhudson@google.com93813632011-10-27 20:21:16 +000055 */
56 enum {
twiz@google.com58071162012-07-18 21:41:50 +000057 kNumStages = 5,
tomhudson@google.com93813632011-10-27 20:21:16 +000058 kMaxTexCoords = kNumStages
59 };
60
bsalomon@google.comca432082013-01-23 19:53:46 +000061 GrDrawState() {
reed@google.com75847192013-01-28 20:53:22 +000062#if GR_DEBUG
63 VertexLayoutUnitTest();
64#endif
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000065 this->reset();
66 }
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000067
bsalomon@google.comca432082013-01-23 19:53:46 +000068 GrDrawState(const GrDrawState& state) {
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000069 *this = state;
70 }
71
robertphillips@google.com9ec07532012-06-22 12:01:30 +000072 virtual ~GrDrawState() {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000073 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000074 }
75
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000076 /**
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000077 * Resets to the default state.
bsalomon@google.com08283af2012-10-26 13:01:20 +000078 * GrEffects will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000079 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000080 void reset() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +000081
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000082 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000083
bsalomon@google.comca432082013-01-23 19:53:46 +000084 fRenderTarget.reset(NULL);
85
86 fCommon.fColor = 0xffffffff;
jvanverth@google.comb75b0a02013-02-05 20:33:30 +000087 fCommon.fVertexLayout = kDefault_VertexLayout;
bsalomon@google.comca432082013-01-23 19:53:46 +000088 fCommon.fViewMatrix.reset();
89 fCommon.fSrcBlend = kOne_GrBlendCoeff;
90 fCommon.fDstBlend = kZero_GrBlendCoeff;
91 fCommon.fBlendConstant = 0x0;
92 fCommon.fFlagBits = 0x0;
93 fCommon.fVertexEdgeType = kHairLine_EdgeType;
94 fCommon.fStencilSettings.setDisabled();
95 fCommon.fFirstCoverageStage = kNumStages;
96 fCommon.fCoverage = 0xffffffff;
97 fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
98 fCommon.fColorFilterColor = 0x0;
99 fCommon.fDrawFace = kBoth_DrawFace;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000100 }
101
102 /**
103 * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000104 * encompasses more than GrPaint. Aspects of GrDrawState that have no
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000105 * GrPaint equivalents are not modified. GrPaint has fewer stages than
106 * GrDrawState. The extra GrDrawState stages are disabled.
107 */
108 void setFromPaint(const GrPaint& paint);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000109
110 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000111 /// @name Vertex Layout
jvanverth@google.comcc782382013-01-28 20:39:48 +0000112 ////
113
114 /**
115 * The format of vertices is represented as a bitfield of flags.
116 * Flags that indicate the layout of vertex data. Vertices always contain
117 * positions and may also contain up to GrDrawState::kMaxTexCoords sets
118 * of 2D texture coordinates, per-vertex colors, and per-vertex coverage.
119 * Each stage can
120 * use any of the texture coordinates as its input texture coordinates or it
121 * may use the positions as texture coordinates.
122 *
123 * If no texture coordinates are specified for a stage then the stage is
124 * disabled.
125 *
126 * Only one type of texture coord can be specified per stage. For
127 * example StageTexCoordVertexLayoutBit(0, 2) and
128 * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
129 *
130 * The order in memory is always (position, texture coord 0, ..., color,
131 * coverage) with any unused fields omitted. Note that this means that if
132 * only texture coordinates 1 is referenced then there is no texture
133 * coordinates 0 and the order would be (position, texture coordinate 1
134 * [, color][, coverage]).
135 */
136
137 /**
138 * Generates a bit indicating that a texture stage uses texture coordinates
139 *
140 * @param stageIdx the stage that will use texture coordinates.
141 * @param texCoordIdx the index of the texture coordinates to use
142 *
143 * @return the bit to add to a GrVertexLayout bitfield.
144 */
145 static int StageTexCoordVertexLayoutBit(int stageIdx, int texCoordIdx) {
146 GrAssert(stageIdx < kNumStages);
147 GrAssert(texCoordIdx < kMaxTexCoords);
148 return 1 << (stageIdx + (texCoordIdx * kNumStages));
149 }
150
151 static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
skia.committer@gmail.comcdcb2ce2013-01-29 07:05:52 +0000152
jvanverth@google.comcc782382013-01-28 20:39:48 +0000153private:
154 // non-stage bits start at this index.
155 static const int STAGE_BIT_CNT = kNumStages * kMaxTexCoords;
156public:
157
158 /**
159 * Additional Bits that can be specified in GrVertexLayout.
160 */
161 enum VertexLayoutBits {
162 /* vertices have colors (GrColor) */
163 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
164 /* vertices have coverage (GrColor)
165 */
166 kCoverage_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
jvanverth@google.comcc782382013-01-28 20:39:48 +0000167 /* Each vertex specificies an edge. Distance to the edge is used to
168 * compute a coverage. See GrDrawState::setVertexEdgeType().
169 */
bsalomon@google.com85983282013-02-07 22:00:29 +0000170 kEdge_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 2),
jvanverth@google.comcc782382013-01-28 20:39:48 +0000171 // for below assert
172 kDummyVertexLayoutBit,
173 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
174 };
175 // make sure we haven't exceeded the number of bits in GrVertexLayout.
176 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
177
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000178 enum VertexLayout {
179 kDefault_VertexLayout = 0
180 };
181
182 /**
183 * Sets vertex layout for next draw.
184 *
185 * @param layout the vertex layout to set.
186 */
187 void setVertexLayout(GrVertexLayout layout) { fCommon.fVertexLayout = layout; }
188
189 GrVertexLayout getVertexLayout() const { return fCommon.fVertexLayout; }
190 size_t getVertexSize() const { return VertexSize(fCommon.fVertexLayout); }
191
192
jvanverth@google.comcc782382013-01-28 20:39:48 +0000193 ////////////////////////////////////////////////////////////////////////////
194 // Helpers for picking apart vertex layouts
195
196 /**
197 * Helper function to compute the size of a vertex from a vertex layout
198 * @return size of a single vertex.
199 */
200 static size_t VertexSize(GrVertexLayout vertexLayout);
201
202 /**
203 * Helper function for determining the index of texture coordinates that
204 * is input for a texture stage. Note that a stage may instead use positions
205 * as texture coordinates, in which case the result of the function is
206 * indistinguishable from the case when the stage is disabled.
207 *
208 * @param stageIdx the stage to query
209 * @param vertexLayout layout to query
210 *
211 * @return the texture coordinate index or -1 if the stage doesn't use
212 * separate (non-position) texture coordinates.
213 */
214 static int VertexTexCoordsForStage(int stageIdx, GrVertexLayout vertexLayout);
215
216 /**
217 * Helper function to compute the offset of texture coordinates in a vertex
218 * @return offset of texture coordinates in vertex layout or -1 if the
219 * layout has no texture coordinates. Will be 0 if positions are
220 * used as texture coordinates for the stage.
221 */
222 static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
223
224 /**
225 * Helper function to compute the offset of the color in a vertex
226 * @return offset of color in vertex layout or -1 if the
227 * layout has no color.
228 */
229 static int VertexColorOffset(GrVertexLayout vertexLayout);
230
231 /**
232 * Helper function to compute the offset of the coverage in a vertex
233 * @return offset of coverage in vertex layout or -1 if the
234 * layout has no coverage.
235 */
236 static int VertexCoverageOffset(GrVertexLayout vertexLayout);
237
238 /**
239 * Helper function to compute the offset of the edge pts in a vertex
240 * @return offset of edge in vertex layout or -1 if the
241 * layout has no edge.
242 */
243 static int VertexEdgeOffset(GrVertexLayout vertexLayout);
244
245 /**
246 * Helper function to determine if vertex layout contains explicit texture
247 * coordinates of some index.
248 *
249 * @param coordIndex the tex coord index to query
250 * @param vertexLayout layout to query
251 *
252 * @return true if vertex specifies texture coordinates for the index,
253 * false otherwise.
254 */
255 static bool VertexUsesTexCoordIdx(int coordIndex,
256 GrVertexLayout vertexLayout);
257
258 /**
259 * Helper function to compute the size of each vertex and the offsets of
260 * texture coordinates and color. Determines tex coord offsets by tex coord
261 * index rather than by stage. (Each stage can be mapped to any t.c. index
262 * by StageTexCoordVertexLayoutBit.)
263 *
264 * @param vertexLayout the layout to query
265 * @param texCoordOffsetsByIdx after return it is the offset of each
266 * tex coord index in the vertex or -1 if
267 * index isn't used. (optional)
268 * @param colorOffset after return it is the offset of the
269 * color field in each vertex, or -1 if
270 * there aren't per-vertex colors. (optional)
271 * @param coverageOffset after return it is the offset of the
272 * coverage field in each vertex, or -1 if
273 * there aren't per-vertex coeverages.
274 * (optional)
275 * @param edgeOffset after return it is the offset of the
276 * edge eq field in each vertex, or -1 if
277 * there aren't per-vertex edge equations.
278 * (optional)
279 * @return size of a single vertex
280 */
281 static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
282 int texCoordOffsetsByIdx[kMaxTexCoords],
283 int *colorOffset,
284 int *coverageOffset,
285 int* edgeOffset);
286
287 /**
288 * Helper function to compute the size of each vertex and the offsets of
289 * texture coordinates and color. Determines tex coord offsets by stage
290 * rather than by index. (Each stage can be mapped to any t.c. index
291 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
292 * tex coords then that stage's offset will be 0 (positions are always at 0).
293 *
294 * @param vertexLayout the layout to query
295 * @param texCoordOffsetsByStage after return it is the offset of each
296 * tex coord index in the vertex or -1 if
297 * index isn't used. (optional)
298 * @param colorOffset after return it is the offset of the
299 * color field in each vertex, or -1 if
300 * there aren't per-vertex colors.
301 * (optional)
302 * @param coverageOffset after return it is the offset of the
303 * coverage field in each vertex, or -1 if
304 * there aren't per-vertex coeverages.
305 * (optional)
306 * @param edgeOffset after return it is the offset of the
307 * edge eq field in each vertex, or -1 if
308 * there aren't per-vertex edge equations.
309 * (optional)
310 * @return size of a single vertex
311 */
312 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
313 int texCoordOffsetsByStage[kNumStages],
314 int* colorOffset,
315 int* coverageOffset,
316 int* edgeOffset);
317
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000318 /**
319 * Determines whether src alpha is guaranteed to be one for all src pixels
320 */
321 bool srcAlphaWillBeOne(GrVertexLayout) const;
322
323 /**
324 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
325 */
326 bool hasSolidCoverage(GrVertexLayout) const;
jvanverth@google.comcc782382013-01-28 20:39:48 +0000327
328 /**
329 * Accessing positions, texture coords, or colors, of a vertex within an
330 * array is a hassle involving casts and simple math. These helpers exist
331 * to keep GrDrawTarget clients' code a bit nicer looking.
332 */
333
334 /**
335 * Gets a pointer to a GrPoint of a vertex's position or texture
336 * coordinate.
337 * @param vertices the vetex array
338 * @param vertexIndex the index of the vertex in the array
339 * @param vertexSize the size of each vertex in the array
340 * @param offset the offset in bytes of the vertex component.
341 * Defaults to zero (corresponding to vertex position)
342 * @return pointer to the vertex component as a GrPoint
343 */
344 static GrPoint* GetVertexPoint(void* vertices,
345 int vertexIndex,
346 int vertexSize,
347 int offset = 0) {
348 intptr_t start = GrTCast<intptr_t>(vertices);
349 return GrTCast<GrPoint*>(start + offset +
350 vertexIndex * vertexSize);
351 }
352 static const GrPoint* GetVertexPoint(const void* vertices,
353 int vertexIndex,
354 int vertexSize,
355 int offset = 0) {
356 intptr_t start = GrTCast<intptr_t>(vertices);
357 return GrTCast<const GrPoint*>(start + offset +
358 vertexIndex * vertexSize);
359 }
360
361 /**
362 * Gets a pointer to a GrColor inside a vertex within a vertex array.
363 * @param vertices the vetex array
364 * @param vertexIndex the index of the vertex in the array
365 * @param vertexSize the size of each vertex in the array
366 * @param offset the offset in bytes of the vertex color
367 * @return pointer to the vertex component as a GrColor
368 */
369 static GrColor* GetVertexColor(void* vertices,
370 int vertexIndex,
371 int vertexSize,
372 int offset) {
373 intptr_t start = GrTCast<intptr_t>(vertices);
374 return GrTCast<GrColor*>(start + offset +
375 vertexIndex * vertexSize);
376 }
377 static const GrColor* GetVertexColor(const void* vertices,
378 int vertexIndex,
379 int vertexSize,
380 int offset) {
381 const intptr_t start = GrTCast<intptr_t>(vertices);
382 return GrTCast<const GrColor*>(start + offset +
383 vertexIndex * vertexSize);
384 }
385
386 static void VertexLayoutUnitTest();
387
388 /// @}
389
390 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000391 /// @name Color
392 ////
393
394 /**
395 * Sets color for next draw to a premultiplied-alpha color.
396 *
397 * @param color the color to set.
398 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000399 void setColor(GrColor color) { fCommon.fColor = color; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000400
bsalomon@google.comca432082013-01-23 19:53:46 +0000401 GrColor getColor() const { return fCommon.fColor; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000402
403 /**
404 * Sets the color to be used for the next draw to be
405 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
406 *
407 * @param alpha The alpha value to set as the color.
408 */
409 void setAlpha(uint8_t a) {
410 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
411 }
412
413 /**
414 * Add a color filter that can be represented by a color and a mode. Applied
415 * after color-computing texture stages.
416 */
417 void setColorFilter(GrColor c, SkXfermode::Mode mode) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000418 fCommon.fColorFilterColor = c;
419 fCommon.fColorFilterMode = mode;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000420 }
421
bsalomon@google.comca432082013-01-23 19:53:46 +0000422 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
423 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000424
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000425 /**
426 * Constructor sets the color to be 'color' which is undone by the destructor.
427 */
428 class AutoColorRestore : public ::GrNoncopyable {
429 public:
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000430 AutoColorRestore() : fDrawState(NULL) {}
431
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000432 AutoColorRestore(GrDrawState* drawState, GrColor color) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000433 fDrawState = NULL;
434 this->set(drawState, color);
435 }
436
437 void reset() {
438 if (NULL != fDrawState) {
439 fDrawState->setColor(fOldColor);
440 fDrawState = NULL;
441 }
442 }
443
444 void set(GrDrawState* drawState, GrColor color) {
445 this->reset();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000446 fDrawState = drawState;
447 fOldColor = fDrawState->getColor();
448 fDrawState->setColor(color);
449 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000450
451 ~AutoColorRestore() { this->reset(); }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000452 private:
453 GrDrawState* fDrawState;
454 GrColor fOldColor;
455 };
456
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000457 /// @}
458
459 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000460 /// @name Coverage
461 ////
462
463 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000464 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000465 * initial value (after construction or reset()) is 0xff. The constant
466 * coverage is ignored when per-vertex coverage is provided.
467 */
468 void setCoverage(uint8_t coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000469 fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000470 }
471
472 /**
473 * Version of above that specifies 4 channel per-vertex color. The value
474 * should be premultiplied.
475 */
476 void setCoverage4(GrColor coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000477 fCommon.fCoverage = coverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000478 }
479
480 GrColor getCoverage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000481 return fCommon.fCoverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000482 }
483
484 /// @}
485
486 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000487 /// @name Effect Stages
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000488 ////
489
bsalomon@google.comadc65362013-01-28 14:26:09 +0000490 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
491 fStages[stageIdx].setEffect(effect);
492 return effect;
493 }
494
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000495 /**
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000496 * Creates a GrSimpleTextureEffect.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000497 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000498 void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000499 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000500 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000501 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000502 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000503 void createTextureEffect(int stageIdx,
504 GrTexture* texture,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000505 const SkMatrix& matrix,
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000506 const GrTextureParams& params) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000507 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000508 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000509 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000510 }
511
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000512 bool stagesDisabled() {
513 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000514 if (NULL != fStages[i].getEffect()) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000515 return false;
516 }
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000517 }
tomhudson@google.com3eee8fb2012-06-25 12:30:34 +0000518 return true;
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000519 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000520
bsalomon@google.comadc65362013-01-28 14:26:09 +0000521 void disableStage(int stageIdx) { this->setEffect(stageIdx, NULL); }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000522
robertphillips@google.com972265d2012-06-13 18:49:30 +0000523 /**
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000524 * Release all the GrEffects referred to by this draw state.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000525 */
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000526 void disableStages() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000527 for (int i = 0; i < kNumStages; ++i) {
tomhudson@google.com676e6602012-07-10 17:21:48 +0000528 this->disableStage(i);
robertphillips@google.com972265d2012-06-13 18:49:30 +0000529 }
530 }
531
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000532 class AutoStageDisable : public ::GrNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000533 public:
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000534 AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
535 ~AutoStageDisable() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000536 if (NULL != fDrawState) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000537 fDrawState->disableStages();
robertphillips@google.com972265d2012-06-13 18:49:30 +0000538 }
539 }
540 private:
541 GrDrawState* fDrawState;
542 };
543
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000544 /**
bsalomon@google.com08283af2012-10-26 13:01:20 +0000545 * Returns the current stage by index.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000546 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000547 const GrEffectStage& getStage(int stageIdx) const {
548 GrAssert((unsigned)stageIdx < kNumStages);
549 return fStages[stageIdx];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000550 }
551
552 /**
bsalomon@google.com288d9542012-10-17 12:53:54 +0000553 * Called when the source coord system is changing. preConcat gives the transformation from the
554 * old coord system to the new coord system.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000555 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000556 void preConcatStageMatrices(const SkMatrix& preConcat) {
bsalomon@google.comcabe00e2013-01-28 16:46:55 +0000557 this->preConcatStageMatrices(~0U, preConcat);
558 }
559 /**
560 * Version of above that applies the update matrix selectively to stages via a mask.
561 */
562 void preConcatStageMatrices(uint32_t stageMask, const SkMatrix& preConcat) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000563 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.comcabe00e2013-01-28 16:46:55 +0000564 if (((1 << i) & stageMask) && this->isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000565 fStages[i].preConcatCoordChange(preConcat);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000566 }
567 }
568 }
569
bsalomon@google.come3d32162012-07-20 13:37:06 +0000570 /**
bsalomon@google.com288d9542012-10-17 12:53:54 +0000571 * Called when the source coord system is changing. preConcatInverse is the inverse of the
572 * transformation from the old coord system to the new coord system. Returns false if the matrix
573 * cannot be inverted.
bsalomon@google.come3d32162012-07-20 13:37:06 +0000574 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000575 bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) {
576 SkMatrix inv;
bsalomon@google.come3d32162012-07-20 13:37:06 +0000577 bool computed = false;
578 for (int i = 0; i < kNumStages; ++i) {
579 if (this->isStageEnabled(i)) {
bsalomon@google.com288d9542012-10-17 12:53:54 +0000580 if (!computed && !preConcatInverse.invert(&inv)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000581 return false;
582 } else {
583 computed = true;
584 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000585 fStages[i].preConcatCoordChange(preConcatInverse);
bsalomon@google.come3d32162012-07-20 13:37:06 +0000586 }
587 }
588 return true;
589 }
590
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000591 /// @}
592
593 ///////////////////////////////////////////////////////////////////////////
594 /// @name Coverage / Color Stages
595 ////
596
597 /**
598 * A common pattern is to compute a color with the initial stages and then
599 * modulate that color by a coverage value in later stage(s) (AA, mask-
rmistry@google.comd6176b02012-08-23 18:14:13 +0000600 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
601 * computed based on the pre-coverage-modulated color. The division of
602 * stages between color-computing and coverage-computing is specified by
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000603 * this method. Initially this is kNumStages (all stages
604 * are color-computing).
605 */
606 void setFirstCoverageStage(int firstCoverageStage) {
607 GrAssert((unsigned)firstCoverageStage <= kNumStages);
bsalomon@google.comca432082013-01-23 19:53:46 +0000608 fCommon.fFirstCoverageStage = firstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000609 }
610
611 /**
612 * Gets the index of the first coverage-computing stage.
613 */
614 int getFirstCoverageStage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000615 return fCommon.fFirstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000616 }
617
618 ///@}
619
620 ///////////////////////////////////////////////////////////////////////////
621 /// @name Blending
622 ////
623
624 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000625 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000626 *
627 * The blend function will be:
628 * D' = sat(S*srcCoef + D*dstCoef)
629 *
630 * where D is the existing destination color, S is the incoming source
631 * color, and D' is the new destination color that will be written. sat()
632 * is the saturation function.
633 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000634 * @param srcCoef coefficient applied to the src color.
635 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000636 */
637 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000638 fCommon.fSrcBlend = srcCoeff;
639 fCommon.fDstBlend = dstCoeff;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000640 #if GR_DEBUG
641 switch (dstCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000642 case kDC_GrBlendCoeff:
643 case kIDC_GrBlendCoeff:
644 case kDA_GrBlendCoeff:
645 case kIDA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000646 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
647 "coverage stages.\n");
648 break;
649 default:
650 break;
651 }
652 switch (srcCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000653 case kSC_GrBlendCoeff:
654 case kISC_GrBlendCoeff:
655 case kSA_GrBlendCoeff:
656 case kISA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000657 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
658 "coverage stages.\n");
659 break;
660 default:
661 break;
662 }
663 #endif
664 }
665
bsalomon@google.comca432082013-01-23 19:53:46 +0000666 GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
667 GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000668
669 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
670 GrBlendCoeff* dstBlendCoeff) const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000671 *srcBlendCoeff = fCommon.fSrcBlend;
672 *dstBlendCoeff = fCommon.fDstBlend;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000673 }
674
675 /**
676 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000677 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000678 * kConstC_GrBlendCoeff
679 * kIConstC_GrBlendCoeff
680 * kConstA_GrBlendCoeff
681 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000682 *
683 * @param constant the constant to set
684 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000685 void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000686
687 /**
688 * Retrieves the last value set by setBlendConstant()
689 * @return the blending constant value
690 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000691 GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000692
bsalomon@google.com2b446732013-02-12 16:47:41 +0000693 /**
694 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
695 * coverage before the blend will give the correct final destination color. In general it
696 * will not as coverage is applied after blending.
697 */
698 bool canTweakAlphaForCoverage() const;
699
700 /**
701 * Optimizations for blending / coverage to that can be applied based on the current state.
702 */
703 enum BlendOptFlags {
704 /**
705 * No optimization
706 */
707 kNone_BlendOpt = 0,
708 /**
709 * Don't draw at all
710 */
711 kSkipDraw_BlendOptFlag = 0x1,
712 /**
713 * Emit the src color, disable HW blending (replace dst with src)
714 */
715 kDisableBlend_BlendOptFlag = 0x2,
716 /**
717 * The coverage value does not have to be computed separately from alpha, the the output
718 * color can be the modulation of the two.
719 */
720 kCoverageAsAlpha_BlendOptFlag = 0x4,
721 /**
722 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
723 * "don't cares".
724 */
725 kEmitCoverage_BlendOptFlag = 0x8,
726 /**
727 * Emit transparent black instead of the src color, no need to compute coverage.
728 */
729 kEmitTransBlack_BlendOptFlag = 0x10,
730 };
731 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
732
733 /**
734 * Determines what optimizations can be applied based on the blend. The coefficients may have
735 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
736 * params that receive the tweaked coefficients. Normally the function looks at the current
737 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
738 * determine the blend optimizations that would be used if there was partial pixel coverage.
739 *
740 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
741 * playback) must call this function and respect the flags that replace the output color.
742 */
743 BlendOptFlags getBlendOpts(bool forceCoverage = false,
744 GrBlendCoeff* srcCoeff = NULL,
745 GrBlendCoeff* dstCoeff = NULL) const;
746
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000747 /// @}
748
749 ///////////////////////////////////////////////////////////////////////////
750 /// @name View Matrix
751 ////
752
753 /**
robertphillips@google.coma72eef32012-05-01 17:22:59 +0000754 * Sets the matrix applied to vertex positions.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000755 *
756 * In the post-view-matrix space the rectangle [0,w]x[0,h]
757 * fully covers the render target. (w and h are the width and height of the
bsalomon@google.comca432082013-01-23 19:53:46 +0000758 * the render-target.)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000759 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000760 void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000761
762 /**
763 * Gets a writable pointer to the view matrix.
764 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000765 SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000766
767 /**
768 * Multiplies the current view matrix by a matrix
769 *
770 * After this call V' = V*m where V is the old view matrix,
771 * m is the parameter to this function, and V' is the new view matrix.
772 * (We consider positions to be column vectors so position vector p is
773 * transformed by matrix X as p' = X*p.)
774 *
775 * @param m the matrix used to modify the view matrix.
776 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000777 void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000778
779 /**
780 * Multiplies the current view matrix by a matrix
781 *
782 * After this call V' = m*V where V is the old view matrix,
783 * m is the parameter to this function, and V' is the new view matrix.
784 * (We consider positions to be column vectors so position vector p is
785 * transformed by matrix X as p' = X*p.)
786 *
787 * @param m the matrix used to modify the view matrix.
788 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000789 void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000790
791 /**
792 * Retrieves the current view matrix
793 * @return the current view matrix.
794 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000795 const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000796
797 /**
798 * Retrieves the inverse of the current view matrix.
799 *
800 * If the current view matrix is invertible, return true, and if matrix
801 * is non-null, copy the inverse into it. If the current view matrix is
802 * non-invertible, return false and ignore the matrix parameter.
803 *
804 * @param matrix if not null, will receive a copy of the current inverse.
805 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000806 bool getViewInverse(SkMatrix* matrix) const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000807 // TODO: determine whether we really need to leave matrix unmodified
808 // at call sites when inversion fails.
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000809 SkMatrix inverse;
bsalomon@google.comca432082013-01-23 19:53:46 +0000810 if (fCommon.fViewMatrix.invert(&inverse)) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000811 if (matrix) {
812 *matrix = inverse;
813 }
814 return true;
815 }
816 return false;
817 }
818
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000819 ////////////////////////////////////////////////////////////////////////////
820
821 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000822 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.comc196b522012-10-25 21:52:43 +0000823 * Effect matrices are automatically adjusted to compensate.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000824 */
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000825 class AutoViewMatrixRestore : public ::GrNoncopyable {
826 public:
827 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000828
829 AutoViewMatrixRestore(GrDrawState* ds,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000830 const SkMatrix& preconcatMatrix,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000831 uint32_t explicitCoordStageMask = 0) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000832 fDrawState = NULL;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000833 this->set(ds, preconcatMatrix, explicitCoordStageMask);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000834 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000835
836 ~AutoViewMatrixRestore() { this->restore(); }
837
bsalomon@google.coma8347462012-10-08 18:59:39 +0000838 /**
839 * Can be called prior to destructor to restore the original matrix.
840 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000841 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000842
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000843 void set(GrDrawState* drawState,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000844 const SkMatrix& preconcatMatrix,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000845 uint32_t explicitCoordStageMask = 0);
846
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000847 bool isSet() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000848
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000849 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000850 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000851 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000852 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000853 uint32_t fRestoreMask;
tomhudson@google.com93813632011-10-27 20:21:16 +0000854 };
855
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000856 ////////////////////////////////////////////////////////////////////////////
857
858 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000859 * This sets the view matrix to identity and adjusts stage matrices to compensate. The
860 * destructor undoes the changes, restoring the view matrix that was set before the
861 * constructor. It is similar to passing the inverse of the current view matrix to
862 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000863 */
864 class AutoDeviceCoordDraw : ::GrNoncopyable {
865 public:
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000866 AutoDeviceCoordDraw() : fDrawState(NULL) {}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000867 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000868 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
869 * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
870 * to specify such stages.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000871 */
872 AutoDeviceCoordDraw(GrDrawState* drawState,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000873 uint32_t explicitCoordStageMask = 0) {
874 fDrawState = NULL;
875 this->set(drawState, explicitCoordStageMask);
876 }
877
bsalomon@google.coma8347462012-10-08 18:59:39 +0000878 ~AutoDeviceCoordDraw() { this->restore(); }
879
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000880 bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
881
bsalomon@google.coma8347462012-10-08 18:59:39 +0000882 /**
883 * Returns true if this object was successfully initialized on to a GrDrawState. It may
884 * return false because a non-default constructor or set() were never called or because
885 * the view matrix was not invertible.
886 */
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000887 bool succeeded() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000888
bsalomon@google.coma8347462012-10-08 18:59:39 +0000889 /**
890 * Returns the matrix that was set previously set on the drawState. This is only valid
891 * if succeeded returns true.
892 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000893 const SkMatrix& getOriginalMatrix() const {
bsalomon@google.coma8347462012-10-08 18:59:39 +0000894 GrAssert(this->succeeded());
895 return fViewMatrix;
896 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000897
bsalomon@google.coma8347462012-10-08 18:59:39 +0000898 /**
899 * Can be called prior to destructor to restore the original matrix.
900 */
901 void restore();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000902
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000903 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000904 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000905 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000906 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000907 uint32_t fRestoreMask;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000908 };
909
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000910 /// @}
911
912 ///////////////////////////////////////////////////////////////////////////
913 /// @name Render Target
914 ////
915
916 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000917 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000918 *
919 * @param target The render target to set.
920 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000921 void setRenderTarget(GrRenderTarget* target) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000922 fRenderTarget.reset(SkSafeRef(target));
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000923 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000924
925 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000926 * Retrieves the currently set render-target.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000927 *
928 * @return The currently set render target.
929 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000930 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
931 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000932
933 class AutoRenderTargetRestore : public ::GrNoncopyable {
934 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000935 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000936 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
937 fDrawState = NULL;
robertphillips@google.com7460b372012-04-25 16:54:51 +0000938 fSavedTarget = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000939 this->set(ds, newTarget);
940 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000941 ~AutoRenderTargetRestore() { this->restore(); }
942
943 void restore() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000944 if (NULL != fDrawState) {
945 fDrawState->setRenderTarget(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000946 fDrawState = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000947 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000948 GrSafeSetNull(fSavedTarget);
949 }
950
951 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
952 this->restore();
953
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000954 if (NULL != ds) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000955 GrAssert(NULL == fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000956 fSavedTarget = ds->getRenderTarget();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000957 SkSafeRef(fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000958 ds->setRenderTarget(newTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000959 fDrawState = ds;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000960 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000961 }
962 private:
963 GrDrawState* fDrawState;
964 GrRenderTarget* fSavedTarget;
965 };
966
967 /// @}
968
969 ///////////////////////////////////////////////////////////////////////////
970 /// @name Stencil
971 ////
972
973 /**
974 * Sets the stencil settings to use for the next draw.
975 * Changing the clip has the side-effect of possibly zeroing
976 * out the client settable stencil bits. So multipass algorithms
977 * using stencil should not change the clip between passes.
978 * @param settings the stencil settings to use.
979 */
980 void setStencil(const GrStencilSettings& settings) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000981 fCommon.fStencilSettings = settings;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000982 }
983
984 /**
985 * Shortcut to disable stencil testing and ops.
986 */
987 void disableStencil() {
bsalomon@google.comca432082013-01-23 19:53:46 +0000988 fCommon.fStencilSettings.setDisabled();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000989 }
990
bsalomon@google.comca432082013-01-23 19:53:46 +0000991 const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000992
bsalomon@google.comca432082013-01-23 19:53:46 +0000993 GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000994
995 /// @}
996
997 ///////////////////////////////////////////////////////////////////////////
998 // @name Edge AA
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000999 // Edge equations can be specified to perform anti-aliasing. Because the
bsalomon@google.com7ffe6812012-05-11 17:32:43 +00001000 // edges are specified as per-vertex data, vertices that are shared by
1001 // multiple edges must be split.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001002 //
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001003 ////
1004
1005 /**
tomhudson@google.com93813632011-10-27 20:21:16 +00001006 * When specifying edges as vertex data this enum specifies what type of
bsalomon@google.com81712882012-11-01 17:12:34 +00001007 * edges are in use. The edges are always 4 SkScalars in memory, even when
tomhudson@google.com93813632011-10-27 20:21:16 +00001008 * the edge type requires fewer than 4.
bsalomon@google.com93c96602012-04-27 13:05:21 +00001009 *
1010 * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
1011 * (either adjust in VS or use origin_upper_left in GLSL)
tomhudson@google.com93813632011-10-27 20:21:16 +00001012 */
1013 enum VertexEdgeType {
1014 /* 1-pixel wide line
1015 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
1016 kHairLine_EdgeType,
rmistry@google.comd6176b02012-08-23 18:14:13 +00001017 /* Quadratic specified by u^2-v canonical coords (only 2
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001018 components used). Coverage based on signed distance with negative
bsalomon@google.com93c96602012-04-27 13:05:21 +00001019 being inside, positive outside. Edge specified in window space
1020 (y-down) */
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001021 kQuad_EdgeType,
1022 /* Same as above but for hairline quadratics. Uses unsigned distance.
1023 Coverage is min(0, 1-distance). */
1024 kHairQuad_EdgeType,
bsalomon@google.com93c96602012-04-27 13:05:21 +00001025 /* Circle specified as center_x, center_y, outer_radius, inner_radius
1026 all in window space (y-down). */
1027 kCircle_EdgeType,
jvanverth@google.com46d3d392013-01-22 13:34:01 +00001028 /* Axis-aligned ellipse specified as center_x, center_y, x_radius, x_radius/y_radius
1029 all in window space (y-down). */
1030 kEllipse_EdgeType,
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001031
1032 kVertexEdgeTypeCnt
tomhudson@google.com93813632011-10-27 20:21:16 +00001033 };
1034
1035 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +00001036 * Determines the interpretation per-vertex edge data when the
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001037 * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
1038 * are not specified the value of this setting has no effect.
1039 */
1040 void setVertexEdgeType(VertexEdgeType type) {
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001041 GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
bsalomon@google.comca432082013-01-23 19:53:46 +00001042 fCommon.fVertexEdgeType = type;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001043 }
1044
bsalomon@google.comca432082013-01-23 19:53:46 +00001045 VertexEdgeType getVertexEdgeType() const { return fCommon.fVertexEdgeType; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001046
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001047 /// @}
tomhudson@google.com62b09682011-11-09 16:39:17 +00001048
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001049 ///////////////////////////////////////////////////////////////////////////
1050 /// @name State Flags
1051 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +00001052
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001053 /**
1054 * Flags that affect rendering. Controlled using enable/disableState(). All
1055 * default to disabled.
1056 */
1057 enum StateBits {
1058 /**
1059 * Perform dithering. TODO: Re-evaluate whether we need this bit
1060 */
1061 kDither_StateBit = 0x01,
1062 /**
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001063 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
1064 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
1065 * the 3D API.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001066 */
1067 kHWAntialias_StateBit = 0x02,
1068 /**
1069 * Draws will respect the clip, otherwise the clip is ignored.
1070 */
1071 kClip_StateBit = 0x04,
1072 /**
1073 * Disables writing to the color buffer. Useful when performing stencil
1074 * operations.
1075 */
1076 kNoColorWrites_StateBit = 0x08,
bsalomon@google.com0342a852012-08-20 19:22:38 +00001077
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001078 /**
1079 * Usually coverage is applied after color blending. The color is blended using the coeffs
1080 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
1081 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
1082 * this case there is no distinction between coverage and color and the caller needs direct
1083 * control over the blend coeffs. When set, there will be a single blend step controlled by
1084 * setBlendFunc() which will use coverage*color as the src color.
1085 */
1086 kCoverageDrawing_StateBit = 0x10,
1087
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001088 // Users of the class may add additional bits to the vector
1089 kDummyStateBit,
1090 kLastPublicStateBit = kDummyStateBit-1,
1091 };
1092
1093 void resetStateFlags() {
bsalomon@google.comca432082013-01-23 19:53:46 +00001094 fCommon.fFlagBits = 0;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001095 }
1096
1097 /**
1098 * Enable render state settings.
1099 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001100 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001101 */
1102 void enableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001103 fCommon.fFlagBits |= stateBits;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001104 }
1105
1106 /**
1107 * Disable render state settings.
1108 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001109 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001110 */
1111 void disableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001112 fCommon.fFlagBits &= ~(stateBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001113 }
1114
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +00001115 /**
1116 * Enable or disable stateBits based on a boolean.
1117 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001118 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +00001119 * @param enable if true enable stateBits, otherwise disable
1120 */
1121 void setState(uint32_t stateBits, bool enable) {
1122 if (enable) {
1123 this->enableState(stateBits);
1124 } else {
1125 this->disableState(stateBits);
1126 }
1127 }
1128
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001129 bool isDitherState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001130 return 0 != (fCommon.fFlagBits & kDither_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001131 }
1132
1133 bool isHWAntialiasState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001134 return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001135 }
1136
1137 bool isClipState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001138 return 0 != (fCommon.fFlagBits & kClip_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001139 }
1140
1141 bool isColorWriteDisabled() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001142 return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001143 }
1144
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001145 bool isCoverageDrawing() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001146 return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001147 }
1148
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001149 bool isStateFlagEnabled(uint32_t stateBit) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001150 return 0 != (stateBit & fCommon.fFlagBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001151 }
1152
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001153 /// @}
1154
1155 ///////////////////////////////////////////////////////////////////////////
1156 /// @name Face Culling
1157 ////
1158
1159 enum DrawFace {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001160 kInvalid_DrawFace = -1,
1161
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001162 kBoth_DrawFace,
1163 kCCW_DrawFace,
1164 kCW_DrawFace,
1165 };
1166
1167 /**
1168 * Controls whether clockwise, counterclockwise, or both faces are drawn.
1169 * @param face the face(s) to draw.
1170 */
1171 void setDrawFace(DrawFace face) {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001172 GrAssert(kInvalid_DrawFace != face);
bsalomon@google.comca432082013-01-23 19:53:46 +00001173 fCommon.fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001174 }
1175
1176 /**
1177 * Gets whether the target is drawing clockwise, counterclockwise,
1178 * or both faces.
1179 * @return the current draw face(s).
1180 */
bsalomon@google.comca432082013-01-23 19:53:46 +00001181 DrawFace getDrawFace() const { return fCommon.fDrawFace; }
rmistry@google.comd6176b02012-08-23 18:14:13 +00001182
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001183 /// @}
1184
1185 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +00001186
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001187 bool isStageEnabled(int s) const {
1188 GrAssert((unsigned)s < kNumStages);
bsalomon@google.com08283af2012-10-26 13:01:20 +00001189 return (NULL != fStages[s].getEffect());
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001190 }
1191
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001192 // Most stages are usually not used, so conditionals here
1193 // reduce the expected number of bytes touched by 50%.
1194 bool operator ==(const GrDrawState& s) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001195 if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001196 return false;
1197 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001198
1199 for (int i = 0; i < kNumStages; i++) {
bsalomon@google.comf2f8fc32012-07-18 18:25:07 +00001200 bool enabled = this->isStageEnabled(i);
1201 if (enabled != s.isStageEnabled(i)) {
1202 return false;
1203 }
bsalomon@google.com08283af2012-10-26 13:01:20 +00001204 if (enabled && this->fStages[i] != s.fStages[i]) {
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001205 return false;
1206 }
1207 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001208 return true;
1209 }
1210 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
1211
bsalomon@google.comca432082013-01-23 19:53:46 +00001212 GrDrawState& operator= (const GrDrawState& s) {
1213 this->setRenderTarget(s.fRenderTarget.get());
1214 fCommon = s.fCommon;
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001215 for (int i = 0; i < kNumStages; i++) {
tomhudson@google.come742bf02012-07-13 19:54:19 +00001216 if (s.isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +00001217 this->fStages[i] = s.fStages[i];
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001218 }
1219 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001220 return *this;
1221 }
1222
1223private:
bsalomon@google.com2e3d1442012-03-26 20:33:54 +00001224
bsalomon@google.comca432082013-01-23 19:53:46 +00001225 /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1226 struct CommonState {
1227 // These fields are roughly sorted by decreasing likelihood of being different in op==
1228 GrColor fColor;
jvanverth@google.comb75b0a02013-02-05 20:33:30 +00001229 GrVertexLayout fVertexLayout;
bsalomon@google.comca432082013-01-23 19:53:46 +00001230 SkMatrix fViewMatrix;
1231 GrBlendCoeff fSrcBlend;
1232 GrBlendCoeff fDstBlend;
1233 GrColor fBlendConstant;
1234 uint32_t fFlagBits;
1235 VertexEdgeType fVertexEdgeType;
1236 GrStencilSettings fStencilSettings;
1237 int fFirstCoverageStage;
1238 GrColor fCoverage;
1239 SkXfermode::Mode fColorFilterMode;
1240 GrColor fColorFilterColor;
1241 DrawFace fDrawFace;
1242 bool operator== (const CommonState& other) const {
1243 return fColor == other.fColor &&
jvanverth@google.comb75b0a02013-02-05 20:33:30 +00001244 fVertexLayout == other.fVertexLayout &&
bsalomon@google.comca432082013-01-23 19:53:46 +00001245 fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1246 fSrcBlend == other.fSrcBlend &&
1247 fDstBlend == other.fDstBlend &&
1248 fBlendConstant == other.fBlendConstant &&
1249 fFlagBits == other.fFlagBits &&
1250 fVertexEdgeType == other.fVertexEdgeType &&
1251 fStencilSettings == other.fStencilSettings &&
1252 fFirstCoverageStage == other.fFirstCoverageStage &&
1253 fCoverage == other.fCoverage &&
1254 fColorFilterMode == other.fColorFilterMode &&
1255 fColorFilterColor == other.fColorFilterColor &&
1256 fDrawFace == other.fDrawFace;
1257 }
1258 bool operator!= (const CommonState& other) const { return !(*this == other); }
1259 };
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001260
bsalomon@google.comca432082013-01-23 19:53:46 +00001261 /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1262 DeferredState must directly reference GrEffects, however. */
1263 struct SavedEffectStage {
1264 SavedEffectStage() : fEffect(NULL) {}
1265 const GrEffect* fEffect;
1266 GrEffectStage::SavedCoordChange fCoordChange;
1267 };
1268
1269public:
1270 /**
1271 * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1272 * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1273 * dispose mechanism returns them to the cache. This allows recycling resources through the
1274 * the cache while they are in a deferred draw queue.
1275 */
1276 class DeferredState {
1277 public:
1278 DeferredState() : fRenderTarget(NULL) {
1279 GR_DEBUGCODE(fInitialized = false;)
1280 }
1281 // TODO: Remove this when DeferredState no longer holds a ref to the RT
1282 ~DeferredState() { SkSafeUnref(fRenderTarget); }
1283
1284 void saveFrom(const GrDrawState& drawState) {
1285 fCommon = drawState.fCommon;
1286 // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1287 fRenderTarget = drawState.fRenderTarget.get();
1288 SkSafeRef(fRenderTarget);
1289 // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1290 // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1291 // and recycle them to the cache (if no one else is holding a ref to the resources).
1292 for (int i = 0; i < kNumStages; ++i) {
1293 fStages[i].saveFrom(drawState.fStages[i]);
1294 }
1295 GR_DEBUGCODE(fInitialized = true;)
1296 }
1297
1298 void restoreTo(GrDrawState* drawState) {
1299 GrAssert(fInitialized);
1300 drawState->fCommon = fCommon;
1301 drawState->setRenderTarget(fRenderTarget);
1302 for (int i = 0; i < kNumStages; ++i) {
1303 fStages[i].restoreTo(&drawState->fStages[i]);
1304 }
1305 }
1306
1307 bool isEqual(const GrDrawState& state) const {
1308 if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1309 return false;
1310 }
1311 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.comdcd69bf2013-01-24 18:28:51 +00001312 if (!fStages[i].isEqual(state.fStages[i])) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001313 return false;
1314 }
1315 }
1316 return true;
1317 }
1318
1319 private:
1320 GrRenderTarget* fRenderTarget;
1321 CommonState fCommon;
1322 GrEffectStage::DeferredStage fStages[kNumStages];
1323
1324 GR_DEBUGCODE(bool fInitialized;)
1325 };
1326
1327private:
1328 SkAutoTUnref<GrRenderTarget> fRenderTarget;
1329 CommonState fCommon;
1330 GrEffectStage fStages[kNumStages];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001331
reed@google.comfa35e3d2012-06-26 20:16:17 +00001332 typedef GrRefCnt INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +00001333};
1334
bsalomon@google.com2b446732013-02-12 16:47:41 +00001335GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
1336
tomhudson@google.com93813632011-10-27 20:21:16 +00001337#endif