blob: 2203e889e327b88ed5453640225de321c4f83ecd [file] [log] [blame]
tomhudson@google.com93813632011-10-27 20:21:16 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrDrawState_DEFINED
9#define GrDrawState_DEFINED
10
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000011#include "GrBackendEffectFactory.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000012#include "GrColor.h"
bsalomon@google.com08283af2012-10-26 13:01:20 +000013#include "GrEffectStage.h"
jvanverth@google.comcc782382013-01-28 20:39:48 +000014#include "GrRefCnt.h"
robertphillips@google.com9ec07532012-06-22 12:01:30 +000015#include "GrRenderTarget.h"
jvanverth@google.comcc782382013-01-28 20:39:48 +000016#include "GrStencil.h"
17#include "GrTemplates.h"
18#include "GrTexture.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000019#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000020
jvanverth@google.comcc782382013-01-28 20:39:48 +000021#include "SkMatrix.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000022#include "SkXfermode.h"
23
bsalomon@google.comaf84e742012-10-05 13:23:24 +000024class GrPaint;
tomhudson@google.com93813632011-10-27 20:21:16 +000025
jvanverth@google.com9b855c72013-03-01 18:21:22 +000026/**
27 * Types used to describe format of vertices in arrays
28 */
29enum GrVertexAttribType {
30 kFloat_GrVertexAttribType = 0,
31 kVec2f_GrVertexAttribType,
32 kVec3f_GrVertexAttribType,
33 kVec4f_GrVertexAttribType,
34 kVec4ub_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors
35
36 kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
37};
38static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
39
40struct GrVertexAttrib {
skia.committer@gmail.comf140f182013-03-02 07:01:56 +000041 inline void set(GrVertexAttribType type, size_t offset) {
jvanverth@google.com3b0d6312013-03-01 20:30:01 +000042 fType = type; fOffset = offset;
43 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +000044 bool operator==(const GrVertexAttrib& other) const {
45 return fType == other.fType && fOffset == other.fOffset;
46 };
47 bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
48
49 GrVertexAttribType fType;
50 size_t fOffset;
51};
52
53template <int N>
54class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
55
56/**
57 * Type used to describe how attributes bind to program usage
58 */
59typedef int GrAttribBindings;
60
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000061class GrDrawState : public GrRefCnt {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000062public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000063 SK_DECLARE_INST_COUNT(GrDrawState)
rmistry@google.comd6176b02012-08-23 18:14:13 +000064
tomhudson@google.com93813632011-10-27 20:21:16 +000065 /**
bsalomon@google.com13221342012-10-26 13:41:59 +000066 * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
67 * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
68 * output from the previous enabled stage and a position. The position is either derived from
69 * the interpolated vertex positions or explicit per-vertex coords, depending upon the
jvanverth@google.com9b855c72013-03-01 18:21:22 +000070 * GrAttribBindings used to draw.
robertphillips@google.combf5cad42012-05-10 12:40:40 +000071 *
bsalomon@google.com13221342012-10-26 13:41:59 +000072 * The stages are divided into two sets, color-computing and coverage-computing. The final color
73 * stage produces the final pixel color. The coverage-computing stages function exactly as the
74 * color-computing but the output of the final coverage stage is treated as a fractional pixel
75 * coverage rather than as input to the src/dst color blend step.
76 *
77 * The input color to the first enabled color-stage is either the constant color or interpolated
jvanverth@google.com9b855c72013-03-01 18:21:22 +000078 * per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
bsalomon@google.com13221342012-10-26 13:41:59 +000079 * either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or
80 * edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a
81 * GrEffect).
82 *
bsalomon@google.comcf939ae2012-12-13 19:59:23 +000083 * See the documentation of kCoverageDrawing_StateBit for information about disabling the
84 * the color / coverage distinction.
85 *
bsalomon@google.com13221342012-10-26 13:41:59 +000086 * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
87 * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
88 * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +000089 * by GrClipMaskManager.
tomhudson@google.com93813632011-10-27 20:21:16 +000090 */
91 enum {
twiz@google.com58071162012-07-18 21:41:50 +000092 kNumStages = 5,
tomhudson@google.com93813632011-10-27 20:21:16 +000093 };
94
bsalomon@google.comca432082013-01-23 19:53:46 +000095 GrDrawState() {
reed@google.com75847192013-01-28 20:53:22 +000096#if GR_DEBUG
jvanverth@google.com9b855c72013-03-01 18:21:22 +000097 VertexAttributesUnitTest();
reed@google.com75847192013-01-28 20:53:22 +000098#endif
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000099 this->reset();
100 }
bsalomon@google.com46f7afb2012-01-18 19:51:55 +0000101
bsalomon@google.comca432082013-01-23 19:53:46 +0000102 GrDrawState(const GrDrawState& state) {
bsalomon@google.com46f7afb2012-01-18 19:51:55 +0000103 *this = state;
104 }
105
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000106 virtual ~GrDrawState() {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000107 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000108 }
109
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000110 /**
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000111 * Resets to the default state.
bsalomon@google.com08283af2012-10-26 13:01:20 +0000112 * GrEffects will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +0000113 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000114 void reset() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000115
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000116 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000117
bsalomon@google.comca432082013-01-23 19:53:46 +0000118 fRenderTarget.reset(NULL);
119
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000120 this->setDefaultVertexAttribs();
121
bsalomon@google.comca432082013-01-23 19:53:46 +0000122 fCommon.fColor = 0xffffffff;
123 fCommon.fViewMatrix.reset();
124 fCommon.fSrcBlend = kOne_GrBlendCoeff;
125 fCommon.fDstBlend = kZero_GrBlendCoeff;
126 fCommon.fBlendConstant = 0x0;
127 fCommon.fFlagBits = 0x0;
128 fCommon.fVertexEdgeType = kHairLine_EdgeType;
129 fCommon.fStencilSettings.setDisabled();
130 fCommon.fFirstCoverageStage = kNumStages;
131 fCommon.fCoverage = 0xffffffff;
132 fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
133 fCommon.fColorFilterColor = 0x0;
134 fCommon.fDrawFace = kBoth_DrawFace;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000135 }
136
137 /**
138 * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000139 * encompasses more than GrPaint. Aspects of GrDrawState that have no
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000140 * GrPaint equivalents are not modified. GrPaint has fewer stages than
141 * GrDrawState. The extra GrDrawState stages are disabled.
142 */
143 void setFromPaint(const GrPaint& paint);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000144
145 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000146 /// @name Vertex Attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +0000147 ////
148
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000149 enum {
150 kVertexAttribCnt = 6,
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000151 };
152
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000153 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000154 * The format of vertices is represented as an array of vertex attribute
155 * pair, with each pair representing the type of the attribute and the
156 * offset in the vertex structure (see GrVertexAttrib, above).
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000157 *
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000158 * This will only set up the vertex geometry. To bind the attributes in
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000159 * the shaders, attribute indices and attribute bindings need to be set
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000160 * as well.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000161 */
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000162
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000163 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000164 * Sets vertex attributes for next draw.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000165 *
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000166 * @param attribs the array of vertex attributes to set.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000167 * @param count the number of attributes being set.
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000168 * limited to a count of kVertexAttribCnt.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000169 */
170 void setVertexAttribs(const GrVertexAttrib attribs[], int count);
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000171
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000172 const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
173 int getVertexAttribCount() const { return fVertexAttribs.count(); }
174
175 size_t getVertexSize() const;
176
177 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000178 * Sets default vertex attributes for next draw.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000179 *
180 * This will also set default vertex attribute indices and bindings
181 */
182 void setDefaultVertexAttribs();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000183
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000184 bool validateVertexAttribs() const;
185
jvanverth@google.comcc782382013-01-28 20:39:48 +0000186 ////////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000187 // Helpers for picking apart vertex attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +0000188
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000189 // helper array to let us check the expected so we know what bound attrib indices
190 // we care about
191 static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
jvanverth@google.comcc782382013-01-28 20:39:48 +0000192
193 /**
194 * Accessing positions, texture coords, or colors, of a vertex within an
195 * array is a hassle involving casts and simple math. These helpers exist
196 * to keep GrDrawTarget clients' code a bit nicer looking.
197 */
198
199 /**
200 * Gets a pointer to a GrPoint of a vertex's position or texture
201 * coordinate.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000202 * @param vertices the vertex array
jvanverth@google.comcc782382013-01-28 20:39:48 +0000203 * @param vertexIndex the index of the vertex in the array
204 * @param vertexSize the size of each vertex in the array
205 * @param offset the offset in bytes of the vertex component.
206 * Defaults to zero (corresponding to vertex position)
207 * @return pointer to the vertex component as a GrPoint
208 */
209 static GrPoint* GetVertexPoint(void* vertices,
210 int vertexIndex,
211 int vertexSize,
212 int offset = 0) {
213 intptr_t start = GrTCast<intptr_t>(vertices);
214 return GrTCast<GrPoint*>(start + offset +
215 vertexIndex * vertexSize);
216 }
217 static const GrPoint* GetVertexPoint(const void* vertices,
218 int vertexIndex,
219 int vertexSize,
220 int offset = 0) {
221 intptr_t start = GrTCast<intptr_t>(vertices);
222 return GrTCast<const GrPoint*>(start + offset +
223 vertexIndex * vertexSize);
224 }
225
226 /**
227 * Gets a pointer to a GrColor inside a vertex within a vertex array.
228 * @param vertices the vetex array
229 * @param vertexIndex the index of the vertex in the array
230 * @param vertexSize the size of each vertex in the array
231 * @param offset the offset in bytes of the vertex color
232 * @return pointer to the vertex component as a GrColor
233 */
234 static GrColor* GetVertexColor(void* vertices,
235 int vertexIndex,
236 int vertexSize,
237 int offset) {
238 intptr_t start = GrTCast<intptr_t>(vertices);
239 return GrTCast<GrColor*>(start + offset +
240 vertexIndex * vertexSize);
241 }
242 static const GrColor* GetVertexColor(const void* vertices,
243 int vertexIndex,
244 int vertexSize,
245 int offset) {
246 const intptr_t start = GrTCast<intptr_t>(vertices);
247 return GrTCast<const GrColor*>(start + offset +
248 vertexIndex * vertexSize);
249 }
250
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000251 /// @}
252
253 ///////////////////////////////////////////////////////////////////////////
254 /// @name Attribute Bindings
255 ////
256
257 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000258 * The vertex data used by the current program is represented as a bitfield
259 * of flags. Programs always use positions and may also use texture
reed@google.com67e7cde2013-03-20 17:47:16 +0000260 * coordinates, per-vertex colors, per-vertex coverage and edge data. Each
261 * stage can use the explicit texture coordinates as its input texture
262 * coordinates or it may use the positions as texture coordinates.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000263 */
264
265 /**
reed@google.com67e7cde2013-03-20 17:47:16 +0000266 * Generates a bit indicating that a texture stage uses texture coordinates
267 *
268 * @param stageIdx the stage that will use texture coordinates.
269 *
270 * @return the bit to add to a GrAttribBindings bitfield.
271 */
272 static int ExplicitTexCoordAttribBindingsBit(int stageIdx) {
273 GrAssert(stageIdx < kNumStages);
274 return (1 << stageIdx);
275 }
276
277 static bool StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx);
278
279 /**
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000280 * Additional Bits that can be specified in GrAttribBindings.
281 */
282 enum AttribBindingsBits {
283 /* program uses colors (GrColor) */
reed@google.com67e7cde2013-03-20 17:47:16 +0000284 kColor_AttribBindingsBit = 1 << (kNumStages + 0),
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000285 /* program uses coverage (GrColor)
286 */
reed@google.com67e7cde2013-03-20 17:47:16 +0000287 kCoverage_AttribBindingsBit = 1 << (kNumStages + 1),
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000288 /* program uses edge data. Distance to the edge is used to
289 * compute a coverage. See GrDrawState::setVertexEdgeType().
290 */
reed@google.com67e7cde2013-03-20 17:47:16 +0000291 kEdge_AttribBindingsBit = 1 << (kNumStages + 2),
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000292 // for below assert
293 kDummyAttribBindingsBit,
294 kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
295 };
296 // make sure we haven't exceeded the number of bits in GrAttribBindings.
297 GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribBindings)));
298
299 enum AttribBindings {
300 kDefault_AttribBindings = 0
301 };
302
303 /**
304 * Sets attribute bindings for next draw.
305 *
306 * @param bindings the attribute bindings to set.
307 */
308 void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; }
309
310 GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; }
311
312 ////////////////////////////////////////////////////////////////////////////
313 // Helpers for picking apart attribute bindings
314
315 /**
reed@google.com67e7cde2013-03-20 17:47:16 +0000316 * Helper function to determine if program uses explicit texture
317 * coordinates.
318 *
319 * @param bindings attribute bindings to query
320 *
321 * @return true if program uses texture coordinates,
322 * false otherwise.
323 */
324 static bool AttributesBindExplicitTexCoords(GrAttribBindings bindings);
325
326 /**
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000327 * Determines whether src alpha is guaranteed to be one for all src pixels
328 */
329 bool srcAlphaWillBeOne(GrAttribBindings) const;
330
331 /**
332 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
333 */
334 bool hasSolidCoverage(GrAttribBindings) const;
335
336 static void VertexAttributesUnitTest();
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000337
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000338 /// @}
339
340 ///////////////////////////////////////////////////////////////////////////
341 /// @name Vertex Attribute Indices
342 ////
343
344 /**
345 * Vertex attribute indices map the data set in the vertex attribute array
346 * to the bindings specified in the attribute bindings. Each binding type
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000347 * has an associated index in the attribute array. This index is used to
348 * look up the vertex attribute data from the array, and potentially as the
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000349 * attribute index if we're binding attributes in GL.
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000350 *
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000351 * Indices which do not have active attribute bindings will be ignored.
352 */
353
354 enum AttribIndex {
355 kPosition_AttribIndex = 0,
356 kColor_AttribIndex,
357 kCoverage_AttribIndex,
358 kEdge_AttribIndex,
reed@google.com67e7cde2013-03-20 17:47:16 +0000359 kTexCoord_AttribIndex,
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000360
reed@google.com67e7cde2013-03-20 17:47:16 +0000361 kLast_AttribIndex = kTexCoord_AttribIndex
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000362 };
363 static const int kAttribIndexCount = kLast_AttribIndex + 1;
364
365 // these are used when vertex color and coverage isn't set
366 enum {
367 kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt,
368 kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1,
369 };
370
371 ////////////////////////////////////////////////////////////////////////////
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000372 // Helpers to set attribute indices. These should match the index in the
373 // current attribute index array.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000374
375 /**
skia.committer@gmail.comf140f182013-03-02 07:01:56 +0000376 * Sets index for next draw. This is used to look up the offset
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000377 * from the current vertex attribute array and to bind the attributes.
378 *
379 * @param index the attribute index we're setting
380 * @param value the value of the index
381 */
382 void setAttribIndex(AttribIndex index, int value) { fAttribIndices[index] = value; }
383
384 int getAttribIndex(AttribIndex index) const { return fAttribIndices[index]; }
jvanverth@google.comcc782382013-01-28 20:39:48 +0000385
386 /// @}
387
388 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000389 /// @name Color
390 ////
391
392 /**
393 * Sets color for next draw to a premultiplied-alpha color.
394 *
395 * @param color the color to set.
396 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000397 void setColor(GrColor color) { fCommon.fColor = color; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000398
bsalomon@google.comca432082013-01-23 19:53:46 +0000399 GrColor getColor() const { return fCommon.fColor; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000400
401 /**
402 * Sets the color to be used for the next draw to be
403 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
404 *
405 * @param alpha The alpha value to set as the color.
406 */
407 void setAlpha(uint8_t a) {
408 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
409 }
410
411 /**
412 * Add a color filter that can be represented by a color and a mode. Applied
reed@google.com67e7cde2013-03-20 17:47:16 +0000413 * after color-computing texture stages.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000414 */
415 void setColorFilter(GrColor c, SkXfermode::Mode mode) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000416 fCommon.fColorFilterColor = c;
417 fCommon.fColorFilterMode = mode;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000418 }
419
bsalomon@google.comca432082013-01-23 19:53:46 +0000420 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
421 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000422
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000423 /**
424 * Constructor sets the color to be 'color' which is undone by the destructor.
425 */
426 class AutoColorRestore : public ::GrNoncopyable {
427 public:
sugoi@google.com66a58ac2013-03-05 20:40:52 +0000428 AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000429
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000430 AutoColorRestore(GrDrawState* drawState, GrColor color) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000431 fDrawState = NULL;
432 this->set(drawState, color);
433 }
434
435 void reset() {
436 if (NULL != fDrawState) {
437 fDrawState->setColor(fOldColor);
438 fDrawState = NULL;
439 }
440 }
441
442 void set(GrDrawState* drawState, GrColor color) {
443 this->reset();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000444 fDrawState = drawState;
445 fOldColor = fDrawState->getColor();
446 fDrawState->setColor(color);
447 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000448
449 ~AutoColorRestore() { this->reset(); }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000450 private:
451 GrDrawState* fDrawState;
452 GrColor fOldColor;
453 };
454
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000455 /// @}
456
457 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000458 /// @name Coverage
459 ////
460
461 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000462 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000463 * initial value (after construction or reset()) is 0xff. The constant
464 * coverage is ignored when per-vertex coverage is provided.
465 */
466 void setCoverage(uint8_t coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000467 fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000468 }
469
470 /**
471 * Version of above that specifies 4 channel per-vertex color. The value
472 * should be premultiplied.
473 */
474 void setCoverage4(GrColor coverage) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000475 fCommon.fCoverage = coverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000476 }
477
478 GrColor getCoverage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000479 return fCommon.fCoverage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000480 }
481
482 /// @}
483
484 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000485 /// @name Effect Stages
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000486 ////
487
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000488 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
489 fStages[stageIdx].setEffect(effect);
490 return effect;
491 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000492
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000493 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect,
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000494 int attr0, int attr1 = -1) {
495 fStages[stageIdx].setEffect(effect, attr0, attr1);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000496 return effect;
497 }
498
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000499 /**
reed@google.com67e7cde2013-03-20 17:47:16 +0000500 * Creates a GrSimpleTextureEffect.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000501 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000502 void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000503 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000504 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000505 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000506 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000507 void createTextureEffect(int stageIdx,
508 GrTexture* texture,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000509 const SkMatrix& matrix,
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000510 const GrTextureParams& params) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000511 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000512 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000513 this->setEffect(stageIdx, effect)->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000514 }
515
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000516 bool stagesDisabled() {
517 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000518 if (NULL != fStages[i].getEffect()) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000519 return false;
520 }
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000521 }
tomhudson@google.com3eee8fb2012-06-25 12:30:34 +0000522 return true;
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000523 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000524
skia.committer@gmail.com91274b92013-03-13 07:01:04 +0000525 void disableStage(int stageIdx) {
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000526 this->setEffect(stageIdx, NULL);
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000527 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000528
robertphillips@google.com972265d2012-06-13 18:49:30 +0000529 /**
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000530 * Release all the GrEffects referred to by this draw state.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000531 */
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000532 void disableStages() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000533 for (int i = 0; i < kNumStages; ++i) {
tomhudson@google.com676e6602012-07-10 17:21:48 +0000534 this->disableStage(i);
robertphillips@google.com972265d2012-06-13 18:49:30 +0000535 }
536 }
537
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000538 class AutoStageDisable : public ::GrNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000539 public:
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000540 AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
541 ~AutoStageDisable() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000542 if (NULL != fDrawState) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000543 fDrawState->disableStages();
robertphillips@google.com972265d2012-06-13 18:49:30 +0000544 }
545 }
546 private:
547 GrDrawState* fDrawState;
548 };
549
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000550 /**
bsalomon@google.com08283af2012-10-26 13:01:20 +0000551 * Returns the current stage by index.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000552 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000553 const GrEffectStage& getStage(int stageIdx) const {
554 GrAssert((unsigned)stageIdx < kNumStages);
555 return fStages[stageIdx];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000556 }
557
558 /**
reed@google.com67e7cde2013-03-20 17:47:16 +0000559 * Called when the source coord system is changing. preConcat gives the transformation from the
560 * old coord system to the new coord system.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000561 */
reed@google.com67e7cde2013-03-20 17:47:16 +0000562 void preConcatStageMatrices(const SkMatrix& preConcat) {
563 this->preConcatStageMatrices(~0U, preConcat);
564 }
565 /**
566 * Version of above that applies the update matrix selectively to stages via a mask.
567 */
568 void preConcatStageMatrices(uint32_t stageMask, const SkMatrix& preConcat) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000569 for (int i = 0; i < kNumStages; ++i) {
reed@google.com67e7cde2013-03-20 17:47:16 +0000570 if (((1 << i) & stageMask) && this->isStageEnabled(i)) {
571 fStages[i].preConcatCoordChange(preConcat);
bsalomon@google.come3d32162012-07-20 13:37:06 +0000572 }
573 }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000574 }
575
reed@google.com67e7cde2013-03-20 17:47:16 +0000576 /**
577 * Called when the source coord system is changing. preConcatInverse is the inverse of the
578 * transformation from the old coord system to the new coord system. Returns false if the matrix
579 * cannot be inverted.
580 */
581 bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) {
582 SkMatrix inv;
583 bool computed = false;
584 for (int i = 0; i < kNumStages; ++i) {
585 if (this->isStageEnabled(i)) {
586 if (!computed && !preConcatInverse.invert(&inv)) {
587 return false;
588 } else {
589 computed = true;
590 }
591 fStages[i].preConcatCoordChange(preConcatInverse);
592 }
593 }
594 return true;
595 }
596
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000597 /// @}
598
599 ///////////////////////////////////////////////////////////////////////////
600 /// @name Coverage / Color Stages
601 ////
602
603 /**
604 * A common pattern is to compute a color with the initial stages and then
605 * modulate that color by a coverage value in later stage(s) (AA, mask-
rmistry@google.comd6176b02012-08-23 18:14:13 +0000606 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
607 * computed based on the pre-coverage-modulated color. The division of
608 * stages between color-computing and coverage-computing is specified by
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000609 * this method. Initially this is kNumStages (all stages
610 * are color-computing).
611 */
612 void setFirstCoverageStage(int firstCoverageStage) {
613 GrAssert((unsigned)firstCoverageStage <= kNumStages);
bsalomon@google.comca432082013-01-23 19:53:46 +0000614 fCommon.fFirstCoverageStage = firstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000615 }
616
617 /**
618 * Gets the index of the first coverage-computing stage.
619 */
620 int getFirstCoverageStage() const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000621 return fCommon.fFirstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000622 }
623
624 ///@}
625
626 ///////////////////////////////////////////////////////////////////////////
627 /// @name Blending
628 ////
629
630 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000631 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000632 *
633 * The blend function will be:
634 * D' = sat(S*srcCoef + D*dstCoef)
635 *
636 * where D is the existing destination color, S is the incoming source
637 * color, and D' is the new destination color that will be written. sat()
638 * is the saturation function.
639 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000640 * @param srcCoef coefficient applied to the src color.
641 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000642 */
643 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000644 fCommon.fSrcBlend = srcCoeff;
645 fCommon.fDstBlend = dstCoeff;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000646 #if GR_DEBUG
647 switch (dstCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000648 case kDC_GrBlendCoeff:
649 case kIDC_GrBlendCoeff:
650 case kDA_GrBlendCoeff:
651 case kIDA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000652 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
653 "coverage stages.\n");
654 break;
655 default:
656 break;
657 }
658 switch (srcCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000659 case kSC_GrBlendCoeff:
660 case kISC_GrBlendCoeff:
661 case kSA_GrBlendCoeff:
662 case kISA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000663 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
664 "coverage stages.\n");
665 break;
666 default:
667 break;
668 }
669 #endif
670 }
671
bsalomon@google.comca432082013-01-23 19:53:46 +0000672 GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
673 GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000674
675 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
676 GrBlendCoeff* dstBlendCoeff) const {
bsalomon@google.comca432082013-01-23 19:53:46 +0000677 *srcBlendCoeff = fCommon.fSrcBlend;
678 *dstBlendCoeff = fCommon.fDstBlend;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000679 }
680
681 /**
682 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000683 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000684 * kConstC_GrBlendCoeff
685 * kIConstC_GrBlendCoeff
686 * kConstA_GrBlendCoeff
687 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000688 *
689 * @param constant the constant to set
690 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000691 void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000692
693 /**
694 * Retrieves the last value set by setBlendConstant()
695 * @return the blending constant value
696 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000697 GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000698
bsalomon@google.com2b446732013-02-12 16:47:41 +0000699 /**
700 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
701 * coverage before the blend will give the correct final destination color. In general it
702 * will not as coverage is applied after blending.
703 */
704 bool canTweakAlphaForCoverage() const;
705
706 /**
707 * Optimizations for blending / coverage to that can be applied based on the current state.
708 */
709 enum BlendOptFlags {
710 /**
711 * No optimization
712 */
713 kNone_BlendOpt = 0,
714 /**
715 * Don't draw at all
716 */
717 kSkipDraw_BlendOptFlag = 0x1,
718 /**
719 * Emit the src color, disable HW blending (replace dst with src)
720 */
721 kDisableBlend_BlendOptFlag = 0x2,
722 /**
723 * The coverage value does not have to be computed separately from alpha, the the output
724 * color can be the modulation of the two.
725 */
726 kCoverageAsAlpha_BlendOptFlag = 0x4,
727 /**
728 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
729 * "don't cares".
730 */
731 kEmitCoverage_BlendOptFlag = 0x8,
732 /**
733 * Emit transparent black instead of the src color, no need to compute coverage.
734 */
735 kEmitTransBlack_BlendOptFlag = 0x10,
736 };
737 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
738
739 /**
740 * Determines what optimizations can be applied based on the blend. The coefficients may have
741 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
742 * params that receive the tweaked coefficients. Normally the function looks at the current
743 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
744 * determine the blend optimizations that would be used if there was partial pixel coverage.
745 *
746 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
747 * playback) must call this function and respect the flags that replace the output color.
748 */
749 BlendOptFlags getBlendOpts(bool forceCoverage = false,
750 GrBlendCoeff* srcCoeff = NULL,
751 GrBlendCoeff* dstCoeff = NULL) const;
752
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000753 /// @}
754
755 ///////////////////////////////////////////////////////////////////////////
756 /// @name View Matrix
757 ////
758
759 /**
robertphillips@google.coma72eef32012-05-01 17:22:59 +0000760 * Sets the matrix applied to vertex positions.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000761 *
762 * In the post-view-matrix space the rectangle [0,w]x[0,h]
763 * fully covers the render target. (w and h are the width and height of the
bsalomon@google.comca432082013-01-23 19:53:46 +0000764 * the render-target.)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000765 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000766 void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000767
768 /**
769 * Gets a writable pointer to the view matrix.
770 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000771 SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000772
773 /**
774 * Multiplies the current view matrix by a matrix
775 *
776 * After this call V' = V*m where V is the old view matrix,
777 * m is the parameter to this function, and V' is the new view matrix.
778 * (We consider positions to be column vectors so position vector p is
779 * transformed by matrix X as p' = X*p.)
780 *
781 * @param m the matrix used to modify the view matrix.
782 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000783 void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000784
785 /**
786 * Multiplies the current view matrix by a matrix
787 *
788 * After this call V' = m*V where V is the old view matrix,
789 * m is the parameter to this function, and V' is the new view matrix.
790 * (We consider positions to be column vectors so position vector p is
791 * transformed by matrix X as p' = X*p.)
792 *
793 * @param m the matrix used to modify the view matrix.
794 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000795 void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000796
797 /**
798 * Retrieves the current view matrix
799 * @return the current view matrix.
800 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000801 const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000802
803 /**
804 * Retrieves the inverse of the current view matrix.
805 *
806 * If the current view matrix is invertible, return true, and if matrix
807 * is non-null, copy the inverse into it. If the current view matrix is
808 * non-invertible, return false and ignore the matrix parameter.
809 *
810 * @param matrix if not null, will receive a copy of the current inverse.
811 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000812 bool getViewInverse(SkMatrix* matrix) const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000813 // TODO: determine whether we really need to leave matrix unmodified
814 // at call sites when inversion fails.
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000815 SkMatrix inverse;
bsalomon@google.comca432082013-01-23 19:53:46 +0000816 if (fCommon.fViewMatrix.invert(&inverse)) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000817 if (matrix) {
818 *matrix = inverse;
819 }
820 return true;
821 }
822 return false;
823 }
824
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000825 ////////////////////////////////////////////////////////////////////////////
826
827 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000828 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.comc196b522012-10-25 21:52:43 +0000829 * Effect matrices are automatically adjusted to compensate.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000830 */
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000831 class AutoViewMatrixRestore : public ::GrNoncopyable {
832 public:
833 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000834
reed@google.com67e7cde2013-03-20 17:47:16 +0000835 AutoViewMatrixRestore(GrDrawState* ds,
836 const SkMatrix& preconcatMatrix,
837 uint32_t explicitCoordStageMask = 0) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000838 fDrawState = NULL;
reed@google.com67e7cde2013-03-20 17:47:16 +0000839 this->set(ds, preconcatMatrix, explicitCoordStageMask);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000840 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000841
842 ~AutoViewMatrixRestore() { this->restore(); }
843
bsalomon@google.coma8347462012-10-08 18:59:39 +0000844 /**
845 * Can be called prior to destructor to restore the original matrix.
846 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000847 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000848
reed@google.com67e7cde2013-03-20 17:47:16 +0000849 void set(GrDrawState* drawState,
850 const SkMatrix& preconcatMatrix,
851 uint32_t explicitCoordStageMask = 0);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000852
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000853 bool isSet() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000854
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000855 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000856 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000857 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000858 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000859 uint32_t fRestoreMask;
tomhudson@google.com93813632011-10-27 20:21:16 +0000860 };
861
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000862 ////////////////////////////////////////////////////////////////////////////
863
864 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000865 * This sets the view matrix to identity and adjusts stage matrices to compensate. The
866 * destructor undoes the changes, restoring the view matrix that was set before the
867 * constructor. It is similar to passing the inverse of the current view matrix to
868 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000869 */
870 class AutoDeviceCoordDraw : ::GrNoncopyable {
871 public:
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000872 AutoDeviceCoordDraw() : fDrawState(NULL) {}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000873 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000874 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
875 * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
876 * to specify such stages.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000877 */
reed@google.com67e7cde2013-03-20 17:47:16 +0000878 AutoDeviceCoordDraw(GrDrawState* drawState,
879 uint32_t explicitCoordStageMask = 0) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000880 fDrawState = NULL;
reed@google.com67e7cde2013-03-20 17:47:16 +0000881 this->set(drawState, explicitCoordStageMask);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000882 }
883
bsalomon@google.coma8347462012-10-08 18:59:39 +0000884 ~AutoDeviceCoordDraw() { this->restore(); }
885
reed@google.com67e7cde2013-03-20 17:47:16 +0000886 bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000887
bsalomon@google.coma8347462012-10-08 18:59:39 +0000888 /**
889 * Returns true if this object was successfully initialized on to a GrDrawState. It may
890 * return false because a non-default constructor or set() were never called or because
891 * the view matrix was not invertible.
892 */
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000893 bool succeeded() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000894
bsalomon@google.coma8347462012-10-08 18:59:39 +0000895 /**
896 * Returns the matrix that was set previously set on the drawState. This is only valid
897 * if succeeded returns true.
898 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000899 const SkMatrix& getOriginalMatrix() const {
bsalomon@google.coma8347462012-10-08 18:59:39 +0000900 GrAssert(this->succeeded());
901 return fViewMatrix;
902 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000903
bsalomon@google.coma8347462012-10-08 18:59:39 +0000904 /**
905 * Can be called prior to destructor to restore the original matrix.
906 */
907 void restore();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000908
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000909 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000910 GrDrawState* fDrawState;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000911 SkMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000912 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000913 uint32_t fRestoreMask;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000914 };
915
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000916 /// @}
917
918 ///////////////////////////////////////////////////////////////////////////
919 /// @name Render Target
920 ////
921
922 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000923 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000924 *
925 * @param target The render target to set.
926 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000927 void setRenderTarget(GrRenderTarget* target) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000928 fRenderTarget.reset(SkSafeRef(target));
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000929 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000930
931 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000932 * Retrieves the currently set render-target.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000933 *
934 * @return The currently set render target.
935 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000936 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
937 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000938
939 class AutoRenderTargetRestore : public ::GrNoncopyable {
940 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000941 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000942 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
943 fDrawState = NULL;
robertphillips@google.com7460b372012-04-25 16:54:51 +0000944 fSavedTarget = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000945 this->set(ds, newTarget);
946 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000947 ~AutoRenderTargetRestore() { this->restore(); }
948
949 void restore() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000950 if (NULL != fDrawState) {
951 fDrawState->setRenderTarget(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000952 fDrawState = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000953 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000954 GrSafeSetNull(fSavedTarget);
955 }
956
957 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
958 this->restore();
959
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000960 if (NULL != ds) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000961 GrAssert(NULL == fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000962 fSavedTarget = ds->getRenderTarget();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000963 SkSafeRef(fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000964 ds->setRenderTarget(newTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000965 fDrawState = ds;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000966 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000967 }
968 private:
969 GrDrawState* fDrawState;
970 GrRenderTarget* fSavedTarget;
971 };
972
973 /// @}
974
975 ///////////////////////////////////////////////////////////////////////////
976 /// @name Stencil
977 ////
978
979 /**
980 * Sets the stencil settings to use for the next draw.
981 * Changing the clip has the side-effect of possibly zeroing
982 * out the client settable stencil bits. So multipass algorithms
983 * using stencil should not change the clip between passes.
984 * @param settings the stencil settings to use.
985 */
986 void setStencil(const GrStencilSettings& settings) {
bsalomon@google.comca432082013-01-23 19:53:46 +0000987 fCommon.fStencilSettings = settings;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000988 }
989
990 /**
991 * Shortcut to disable stencil testing and ops.
992 */
993 void disableStencil() {
bsalomon@google.comca432082013-01-23 19:53:46 +0000994 fCommon.fStencilSettings.setDisabled();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000995 }
996
bsalomon@google.comca432082013-01-23 19:53:46 +0000997 const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000998
bsalomon@google.comca432082013-01-23 19:53:46 +0000999 GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001000
1001 /// @}
1002
1003 ///////////////////////////////////////////////////////////////////////////
1004 // @name Edge AA
bsalomon@google.com1e269b52012-10-15 14:25:31 +00001005 // Edge equations can be specified to perform anti-aliasing. Because the
bsalomon@google.com7ffe6812012-05-11 17:32:43 +00001006 // edges are specified as per-vertex data, vertices that are shared by
1007 // multiple edges must be split.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001008 //
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001009 ////
1010
1011 /**
tomhudson@google.com93813632011-10-27 20:21:16 +00001012 * When specifying edges as vertex data this enum specifies what type of
bsalomon@google.com81712882012-11-01 17:12:34 +00001013 * edges are in use. The edges are always 4 SkScalars in memory, even when
tomhudson@google.com93813632011-10-27 20:21:16 +00001014 * the edge type requires fewer than 4.
bsalomon@google.com93c96602012-04-27 13:05:21 +00001015 *
1016 * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
1017 * (either adjust in VS or use origin_upper_left in GLSL)
tomhudson@google.com93813632011-10-27 20:21:16 +00001018 */
1019 enum VertexEdgeType {
1020 /* 1-pixel wide line
1021 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
1022 kHairLine_EdgeType,
rmistry@google.comd6176b02012-08-23 18:14:13 +00001023 /* Quadratic specified by u^2-v canonical coords (only 2
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001024 components used). Coverage based on signed distance with negative
bsalomon@google.com93c96602012-04-27 13:05:21 +00001025 being inside, positive outside. Edge specified in window space
1026 (y-down) */
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +00001027 kQuad_EdgeType,
1028 /* Same as above but for hairline quadratics. Uses unsigned distance.
1029 Coverage is min(0, 1-distance). */
1030 kHairQuad_EdgeType,
1031
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
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001037 * kEdge_AttribBindingsBit is set (see GrDrawTarget). When per-vertex edges
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001038 * 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 bool operator ==(const GrDrawState& s) const {
bsalomon@google.comca432082013-01-23 19:53:46 +00001193 if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001194 return false;
1195 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +00001196 if (fVertexAttribs != s.fVertexAttribs) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001197 return false;
1198 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001199 for (int i = 0; i < kAttribIndexCount; ++i) {
reed@google.com67e7cde2013-03-20 17:47:16 +00001200 if ((i == kPosition_AttribIndex ||
1201 s.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001202 fAttribIndices[i] != s.fAttribIndices[i]) {
1203 return false;
1204 }
1205 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001206 for (int i = 0; i < kNumStages; i++) {
bsalomon@google.comf2f8fc32012-07-18 18:25:07 +00001207 bool enabled = this->isStageEnabled(i);
1208 if (enabled != s.isStageEnabled(i)) {
1209 return false;
1210 }
bsalomon@google.com08283af2012-10-26 13:01:20 +00001211 if (enabled && this->fStages[i] != s.fStages[i]) {
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001212 return false;
1213 }
1214 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001215 return true;
1216 }
1217 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
1218
bsalomon@google.comca432082013-01-23 19:53:46 +00001219 GrDrawState& operator= (const GrDrawState& s) {
1220 this->setRenderTarget(s.fRenderTarget.get());
1221 fCommon = s.fCommon;
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001222 fVertexAttribs = s.fVertexAttribs;
1223 for (int i = 0; i < kAttribIndexCount; i++) {
1224 fAttribIndices[i] = s.fAttribIndices[i];
1225 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001226 for (int i = 0; i < kNumStages; i++) {
tomhudson@google.come742bf02012-07-13 19:54:19 +00001227 if (s.isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +00001228 this->fStages[i] = s.fStages[i];
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001229 }
1230 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +00001231 return *this;
1232 }
1233
1234private:
bsalomon@google.com2e3d1442012-03-26 20:33:54 +00001235
bsalomon@google.comca432082013-01-23 19:53:46 +00001236 /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1237 struct CommonState {
1238 // These fields are roughly sorted by decreasing likelihood of being different in op==
1239 GrColor fColor;
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001240 GrAttribBindings fAttribBindings;
bsalomon@google.comca432082013-01-23 19:53:46 +00001241 SkMatrix fViewMatrix;
1242 GrBlendCoeff fSrcBlend;
1243 GrBlendCoeff fDstBlend;
1244 GrColor fBlendConstant;
1245 uint32_t fFlagBits;
1246 VertexEdgeType fVertexEdgeType;
1247 GrStencilSettings fStencilSettings;
1248 int fFirstCoverageStage;
1249 GrColor fCoverage;
1250 SkXfermode::Mode fColorFilterMode;
1251 GrColor fColorFilterColor;
1252 DrawFace fDrawFace;
1253 bool operator== (const CommonState& other) const {
1254 return fColor == other.fColor &&
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001255 fAttribBindings == other.fAttribBindings &&
bsalomon@google.comca432082013-01-23 19:53:46 +00001256 fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1257 fSrcBlend == other.fSrcBlend &&
1258 fDstBlend == other.fDstBlend &&
1259 fBlendConstant == other.fBlendConstant &&
1260 fFlagBits == other.fFlagBits &&
1261 fVertexEdgeType == other.fVertexEdgeType &&
1262 fStencilSettings == other.fStencilSettings &&
1263 fFirstCoverageStage == other.fFirstCoverageStage &&
1264 fCoverage == other.fCoverage &&
1265 fColorFilterMode == other.fColorFilterMode &&
1266 fColorFilterColor == other.fColorFilterColor &&
1267 fDrawFace == other.fDrawFace;
1268 }
1269 bool operator!= (const CommonState& other) const { return !(*this == other); }
1270 };
bsalomon@google.com8fe84b52012-03-26 15:24:27 +00001271
bsalomon@google.comca432082013-01-23 19:53:46 +00001272 /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1273 DeferredState must directly reference GrEffects, however. */
1274 struct SavedEffectStage {
1275 SavedEffectStage() : fEffect(NULL) {}
1276 const GrEffect* fEffect;
1277 GrEffectStage::SavedCoordChange fCoordChange;
1278 };
1279
1280public:
1281 /**
1282 * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1283 * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1284 * dispose mechanism returns them to the cache. This allows recycling resources through the
1285 * the cache while they are in a deferred draw queue.
1286 */
1287 class DeferredState {
1288 public:
1289 DeferredState() : fRenderTarget(NULL) {
1290 GR_DEBUGCODE(fInitialized = false;)
1291 }
1292 // TODO: Remove this when DeferredState no longer holds a ref to the RT
1293 ~DeferredState() { SkSafeUnref(fRenderTarget); }
1294
1295 void saveFrom(const GrDrawState& drawState) {
1296 fCommon = drawState.fCommon;
1297 // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1298 fRenderTarget = drawState.fRenderTarget.get();
1299 SkSafeRef(fRenderTarget);
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001300 fVertexAttribs = drawState.fVertexAttribs;
1301 for (int i = 0; i < kAttribIndexCount; i++) {
1302 fAttribIndices[i] = drawState.fAttribIndices[i];
1303 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001304 // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1305 // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1306 // and recycle them to the cache (if no one else is holding a ref to the resources).
1307 for (int i = 0; i < kNumStages; ++i) {
1308 fStages[i].saveFrom(drawState.fStages[i]);
1309 }
1310 GR_DEBUGCODE(fInitialized = true;)
1311 }
1312
1313 void restoreTo(GrDrawState* drawState) {
1314 GrAssert(fInitialized);
1315 drawState->fCommon = fCommon;
1316 drawState->setRenderTarget(fRenderTarget);
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001317 drawState->fVertexAttribs = fVertexAttribs;
1318 for (int i = 0; i < kAttribIndexCount; i++) {
1319 drawState->fAttribIndices[i] = fAttribIndices[i];
1320 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001321 for (int i = 0; i < kNumStages; ++i) {
1322 fStages[i].restoreTo(&drawState->fStages[i]);
1323 }
1324 }
1325
1326 bool isEqual(const GrDrawState& state) const {
1327 if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1328 return false;
1329 }
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001330 for (int i = 0; i < kAttribIndexCount; ++i) {
skia.committer@gmail.comf140f182013-03-02 07:01:56 +00001331 if ((i == kPosition_AttribIndex ||
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001332 state.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
1333 fAttribIndices[i] != state.fAttribIndices[i]) {
1334 return false;
1335 }
1336 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +00001337 if (fVertexAttribs != state.fVertexAttribs) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001338 return false;
1339 }
bsalomon@google.comca432082013-01-23 19:53:46 +00001340 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.comdcd69bf2013-01-24 18:28:51 +00001341 if (!fStages[i].isEqual(state.fStages[i])) {
bsalomon@google.comca432082013-01-23 19:53:46 +00001342 return false;
1343 }
1344 }
1345 return true;
1346 }
1347
1348 private:
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001349 GrRenderTarget* fRenderTarget;
1350 CommonState fCommon;
1351 int fAttribIndices[kAttribIndexCount];
1352 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
1353 GrEffectStage::DeferredStage fStages[kNumStages];
bsalomon@google.comca432082013-01-23 19:53:46 +00001354
1355 GR_DEBUGCODE(bool fInitialized;)
1356 };
1357
1358private:
jvanverth@google.com9b855c72013-03-01 18:21:22 +00001359 // helper array to let us check the current bindings so we know what bound attrib indices
1360 // we care about
1361 static const GrAttribBindings kAttribIndexMasks[kAttribIndexCount];
1362
1363 SkAutoTUnref<GrRenderTarget> fRenderTarget;
1364 CommonState fCommon;
1365 int fAttribIndices[kAttribIndexCount];
1366 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
1367 GrEffectStage fStages[kNumStages];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +00001368
reed@google.comfa35e3d2012-06-26 20:16:17 +00001369 typedef GrRefCnt INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +00001370};
1371
bsalomon@google.com2b446732013-02-12 16:47:41 +00001372GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
1373
tomhudson@google.com93813632011-10-27 20:21:16 +00001374#endif