| Index: src/gpu/gl/GrGLProgramEffects.cpp
|
| diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp
|
| index d5826abe3042e9e1eb9057996d763483161a3044..b24d157642ef8a2a9af51afc4b8a0e1b80a2e9b3 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,6 +68,74 @@ 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) {
|
| @@ -179,23 +246,14 @@ void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& unifor
|
| 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());
|
| + SkASSERT(get_transform_matrix(drawEffect, t).isIdentity());
|
| 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];
|
| + 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);
|
| @@ -205,21 +263,10 @@ void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& unifor
|
| 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;
|
| + 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;
|
| }
|
| @@ -229,6 +276,62 @@ void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& unifor
|
| }
|
| }
|
|
|
| +void GrGLTexGenProgramEffects::setData(GrGpuGL* gpu,
|
| + const GrGLUniformManager& uniformManager,
|
| + const GrEffectStage* effectStages[]) {
|
| + int numEffects = fGLEffects.count();
|
| + SkASSERT(numEffects == fTransformKeys.count());
|
| + SkASSERT(numEffects == fSamplers.count());
|
| + int texCoordIdx = fFirstTexCoordIdx;
|
| + SkASSERT(texCoordIdx >= 0);
|
| + for (int e = 0; e < numEffects; ++e) {
|
| + GrDrawEffect drawEffect(*effectStages[e], false);
|
| + fGLEffects[e]->setData(uniformManager, drawEffect);
|
| + this->setTexGenState(gpu, drawEffect, &texCoordIdx, e);
|
| + this->bindTextures(gpu, *drawEffect.effect(), e);
|
| + }
|
| + SkASSERT(fNumTexCoordSets == texCoordIdx - fFirstTexCoordIdx);
|
| +}
|
| +
|
| +void GrGLTexGenProgramEffects::setTexGenState(GrGpuGL* gpu,
|
| + const GrDrawEffect& drawEffect,
|
| + int* texCoordIdx,
|
| + int effectIdx) {
|
| + EffectKey transformKey = fTransformKeys[effectIdx];
|
| + int numTransforms = (*drawEffect.effect())->numTransforms();
|
| + for (int t = 0; t < numTransforms; ++t) {
|
| + switch (get_matrix_type(transformKey, t)) {
|
| + case kIdentity_MatrixType: {
|
| + SkASSERT(get_transform_matrix(drawEffect, t).isIdentity());
|
| + GrGLfloat identity[] = {1, 0, 0,
|
| + 0, 1, 0};
|
| + gpu->enableTexGen((*texCoordIdx)++, 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((*texCoordIdx)++, GrGpuGL::kST_TexGenComponents, translate);
|
| + break;
|
| + }
|
| + case kNoPersp_MatrixType: {
|
| + const SkMatrix& transform = get_transform_matrix(drawEffect, t);
|
| + gpu->enableTexGen((*texCoordIdx)++, GrGpuGL::kST_TexGenComponents, transform);
|
| + break;
|
| + }
|
| + case kGeneral_MatrixType: {
|
| + const SkMatrix& transform = get_transform_matrix(drawEffect, t);
|
| + gpu->enableTexGen((*texCoordIdx)++, GrGpuGL::kSTR_TexGenComponents, transform);
|
| + break;
|
| + }
|
| + default:
|
| + GrCrash("Unexpected matrixs type.");
|
| + }
|
| + }
|
| +}
|
| +
|
| void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, int effectIdx) {
|
| const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx];
|
| int numSamplers = samplers.count();
|
| @@ -305,14 +408,13 @@ void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect,
|
| TransformedCoordsArray* outCoords) {
|
| typedef GrGLVertexProgramEffects::Transform Transform;
|
| SkTArray<Transform, true>& transforms = fProgramEffects->fTransforms.push_back();
|
| - EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey);
|
| + EffectKey transformKey = 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(transformKey, t)) {
|
| case kIdentity_MatrixType:
|
| transforms[t].fType = kVoid_GrSLType;
|
| uniName = NULL;
|
| @@ -360,7 +462,7 @@ void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect,
|
| const char* fsVaryingName;
|
| fBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
|
|
|
| - const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ?
|
| + const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(transformKey, t) ?
|
| fBuilder->positionAttribute() :
|
| fBuilder->localCoordsAttribute();
|
| // varying = matrix * coords (logically)
|
| @@ -388,7 +490,63 @@ void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect,
|
| default:
|
| GrCrash("Unexpected uniform type.");
|
| }
|
| - SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (fsVaryingName, varyingType));
|
| + SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
|
| + (SkString(fsVaryingName), varyingType));
|
| + }
|
| +}
|
| +
|
| +GrGLTexGenProgramEffectsBuilder::GrGLTexGenProgramEffectsBuilder(
|
| + GrGLFragmentOnlyShaderBuilder* builder,
|
| + int reserveCount)
|
| + : fBuilder(builder)
|
| + , fProgramEffects(SkNEW_ARGS(GrGLTexGenProgramEffects, (reserveCount))) {
|
| +}
|
| +
|
| +void GrGLTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
|
| + EffectKey key,
|
| + const char* outColor,
|
| + const char* inColor,
|
| + int stageIndex) {
|
| + SkASSERT(NULL != fProgramEffects.get());
|
| +
|
| + 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(effect, key, &coords);
|
| + INHERITED::emitSamplers(fBuilder, fProgramEffects.get(), effect, &samplers);
|
| +
|
| + GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
|
| + fProgramEffects->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->fsCodeAppend(openBrace.c_str());
|
| +
|
| + SkASSERT(!glEffect->isVertexEffect());
|
| + glEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers);
|
| +
|
| + fBuilder->fsCodeAppend("\t}\n");
|
| +}
|
| +
|
| +void GrGLTexGenProgramEffectsBuilder::setupTexGen(const GrEffectRef& effect,
|
| + EffectKey effectKey,
|
| + TransformedCoordsArray* outCoords) {
|
| + int numTransforms = effect->numTransforms();
|
| + SkDEBUGCODE(fProgramEffects->fNumTexCoordSets += numTransforms;)
|
| + int texCoordIdx = fBuilder->addTexCoordSets(numTransforms);
|
| + EffectKey transformKey = GrBackendEffectFactory::GetTransformKey(effectKey);
|
| + fProgramEffects->fTransformKeys.push_back(transformKey);
|
| + SkString name;
|
| + for (int t = 0; t < numTransforms; ++t) {
|
| + GrSLType type = kGeneral_MatrixType == get_matrix_type(transformKey, t) ?
|
| + kVec3f_GrSLType :
|
| + kVec2f_GrSLType;
|
| + name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIdx++);
|
| + SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (name, type));
|
| }
|
| }
|
|
|
|
|