Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/gpu/gl/GrGLEffectArray.cpp

Issue 25605008: Repurpose GrGLCoordTransform as GrGLEffectArray (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 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 "GrGLEffectArray.h"
9 #include "GrDrawEffect.h"
10 #include "gl/GrGLEffect.h"
11 #include "gl/GrGLShaderBuilder.h"
12 #include "gl/GrGpuGL.h"
13
14 typedef GrGLEffectArray::EffectKey EffectKey;
15 typedef GrGLEffectArray::TransformedCoords TransformedCoords;
16 typedef GrGLEffectArray::TransformedCoordsArray TransformedCoordsArray;
17 typedef GrGLEffectArray::TextureSampler TextureSampler;
18 typedef GrGLEffectArray::TextureSamplerArray TextureSamplerArray;
19
20 /**
21 * We specialize the vertex code for each of these matrix types.
22 */
23 enum MatrixType {
24 kIdentity_MatrixType = 0,
25 kTrans_MatrixType = 1,
26 kNoPersp_MatrixType = 2,
27 kGeneral_MatrixType = 3,
28 };
29
30 /**
31 * The key for an individual coord transform is made up of a matrix type and a b it that
32 * indicates the source of the input coords.
33 */
34 enum {
35 kMatrixTypeKeyBits = 2,
36 kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
37 kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
38 kTransformKeyBits = kMatrixTypeKeyBits + 1,
39 kTransformKeyMask = (1 << kTransformKeyBits) - 1,
40 };
41
42 namespace {
43
44 /**
45 * Do we need to either map r,g,b->a or a->r. configComponentMask indicates whic h channels are
46 * present in the texture's config. swizzleComponentMask indicates the channels present in the
47 * shader swizzle.
48 */
49 inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
50 uint32_t configComponentMask,
51 uint32_t swizzleComponentMask) {
52 if (caps.textureSwizzleSupport()) {
53 // Any remapping is handled using texture swizzling not shader modificat ions.
54 return false;
55 }
56 // check if the texture is alpha-only
57 if (kA_GrColorComponentFlag == configComponentMask) {
58 if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleCompon entMask)) {
59 // we must map the swizzle 'a's to 'r'.
60 return true;
61 }
62 if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
63 // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
64 // alpha-only textures smear alpha across all four channels when rea d.
65 return true;
66 }
67 }
68 return false;
69 }
70
71 }
72
73 EffectKey GrGLEffectArray::GenAttribKey(const GrDrawEffect& drawEffect) {
74 EffectKey key = 0;
75 int numAttributes = drawEffect.getVertexAttribIndexCount();
76 SkASSERT(numAttributes <= 2);
77 const int* attributeIndices = drawEffect.getVertexAttribIndices();
78 for (int a = 0; a < numAttributes; ++a) {
79 EffectKey value = attributeIndices[a] << 3 * a;
80 SkASSERT(0 == (value & key)); // keys for each attribute ought not to ov erlap
81 key |= value;
82 }
83 return key;
84 }
85
86 EffectKey GrGLEffectArray::GenTransformKey(const GrDrawEffect& drawEffect) {
87 EffectKey totalKey = 0;
88 int numTransforms = (*drawEffect.effect())->numTransforms();
89 for (int t = 0; t < numTransforms; ++t) {
90 EffectKey key = 0;
91 const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTr ansform(t);
92 SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
93 SkMatrix::TypeMask type1;
94 if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
95 type1 = drawEffect.getCoordChangeMatrix().getType();
96 } else {
97 if (drawEffect.programHasExplicitLocalCoords()) {
98 // We only make the key indicate that device coords are referenc ed when the local coords
99 // are not actually determined by positions. Otherwise the local coords var and position
100 // var are identical.
101 key |= kPositionCoords_Flag;
102 }
103 type1 = SkMatrix::kIdentity_Mask;
104 }
105
106 int combinedTypes = type0 | type1;
107
108 bool reverseY = coordTransform.reverseY();
109
110 if (SkMatrix::kPerspective_Mask & combinedTypes) {
111 key |= kGeneral_MatrixType;
112 } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedT ypes) || reverseY) {
113 key |= kNoPersp_MatrixType;
114 } else if (SkMatrix::kTranslate_Mask & combinedTypes) {
115 key |= kTrans_MatrixType;
116 } else {
117 key |= kIdentity_MatrixType;
118 }
119 key <<= kTransformKeyBits * t;
120 SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap
121 totalKey |= key;
122 }
123 return totalKey;
124 }
125
126 EffectKey GrGLEffectArray::GenTextureKey(const GrDrawEffect& drawEffect, const G rGLCaps& caps) {
127 EffectKey key = 0;
128 int numTextures = (*drawEffect.effect())->numTextures();
129 for (int t = 0; t < numTextures; ++t) {
130 const GrTextureAccess& access = (*drawEffect.effect())->textureAccess(t) ;
131 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getText ure()->config());
132 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.s wizzleMask())) {
133 key |= 1 << t;
134 }
135 }
136 return key;
137 }
138
139 void GrGLEffectArray::initSamplers(const GrGLUniformManager& uniformManager, int * texUnitIdx) {
140 int numEffects = fGLEffects.count();
141 SkASSERT(numEffects == fSamplers.count());
142 for (int e = 0; e < numEffects; ++e) {
143 SkTArray<Sampler, true>& samplers = fSamplers[e];
144 int numSamplers = samplers.count();
145 for (int s = 0; s < numSamplers; ++s) {
146 SkASSERT(samplers[s].fUniform.isValid());
147 uniformManager.setSampler(samplers[s].fUniform, *texUnitIdx);
148 samplers[s].fTextureUnit = (*texUnitIdx)++;
149 }
150 }
151 }
152
153 void GrGLEffectArray::setData(GrGpuGL* gpu,
154 const GrGLUniformManager& uniformManager,
155 const GrEffectStage* effectStages[]) {
156 int numEffects = fGLEffects.count();
157 SkASSERT(numEffects == fTransforms.count());
158 SkASSERT(numEffects == fSamplers.count());
159 for (int e = 0; e < numEffects; ++e) {
160 GrDrawEffect drawEffect(*effectStages[e], fHasExplicitLocalCoords);
161 fGLEffects[e]->setData(uniformManager, drawEffect);
162 this->setTransformData(uniformManager, drawEffect, e);
163 this->bindTextures(gpu, *drawEffect.effect(), e);
164 }
165 }
166
167 void GrGLEffectArray::setTransformData(const GrGLUniformManager& uniformManager,
168 const GrDrawEffect& drawEffect,
169 int effectIdx) {
170 SkTArray<Transform, true>& transforms = fTransforms[effectIdx];
171 int numTransforms = transforms.count();
172 SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms());
173 for (int t = 0; t < numTransforms; ++t) {
174 const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTr ansform(t);
175 const SkMatrix& matrix = coordTransform.getMatrix();
176 const SkMatrix& coordChangeMatrix = kLocal_GrCoordSet == coordTransform. sourceCoords() ?
177 drawEffect.getCoordChangeMatrix( ) :
178 SkMatrix::I();
179 SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transform s[t].fType));
180 switch (transforms[t].fType) {
181 case kVoid_GrSLType:
182 SkASSERT(matrix.isIdentity());
183 SkASSERT(coordChangeMatrix.isIdentity());
184 SkASSERT(!coordTransform.reverseY());
185 return;
186 case kVec2f_GrSLType: {
187 SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordC hangeMatrix.getType()));
188 SkASSERT(!coordTransform.reverseY());
189 SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[S kMatrix::kMTransX];
190 SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[S kMatrix::kMTransY];
191 if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx ||
192 transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) {
193 uniformManager.set2f(transforms[t].fHandle, tx, ty);
194 transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx);
195 transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty);
196 }
197 break;
198 }
199 case kMat33f_GrSLType: {
200 SkMatrix combined;
201 combined.setConcat(matrix, coordChangeMatrix);
202 if (coordTransform.reverseY()) {
203 // combined.postScale(1,-1);
204 // combined.postTranslate(0,1);
205 combined.set(SkMatrix::kMSkewY,
206 combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkew Y]);
207 combined.set(SkMatrix::kMScaleY,
208 combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScal eY]);
209 combined.set(SkMatrix::kMTransY,
210 combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTran sY]);
211 }
212 if (!transforms[t].fCurrentValue.cheapEqualTo(combined)) {
213 uniformManager.setSkMatrix(transforms[t].fHandle, combined);
214 transforms[t].fCurrentValue = combined;
215 }
216 break;
217 }
218 default:
219 GrCrash("Unexpected uniform type.");
220 }
221 }
222 }
223
224 void GrGLEffectArray::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, int effectIdx) {
225 const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx];
226 int numSamplers = samplers.count();
227 SkASSERT(numSamplers == effect->numTextures());
228 for (int s = 0; s < numSamplers; ++s) {
229 SkASSERT(samplers[s].fTextureUnit >= 0);
230 const GrTextureAccess& textureAccess = effect->textureAccess(s);
231 gpu->bindTexture(samplers[s].fTextureUnit,
232 textureAccess.getParams(),
233 static_cast<GrGLTexture*>(textureAccess.getTexture()));
234 }
235 }
236
237 ////////////////////////////////////////////////////////////////////////////////
238
239 GrGLEffectArrayBuilder::GrGLEffectArrayBuilder(GrGLShaderBuilder* builder, int r eserveCount)
240 : fBuilder(builder) {
241 GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder ();
242 SkASSERT(NULL != vertexBuilder);
243 fEffectArray.reset(SkNEW_ARGS(GrGLEffectArray,
244 (reserveCount, vertexBuilder->hasExplicitLocal Coords())));
245 }
246
247 void GrGLEffectArrayBuilder::emitEffect(const GrEffectStage& stage,
248 EffectKey key,
249 const char* outColor,
250 const char* inColor,
251 int stageIndex) {
252 GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder ();
253 SkASSERT(NULL != vertexBuilder);
254 SkASSERT(NULL != fEffectArray.get());
255
256 GrDrawEffect drawEffect(stage, fEffectArray->fHasExplicitLocalCoords);
257 const GrEffectRef& effect = *stage.getEffect();
258 SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
259 SkSTArray<4, TextureSampler> samplers(effect->numTextures());
260
261 this->emitAttributes(stage);
262 this->emitTransforms(effect, key, &coords);
263 this->emitSamplers(effect, &samplers);
264
265 GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
266 *fEffectArray->fGLEffects.append() = glEffect;
267
268 // Enclose custom code in a block to avoid namespace conflicts
269 SkString openBrace;
270 openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
271 vertexBuilder->vsCodeAppend(openBrace.c_str());
272 fBuilder->fsCodeAppend(openBrace.c_str());
273
274 glEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, sam plers);
275
276 vertexBuilder->vsCodeAppend("\t}\n");
277 fBuilder->fsCodeAppend("\t}\n");
278 }
279
280 void GrGLEffectArrayBuilder::emitAttributes(const GrEffectStage& stage) {
281 GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder ();
282 SkASSERT(NULL != vertexBuilder);
283
284 int numAttributes = stage.getVertexAttribIndexCount();
285 const int* attributeIndices = stage.getVertexAttribIndices();
286 for (int a = 0; a < numAttributes; ++a) {
287 // TODO: Make addAttribute mangle the name.
288 SkString attributeName("aAttr");
289 attributeName.appendS32(attributeIndices[a]);
290 vertexBuilder->addEffectAttribute(attributeIndices[a],
291 (*stage.getEffect())->vertexAttribType (a),
292 attributeName);
293 }
294 }
295
296 void GrGLEffectArrayBuilder::emitTransforms(const GrEffectRef& effect,
297 EffectKey effectKey,
298 TransformedCoordsArray* outCoords) {
299 GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder ();
300 SkASSERT(NULL != vertexBuilder);
301
302 typedef GrGLEffectArray::Transform Transform;
303 SkTArray<Transform, true>& transforms = fEffectArray->fTransforms.push_back( );
304 EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey);
305 int numTransforms = effect->numTransforms();
306 transforms.push_back_n(numTransforms);
307 for (int t = 0; t < numTransforms; t++) {
308 EffectKey key = (totalKey >> (kTransformKeyBits * t)) & kTransformKeyMas k;
309 GrSLType varyingType = kVoid_GrSLType;
310 const char* uniName;
311 switch (key & kMatrixTypeKeyMask) {
312 case kIdentity_MatrixType:
313 transforms[t].fType = kVoid_GrSLType;
314 uniName = NULL;
315 varyingType = kVec2f_GrSLType;
316 break;
317 case kTrans_MatrixType:
318 transforms[t].fType = kVec2f_GrSLType;
319 uniName = "StageTranslate";
320 varyingType = kVec2f_GrSLType;
321 break;
322 case kNoPersp_MatrixType:
323 transforms[t].fType = kMat33f_GrSLType;
324 uniName = "StageMatrix";
325 varyingType = kVec2f_GrSLType;
326 break;
327 case kGeneral_MatrixType:
328 transforms[t].fType = kMat33f_GrSLType;
329 uniName = "StageMatrix";
330 varyingType = kVec3f_GrSLType;
331 break;
332 default:
333 GrCrash("Unexpected key.");
334 }
335 SkString suffixedUniName;
336 if (kVoid_GrSLType != transforms[t].fType) {
337 if (0 != t) {
338 suffixedUniName.append(uniName);
339 suffixedUniName.appendf("_%i", t);
340 uniName = suffixedUniName.c_str();
341 }
342 transforms[t].fHandle = fBuilder->addUniform(GrGLShaderBuilder::kVer tex_Visibility,
343 transforms[t].fType,
344 uniName,
345 &uniName);
346 }
347
348 const char* varyingName = "MatrixCoord";
349 SkString suffixedVaryingName;
350 if (0 != t) {
351 suffixedVaryingName.append(varyingName);
352 suffixedVaryingName.appendf("_%i", t);
353 varyingName = suffixedVaryingName.c_str();
354 }
355 const char* vsVaryingName;
356 const char* fsVaryingName;
357 vertexBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsV aryingName);
358
359 const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ?
360 vertexBuilder->positionAttribute() :
361 vertexBuilder->localCoordsAttribute();
362 // varying = matrix * coords (logically)
363 switch (transforms[t].fType) {
364 case kVoid_GrSLType:
365 SkASSERT(kVec2f_GrSLType == varyingType);
366 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coor ds.c_str());
367 break;
368 case kVec2f_GrSLType:
369 SkASSERT(kVec2f_GrSLType == varyingType);
370 vertexBuilder->vsCodeAppendf("\t%s = %s + %s;\n",
371 vsVaryingName, uniName, coords.c_st r());
372 break;
373 case kMat33f_GrSLType: {
374 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == va ryingType);
375 if (kVec2f_GrSLType == varyingType) {
376 vertexBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\ n",
377 vsVaryingName, uniName, coords. c_str());
378 } else {
379 vertexBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
380 vsVaryingName, uniName, coords. c_str());
381 }
382 break;
383 }
384 default:
385 GrCrash("Unexpected uniform type.");
386 }
387 SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
388 (fsVaryingName, varyingType, vsVaryingName));
389 }
390 }
391
392 void GrGLEffectArrayBuilder::emitSamplers(const GrEffectRef& effect,
393 TextureSamplerArray* outSamplers) {
394 typedef GrGLEffectArray::Sampler Sampler;
395 SkTArray<Sampler, true>& samplers = fEffectArray->fSamplers.push_back();
396 int numTextures = effect->numTextures();
397 samplers.push_back_n(numTextures);
398 SkString name;
399 for (int t = 0; t < numTextures; ++t) {
400 name.printf("Sampler%d", t);
401 samplers[t].fUniform = fBuilder->addUniform(GrGLShaderBuilder::kFragment _Visibility,
402 kSampler2D_GrSLType,
403 name.c_str());
404 SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler,
405 (samplers[t].fUniform, effect->textureAccess(t))) ;
406 }
407 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698