OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2012 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 #include "GrGLEffectMatrix.h" | |
9 #include "GrDrawEffect.h" | |
10 #include "GrTexture.h" | |
11 | |
12 GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix, | |
13 const GrDrawEffect& drawEffect, | |
14 CoordsType coordsType, | |
15 const GrTexture* texture) { | |
16 EffectKey key = 0; | |
17 SkMatrix::TypeMask type0 = effectMatrix.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 } | |
29 | |
30 int combinedTypes = type0 | type1; | |
31 | |
32 bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture-
>origin(); | |
33 | |
34 if (SkMatrix::kPerspective_Mask & combinedTypes) { | |
35 key |= kGeneral_MatrixType; | |
36 } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes
) || reverseY) { | |
37 key |= kNoPersp_MatrixType; | |
38 } else if (SkMatrix::kTranslate_Mask & combinedTypes) { | |
39 key |= kTrans_MatrixType; | |
40 } else { | |
41 key |= kIdentity_MatrixType; | |
42 } | |
43 return key; | |
44 } | |
45 | |
46 GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder, | |
47 EffectKey key, | |
48 SkString* fsCoordName, | |
49 SkString* vsCoordName, | |
50 const char* suffix) { | |
51 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(
); | |
52 SkASSERT(NULL != vertexBuilder); | |
53 | |
54 GrSLType varyingType = kVoid_GrSLType; | |
55 const char* uniName; | |
56 key &= kKeyMask; | |
57 switch (key & kMatrixTypeKeyMask) { | |
58 case kIdentity_MatrixType: | |
59 fUniType = kVoid_GrSLType; | |
60 uniName = NULL; | |
61 varyingType = kVec2f_GrSLType; | |
62 break; | |
63 case kTrans_MatrixType: | |
64 fUniType = kVec2f_GrSLType; | |
65 uniName = "StageTranslate"; | |
66 varyingType = kVec2f_GrSLType; | |
67 break; | |
68 case kNoPersp_MatrixType: | |
69 fUniType = kMat33f_GrSLType; | |
70 uniName = "StageMatrix"; | |
71 varyingType = kVec2f_GrSLType; | |
72 break; | |
73 case kGeneral_MatrixType: | |
74 fUniType = kMat33f_GrSLType; | |
75 uniName = "StageMatrix"; | |
76 varyingType = kVec3f_GrSLType; | |
77 break; | |
78 default: | |
79 GrCrash("Unexpected key."); | |
80 } | |
81 SkString suffixedUniName; | |
82 if (kVoid_GrSLType != fUniType) { | |
83 if (NULL != suffix) { | |
84 suffixedUniName.append(uniName); | |
85 suffixedUniName.append(suffix); | |
86 uniName = suffixedUniName.c_str(); | |
87 } | |
88 fUni = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility, | |
89 fUniType, | |
90 uniName, | |
91 &uniName); | |
92 } | |
93 | |
94 const char* varyingName = "MatrixCoord"; | |
95 SkString suffixedVaryingName; | |
96 if (NULL != suffix) { | |
97 suffixedVaryingName.append(varyingName); | |
98 suffixedVaryingName.append(suffix); | |
99 varyingName = suffixedVaryingName.c_str(); | |
100 } | |
101 const char* vsVaryingName; | |
102 const char* fsVaryingName; | |
103 vertexBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryi
ngName); | |
104 | |
105 const GrGLShaderVar* coords; | |
106 switch (fCoordsType) { | |
107 case GrEffect::kLocal_CoordsType: | |
108 SkASSERT(!(kPositionCoords_Flag & key)); | |
109 coords = &vertexBuilder->localCoordsAttribute(); | |
110 break; | |
111 case GrEffect::kPosition_CoordsType: | |
112 SkASSERT((kPositionCoords_Flag & key) || !vertexBuilder->hasExplicit
LocalCoords()); | |
113 coords = &vertexBuilder->positionAttribute(); | |
114 break; | |
115 default: | |
116 coords = NULL; // prevents warning | |
117 GrCrash("Unexpected coords type."); | |
118 } | |
119 // varying = matrix * coords (logically) | |
120 switch (fUniType) { | |
121 case kVoid_GrSLType: | |
122 SkASSERT(kVec2f_GrSLType == varyingType); | |
123 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords->
c_str()); | |
124 break; | |
125 case kVec2f_GrSLType: | |
126 SkASSERT(kVec2f_GrSLType == varyingType); | |
127 vertexBuilder->vsCodeAppendf("\t%s = %s + %s;\n", | |
128 vsVaryingName, uniName, coords->c_str()
); | |
129 break; | |
130 case kMat33f_GrSLType: { | |
131 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyin
gType); | |
132 if (kVec2f_GrSLType == varyingType) { | |
133 vertexBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", | |
134 vsVaryingName, uniName, coords->c_s
tr()); | |
135 } else { | |
136 vertexBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", | |
137 vsVaryingName, uniName, coords->c_s
tr()); | |
138 } | |
139 break; | |
140 } | |
141 default: | |
142 GrCrash("Unexpected uniform type."); | |
143 } | |
144 if (NULL != vsCoordName) { | |
145 *vsCoordName = vsVaryingName; | |
146 } | |
147 if (NULL != fsCoordName) { | |
148 *fsCoordName = fsVaryingName; | |
149 } | |
150 return varyingType; | |
151 } | |
152 | |
153 /** | |
154 * This is similar to emitCode except that it performs perspective division i
n the FS if the | |
155 * texture coordinates have a w coordinate. The fsCoordName always refers to
a vec2f. | |
156 */ | |
157 void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder, | |
158 EffectKey key, | |
159 SkString* fsCoordName, | |
160 SkString* vsVaryingName, | |
161 GrSLType* vsVaryingType, | |
162 const char* suffix) { | |
163 SkString fsVaryingName; | |
164 | |
165 GrSLType varyingType = this->emitCode(builder, | |
166 key, | |
167 &fsVaryingName, | |
168 vsVaryingName, | |
169 suffix); | |
170 if (kVec3f_GrSLType == varyingType) { | |
171 | |
172 const char* coordName = "coords2D"; | |
173 SkString suffixedCoordName; | |
174 if (NULL != suffix) { | |
175 suffixedCoordName.append(coordName); | |
176 suffixedCoordName.append(suffix); | |
177 coordName = suffixedCoordName.c_str(); | |
178 } | |
179 builder->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;", | |
180 coordName, fsVaryingName.c_str(), fsVaryingName.c
_str()); | |
181 if (NULL != fsCoordName) { | |
182 *fsCoordName = coordName; | |
183 } | |
184 } else if(NULL != fsCoordName) { | |
185 *fsCoordName = fsVaryingName; | |
186 } | |
187 if (NULL != vsVaryingType) { | |
188 *vsVaryingType = varyingType; | |
189 } | |
190 } | |
191 | |
192 void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager, | |
193 const SkMatrix& matrix, | |
194 const GrDrawEffect& drawEffect, | |
195 const GrTexture* texture) { | |
196 SkASSERT(fUni.isValid() != (kVoid_GrSLType == fUniType)); | |
197 const SkMatrix& coordChangeMatrix = GrEffect::kLocal_CoordsType == fCoordsTy
pe ? | |
198 drawEffect.getCoordChangeMatrix() : | |
199 SkMatrix::I(); | |
200 switch (fUniType) { | |
201 case kVoid_GrSLType: | |
202 SkASSERT(matrix.isIdentity()); | |
203 SkASSERT(coordChangeMatrix.isIdentity()); | |
204 SkASSERT(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->ori
gin()); | |
205 return; | |
206 case kVec2f_GrSLType: { | |
207 SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChang
eMatrix.getType())); | |
208 SkASSERT(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->ori
gin()); | |
209 SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMat
rix::kMTransX]; | |
210 SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMat
rix::kMTransY]; | |
211 if (fPrevMatrix.get(SkMatrix::kMTransX) != tx || | |
212 fPrevMatrix.get(SkMatrix::kMTransY) != ty) { | |
213 uniformManager.set2f(fUni, tx, ty); | |
214 fPrevMatrix.set(SkMatrix::kMTransX, tx); | |
215 fPrevMatrix.set(SkMatrix::kMTransY, ty); | |
216 } | |
217 break; | |
218 } | |
219 case kMat33f_GrSLType: { | |
220 SkMatrix combined; | |
221 combined.setConcat(matrix, coordChangeMatrix); | |
222 if (NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origi
n()) { | |
223 // combined.postScale(1,-1); | |
224 // combined.postTranslate(0,1); | |
225 combined.set(SkMatrix::kMSkewY, | |
226 combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); | |
227 combined.set(SkMatrix::kMScaleY, | |
228 combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY])
; | |
229 combined.set(SkMatrix::kMTransY, | |
230 combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY])
; | |
231 } | |
232 if (!fPrevMatrix.cheapEqualTo(combined)) { | |
233 uniformManager.setSkMatrix(fUni, combined); | |
234 fPrevMatrix = combined; | |
235 } | |
236 break; | |
237 } | |
238 default: | |
239 GrCrash("Unexpected uniform type."); | |
240 } | |
241 } | |
OLD | NEW |