blob: 90de1a3f7fa695676f9afce4e5cc0e0e6cf0d507 [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
11#include "GrColor.h"
12#include "GrMatrix.h"
13#include "GrSamplerState.h"
14#include "GrStencil.h"
15
16#include "SkXfermode.h"
17
18class GrRenderTarget;
19class GrTexture;
20
21struct GrDrawState {
22
23 /**
24 * Number of texture stages. Each stage takes as input a color and
25 * 2D texture coordinates. The color input to the first enabled stage is the
26 * per-vertex color or the constant color (setColor/setAlpha) if there are
27 * no per-vertex colors. For subsequent stages the input color is the output
28 * color from the previous enabled stage. The output color of each stage is
29 * the input color modulated with the result of a texture lookup. Texture
30 * lookups are specified by a texture a sampler (setSamplerState). Texture
31 * coordinates for each stage come from the vertices based on a
32 * GrVertexLayout bitfield. The output fragment color is the output color of
33 * the last enabled stage. The presence or absence of texture coordinates
34 * for each stage in the vertex layout indicates whether a stage is enabled
35 * or not.
36 */
37 enum {
38 kNumStages = 3,
39 kMaxTexCoords = kNumStages
40 };
41
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000042 /**
43 * Bitfield used to indicate a set of stages.
44 */
45 typedef uint32_t StageMask;
46 GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
47
bsalomon@google.com3d0835b2011-12-08 16:12:03 +000048 enum DrawFace {
49 kBoth_DrawFace,
50 kCCW_DrawFace,
51 kCW_DrawFace,
tomhudson@google.com93813632011-10-27 20:21:16 +000052 };
53
bsalomon@google.com3d0835b2011-12-08 16:12:03 +000054 /**
tomhudson@google.com93813632011-10-27 20:21:16 +000055 * When specifying edges as vertex data this enum specifies what type of
56 * edges are in use. The edges are always 4 GrScalars in memory, even when
57 * the edge type requires fewer than 4.
58 */
59 enum VertexEdgeType {
60 /* 1-pixel wide line
61 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
62 kHairLine_EdgeType,
63 /* 1-pixel wide quadratic
64 u^2-v canonical coords (only 2 components used) */
65 kHairQuad_EdgeType
66 };
67
68 /**
69 * The absolute maximum number of edges that may be specified for
70 * a single draw call when performing edge antialiasing. This is used for
71 * the size of several static buffers, so implementations of getMaxEdges()
72 * (below) should clamp to this value.
73 */
74 enum {
tomhudson@google.com62b09682011-11-09 16:39:17 +000075 // TODO: this should be 32 when GrTesselatedPathRenderer is used
76 // Visual Studio 2010 does not permit a member array of size 0.
77 kMaxEdges = 1
tomhudson@google.com93813632011-10-27 20:21:16 +000078 };
79
80 class Edge {
81 public:
82 Edge() {}
83 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
84 GrPoint intersect(const Edge& other) {
85 return GrPoint::Make(
bsalomon@google.com72e49b82011-10-27 21:47:03 +000086 SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
87 (fX * other.fY - other.fX * fY)),
88 SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
89 (other.fX * fY - fX * other.fY)));
tomhudson@google.com93813632011-10-27 20:21:16 +000090 }
91 float fX, fY, fZ;
92 };
93
bsalomon@google.com3d0835b2011-12-08 16:12:03 +000094 GrDrawState() {
95 // make sure any pad is zero for memcmp
96 // all GrDrawState members should default to something
97 // valid by the memset
98 memset(this, 0, sizeof(GrDrawState));
99
100 // memset exceptions
101 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
102 fFirstCoverageStage = kNumStages;
103
104 // pedantic assertion that our ptrs will
105 // be NULL (0 ptr is mem addr 0)
106 GrAssert((intptr_t)(void*)NULL == 0LL);
107
108 // default stencil setting should be disabled
109 GrAssert(fStencilSettings.isDisabled());
110 fFirstCoverageStage = kNumStages;
tomhudson@google.com93813632011-10-27 20:21:16 +0000111 }
112
tomhudson@google.com62b09682011-11-09 16:39:17 +0000113 uint8_t fFlagBits;
114 GrBlendCoeff fSrcBlend : 8;
115 GrBlendCoeff fDstBlend : 8;
116 DrawFace fDrawFace : 8;
117 uint8_t fFirstCoverageStage;
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000118 SkXfermode::Mode fColorFilterXfermode : 8;
tomhudson@google.com93813632011-10-27 20:21:16 +0000119 GrColor fBlendConstant;
120 GrTexture* fTextures[kNumStages];
tomhudson@google.com93813632011-10-27 20:21:16 +0000121 GrRenderTarget* fRenderTarget;
122 GrColor fColor;
tomhudson@google.com93813632011-10-27 20:21:16 +0000123 GrColor fColorFilterColor;
tomhudson@google.com93813632011-10-27 20:21:16 +0000124
125 GrStencilSettings fStencilSettings;
126 GrMatrix fViewMatrix;
tomhudson@google.com62b09682011-11-09 16:39:17 +0000127
128 // @{ Data for GrTesselatedPathRenderer
129 // TODO: currently ignored in copying & comparison for performance.
130 // Must be considered if GrTesselatedPathRenderer is being used.
131
132 int fEdgeAANumEdges;
tomhudson@google.com93813632011-10-27 20:21:16 +0000133 VertexEdgeType fVertexEdgeType;
134 Edge fEdgeAAEdges[kMaxEdges];
tomhudson@google.com62b09682011-11-09 16:39:17 +0000135
136 // @}
137
138 // This field must be last; it will not be copied or compared
139 // if the corresponding fTexture[] is NULL.
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000140 GrSamplerState fSamplerStates[kNumStages];
tomhudson@google.com62b09682011-11-09 16:39:17 +0000141
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000142 // Most stages are usually not used, so conditionals here
143 // reduce the expected number of bytes touched by 50%.
144 bool operator ==(const GrDrawState& s) const {
145 if (memcmp(this, &s, this->leadingBytes())) return false;
146
147 for (int i = 0; i < kNumStages; i++) {
148 if (fTextures[i] &&
149 memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
150 sizeof(GrSamplerState))) {
151 return false;
152 }
153 }
154
155 return true;
156 }
157 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
158
159 // Most stages are usually not used, so conditionals here
160 // reduce the expected number of bytes touched by 50%.
161 GrDrawState& operator =(const GrDrawState& s) {
162 memcpy(this, &s, this->leadingBytes());
163
164 for (int i = 0; i < kNumStages; i++) {
165 if (s.fTextures[i]) {
166 memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
167 sizeof(GrSamplerState));
168 }
169 }
170
171 return *this;
172 }
173
174private:
tomhudson@google.com62b09682011-11-09 16:39:17 +0000175 size_t leadingBytes() const {
176 // Can't use offsetof() with non-POD types, so stuck with pointer math.
177 // TODO: ignores GrTesselatedPathRenderer data structures. We don't
178 // have a compile-time flag that lets us know if it's being used, and
179 // checking at runtime seems to cost 5% performance.
180 return (size_t) ((unsigned char*)&fEdgeAANumEdges -
181 (unsigned char*)&fFlagBits);
182 }
183
tomhudson@google.com93813632011-10-27 20:21:16 +0000184};
185
186#endif
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000187