blob: 05492a73aee5242bd932d74edbad522f184f9980 [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
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +000035 * 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
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +000043 * per-vertex colors, depending upon GrVertexLayout. The input to the first coverage stage is
bsalomon@google.com13221342012-10-26 13:41:59 +000044 * 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 };
59
bsalomon@google.comca432082013-01-23 19:53:46 +000060 GrDrawState() {
reed@google.com75847192013-01-28 20:53:22 +000061#if GR_DEBUG
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +000062 VertexLayoutUnitTest();
reed@google.com75847192013-01-28 20:53:22 +000063#endif
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000064 this->reset();
65 }
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000066
bsalomon@google.comca432082013-01-23 19:53:46 +000067 GrDrawState(const GrDrawState& state) {
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000068 *this = state;
69 }
70
robertphillips@google.com9ec07532012-06-22 12:01:30 +000071 virtual ~GrDrawState() {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000072 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000073 }
74
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000075 /**
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000076 * Resets to the default state.
bsalomon@google.com08283af2012-10-26 13:01:20 +000077 * GrEffects will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000078 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000079 void reset() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +000080
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000081 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000082
bsalomon@google.comca432082013-01-23 19:53:46 +000083 fRenderTarget.reset(NULL);
84
85 fCommon.fColor = 0xffffffff;
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +000086 fCommon.fVertexLayout = kDefault_VertexLayout;
bsalomon@google.comca432082013-01-23 19:53:46 +000087 fCommon.fViewMatrix.reset();
88 fCommon.fSrcBlend = kOne_GrBlendCoeff;
89 fCommon.fDstBlend = kZero_GrBlendCoeff;
90 fCommon.fBlendConstant = 0x0;
91 fCommon.fFlagBits = 0x0;
92 fCommon.fVertexEdgeType = kHairLine_EdgeType;
93 fCommon.fStencilSettings.setDisabled();
94 fCommon.fFirstCoverageStage = kNumStages;
95 fCommon.fCoverage = 0xffffffff;
96 fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
97 fCommon.fColorFilterColor = 0x0;
98 fCommon.fDrawFace = kBoth_DrawFace;
bsalomon@google.comaf84e742012-10-05 13:23:24 +000099 }
100
101 /**
102 * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000103 * encompasses more than GrPaint. Aspects of GrDrawState that have no
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000104 * GrPaint equivalents are not modified. GrPaint has fewer stages than
105 * GrDrawState. The extra GrDrawState stages are disabled.
106 */
107 void setFromPaint(const GrPaint& paint);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000108
109 ///////////////////////////////////////////////////////////////////////////
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000110 /// @name Vertex Layout
jvanverth@google.comcc782382013-01-28 20:39:48 +0000111 ////
112
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000113 /**
114 * The format of vertices is represented as a bitfield of flags.
115 * Flags that indicate the layout of vertex data. Vertices always contain
116 * positions and may also contain texture coordinates, per-vertex colors,
117 * and per-vertex coverage. Each stage can use any texture coordinates as
118 * its input texture coordinates or it may use the positions as texture
119 * coordinates.
120 *
121 * If no texture coordinates are specified for a stage then the stage is
122 * disabled.
123 *
124 * The order in memory is always (position, texture coords, color, coverage)
125 * with any unused fields omitted.
126 */
127
128 /**
129 * Generates a bit indicating that a texture stage uses texture coordinates
130 *
131 * @param stageIdx the stage that will use texture coordinates.
132 *
133 * @return the bit to add to a GrVertexLayout bitfield.
134 */
135 static int StageTexCoordVertexLayoutBit(int stageIdx) {
136 GrAssert(stageIdx < kNumStages);
137 return (1 << stageIdx);
138 }
139
140 static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
141
142private:
143 // non-stage bits start at this index.
144 static const int STAGE_BIT_CNT = kNumStages;
145public:
146
147 /**
148 * Additional Bits that can be specified in GrVertexLayout.
149 */
150 enum VertexLayoutBits {
151 /* vertices have colors (GrColor) */
152 kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
153 /* vertices have coverage (GrColor)
154 */
155 kCoverage_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
156 /* Each vertex specificies an edge. Distance to the edge is used to
157 * compute a coverage. See GrDrawState::setVertexEdgeType().
158 */
159 kEdge_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 2),
160 // for below assert
161 kDummyVertexLayoutBit,
162 kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
163 };
164 // make sure we haven't exceeded the number of bits in GrVertexLayout.
165 GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
166
167 enum VertexLayout {
168 kDefault_VertexLayout = 0
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000169 };
170
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000171 /**
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000172 * Sets vertex layout for next draw.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000173 *
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000174 * @param layout the vertex layout to set.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000175 */
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000176 void setVertexLayout(GrVertexLayout layout) { fCommon.fVertexLayout = layout; }
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000177
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000178 GrVertexLayout getVertexLayout() const { return fCommon.fVertexLayout; }
179 size_t getVertexSize() const { return VertexSize(fCommon.fVertexLayout); }
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000180
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000181
jvanverth@google.comcc782382013-01-28 20:39:48 +0000182 ////////////////////////////////////////////////////////////////////////////
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000183 // Helpers for picking apart vertex layouts
jvanverth@google.comcc782382013-01-28 20:39:48 +0000184
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000185 /**
186 * Helper function to compute the size of a vertex from a vertex layout
187 * @return size of a single vertex.
188 */
189 static size_t VertexSize(GrVertexLayout vertexLayout);
190
191 /**
192 * Helper function to compute the offset of texture coordinates in a vertex
193 * @return offset of texture coordinates in vertex layout or 0 if positions
194 * are used as texture coordinates for the stage.
195 */
196 static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
197
198 /**
199 * Helper function to compute the offset of the color in a vertex
200 * @return offset of color in vertex layout or -1 if the
201 * layout has no color.
202 */
203 static int VertexColorOffset(GrVertexLayout vertexLayout);
204
205 /**
206 * Helper function to compute the offset of the coverage in a vertex
207 * @return offset of coverage in vertex layout or -1 if the
208 * layout has no coverage.
209 */
210 static int VertexCoverageOffset(GrVertexLayout vertexLayout);
211
212 /**
213 * Helper function to compute the offset of the edge pts in a vertex
214 * @return offset of edge in vertex layout or -1 if the
215 * layout has no edge.
216 */
217 static int VertexEdgeOffset(GrVertexLayout vertexLayout);
218
219 /**
220 * Helper function to determine if vertex layout contains explicit texture
221 * coordinates.
222 *
223 * @param vertexLayout layout to query
224 *
225 * @return true if vertex specifies texture coordinates,
226 * false otherwise.
227 */
228 static bool VertexUsesTexCoords(GrVertexLayout vertexLayout);
229
230 /**
231 * Helper function to compute the size of each vertex and the offsets of
232 * texture coordinates and color.
233 *
234 * @param vertexLayout the layout to query
235 * @param texCoordOffset after return it is the offset of the
236 * tex coord index in the vertex or -1 if
237 * tex coords aren't used. (optional)
238 * @param colorOffset after return it is the offset of the
239 * color field in each vertex, or -1 if
240 * there aren't per-vertex colors. (optional)
241 * @param coverageOffset after return it is the offset of the
242 * coverage field in each vertex, or -1 if
243 * there aren't per-vertex coeverages.
244 * (optional)
245 * @param edgeOffset after return it is the offset of the
246 * edge eq field in each vertex, or -1 if
247 * there aren't per-vertex edge equations.
248 * (optional)
249 * @return size of a single vertex
250 */
251 static int VertexSizeAndOffsets(GrVertexLayout vertexLayout,
252 int *texCoordOffset,
253 int *colorOffset,
254 int *coverageOffset,
255 int* edgeOffset);
256
257 /**
258 * Helper function to compute the size of each vertex and the offsets of
259 * texture coordinates and color. Determines tex coord offsets by stage
260 * rather than by index. (Each stage can be mapped to any t.c. index
261 * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
262 * tex coords then that stage's offset will be 0 (positions are always at 0).
263 *
264 * @param vertexLayout the layout to query
265 * @param texCoordOffsetsByStage 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.
271 * (optional)
272 * @param coverageOffset after return it is the offset of the
273 * coverage field in each vertex, or -1 if
274 * there aren't per-vertex coeverages.
275 * (optional)
276 * @param edgeOffset after return it is the offset of the
277 * edge eq field in each vertex, or -1 if
278 * there aren't per-vertex edge equations.
279 * (optional)
280 * @return size of a single vertex
281 */
282 static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
283 int texCoordOffsetsByStage[kNumStages],
284 int* colorOffset,
285 int* coverageOffset,
286 int* edgeOffset);
287
288 /**
289 * Determines whether src alpha is guaranteed to be one for all src pixels
290 */
291 bool srcAlphaWillBeOne(GrVertexLayout) const;
292
293 /**
294 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
295 */
296 bool hasSolidCoverage(GrVertexLayout) const;
jvanverth@google.comcc782382013-01-28 20:39:48 +0000297
298 /**
299 * Accessing positions, texture coords, or colors, of a vertex within an
300 * array is a hassle involving casts and simple math. These helpers exist
301 * to keep GrDrawTarget clients' code a bit nicer looking.
302 */
303
304 /**
305 * Gets a pointer to a GrPoint of a vertex's position or texture
306 * coordinate.
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000307 * @param vertices the vetex array
jvanverth@google.comcc782382013-01-28 20:39:48 +0000308 * @param vertexIndex the index of the vertex in the array
309 * @param vertexSize the size of each vertex in the array
310 * @param offset the offset in bytes of the vertex component.
311 * Defaults to zero (corresponding to vertex position)
312 * @return pointer to the vertex component as a GrPoint
313 */
314 static GrPoint* GetVertexPoint(void* vertices,
315 int vertexIndex,
316 int vertexSize,
317 int offset = 0) {
318 intptr_t start = GrTCast<intptr_t>(vertices);
319 return GrTCast<GrPoint*>(start + offset +
320 vertexIndex * vertexSize);
321 }
322 static const GrPoint* GetVertexPoint(const void* vertices,
323 int vertexIndex,
324 int vertexSize,
325 int offset = 0) {
326 intptr_t start = GrTCast<intptr_t>(vertices);
327 return GrTCast<const GrPoint*>(start + offset +
328 vertexIndex * vertexSize);
329 }
330
331 /**
332 * Gets a pointer to a GrColor inside a vertex within a vertex array.
333 * @param vertices the vetex array
334 * @param vertexIndex the index of the vertex in the array
335 * @param vertexSize the size of each vertex in the array
336 * @param offset the offset in bytes of the vertex color
337 * @return pointer to the vertex component as a GrColor
338 */
339 static GrColor* GetVertexColor(void* vertices,
340 int vertexIndex,
341 int vertexSize,
342 int offset) {
343 intptr_t start = GrTCast<intptr_t>(vertices);
344 return GrTCast<GrColor*>(start + offset +
345 vertexIndex * vertexSize);
346 }
347 static const GrColor* GetVertexColor(const void* vertices,
348 int vertexIndex,
349 int vertexSize,
350 int offset) {
351 const intptr_t start = GrTCast<intptr_t>(vertices);
352 return GrTCast<const GrColor*>(start + offset +
353 vertexIndex * vertexSize);
354 }
355
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +0000356 static void VertexLayoutUnitTest();
jvanverth@google.comcc782382013-01-28 20:39:48 +0000357
358 /// @}
359
360 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000361 /// @name Color
362 ////
363
364 /**
365 * Sets color for next draw to a premultiplied-alpha color.
366 *
367 * @param color the color to set.
368 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000369 void setColor(GrColor color) { fCommon.fColor = color; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000370
bsalomon@google.comca432082013-01-23 19:53:46 +0000371 GrColor getColor() const { return fCommon.fColor; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000372
373 /**
374 * Sets the color to be used for the next draw to be
375 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
376 *
377 * @param alpha The alpha value to set as the color.
378 */
379 void setAlpha(uint8_t a) {
380 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
381 }
382
383 /**
384 * Add a color filter that can be represented by a color and a mode. Applied
385 * after color-computing texture stages.
386 */
387 void setColorFilter(GrColor c, SkXfermode::Mode mode) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000388 fCommon.fColorFilterColor = c;
389 fCommon.fColorFilterMode = mode;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000390 }
391
bsalomon@google.comca432082013-01-23 19:53:46 +0000392 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
393 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000394
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000395 /**
396 * Constructor sets the color to be 'color' which is undone by the destructor.
397 */
398 class AutoColorRestore : public ::GrNoncopyable {
399 public:
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000400 AutoColorRestore() : fDrawState(NULL) {}
401
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000402 AutoColorRestore(GrDrawState* drawState, GrColor color) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000403 fDrawState = NULL;
404 this->set(drawState, color);
405 }
406
407 void reset() {
408 if (NULL != fDrawState) {
409 fDrawState->setColor(fOldColor);
410 fDrawState = NULL;
411 }
412 }
413
414 void set(GrDrawState* drawState, GrColor color) {
415 this->reset();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000416 fDrawState = drawState;
417 fOldColor = fDrawState->getColor();
418 fDrawState->setColor(color);
419 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000420
421 ~AutoColorRestore() { this->reset(); }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000422 private:
423 GrDrawState* fDrawState;
424 GrColor fOldColor;
425 };
426
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000427 /// @}
428
429 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000430 /// @name Coverage
431 ////
432
433 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000434 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000435 * initial value (after construction or reset()) is 0xff. The constant
436 * coverage is ignored when per-vertex coverage is provided.
437 */
438 void setCoverage(uint8_t coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000439 fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000440 }
441
442 /**
443 * Version of above that specifies 4 channel per-vertex color. The value
444 * should be premultiplied.
445 */
446 void setCoverage4(GrColor coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000447 fCommon.fCoverage = coverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000448 }
449
450 GrColor getCoverage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000451 return fCommon.fCoverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000452 }
453
454 /// @}
455
456 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000457 /// @name Effect Stages
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000458 ////
459
bsalomon@google.comadc65362013-01-28 14:26:09 +0000460 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
461 fStages[stageIdx].setEffect(effect);
462 return effect;
463 }
464
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000465 /**
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000466 * Creates a GrSimpleTextureEffect.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000467 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000468 void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000469 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000470 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000471 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000472 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000473 void createTextureEffect(int stageIdx,
474 GrTexture* texture,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000475 const SkMatrix& matrix,
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000476 const GrTextureParams& params) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000477 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000478 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000479 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000480 }
481
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000482 bool stagesDisabled() {
483 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000484 if (NULL != fStages[i].getEffect()) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000485 return false;
486 }
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000487 }
tomhudson@google.com3eee8fb2012-06-25 12:30:34 +0000488 return true;
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000489 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000490
bsalomon@google.comadc65362013-01-28 14:26:09 +0000491 void disableStage(int stageIdx) { this->setEffect(stageIdx, NULL); }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000492
robertphillips@google.com972265d2012-06-13 18:49:30 +0000493 /**
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000494 * Release all the GrEffects referred to by this draw state.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000495 */
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000496 void disableStages() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000497 for (int i = 0; i < kNumStages; ++i) {
tomhudson@google.com676e6602012-07-10 17:21:48 +0000498 this->disableStage(i);
robertphillips@google.com972265d2012-06-13 18:49:30 +0000499 }
500 }
501
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000502 class AutoStageDisable : public ::GrNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000503 public:
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000504 AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
505 ~AutoStageDisable() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000506 if (NULL != fDrawState) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000507 fDrawState->disableStages();
robertphillips@google.com972265d2012-06-13 18:49:30 +0000508 }
509 }
510 private:
511 GrDrawState* fDrawState;
512 };
513
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000514 /**
bsalomon@google.com08283af2012-10-26 13:01:20 +0000515 * Returns the current stage by index.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000516 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000517 const GrEffectStage& getStage(int stageIdx) const {
518 GrAssert((unsigned)stageIdx < kNumStages);
519 return fStages[stageIdx];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000520 }
521
522 /**
bsalomon@google.com288d9542012-10-17 12:53:54 +0000523 * Called when the source coord system is changing. preConcat gives the transformation from the
524 * old coord system to the new coord system.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000525 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000526 void preConcatStageMatrices(const SkMatrix& preConcat) {
bsalomon@google.comcabe00e2013-01-28 16:46:55 +0000527 this->preConcatStageMatrices(~0U, preConcat);
528 }
529 /**
530 * Version of above that applies the update matrix selectively to stages via a mask.
531 */
532 void preConcatStageMatrices(uint32_t stageMask, const SkMatrix& preConcat) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000533 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.comcabe00e2013-01-28 16:46:55 +0000534 if (((1 << i) & stageMask) && this->isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000535 fStages[i].preConcatCoordChange(preConcat);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000536 }
537 }
538 }
539
bsalomon@google.come3d32162012-07-20 13:37:06 +0000540 /**
bsalomon@google.com288d9542012-10-17 12:53:54 +0000541 * Called when the source coord system is changing. preConcatInverse is the inverse of the
542 * transformation from the old coord system to the new coord system. Returns false if the matrix
543 * cannot be inverted.
bsalomon@google.come3d32162012-07-20 13:37:06 +0000544 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000545 bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) {
546 SkMatrix inv;
bsalomon@google.come3d32162012-07-20 13:37:06 +0000547 bool computed = false;
548 for (int i = 0; i < kNumStages; ++i) {
549 if (this->isStageEnabled(i)) {
bsalomon@google.com288d9542012-10-17 12:53:54 +0000550 if (!computed && !preConcatInverse.invert(&inv)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000551 return false;
552 } else {
553 computed = true;
554 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000555 fStages[i].preConcatCoordChange(preConcatInverse);
bsalomon@google.come3d32162012-07-20 13:37:06 +0000556 }
557 }
558 return true;
559 }
560
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000561 /// @}
562
563 ///////////////////////////////////////////////////////////////////////////
564 /// @name Coverage / Color Stages
565 ////
566
567 /**
568 * A common pattern is to compute a color with the initial stages and then
569 * modulate that color by a coverage value in later stage(s) (AA, mask-
rmistry@google.comd6176b02012-08-23 18:14:13 +0000570 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
571 * computed based on the pre-coverage-modulated color. The division of
572 * stages between color-computing and coverage-computing is specified by
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000573 * this method. Initially this is kNumStages (all stages
574 * are color-computing).
575 */
576 void setFirstCoverageStage(int firstCoverageStage) {
577 GrAssert((unsigned)firstCoverageStage <= kNumStages);
bsalomon@google.comca432082013-01-23 19:53:46 +0000578 fCommon.fFirstCoverageStage = firstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000579 }
580
581 /**
582 * Gets the index of the first coverage-computing stage.
583 */
584 int getFirstCoverageStage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000585 return fCommon.fFirstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000586 }
587
588 ///@}
589
590 ///////////////////////////////////////////////////////////////////////////
591 /// @name Blending
592 ////
593
594 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000595 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000596 *
597 * The blend function will be:
598 * D' = sat(S*srcCoef + D*dstCoef)
599 *
600 * where D is the existing destination color, S is the incoming source
601 * color, and D' is the new destination color that will be written. sat()
602 * is the saturation function.
603 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000604 * @param srcCoef coefficient applied to the src color.
605 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000606 */
607 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000608 fCommon.fSrcBlend = srcCoeff;
609 fCommon.fDstBlend = dstCoeff;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000610 #if GR_DEBUG
611 switch (dstCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000612 case kDC_GrBlendCoeff:
613 case kIDC_GrBlendCoeff:
614 case kDA_GrBlendCoeff:
615 case kIDA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000616 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
617 "coverage stages.\n");
618 break;
619 default:
620 break;
621 }
622 switch (srcCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000623 case kSC_GrBlendCoeff:
624 case kISC_GrBlendCoeff:
625 case kSA_GrBlendCoeff:
626 case kISA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000627 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
628 "coverage stages.\n");
629 break;
630 default:
631 break;
632 }
633 #endif
634 }
635
bsalomon@google.comca432082013-01-23 19:53:46 +0000636 GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
637 GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000638
639 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
640 GrBlendCoeff* dstBlendCoeff) const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000641 *srcBlendCoeff = fCommon.fSrcBlend;
642 *dstBlendCoeff = fCommon.fDstBlend;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000643 }
644
645 /**
646 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000647 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000648 * kConstC_GrBlendCoeff
649 * kIConstC_GrBlendCoeff
650 * kConstA_GrBlendCoeff
651 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000652 *
653 * @param constant the constant to set
654 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000655 void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000656
657 /**
658 * Retrieves the last value set by setBlendConstant()
659 * @return the blending constant value
660 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000661 GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000662
bsalomon@google.com2b446732013-02-12 16:47:41 +0000663 /**
664 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
665 * coverage before the blend will give the correct final destination color. In general it
666 * will not as coverage is applied after blending.
667 */
668 bool canTweakAlphaForCoverage() const;
669
670 /**
671 * Optimizations for blending / coverage to that can be applied based on the current state.
672 */
673 enum BlendOptFlags {
674 /**
675 * No optimization
676 */
677 kNone_BlendOpt = 0,
678 /**
679 * Don't draw at all
680 */
681 kSkipDraw_BlendOptFlag = 0x1,
682 /**
683 * Emit the src color, disable HW blending (replace dst with src)
684 */
685 kDisableBlend_BlendOptFlag = 0x2,
686 /**
687 * The coverage value does not have to be computed separately from alpha, the the output
688 * color can be the modulation of the two.
689 */
690 kCoverageAsAlpha_BlendOptFlag = 0x4,
691 /**
692 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
693 * "don't cares".
694 */
695 kEmitCoverage_BlendOptFlag = 0x8,
696 /**
697 * Emit transparent black instead of the src color, no need to compute coverage.
698 */
699 kEmitTransBlack_BlendOptFlag = 0x10,
700 };
701 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
702
703 /**
704 * Determines what optimizations can be applied based on the blend. The coefficients may have
705 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
706 * params that receive the tweaked coefficients. Normally the function looks at the current
707 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
708 * determine the blend optimizations that would be used if there was partial pixel coverage.
709 *
710 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
711 * playback) must call this function and respect the flags that replace the output color.
712 */
713 BlendOptFlags getBlendOpts(bool forceCoverage = false,
714 GrBlendCoeff* srcCoeff = NULL,
715 GrBlendCoeff* dstCoeff = NULL) const;
716
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000717 /// @}
718
719 ///////////////////////////////////////////////////////////////////////////
720 /// @name View Matrix
721 ////
722
723 /**
robertphillips@google.coma72eef32012-05-01 17:22:59 +0000724 * Sets the matrix applied to vertex positions.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000725 *
726 * In the post-view-matrix space the rectangle [0,w]x[0,h]
727 * fully covers the render target. (w and h are the width and height of the
bsalomon@google.comca432082013-01-23 19:53:46 +0000728 * the render-target.)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000729 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000730 void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000731
732 /**
733 * Gets a writable pointer to the view matrix.
734 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000735 SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000736
737 /**
738 * Multiplies the current view matrix by a matrix
739 *
740 * After this call V' = V*m where V is the old view matrix,
741 * m is the parameter to this function, and V' is the new view matrix.
742 * (We consider positions to be column vectors so position vector p is
743 * transformed by matrix X as p' = X*p.)
744 *
745 * @param m the matrix used to modify the view matrix.
746 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000747 void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000748
749 /**
750 * Multiplies the current view matrix by a matrix
751 *
752 * After this call V' = m*V where V is the old view matrix,
753 * m is the parameter to this function, and V' is the new view matrix.
754 * (We consider positions to be column vectors so position vector p is
755 * transformed by matrix X as p' = X*p.)
756 *
757 * @param m the matrix used to modify the view matrix.
758 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000759 void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000760
761 /**
762 * Retrieves the current view matrix
763 * @return the current view matrix.
764 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000765 const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000766
767 /**
768 * Retrieves the inverse of the current view matrix.
769 *
770 * If the current view matrix is invertible, return true, and if matrix
771 * is non-null, copy the inverse into it. If the current view matrix is
772 * non-invertible, return false and ignore the matrix parameter.
773 *
774 * @param matrix if not null, will receive a copy of the current inverse.
775 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000776 bool getViewInverse(SkMatrix* matrix) const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000777 // TODO: determine whether we really need to leave matrix unmodified
778 // at call sites when inversion fails.
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000779 SkMatrix inverse;
bsalomon@google.comca432082013-01-23 19:53:46 +0000780 if (fCommon.fViewMatrix.invert(&inverse)) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000781 if (matrix) {
782 *matrix = inverse;
783 }
784 return true;
785 }
786 return false;
787 }
788
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000789 ////////////////////////////////////////////////////////////////////////////
790
791 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000792 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.comc196b522012-10-25 21:52:43 +0000793 * Effect matrices are automatically adjusted to compensate.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000794 */
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000795 class AutoViewMatrixRestore : public ::GrNoncopyable {
796 public:
797 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000798
799 AutoViewMatrixRestore(GrDrawState* ds,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000800 const SkMatrix& preconcatMatrix,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000801 uint32_t explicitCoordStageMask = 0) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000802 fDrawState = NULL;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000803 this->set(ds, preconcatMatrix, explicitCoordStageMask);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000804 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000805
806 ~AutoViewMatrixRestore() { this->restore(); }
807
bsalomon@google.coma8347462012-10-08 18:59:39 +0000808 /**
809 * Can be called prior to destructor to restore the original matrix.
810 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000811 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000812
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000813 void set(GrDrawState* drawState,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000814 const SkMatrix& preconcatMatrix,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000815 uint32_t explicitCoordStageMask = 0);
816
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000817 bool isSet() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000818
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000819 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000820 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000821 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000822 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000823 uint32_t fRestoreMask;
tomhudson@google.com93813632011-10-27 20:21:16 +0000824 };
825
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000826 ////////////////////////////////////////////////////////////////////////////
827
828 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000829 * This sets the view matrix to identity and adjusts stage matrices to compensate. The
830 * destructor undoes the changes, restoring the view matrix that was set before the
831 * constructor. It is similar to passing the inverse of the current view matrix to
832 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000833 */
834 class AutoDeviceCoordDraw : ::GrNoncopyable {
835 public:
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000836 AutoDeviceCoordDraw() : fDrawState(NULL) {}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000837 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000838 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
839 * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
840 * to specify such stages.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000841 */
842 AutoDeviceCoordDraw(GrDrawState* drawState,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000843 uint32_t explicitCoordStageMask = 0) {
844 fDrawState = NULL;
845 this->set(drawState, explicitCoordStageMask);
846 }
847
bsalomon@google.coma8347462012-10-08 18:59:39 +0000848 ~AutoDeviceCoordDraw() { this->restore(); }
849
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000850 bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
851
bsalomon@google.coma8347462012-10-08 18:59:39 +0000852 /**
853 * Returns true if this object was successfully initialized on to a GrDrawState. It may
854 * return false because a non-default constructor or set() were never called or because
855 * the view matrix was not invertible.
856 */
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000857 bool succeeded() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000858
bsalomon@google.coma8347462012-10-08 18:59:39 +0000859 /**
860 * Returns the matrix that was set previously set on the drawState. This is only valid
861 * if succeeded returns true.
862 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000863 const SkMatrix& getOriginalMatrix() const {
bsalomon@google.coma8347462012-10-08 18:59:39 +0000864 GrAssert(this->succeeded());
865 return fViewMatrix;
866 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000867
bsalomon@google.coma8347462012-10-08 18:59:39 +0000868 /**
869 * Can be called prior to destructor to restore the original matrix.
870 */
871 void restore();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000872
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000873 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000874 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000875 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000876 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000877 uint32_t fRestoreMask;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000878 };
879
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000880 /// @}
881
882 ///////////////////////////////////////////////////////////////////////////
883 /// @name Render Target
884 ////
885
886 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000887 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000888 *
889 * @param target The render target to set.
890 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000891 void setRenderTarget(GrRenderTarget* target) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000892 fRenderTarget.reset(SkSafeRef(target));
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000893 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000894
895 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000896 * Retrieves the currently set render-target.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000897 *
898 * @return The currently set render target.
899 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000900 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
901 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000902
903 class AutoRenderTargetRestore : public ::GrNoncopyable {
904 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000905 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000906 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
907 fDrawState = NULL;
robertphillips@google.com7460b372012-04-25 16:54:51 +0000908 fSavedTarget = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000909 this->set(ds, newTarget);
910 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000911 ~AutoRenderTargetRestore() { this->restore(); }
912
913 void restore() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000914 if (NULL != fDrawState) {
915 fDrawState->setRenderTarget(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000916 fDrawState = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000917 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000918 GrSafeSetNull(fSavedTarget);
919 }
920
921 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
922 this->restore();
923
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000924 if (NULL != ds) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000925 GrAssert(NULL == fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000926 fSavedTarget = ds->getRenderTarget();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000927 SkSafeRef(fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000928 ds->setRenderTarget(newTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000929 fDrawState = ds;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000930 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000931 }
932 private:
933 GrDrawState* fDrawState;
934 GrRenderTarget* fSavedTarget;
935 };
936
937 /// @}
938
939 ///////////////////////////////////////////////////////////////////////////
940 /// @name Stencil
941 ////
942
943 /**
944 * Sets the stencil settings to use for the next draw.
945 * Changing the clip has the side-effect of possibly zeroing
946 * out the client settable stencil bits. So multipass algorithms
947 * using stencil should not change the clip between passes.
948 * @param settings the stencil settings to use.
949 */
950 void setStencil(const GrStencilSettings& settings) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000951 fCommon.fStencilSettings = settings;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000952 }
953
954 /**
955 * Shortcut to disable stencil testing and ops.
956 */
957 void disableStencil() {
bsalomon@google.comca432082013-01-23 19:53:46 +0000958 fCommon.fStencilSettings.setDisabled();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000959 }
960
bsalomon@google.comca432082013-01-23 19:53:46 +0000961 const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000962
bsalomon@google.comca432082013-01-23 19:53:46 +0000963 GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000964
965 /// @}
966
967 ///////////////////////////////////////////////////////////////////////////
968 // @name Edge AA
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000969 // Edge equations can be specified to perform anti-aliasing. Because the
bsalomon@google.com7ffe6812012-05-11 17:32:43 +0000970 // edges are specified as per-vertex data, vertices that are shared by
971 // multiple edges must be split.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000972 //
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000973 ////
974
975 /**
tomhudson@google.com93813632011-10-27 20:21:16 +0000976 * When specifying edges as vertex data this enum specifies what type of
bsalomon@google.com81712882012-11-01 17:12:34 +0000977 * edges are in use. The edges are always 4 SkScalars in memory, even when
tomhudson@google.com93813632011-10-27 20:21:16 +0000978 * the edge type requires fewer than 4.
bsalomon@google.com93c96602012-04-27 13:05:21 +0000979 *
980 * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
981 * (either adjust in VS or use origin_upper_left in GLSL)
tomhudson@google.com93813632011-10-27 20:21:16 +0000982 */
983 enum VertexEdgeType {
984 /* 1-pixel wide line
985 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
986 kHairLine_EdgeType,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000987 /* Quadratic specified by u^2-v canonical coords (only 2
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000988 components used). Coverage based on signed distance with negative
bsalomon@google.com93c96602012-04-27 13:05:21 +0000989 being inside, positive outside. Edge specified in window space
990 (y-down) */
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000991 kQuad_EdgeType,
992 /* Same as above but for hairline quadratics. Uses unsigned distance.
993 Coverage is min(0, 1-distance). */
994 kHairQuad_EdgeType,
bsalomon@google.com93c96602012-04-27 13:05:21 +0000995 /* Circle specified as center_x, center_y, outer_radius, inner_radius
996 all in window space (y-down). */
997 kCircle_EdgeType,
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000998 /* Axis-aligned ellipse specified as center_x, center_y, x_radius, x_radius/y_radius
999 all in window space (y-down). */
1000 kEllipse_EdgeType,
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001001
1002 kVertexEdgeTypeCnt
tomhudson@google.com93813632011-10-27 20:21:16 +00001003 };
1004
1005 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +00001006 * Determines the interpretation per-vertex edge data when the
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +00001007 * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001008 * are not specified the value of this setting has no effect.
1009 */
1010 void setVertexEdgeType(VertexEdgeType type) {
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001011 GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
bsalomon@google.comca432082013-01-23 19:53:46 +00001012 fCommon.fVertexEdgeType = type;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001013 }
1014
bsalomon@google.comca432082013-01-23 19:53:46 +00001015 VertexEdgeType getVertexEdgeType() const { return fCommon.fVertexEdgeType; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001016
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001017 /// @}
tomhudson@google.com62b09682011-11-09 16:39:17 +00001018
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001019 ///////////////////////////////////////////////////////////////////////////
1020 /// @name State Flags
1021 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +00001022
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001023 /**
1024 * Flags that affect rendering. Controlled using enable/disableState(). All
1025 * default to disabled.
1026 */
1027 enum StateBits {
1028 /**
1029 * Perform dithering. TODO: Re-evaluate whether we need this bit
1030 */
1031 kDither_StateBit = 0x01,
1032 /**
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001033 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
1034 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
1035 * the 3D API.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001036 */
1037 kHWAntialias_StateBit = 0x02,
1038 /**
1039 * Draws will respect the clip, otherwise the clip is ignored.
1040 */
1041 kClip_StateBit = 0x04,
1042 /**
1043 * Disables writing to the color buffer. Useful when performing stencil
1044 * operations.
1045 */
1046 kNoColorWrites_StateBit = 0x08,
bsalomon@google.com0342a852012-08-20 19:22:38 +00001047
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001048 /**
1049 * Usually coverage is applied after color blending. The color is blended using the coeffs
1050 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
1051 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
1052 * this case there is no distinction between coverage and color and the caller needs direct
1053 * control over the blend coeffs. When set, there will be a single blend step controlled by
1054 * setBlendFunc() which will use coverage*color as the src color.
1055 */
1056 kCoverageDrawing_StateBit = 0x10,
1057
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001058 // Users of the class may add additional bits to the vector
1059 kDummyStateBit,
1060 kLastPublicStateBit = kDummyStateBit-1,
1061 };
1062
1063 void resetStateFlags() {
bsalomon@google.comca432082013-01-23 19:53:46 +00001064 fCommon.fFlagBits = 0;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001065 }
1066
1067 /**
1068 * Enable render state settings.
1069 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001070 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001071 */
1072 void enableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001073 fCommon.fFlagBits |= stateBits;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001074 }
1075
1076 /**
1077 * Disable render state settings.
1078 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001079 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001080 */
1081 void disableState(uint32_t stateBits) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001082 fCommon.fFlagBits &= ~(stateBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001083 }
1084
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +00001085 /**
1086 * Enable or disable stateBits based on a boolean.
1087 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001088 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +00001089 * @param enable if true enable stateBits, otherwise disable
1090 */
1091 void setState(uint32_t stateBits, bool enable) {
1092 if (enable) {
1093 this->enableState(stateBits);
1094 } else {
1095 this->disableState(stateBits);
1096 }
1097 }
1098
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001099 bool isDitherState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001100 return 0 != (fCommon.fFlagBits & kDither_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001101 }
1102
1103 bool isHWAntialiasState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001104 return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001105 }
1106
1107 bool isClipState() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001108 return 0 != (fCommon.fFlagBits & kClip_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001109 }
1110
1111 bool isColorWriteDisabled() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001112 return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001113 }
1114
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001115 bool isCoverageDrawing() const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001116 return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
bsalomon@google.comcf939ae2012-12-13 19:59:23 +00001117 }
1118
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001119 bool isStateFlagEnabled(uint32_t stateBit) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001120 return 0 != (stateBit & fCommon.fFlagBits);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001121 }
1122
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001123 /// @}
1124
1125 ///////////////////////////////////////////////////////////////////////////
1126 /// @name Face Culling
1127 ////
1128
1129 enum DrawFace {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001130 kInvalid_DrawFace = -1,
1131
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001132 kBoth_DrawFace,
1133 kCCW_DrawFace,
1134 kCW_DrawFace,
1135 };
1136
1137 /**
1138 * Controls whether clockwise, counterclockwise, or both faces are drawn.
1139 * @param face the face(s) to draw.
1140 */
1141 void setDrawFace(DrawFace face) {
bsalomon@google.com978c8c62012-05-21 14:45:49 +00001142 GrAssert(kInvalid_DrawFace != face);
bsalomon@google.comca432082013-01-23 19:53:46 +00001143 fCommon.fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001144 }
1145
1146 /**
1147 * Gets whether the target is drawing clockwise, counterclockwise,
1148 * or both faces.
1149 * @return the current draw face(s).
1150 */
bsalomon@google.comca432082013-01-23 19:53:46 +00001151 DrawFace getDrawFace() const { return fCommon.fDrawFace; }
rmistry@google.comd6176b02012-08-23 18:14:13 +00001152
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001153 /// @}
1154
1155 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +00001156
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001157 bool isStageEnabled(int s) const {
1158 GrAssert((unsigned)s < kNumStages);
bsalomon@google.com08283af2012-10-26 13:01:20 +00001159 return (NULL != fStages[s].getEffect());
tomhudson@google.comf13f5882012-06-25 17:27:28 +00001160 }
1161
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +00001162 // Most stages are usually not used, so conditionals here
1163 // reduce the expected number of bytes touched by 50%.
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001164 bool operator ==(const GrDrawState& s) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001165 if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001166 return false;
1167 }
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +00001168
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001169 for (int i = 0; i < kNumStages; i++) {
bsalomon@google.comf2f8fc32012-07-18 18:25:07 +00001170 bool enabled = this->isStageEnabled(i);
1171 if (enabled != s.isStageEnabled(i)) {
1172 return false;
1173 }
bsalomon@google.com08283af2012-10-26 13:01:20 +00001174 if (enabled && this->fStages[i] != s.fStages[i]) {
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001175 return false;
1176 }
1177 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001178 return true;
1179 }
1180 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
1181
bsalomon@google.comca432082013-01-23 19:53:46 +00001182 GrDrawState& operator= (const GrDrawState& s) {
1183 this->setRenderTarget(s.fRenderTarget.get());
1184 fCommon = s.fCommon;
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001185 for (int i = 0; i < kNumStages; i++) {
tomhudson@google.come742bf02012-07-13 19:54:19 +00001186 if (s.isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +00001187 this->fStages[i] = s.fStages[i];
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001188 }
1189 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001190 return *this;
1191 }
1192
1193private:
bsalomon@google.com2e3d1442012-03-26 20:33:54 +00001194
bsalomon@google.comca432082013-01-23 19:53:46 +00001195 /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1196 struct CommonState {
1197 // These fields are roughly sorted by decreasing likelihood of being different in op==
1198 GrColor fColor;
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +00001199 GrVertexLayout fVertexLayout;
bsalomon@google.comca432082013-01-23 19:53:46 +00001200 SkMatrix fViewMatrix;
1201 GrBlendCoeff fSrcBlend;
1202 GrBlendCoeff fDstBlend;
1203 GrColor fBlendConstant;
1204 uint32_t fFlagBits;
1205 VertexEdgeType fVertexEdgeType;
1206 GrStencilSettings fStencilSettings;
1207 int fFirstCoverageStage;
1208 GrColor fCoverage;
1209 SkXfermode::Mode fColorFilterMode;
1210 GrColor fColorFilterColor;
1211 DrawFace fDrawFace;
1212 bool operator== (const CommonState& other) const {
1213 return fColor == other.fColor &&
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +00001214 fVertexLayout == other.fVertexLayout &&
bsalomon@google.comca432082013-01-23 19:53:46 +00001215 fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1216 fSrcBlend == other.fSrcBlend &&
1217 fDstBlend == other.fDstBlend &&
1218 fBlendConstant == other.fBlendConstant &&
1219 fFlagBits == other.fFlagBits &&
1220 fVertexEdgeType == other.fVertexEdgeType &&
1221 fStencilSettings == other.fStencilSettings &&
1222 fFirstCoverageStage == other.fFirstCoverageStage &&
1223 fCoverage == other.fCoverage &&
1224 fColorFilterMode == other.fColorFilterMode &&
1225 fColorFilterColor == other.fColorFilterColor &&
1226 fDrawFace == other.fDrawFace;
1227 }
1228 bool operator!= (const CommonState& other) const { return !(*this == other); }
1229 };
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001230
bsalomon@google.comca432082013-01-23 19:53:46 +00001231 /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1232 DeferredState must directly reference GrEffects, however. */
1233 struct SavedEffectStage {
1234 SavedEffectStage() : fEffect(NULL) {}
1235 const GrEffect* fEffect;
1236 GrEffectStage::SavedCoordChange fCoordChange;
1237 };
1238
1239public:
1240 /**
1241 * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1242 * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1243 * dispose mechanism returns them to the cache. This allows recycling resources through the
1244 * the cache while they are in a deferred draw queue.
1245 */
1246 class DeferredState {
1247 public:
1248 DeferredState() : fRenderTarget(NULL) {
1249 GR_DEBUGCODE(fInitialized = false;)
1250 }
1251 // TODO: Remove this when DeferredState no longer holds a ref to the RT
1252 ~DeferredState() { SkSafeUnref(fRenderTarget); }
1253
1254 void saveFrom(const GrDrawState& drawState) {
1255 fCommon = drawState.fCommon;
1256 // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1257 fRenderTarget = drawState.fRenderTarget.get();
1258 SkSafeRef(fRenderTarget);
1259 // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1260 // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1261 // and recycle them to the cache (if no one else is holding a ref to the resources).
1262 for (int i = 0; i < kNumStages; ++i) {
1263 fStages[i].saveFrom(drawState.fStages[i]);
1264 }
1265 GR_DEBUGCODE(fInitialized = true;)
1266 }
1267
1268 void restoreTo(GrDrawState* drawState) {
1269 GrAssert(fInitialized);
1270 drawState->fCommon = fCommon;
1271 drawState->setRenderTarget(fRenderTarget);
1272 for (int i = 0; i < kNumStages; ++i) {
1273 fStages[i].restoreTo(&drawState->fStages[i]);
1274 }
1275 }
1276
1277 bool isEqual(const GrDrawState& state) const {
1278 if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1279 return false;
1280 }
1281 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.comdcd69bf2013-01-24 18:28:51 +00001282 if (!fStages[i].isEqual(state.fStages[i])) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001283 return false;
1284 }
1285 }
1286 return true;
1287 }
1288
1289 private:
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +00001290 GrRenderTarget* fRenderTarget;
1291 CommonState fCommon;
1292 GrEffectStage::DeferredStage fStages[kNumStages];
bsalomon@google.comca432082013-01-23 19:53:46 +00001293
1294 GR_DEBUGCODE(bool fInitialized;)
1295 };
1296
1297private:
robertphillips@google.comaf3a3b92013-02-28 23:08:28 +00001298 SkAutoTUnref<GrRenderTarget> fRenderTarget;
1299 CommonState fCommon;
1300 GrEffectStage fStages[kNumStages];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001301
reed@google.comfa35e3d2012-06-26 20:16:17 +00001302 typedef GrRefCnt INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +00001303};
1304
bsalomon@google.com2b446732013-02-12 16:47:41 +00001305GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
1306
tomhudson@google.com93813632011-10-27 20:21:16 +00001307#endif