OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrGLEffectMatrix.h" | 8 #include "GrGLEffectMatrix.h" |
| 9 #include "GrDrawEffect.h" |
9 #include "GrTexture.h" | 10 #include "GrTexture.h" |
10 | 11 |
11 GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix, | 12 GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix, |
12 const SkMatrix& coordChangeMatrix
, | 13 const GrDrawEffect& drawEffect, |
| 14 CoordsType coordsType, |
13 const GrTexture* texture) { | 15 const GrTexture* texture) { |
| 16 EffectKey key = 0; |
14 SkMatrix::TypeMask type0 = effectMatrix.getType(); | 17 SkMatrix::TypeMask type0 = effectMatrix.getType(); |
15 SkMatrix::TypeMask type1 = coordChangeMatrix.getType(); | 18 SkMatrix::TypeMask type1; |
| 19 if (GrEffect::kLocal_CoordsType == coordsType) { |
| 20 type1 = drawEffect.getCoordChangeMatrix().getType(); |
| 21 } else { |
| 22 if (drawEffect.programHasExplicitLocalCoords()) { |
| 23 // We only make the key indicate that device coords are referenced w
hen the local coords |
| 24 // are not actually determined by positions. |
| 25 key |= kPositionCoords_Flag; |
| 26 } |
| 27 type1 = SkMatrix::kIdentity_Mask; |
| 28 } |
16 | 29 |
17 static const int kNonTransMask = SkMatrix::kAffine_Mask | | |
18 SkMatrix::kScale_Mask | | |
19 SkMatrix::kPerspective_Mask; | |
20 int combinedTypes = type0 | type1; | 30 int combinedTypes = type0 | type1; |
21 | 31 |
22 bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture-
>origin(); | 32 bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture-
>origin(); |
23 | 33 |
24 if (SkMatrix::kPerspective_Mask & combinedTypes) { | 34 if (SkMatrix::kPerspective_Mask & combinedTypes) { |
25 return kGeneral_Key; | 35 key |= kGeneral_MatrixType; |
26 } else if ((kNonTransMask & combinedTypes) || reverseY) { | 36 } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes
) || reverseY) { |
27 return kNoPersp_Key; | 37 key |= kNoPersp_MatrixType; |
28 } else if (kTrans_Key & combinedTypes) { | 38 } else if (SkMatrix::kTranslate_Mask & combinedTypes) { |
29 return kTrans_Key; | 39 key |= kTrans_MatrixType; |
30 } else { | 40 } else { |
31 GrAssert(effectMatrix.isIdentity() && coordChangeMatrix.isIdentity()); | 41 key |= kIdentity_MatrixType; |
32 return kIdentity_Key; | |
33 } | 42 } |
| 43 return key; |
34 } | 44 } |
35 | 45 |
36 GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder, | 46 GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder, |
37 EffectKey key, | 47 EffectKey key, |
38 const char* vertexCoords, | |
39 const char** fsCoordName, | 48 const char** fsCoordName, |
40 const char** vsCoordName, | 49 const char** vsCoordName, |
41 const char* suffix) { | 50 const char* suffix) { |
42 GrSLType varyingType; | 51 GrSLType varyingType; |
43 const char* uniName; | 52 const char* uniName; |
44 key &= kKeyMask; | 53 key &= kKeyMask; |
45 switch (key) { | 54 switch (key & kMatrixTypeKeyMask) { |
46 case kIdentity_Key: | 55 case kIdentity_MatrixType: |
47 fUniType = kVoid_GrSLType; | 56 fUniType = kVoid_GrSLType; |
48 varyingType = kVec2f_GrSLType; | 57 varyingType = kVec2f_GrSLType; |
49 break; | 58 break; |
50 case kTrans_Key: | 59 case kTrans_MatrixType: |
51 fUniType = kVec2f_GrSLType; | 60 fUniType = kVec2f_GrSLType; |
52 uniName = "StageTranslate"; | 61 uniName = "StageTranslate"; |
53 varyingType = kVec2f_GrSLType; | 62 varyingType = kVec2f_GrSLType; |
54 break; | 63 break; |
55 case kNoPersp_Key: | 64 case kNoPersp_MatrixType: |
56 fUniType = kMat33f_GrSLType; | 65 fUniType = kMat33f_GrSLType; |
57 uniName = "StageMatrix"; | 66 uniName = "StageMatrix"; |
58 varyingType = kVec2f_GrSLType; | 67 varyingType = kVec2f_GrSLType; |
59 break; | 68 break; |
60 case kGeneral_Key: | 69 case kGeneral_MatrixType: |
61 fUniType = kMat33f_GrSLType; | 70 fUniType = kMat33f_GrSLType; |
62 uniName = "StageMatrix"; | 71 uniName = "StageMatrix"; |
63 varyingType = kVec3f_GrSLType; | 72 varyingType = kVec3f_GrSLType; |
64 break; | 73 break; |
65 default: | 74 default: |
66 GrCrash("Unexpected key."); | 75 GrCrash("Unexpected key."); |
67 } | 76 } |
68 SkString suffixedUniName; | 77 SkString suffixedUniName; |
69 if (NULL != suffix) { | 78 if (NULL != suffix) { |
70 suffixedUniName.append(uniName); | 79 suffixedUniName.append(uniName); |
(...skipping 11 matching lines...) Expand all Loading... |
82 SkString suffixedVaryingName; | 91 SkString suffixedVaryingName; |
83 if (NULL != suffix) { | 92 if (NULL != suffix) { |
84 suffixedVaryingName.append(varyingName); | 93 suffixedVaryingName.append(varyingName); |
85 suffixedVaryingName.append(suffix); | 94 suffixedVaryingName.append(suffix); |
86 varyingName = suffixedVaryingName.c_str(); | 95 varyingName = suffixedVaryingName.c_str(); |
87 } | 96 } |
88 const char* vsVaryingName; | 97 const char* vsVaryingName; |
89 const char* fsVaryingName; | 98 const char* fsVaryingName; |
90 builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName
); | 99 builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName
); |
91 | 100 |
92 // varying = matrix * vertex-coords (logically) | 101 const GrGLShaderVar* coords; |
| 102 switch (fCoordsType) { |
| 103 case GrEffect::kLocal_CoordsType: |
| 104 GrAssert(!(kPositionCoords_Flag & key)); |
| 105 coords = &builder->localCoordsAttribute(); |
| 106 break; |
| 107 case GrEffect::kPosition_CoordsType: |
| 108 GrAssert((kPositionCoords_Flag & key) || !builder->hasExplicitLocalC
oords()); |
| 109 coords = &builder->positionAttribute(); |
| 110 break; |
| 111 default: |
| 112 GrCrash("Unexpected coords type."); |
| 113 } |
| 114 // varying = matrix * coords (logically) |
93 switch (fUniType) { | 115 switch (fUniType) { |
94 case kVoid_GrSLType: | 116 case kVoid_GrSLType: |
95 GrAssert(kVec2f_GrSLType == varyingType); | 117 GrAssert(kVec2f_GrSLType == varyingType); |
96 builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, vertexCoords); | 118 builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords->c_str(
)); |
97 break; | 119 break; |
98 case kVec2f_GrSLType: | 120 case kVec2f_GrSLType: |
99 GrAssert(kVec2f_GrSLType == varyingType); | 121 GrAssert(kVec2f_GrSLType == varyingType); |
100 builder->vsCodeAppendf("\t%s = %s + %s;\n", vsVaryingName, uniName,
vertexCoords); | 122 builder->vsCodeAppendf("\t%s = %s + %s;\n", |
| 123 vsVaryingName, uniName, coords->c_str()); |
101 break; | 124 break; |
102 case kMat33f_GrSLType: { | 125 case kMat33f_GrSLType: { |
103 GrAssert(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyin
gType); | 126 GrAssert(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyin
gType); |
104 if (kVec2f_GrSLType == varyingType) { | 127 if (kVec2f_GrSLType == varyingType) { |
105 builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", | 128 builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", |
106 vsVaryingName, uniName, vertexCoords); | 129 vsVaryingName, uniName, coords->c_str()); |
107 } else { | 130 } else { |
108 builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", | 131 builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", |
109 vsVaryingName, uniName, vertexCoords); | 132 vsVaryingName, uniName, coords->c_str()); |
110 } | 133 } |
111 break; | 134 break; |
112 } | 135 } |
113 default: | 136 default: |
114 GrCrash("Unexpected uniform type."); | 137 GrCrash("Unexpected uniform type."); |
115 } | 138 } |
116 if (NULL != vsCoordName) { | 139 if (NULL != vsCoordName) { |
117 *vsCoordName = vsVaryingName; | 140 *vsCoordName = vsVaryingName; |
118 } | 141 } |
119 if (NULL != fsCoordName) { | 142 if (NULL != fsCoordName) { |
120 *fsCoordName = fsVaryingName; | 143 *fsCoordName = fsVaryingName; |
121 } | 144 } |
122 return varyingType; | 145 return varyingType; |
123 } | 146 } |
124 | 147 |
125 /** | 148 /** |
126 * This is similar to emitCode except that it performs perspective division i
n the FS if the | 149 * This is similar to emitCode except that it performs perspective division i
n the FS if the |
127 * texture coordinates have a w coordinate. The fsCoordName always refers to
a vec2f. | 150 * texture coordinates have a w coordinate. The fsCoordName always refers to
a vec2f. |
128 */ | 151 */ |
129 void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder, | 152 void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder, |
130 EffectKey key, | 153 EffectKey key, |
131 const char* vertexCoords, | |
132 const char** fsCoordName, | 154 const char** fsCoordName, |
133 const char** vsVaryingName, | 155 const char** vsVaryingName, |
134 GrSLType* vsVaryingType, | 156 GrSLType* vsVaryingType, |
135 const char* suffix) { | 157 const char* suffix) { |
136 const char* fsVaryingName; | 158 const char* fsVaryingName; |
137 | 159 |
138 GrSLType varyingType = this->emitCode(builder, | 160 GrSLType varyingType = this->emitCode(builder, |
139 key, | 161 key, |
140 vertexCoords, | |
141 &fsVaryingName, | 162 &fsVaryingName, |
142 vsVaryingName, | 163 vsVaryingName, |
143 suffix); | 164 suffix); |
144 if (kVec3f_GrSLType == varyingType) { | 165 if (kVec3f_GrSLType == varyingType) { |
145 | 166 |
146 const char* coordName = "coords2D"; | 167 const char* coordName = "coords2D"; |
147 SkString suffixedCoordName; | 168 SkString suffixedCoordName; |
148 if (NULL != suffix) { | 169 if (NULL != suffix) { |
149 suffixedCoordName.append(coordName); | 170 suffixedCoordName.append(coordName); |
150 suffixedCoordName.append(suffix); | 171 suffixedCoordName.append(suffix); |
151 coordName = suffixedCoordName.c_str(); | 172 coordName = suffixedCoordName.c_str(); |
152 } | 173 } |
153 builder->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;", | 174 builder->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;", |
154 coordName, fsVaryingName, fsVaryingName); | 175 coordName, fsVaryingName, fsVaryingName); |
155 if (NULL != fsCoordName) { | 176 if (NULL != fsCoordName) { |
156 *fsCoordName = coordName; | 177 *fsCoordName = coordName; |
157 } | 178 } |
158 } else if(NULL != fsCoordName) { | 179 } else if(NULL != fsCoordName) { |
159 *fsCoordName = fsVaryingName; | 180 *fsCoordName = fsVaryingName; |
160 } | 181 } |
161 if (NULL != vsVaryingType) { | 182 if (NULL != vsVaryingType) { |
162 *vsVaryingType = varyingType; | 183 *vsVaryingType = varyingType; |
163 } | 184 } |
164 } | 185 } |
165 | 186 |
166 void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager, | 187 void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager, |
167 const SkMatrix& matrix, | 188 const SkMatrix& matrix, |
168 const SkMatrix& coordChangeMatrix, | 189 const GrDrawEffect& drawEffect, |
169 const GrTexture* texture) { | 190 const GrTexture* texture) { |
170 GrAssert((GrGLUniformManager::kInvalidUniformHandle == fUni) == | 191 GrAssert((GrGLUniformManager::kInvalidUniformHandle == fUni) == |
171 (kVoid_GrSLType == fUniType)); | 192 (kVoid_GrSLType == fUniType)); |
| 193 const SkMatrix& coordChangeMatrix = GrEffect::kLocal_CoordsType == fCoordsTy
pe ? |
| 194 drawEffect.getCoordChangeMatrix() : |
| 195 SkMatrix::I(); |
172 switch (fUniType) { | 196 switch (fUniType) { |
173 case kVoid_GrSLType: | 197 case kVoid_GrSLType: |
174 GrAssert(matrix.isIdentity()); | 198 GrAssert(matrix.isIdentity()); |
175 GrAssert(coordChangeMatrix.isIdentity()); | 199 GrAssert(coordChangeMatrix.isIdentity()); |
176 GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->ori
gin()); | 200 GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->ori
gin()); |
177 return; | 201 return; |
178 case kVec2f_GrSLType: { | 202 case kVec2f_GrSLType: { |
179 GrAssert(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChang
eMatrix.getType())); | 203 GrAssert(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChang
eMatrix.getType())); |
180 GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->ori
gin()); | 204 GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->ori
gin()); |
181 SkScalar tx = matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatri
x::kMTransX]; | 205 SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMat
rix::kMTransX]; |
182 SkScalar ty = matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatri
x::kMTransY]; | 206 SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMat
rix::kMTransY]; |
183 if (fPrevMatrix.get(SkMatrix::kMTransX) != tx || | 207 if (fPrevMatrix.get(SkMatrix::kMTransX) != tx || |
184 fPrevMatrix.get(SkMatrix::kMTransY) != ty) { | 208 fPrevMatrix.get(SkMatrix::kMTransY) != ty) { |
185 uniformManager.set2f(fUni, tx, ty); | 209 uniformManager.set2f(fUni, tx, ty); |
186 fPrevMatrix.set(SkMatrix::kMTransX, tx); | 210 fPrevMatrix.set(SkMatrix::kMTransX, tx); |
187 fPrevMatrix.set(SkMatrix::kMTransY, ty); | 211 fPrevMatrix.set(SkMatrix::kMTransY, ty); |
188 } | 212 } |
189 break; | 213 break; |
190 } | 214 } |
191 case kMat33f_GrSLType: { | 215 case kMat33f_GrSLType: { |
192 SkMatrix combined; | 216 SkMatrix combined; |
(...skipping 11 matching lines...) Expand all Loading... |
204 if (!fPrevMatrix.cheapEqualTo(combined)) { | 228 if (!fPrevMatrix.cheapEqualTo(combined)) { |
205 uniformManager.setSkMatrix(fUni, combined); | 229 uniformManager.setSkMatrix(fUni, combined); |
206 fPrevMatrix = combined; | 230 fPrevMatrix = combined; |
207 } | 231 } |
208 break; | 232 break; |
209 } | 233 } |
210 default: | 234 default: |
211 GrCrash("Unexpected uniform type."); | 235 GrCrash("Unexpected uniform type."); |
212 } | 236 } |
213 } | 237 } |
OLD | NEW |