Index: src/gpu/gl/GrGLProgramEffects.cpp |
diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp |
index d5826abe3042e9e1eb9057996d763483161a3044..17c666a015b87369c631ec65f027dcc33b66baa0 100644 |
--- a/src/gpu/gl/GrGLProgramEffects.cpp |
+++ b/src/gpu/gl/GrGLProgramEffects.cpp |
@@ -37,7 +37,6 @@ enum { |
kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, |
kPositionCoords_Flag = (1 << kMatrixTypeKeyBits), |
kTransformKeyBits = kMatrixTypeKeyBits + 1, |
- kTransformKeyMask = (1 << kTransformKeyBits) - 1, |
}; |
namespace { |
@@ -69,8 +68,78 @@ inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, |
return false; |
} |
+/** |
+ * Retrieves the matrix type from transformKey for the transform at transformIdx. |
+ */ |
+MatrixType get_matrix_type(EffectKey transformKey, int transformIdx) { |
+ return static_cast<MatrixType>( |
+ (transformKey >> (kTransformKeyBits * transformIdx)) & kMatrixTypeKeyMask); |
+} |
+ |
+/** |
+ * Retrieves the source coords from transformKey for the transform at transformIdx. It may not be |
+ * the same coordinate set as the original GrCoordTransform if the position and local coords are |
+ * identical for this program. |
+ */ |
+GrCoordSet get_source_coords(EffectKey transformKey, int transformIdx) { |
+ return (transformKey >> (kTransformKeyBits * transformIdx)) & kPositionCoords_Flag ? |
+ kPosition_GrCoordSet : |
+ kLocal_GrCoordSet; |
+} |
+ |
+/** |
+ * Retrieves the final translation that a transform needs to apply to its source coords (and |
+ * verifies that a translation is all it needs). |
+ */ |
+void get_transform_translation(const GrDrawEffect& drawEffect, |
+ int transformIdx, |
+ GrGLfloat* tx, |
+ GrGLfloat* ty) { |
+ const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx); |
+ SkASSERT(!coordTransform.reverseY()); |
+ const SkMatrix& matrix = coordTransform.getMatrix(); |
+ if (kLocal_GrCoordSet == coordTransform.sourceCoords() && |
+ !drawEffect.programHasExplicitLocalCoords()) { |
+ const SkMatrix& coordChangeMatrix = drawEffect.getCoordChangeMatrix(); |
+ SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType())); |
+ *tx = SkScalarToFloat(matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX]); |
+ *ty = SkScalarToFloat(matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY]); |
+ } else { |
+ SkASSERT(SkMatrix::kTranslate_Mask == matrix.getType()); |
+ *tx = SkScalarToFloat(matrix[SkMatrix::kMTransX]); |
+ *ty = SkScalarToFloat(matrix[SkMatrix::kMTransY]); |
+ } |
} |
+/** |
+ * Retrieves the final matrix that a transform needs to apply to its source coords. |
+ */ |
+SkMatrix get_transform_matrix(const GrDrawEffect& drawEffect, int transformIdx) { |
+ const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx); |
+ SkMatrix combined; |
+ if (kLocal_GrCoordSet == coordTransform.sourceCoords() && |
+ !drawEffect.programHasExplicitLocalCoords()) { |
+ combined.setConcat(coordTransform.getMatrix(), drawEffect.getCoordChangeMatrix()); |
+ } else { |
+ combined = coordTransform.getMatrix(); |
+ } |
+ if (coordTransform.reverseY()) { |
+ // combined.postScale(1,-1); |
+ // combined.postTranslate(0,1); |
+ combined.set(SkMatrix::kMSkewY, |
+ combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); |
+ combined.set(SkMatrix::kMScaleY, |
+ combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); |
+ combined.set(SkMatrix::kMTransY, |
+ combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); |
+ } |
+ return combined; |
+} |
+ |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
EffectKey GrGLProgramEffects::GenAttribKey(const GrDrawEffect& drawEffect) { |
EffectKey key = 0; |
int numAttributes = drawEffect.getVertexAttribIndexCount(); |
@@ -144,6 +213,23 @@ GrGLProgramEffects::~GrGLProgramEffects() { |
} |
} |
+void GrGLProgramEffects::emitSamplers(GrGLShaderBuilder* builder, |
+ const GrEffectRef& effect, |
+ TextureSamplerArray* outSamplers) { |
+ SkTArray<Sampler, true>& samplers = fSamplers.push_back(); |
+ int numTextures = effect->numTextures(); |
+ samplers.push_back_n(numTextures); |
+ SkString name; |
+ for (int t = 0; t < numTextures; ++t) { |
+ name.printf("Sampler%d", t); |
+ samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
+ kSampler2D_GrSLType, |
+ name.c_str()); |
+ SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler, |
+ (samplers[t].fUniform, effect->textureAccess(t))); |
+ } |
+} |
+ |
void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager, int* texUnitIdx) { |
int numEffects = fGLEffects.count(); |
SkASSERT(numEffects == fSamplers.count()); |
@@ -158,77 +244,6 @@ void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager, |
} |
} |
-void GrGLVertexProgramEffects::setData(GrGpuGL* gpu, |
- const GrGLUniformManager& uniformManager, |
- const GrEffectStage* effectStages[]) { |
- int numEffects = fGLEffects.count(); |
- SkASSERT(numEffects == fTransforms.count()); |
- SkASSERT(numEffects == fSamplers.count()); |
- for (int e = 0; e < numEffects; ++e) { |
- GrDrawEffect drawEffect(*effectStages[e], fHasExplicitLocalCoords); |
- fGLEffects[e]->setData(uniformManager, drawEffect); |
- this->setTransformData(uniformManager, drawEffect, e); |
- this->bindTextures(gpu, *drawEffect.effect(), e); |
- } |
-} |
- |
-void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& uniformManager, |
- const GrDrawEffect& drawEffect, |
- int effectIdx) { |
- SkTArray<Transform, true>& transforms = fTransforms[effectIdx]; |
- int numTransforms = transforms.count(); |
- SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms()); |
- for (int t = 0; t < numTransforms; ++t) { |
- const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(t); |
- const SkMatrix& matrix = coordTransform.getMatrix(); |
- const SkMatrix& coordChangeMatrix = kLocal_GrCoordSet == coordTransform.sourceCoords() ? |
- drawEffect.getCoordChangeMatrix() : |
- SkMatrix::I(); |
- SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transforms[t].fType)); |
- switch (transforms[t].fType) { |
- case kVoid_GrSLType: |
- SkASSERT(matrix.isIdentity()); |
- SkASSERT(coordChangeMatrix.isIdentity()); |
- SkASSERT(!coordTransform.reverseY()); |
- return; |
- case kVec2f_GrSLType: { |
- SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType())); |
- SkASSERT(!coordTransform.reverseY()); |
- SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX]; |
- SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY]; |
- if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx || |
- transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) { |
- uniformManager.set2f(transforms[t].fHandle, tx, ty); |
- transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx); |
- transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty); |
- } |
- break; |
- } |
- case kMat33f_GrSLType: { |
- SkMatrix combined; |
- combined.setConcat(matrix, coordChangeMatrix); |
- if (coordTransform.reverseY()) { |
- // combined.postScale(1,-1); |
- // combined.postTranslate(0,1); |
- combined.set(SkMatrix::kMSkewY, |
- combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); |
- combined.set(SkMatrix::kMScaleY, |
- combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); |
- combined.set(SkMatrix::kMTransY, |
- combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); |
- } |
- if (!transforms[t].fCurrentValue.cheapEqualTo(combined)) { |
- uniformManager.setSkMatrix(transforms[t].fHandle, combined); |
- transforms[t].fCurrentValue = combined; |
- } |
- break; |
- } |
- default: |
- GrCrash("Unexpected uniform type."); |
- } |
- } |
-} |
- |
void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, int effectIdx) { |
const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx]; |
int numSamplers = samplers.count(); |
@@ -244,75 +259,67 @@ void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, i |
//////////////////////////////////////////////////////////////////////////////// |
-GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder, |
- int reserveCount) |
- : fBuilder(builder) |
- , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects, |
- (reserveCount, fBuilder->hasExplicitLocalCoords()))) { |
-} |
- |
-void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, |
- EffectKey key, |
- const char* outColor, |
- const char* inColor, |
- int stageIndex) { |
- SkASSERT(NULL != fProgramEffects.get()); |
- |
- GrDrawEffect drawEffect(stage, fProgramEffects->fHasExplicitLocalCoords); |
+void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder, |
+ const GrEffectStage& stage, |
+ EffectKey key, |
+ const char* outColor, |
+ const char* inColor, |
+ int stageIndex) { |
+ GrDrawEffect drawEffect(stage, fHasExplicitLocalCoords); |
const GrEffectRef& effect = *stage.getEffect(); |
SkSTArray<2, TransformedCoords> coords(effect->numTransforms()); |
SkSTArray<4, TextureSampler> samplers(effect->numTextures()); |
- this->emitAttributes(stage); |
- this->emitTransforms(effect, key, &coords); |
- INHERITED::emitSamplers(fBuilder, fProgramEffects.get(), effect, &samplers); |
+ this->emitAttributes(builder, stage); |
+ this->emitTransforms(builder, effect, key, &coords); |
+ this->emitSamplers(builder, effect, &samplers); |
GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect); |
- fProgramEffects->fGLEffects.push_back(glEffect); |
+ fGLEffects.push_back(glEffect); |
// Enclose custom code in a block to avoid namespace conflicts |
SkString openBrace; |
openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name()); |
- fBuilder->vsCodeAppend(openBrace.c_str()); |
- fBuilder->fsCodeAppend(openBrace.c_str()); |
+ builder->vsCodeAppend(openBrace.c_str()); |
+ builder->fsCodeAppend(openBrace.c_str()); |
if (glEffect->isVertexEffect()) { |
GrGLVertexEffect* vertexEffect = static_cast<GrGLVertexEffect*>(glEffect); |
- vertexEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers); |
+ vertexEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers); |
} else { |
- glEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers); |
+ glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers); |
} |
- fBuilder->vsCodeAppend("\t}\n"); |
- fBuilder->fsCodeAppend("\t}\n"); |
+ builder->vsCodeAppend("\t}\n"); |
+ builder->fsCodeAppend("\t}\n"); |
} |
-void GrGLVertexProgramEffectsBuilder::emitAttributes(const GrEffectStage& stage) { |
+void GrGLVertexProgramEffects::emitAttributes(GrGLFullShaderBuilder* builder, |
+ const GrEffectStage& stage) { |
int numAttributes = stage.getVertexAttribIndexCount(); |
const int* attributeIndices = stage.getVertexAttribIndices(); |
for (int a = 0; a < numAttributes; ++a) { |
// TODO: Make addAttribute mangle the name. |
SkString attributeName("aAttr"); |
attributeName.appendS32(attributeIndices[a]); |
- fBuilder->addEffectAttribute(attributeIndices[a], |
- (*stage.getEffect())->vertexAttribType(a), |
- attributeName); |
+ builder->addEffectAttribute(attributeIndices[a], |
+ (*stage.getEffect())->vertexAttribType(a), |
+ attributeName); |
} |
} |
-void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect, |
- EffectKey effectKey, |
- TransformedCoordsArray* outCoords) { |
- typedef GrGLVertexProgramEffects::Transform Transform; |
- SkTArray<Transform, true>& transforms = fProgramEffects->fTransforms.push_back(); |
+void GrGLVertexProgramEffects::emitTransforms(GrGLFullShaderBuilder* builder, |
+ const GrEffectRef& effect, |
+ EffectKey effectKey, |
+ TransformedCoordsArray* outCoords) { |
+ SkTArray<Transform, true>& transforms = fTransforms.push_back(); |
EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey); |
int numTransforms = effect->numTransforms(); |
transforms.push_back_n(numTransforms); |
for (int t = 0; t < numTransforms; t++) { |
- EffectKey key = (totalKey >> (kTransformKeyBits * t)) & kTransformKeyMask; |
GrSLType varyingType = kVoid_GrSLType; |
const char* uniName; |
- switch (key & kMatrixTypeKeyMask) { |
+ switch (get_matrix_type(totalKey, t)) { |
case kIdentity_MatrixType: |
transforms[t].fType = kVoid_GrSLType; |
uniName = NULL; |
@@ -343,10 +350,10 @@ void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect, |
suffixedUniName.appendf("_%i", t); |
uniName = suffixedUniName.c_str(); |
} |
- transforms[t].fHandle = fBuilder->addUniform(GrGLShaderBuilder::kVertex_Visibility, |
- transforms[t].fType, |
- uniName, |
- &uniName); |
+ transforms[t].fHandle = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility, |
+ transforms[t].fType, |
+ uniName, |
+ &uniName); |
} |
const char* varyingName = "MatrixCoord"; |
@@ -358,55 +365,222 @@ void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect, |
} |
const char* vsVaryingName; |
const char* fsVaryingName; |
- fBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName); |
+ builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName); |
- const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ? |
- fBuilder->positionAttribute() : |
- fBuilder->localCoordsAttribute(); |
+ const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(totalKey, t) ? |
+ builder->positionAttribute() : |
+ builder->localCoordsAttribute(); |
// varying = matrix * coords (logically) |
switch (transforms[t].fType) { |
case kVoid_GrSLType: |
SkASSERT(kVec2f_GrSLType == varyingType); |
- fBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str()); |
+ builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str()); |
break; |
case kVec2f_GrSLType: |
SkASSERT(kVec2f_GrSLType == varyingType); |
- fBuilder->vsCodeAppendf("\t%s = %s + %s;\n", |
- vsVaryingName, uniName, coords.c_str()); |
+ builder->vsCodeAppendf("\t%s = %s + %s;\n", |
+ vsVaryingName, uniName, coords.c_str()); |
break; |
case kMat33f_GrSLType: { |
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); |
if (kVec2f_GrSLType == varyingType) { |
- fBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", |
- vsVaryingName, uniName, coords.c_str()); |
+ builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", |
+ vsVaryingName, uniName, coords.c_str()); |
} else { |
- fBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", |
- vsVaryingName, uniName, coords.c_str()); |
+ builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", |
+ vsVaryingName, uniName, coords.c_str()); |
} |
break; |
} |
default: |
GrCrash("Unexpected uniform type."); |
} |
- SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (fsVaryingName, varyingType)); |
+ SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, |
+ (SkString(fsVaryingName), varyingType)); |
} |
} |
-void GrGLProgramEffectsBuilder::emitSamplers(GrGLShaderBuilder* builder, |
- GrGLProgramEffects* programEffects, |
- const GrEffectRef& effect, |
- TextureSamplerArray* outSamplers) { |
- typedef GrGLProgramEffects::Sampler Sampler; |
- SkTArray<Sampler, true>& samplers = programEffects->fSamplers.push_back(); |
- int numTextures = effect->numTextures(); |
- samplers.push_back_n(numTextures); |
+void GrGLVertexProgramEffects::setData(GrGpuGL* gpu, |
+ const GrGLUniformManager& uniformManager, |
+ const GrEffectStage* effectStages[]) { |
+ int numEffects = fGLEffects.count(); |
+ SkASSERT(numEffects == fTransforms.count()); |
+ SkASSERT(numEffects == fSamplers.count()); |
+ for (int e = 0; e < numEffects; ++e) { |
+ GrDrawEffect drawEffect(*effectStages[e], fHasExplicitLocalCoords); |
+ fGLEffects[e]->setData(uniformManager, drawEffect); |
+ this->setTransformData(uniformManager, drawEffect, e); |
+ this->bindTextures(gpu, *drawEffect.effect(), e); |
+ } |
+} |
+ |
+void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& uniformManager, |
+ const GrDrawEffect& drawEffect, |
+ int effectIdx) { |
+ SkTArray<Transform, true>& transforms = fTransforms[effectIdx]; |
+ int numTransforms = transforms.count(); |
+ SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms()); |
+ for (int t = 0; t < numTransforms; ++t) { |
+ SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transforms[t].fType)); |
+ switch (transforms[t].fType) { |
+ case kVoid_GrSLType: |
+ SkASSERT(get_transform_matrix(drawEffect, t).isIdentity()); |
+ return; |
+ case kVec2f_GrSLType: { |
+ GrGLfloat tx, ty; |
+ get_transform_translation(drawEffect, t, &tx, &ty); |
+ if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx || |
+ transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) { |
+ uniformManager.set2f(transforms[t].fHandle, tx, ty); |
+ transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx); |
+ transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty); |
+ } |
+ break; |
+ } |
+ case kMat33f_GrSLType: { |
+ const SkMatrix& matrix = get_transform_matrix(drawEffect, t); |
+ if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) { |
+ uniformManager.setSkMatrix(transforms[t].fHandle, matrix); |
+ transforms[t].fCurrentValue = matrix; |
+ } |
+ break; |
+ } |
+ default: |
+ GrCrash("Unexpected uniform type."); |
+ } |
+ } |
+} |
+ |
+GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder, |
+ int reserveCount) |
+ : fBuilder(builder) |
+ , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects, |
+ (reserveCount, fBuilder->hasExplicitLocalCoords()))) { |
+} |
+ |
+void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, |
+ GrGLProgramEffects::EffectKey key, |
+ const char* outColor, |
+ const char* inColor, |
+ int stageIndex) { |
+ SkASSERT(NULL != fProgramEffects.get()); |
+ fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+void GrGLTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* builder, |
+ const GrEffectStage& stage, |
+ EffectKey key, |
+ const char* outColor, |
+ const char* inColor, |
+ int stageIndex) { |
+ GrDrawEffect drawEffect(stage, false); |
+ const GrEffectRef& effect = *stage.getEffect(); |
+ SkSTArray<2, TransformedCoords> coords(effect->numTransforms()); |
+ SkSTArray<4, TextureSampler> samplers(effect->numTextures()); |
+ |
+ SkASSERT(0 == stage.getVertexAttribIndexCount()); |
+ this->setupTexGen(builder, effect, key, &coords); |
+ this->emitSamplers(builder, effect, &samplers); |
+ |
+ GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect); |
+ fGLEffects.push_back(glEffect); |
+ |
+ // Enclose custom code in a block to avoid namespace conflicts |
+ SkString openBrace; |
+ openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name()); |
+ builder->fsCodeAppend(openBrace.c_str()); |
+ |
+ SkASSERT(!glEffect->isVertexEffect()); |
+ glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers); |
+ |
+ builder->fsCodeAppend("\t}\n"); |
+} |
+ |
+void GrGLTexGenProgramEffects::setupTexGen(GrGLFragmentOnlyShaderBuilder* builder, |
+ const GrEffectRef& effect, |
+ EffectKey effectKey, |
+ TransformedCoordsArray* outCoords) { |
+ int numTransforms = effect->numTransforms(); |
+ EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey); |
+ int texCoordIndex = builder->addTexCoordSets(numTransforms); |
+ SkNEW_APPEND_TO_TARRAY(&fTransforms, Transforms, (totalKey, texCoordIndex)); |
SkString name; |
- for (int t = 0; t < numTextures; ++t) { |
- name.printf("Sampler%d", t); |
- samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
- kSampler2D_GrSLType, |
- name.c_str()); |
- SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler, |
- (samplers[t].fUniform, effect->textureAccess(t))); |
+ for (int t = 0; t < numTransforms; ++t) { |
+ GrSLType type = kGeneral_MatrixType == get_matrix_type(totalKey, t) ? |
+ kVec3f_GrSLType : |
+ kVec2f_GrSLType; |
+ name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++); |
+ SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (name, type)); |
+ } |
+} |
+ |
+void GrGLTexGenProgramEffects::setData(GrGpuGL* gpu, |
+ const GrGLUniformManager& uniformManager, |
+ const GrEffectStage* effectStages[]) { |
+ int numEffects = fGLEffects.count(); |
+ SkASSERT(numEffects == fTransforms.count()); |
+ SkASSERT(numEffects == fSamplers.count()); |
+ for (int e = 0; e < numEffects; ++e) { |
+ GrDrawEffect drawEffect(*effectStages[e], false); |
+ fGLEffects[e]->setData(uniformManager, drawEffect); |
+ this->setTexGenState(gpu, drawEffect, e); |
+ this->bindTextures(gpu, *drawEffect.effect(), e); |
} |
} |
+ |
+void GrGLTexGenProgramEffects::setTexGenState(GrGpuGL* gpu, |
+ const GrDrawEffect& drawEffect, |
+ int effectIdx) { |
+ EffectKey totalKey = fTransforms[effectIdx].fTransformKey; |
+ int texCoordIndex = fTransforms[effectIdx].fTexCoordIndex; |
+ int numTransforms = (*drawEffect.effect())->numTransforms(); |
+ for (int t = 0; t < numTransforms; ++t) { |
+ switch (get_matrix_type(totalKey, t)) { |
+ case kIdentity_MatrixType: { |
+ SkASSERT(get_transform_matrix(drawEffect, t).isIdentity()); |
+ GrGLfloat identity[] = {1, 0, 0, |
+ 0, 1, 0}; |
+ gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, identity); |
+ break; |
+ } |
+ case kTrans_MatrixType: { |
+ GrGLfloat tx, ty; |
+ get_transform_translation(drawEffect, t, &tx, &ty); |
+ GrGLfloat translate[] = {1, 0, tx, |
+ 0, 1, ty}; |
+ gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, translate); |
+ break; |
+ } |
+ case kNoPersp_MatrixType: { |
+ const SkMatrix& transform = get_transform_matrix(drawEffect, t); |
+ gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, transform); |
+ break; |
+ } |
+ case kGeneral_MatrixType: { |
+ const SkMatrix& transform = get_transform_matrix(drawEffect, t); |
+ gpu->enableTexGen(texCoordIndex++, GrGpuGL::kSTR_TexGenComponents, transform); |
+ break; |
+ } |
+ default: |
+ GrCrash("Unexpected matrixs type."); |
+ } |
+ } |
+} |
+ |
+GrGLTexGenProgramEffectsBuilder::GrGLTexGenProgramEffectsBuilder( |
+ GrGLFragmentOnlyShaderBuilder* builder, |
+ int reserveCount) |
+ : fBuilder(builder) |
+ , fProgramEffects(SkNEW_ARGS(GrGLTexGenProgramEffects, (reserveCount))) { |
+} |
+ |
+void GrGLTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, |
+ GrGLProgramEffects::EffectKey key, |
+ const char* outColor, |
+ const char* inColor, |
+ int stageIndex) { |
+ SkASSERT(NULL != fProgramEffects.get()); |
+ fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex); |
+} |