blob: 8401772d92a6a505b814949e02ac2dd72452f0fc [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
42 enum DrawFace {
43 kBoth_DrawFace,
44 kCCW_DrawFace,
45 kCW_DrawFace,
46 };
47
48 /**
49 * When specifying edges as vertex data this enum specifies what type of
50 * edges are in use. The edges are always 4 GrScalars in memory, even when
51 * the edge type requires fewer than 4.
52 */
53 enum VertexEdgeType {
54 /* 1-pixel wide line
55 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
56 kHairLine_EdgeType,
57 /* 1-pixel wide quadratic
58 u^2-v canonical coords (only 2 components used) */
59 kHairQuad_EdgeType
60 };
61
62 /**
63 * The absolute maximum number of edges that may be specified for
64 * a single draw call when performing edge antialiasing. This is used for
65 * the size of several static buffers, so implementations of getMaxEdges()
66 * (below) should clamp to this value.
67 */
68 enum {
tomhudson@google.com62b09682011-11-09 16:39:17 +000069 // TODO: this should be 32 when GrTesselatedPathRenderer is used
70 // Visual Studio 2010 does not permit a member array of size 0.
71 kMaxEdges = 1
tomhudson@google.com93813632011-10-27 20:21:16 +000072 };
73
74 class Edge {
75 public:
76 Edge() {}
77 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
78 GrPoint intersect(const Edge& other) {
79 return GrPoint::Make(
bsalomon@google.com72e49b82011-10-27 21:47:03 +000080 SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
81 (fX * other.fY - other.fX * fY)),
82 SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
83 (other.fX * fY - fX * other.fY)));
tomhudson@google.com93813632011-10-27 20:21:16 +000084 }
85 float fX, fY, fZ;
86 };
87
88 GrDrawState() {
89 // make sure any pad is zero for memcmp
90 // all GrDrawState members should default to something
91 // valid by the memset
92 memset(this, 0, sizeof(GrDrawState));
93
94 // memset exceptions
95 fColorFilterXfermode = SkXfermode::kDstIn_Mode;
96 fFirstCoverageStage = kNumStages;
97
98 // pedantic assertion that our ptrs will
99 // be NULL (0 ptr is mem addr 0)
100 GrAssert((intptr_t)(void*)NULL == 0LL);
101
102 // default stencil setting should be disabled
103 GrAssert(fStencilSettings.isDisabled());
104 fFirstCoverageStage = kNumStages;
105 }
106
tomhudson@google.com62b09682011-11-09 16:39:17 +0000107 uint8_t fFlagBits;
108 GrBlendCoeff fSrcBlend : 8;
109 GrBlendCoeff fDstBlend : 8;
110 DrawFace fDrawFace : 8;
111 uint8_t fFirstCoverageStage;
112 SkXfermode::Mode fColorFilterXfermode : 8;
tomhudson@google.com93813632011-10-27 20:21:16 +0000113 GrColor fBlendConstant;
114 GrTexture* fTextures[kNumStages];
tomhudson@google.com93813632011-10-27 20:21:16 +0000115 GrRenderTarget* fRenderTarget;
116 GrColor fColor;
tomhudson@google.com93813632011-10-27 20:21:16 +0000117 GrColor fColorFilterColor;
tomhudson@google.com93813632011-10-27 20:21:16 +0000118
119 GrStencilSettings fStencilSettings;
120 GrMatrix fViewMatrix;
tomhudson@google.com62b09682011-11-09 16:39:17 +0000121
122 // @{ Data for GrTesselatedPathRenderer
123 // TODO: currently ignored in copying & comparison for performance.
124 // Must be considered if GrTesselatedPathRenderer is being used.
125
126 int fEdgeAANumEdges;
tomhudson@google.com93813632011-10-27 20:21:16 +0000127 VertexEdgeType fVertexEdgeType;
128 Edge fEdgeAAEdges[kMaxEdges];
tomhudson@google.com62b09682011-11-09 16:39:17 +0000129
130 // @}
131
132 // This field must be last; it will not be copied or compared
133 // if the corresponding fTexture[] is NULL.
134 GrSamplerState fSamplerStates[kNumStages];
135
136 // Most stages are usually not used, so conditionals here
137 // reduce the expected number of bytes touched by 50%.
tomhudson@google.com93813632011-10-27 20:21:16 +0000138 bool operator ==(const GrDrawState& s) const {
tomhudson@google.com62b09682011-11-09 16:39:17 +0000139 if (memcmp(this, &s, this->leadingBytes())) return false;
140
141 for (int i = 0; i < kNumStages; i++) {
142 if (fTextures[i] &&
143 memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
144 sizeof(GrSamplerState))) {
145 return false;
146 }
147 }
148
149 return true;
tomhudson@google.com93813632011-10-27 20:21:16 +0000150 }
151 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
tomhudson@google.com62b09682011-11-09 16:39:17 +0000152
153 // Most stages are usually not used, so conditionals here
154 // reduce the expected number of bytes touched by 50%.
155 GrDrawState& operator =(const GrDrawState& s) {
156 memcpy(this, &s, this->leadingBytes());
157
158 for (int i = 0; i < kNumStages; i++) {
159 if (s.fTextures[i]) {
160 memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
161 sizeof(GrSamplerState));
162 }
163 }
164
165 return *this;
166 }
167
168private:
169 size_t leadingBytes() const {
170 // Can't use offsetof() with non-POD types, so stuck with pointer math.
171 // TODO: ignores GrTesselatedPathRenderer data structures. We don't
172 // have a compile-time flag that lets us know if it's being used, and
173 // checking at runtime seems to cost 5% performance.
174 return (size_t) ((unsigned char*)&fEdgeAANumEdges -
175 (unsigned char*)&fFlagBits);
176 }
177
tomhudson@google.com93813632011-10-27 20:21:16 +0000178};
179
180#endif
tomhudson@google.com62b09682011-11-09 16:39:17 +0000181