| 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);
|
| +}
|
|
|