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