/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrGLEffectMatrix.h"
#include "GrDrawEffect.h"
#include "GrTexture.h"

GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix,
                                               const GrDrawEffect& drawEffect,
                                               CoordsType coordsType,
                                               const GrTexture* texture) {
    EffectKey key = 0;
    SkMatrix::TypeMask type0 = effectMatrix.getType();
    SkMatrix::TypeMask type1;
    if (GrEffect::kLocal_CoordsType == coordsType) {
        type1 = drawEffect.getCoordChangeMatrix().getType();
    } else {
        if (drawEffect.programHasExplicitLocalCoords()) {
            // We only make the key indicate that device coords are referenced when the local coords
            // are not actually determined by positions.
            key |= kPositionCoords_Flag;
        }
        type1 = SkMatrix::kIdentity_Mask;
    }

    int combinedTypes = type0 | type1;

    bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture->origin();

    if (SkMatrix::kPerspective_Mask & combinedTypes) {
        key |= kGeneral_MatrixType;
    } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes) || reverseY) {
        key |= kNoPersp_MatrixType;
    } else if (SkMatrix::kTranslate_Mask & combinedTypes) {
        key |= kTrans_MatrixType;
    } else {
        key |= kIdentity_MatrixType;
    }
    return key;
}

GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
                                    EffectKey key,
                                    SkString* fsCoordName,
                                    SkString* vsCoordName,
                                    const char* suffix) {
    GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
    SkASSERT(NULL != vertexBuilder);

    GrSLType varyingType = kVoid_GrSLType;
    const char* uniName;
    key &= kKeyMask;
    switch (key & kMatrixTypeKeyMask) {
        case kIdentity_MatrixType:
            fUniType = kVoid_GrSLType;
            uniName = NULL;
            varyingType = kVec2f_GrSLType;
            break;
        case kTrans_MatrixType:
            fUniType = kVec2f_GrSLType;
            uniName = "StageTranslate";
            varyingType = kVec2f_GrSLType;
            break;
        case kNoPersp_MatrixType:
            fUniType = kMat33f_GrSLType;
            uniName = "StageMatrix";
            varyingType = kVec2f_GrSLType;
            break;
        case kGeneral_MatrixType:
            fUniType = kMat33f_GrSLType;
            uniName = "StageMatrix";
            varyingType = kVec3f_GrSLType;
            break;
        default:
            GrCrash("Unexpected key.");
    }
    SkString suffixedUniName;
    if (kVoid_GrSLType != fUniType) {
        if (NULL != suffix) {
            suffixedUniName.append(uniName);
            suffixedUniName.append(suffix);
            uniName = suffixedUniName.c_str();
        }
        fUni = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
                                   fUniType,
                                   uniName,
                                   &uniName);
    }

    const char* varyingName = "MatrixCoord";
    SkString suffixedVaryingName;
    if (NULL != suffix) {
        suffixedVaryingName.append(varyingName);
        suffixedVaryingName.append(suffix);
        varyingName = suffixedVaryingName.c_str();
    }
    const char* vsVaryingName;
    const char* fsVaryingName;
    vertexBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);

    const GrGLShaderVar* coords;
    switch (fCoordsType) {
        case GrEffect::kLocal_CoordsType:
            SkASSERT(!(kPositionCoords_Flag & key));
            coords = &vertexBuilder->localCoordsAttribute();
            break;
        case GrEffect::kPosition_CoordsType:
            SkASSERT((kPositionCoords_Flag & key) || !vertexBuilder->hasExplicitLocalCoords());
            coords = &vertexBuilder->positionAttribute();
            break;
        default:
            coords = NULL; // prevents warning
            GrCrash("Unexpected coords type.");
    }
    // varying = matrix * coords (logically)
    switch (fUniType) {
        case kVoid_GrSLType:
            SkASSERT(kVec2f_GrSLType == varyingType);
            vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords->c_str());
            break;
        case kVec2f_GrSLType:
            SkASSERT(kVec2f_GrSLType == varyingType);
            vertexBuilder->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) {
                vertexBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
                                             vsVaryingName, uniName, coords->c_str());
            } else {
                vertexBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
                                             vsVaryingName, uniName, coords->c_str());
            }
            break;
        }
        default:
            GrCrash("Unexpected uniform type.");
    }
    if (NULL != vsCoordName) {
        *vsCoordName = vsVaryingName;
    }
    if (NULL != fsCoordName) {
        *fsCoordName = fsVaryingName;
    }
    return varyingType;
}

/**
    * This is similar to emitCode except that it performs perspective division in the FS if the
    * texture coordinates have a w coordinate. The fsCoordName always refers to a vec2f.
    */
void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
                                              EffectKey key,
                                              SkString* fsCoordName,
                                              SkString* vsVaryingName,
                                              GrSLType* vsVaryingType,
                                              const char* suffix) {
    SkString fsVaryingName;

    GrSLType varyingType = this->emitCode(builder,
                                          key,
                                          &fsVaryingName,
                                          vsVaryingName,
                                          suffix);
    if (kVec3f_GrSLType == varyingType) {

        const char* coordName = "coords2D";
        SkString suffixedCoordName;
        if (NULL != suffix) {
            suffixedCoordName.append(coordName);
            suffixedCoordName.append(suffix);
            coordName = suffixedCoordName.c_str();
        }
        builder->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;",
                               coordName, fsVaryingName.c_str(), fsVaryingName.c_str());
        if (NULL != fsCoordName) {
            *fsCoordName = coordName;
        }
    } else if(NULL != fsCoordName) {
        *fsCoordName = fsVaryingName;
    }
    if (NULL != vsVaryingType) {
        *vsVaryingType = varyingType;
    }
}

void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager,
                               const SkMatrix& matrix,
                               const GrDrawEffect& drawEffect,
                               const GrTexture* texture) {
    SkASSERT(fUni.isValid() != (kVoid_GrSLType == fUniType));
    const SkMatrix& coordChangeMatrix = GrEffect::kLocal_CoordsType == fCoordsType ?
                                            drawEffect.getCoordChangeMatrix() :
                                            SkMatrix::I();
    switch (fUniType) {
        case kVoid_GrSLType:
            SkASSERT(matrix.isIdentity());
            SkASSERT(coordChangeMatrix.isIdentity());
            SkASSERT(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
            return;
        case kVec2f_GrSLType: {
            SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
            SkASSERT(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
            SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX];
            SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY];
            if (fPrevMatrix.get(SkMatrix::kMTransX) != tx ||
                fPrevMatrix.get(SkMatrix::kMTransY) != ty) {
                uniformManager.set2f(fUni, tx, ty);
                fPrevMatrix.set(SkMatrix::kMTransX, tx);
                fPrevMatrix.set(SkMatrix::kMTransY, ty);
            }
            break;
        }
        case kMat33f_GrSLType: {
            SkMatrix combined;
            combined.setConcat(matrix, coordChangeMatrix);
            if (NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin()) {
                // 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 (!fPrevMatrix.cheapEqualTo(combined)) {
                uniformManager.setSkMatrix(fUni, combined);
                fPrevMatrix = combined;
            }
            break;
        }
        default:
            GrCrash("Unexpected uniform type.");
    }
}
