/*
    Copyright 2010 Google Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */


#include "GrGLConfig.h"

#include "GrGpuGLFixed.h"
#include "GrGpuVertex.h"

#define SKIP_CACHE_CHECK    true

struct GrGpuMatrix {
    GrGLfloat    fMat[16];

    void reset() {
        Gr_bzero(fMat, sizeof(fMat));
        fMat[0] = fMat[5] = fMat[10] = fMat[15] = GR_Scalar1;
    }

    void set(const GrMatrix& m) {
        Gr_bzero(fMat, sizeof(fMat));
        fMat[0]  = GrScalarToFloat(m[GrMatrix::kMScaleX]);
        fMat[4]  = GrScalarToFloat(m[GrMatrix::kMSkewX]);
        fMat[12] = GrScalarToFloat(m[GrMatrix::kMTransX]);

        fMat[1]  = GrScalarToFloat(m[GrMatrix::kMSkewY]);
        fMat[5]  = GrScalarToFloat(m[GrMatrix::kMScaleY]);
        fMat[13] = GrScalarToFloat(m[GrMatrix::kMTransY]);

        fMat[3]  = GrScalarToFloat(m[GrMatrix::kMPersp0]);
        fMat[7]  = GrScalarToFloat(m[GrMatrix::kMPersp1]);
        fMat[15] = GrScalarToFloat(m[GrMatrix::kMPersp2]);

        fMat[10] = 1.f;    // z-scale
    }
};

// these must match the order in the corresponding enum in GrGpu.h
static const GrGLenum gMatrixMode2Enum[] = {
    GR_GL_MODELVIEW, GR_GL_TEXTURE
};

///////////////////////////////////////////////////////////////////////////////

GrGpuGLFixed::GrGpuGLFixed() {
    f4X4DownsampleFilterSupport = false;
    fDualSourceBlendingSupport = false;
}

GrGpuGLFixed::~GrGpuGLFixed() {
}

void GrGpuGLFixed::resetContext() {
    INHERITED::resetContext();

    GR_GL(Disable(GR_GL_TEXTURE_2D));

    for (int s = 0; s < kNumStages; ++s) {
        setTextureUnit(s);
        GR_GL(EnableClientState(GR_GL_VERTEX_ARRAY));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_TEXTURE_ENV_MODE, GR_GL_COMBINE));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_COMBINE_RGB,   GR_GL_MODULATE));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_SRC0_RGB,      GR_GL_TEXTURE0+s));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_SRC1_RGB,      GR_GL_PREVIOUS));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_OPERAND1_RGB,  GR_GL_SRC_COLOR));

        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_COMBINE_ALPHA, GR_GL_MODULATE));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_SRC0_ALPHA, GR_GL_TEXTURE0+s));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_OPERAND0_ALPHA, GR_GL_SRC_ALPHA));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_SRC1_ALPHA, GR_GL_PREVIOUS));
        GR_GL(TexEnvi(GR_GL_TEXTURE_ENV, GR_GL_OPERAND1_ALPHA, GR_GL_SRC_ALPHA));

        // color oprand0 changes between GL_SRC_COLR and GL_SRC_ALPHA depending
        // upon whether we have a (premultiplied) RGBA texture or just an ALPHA
        // texture, e.g.:
        //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,  GL_SRC_COLOR);
        fHWRGBOperand0[s] = (TextureEnvRGBOperands) -1;
    }

    fHWGeometryState.fVertexLayout = 0;
    fHWGeometryState.fVertexOffset  = ~0;
    GR_GL(EnableClientState(GR_GL_VERTEX_ARRAY));
    GR_GL(DisableClientState(GR_GL_TEXTURE_COORD_ARRAY));
    GR_GL(ShadeModel(GR_GL_FLAT));
    GR_GL(DisableClientState(GR_GL_COLOR_ARRAY));

    GR_GL(PointSize(1.f));

    GrGLClearErr();
    fTextVerts = false;

    fBaseVertex = 0xffffffff;
}


void GrGpuGLFixed::flushProjectionMatrix() {
    float mat[16];
    Gr_bzero(mat, sizeof(mat));

    GrAssert(NULL != fCurrDrawState.fRenderTarget);

    mat[0] = 2.f / fCurrDrawState.fRenderTarget->width();
    mat[5] = -2.f / fCurrDrawState.fRenderTarget->height();
    mat[10] = -1.f;
    mat[15] = 1;

    mat[12] = -1.f;
    mat[13] = 1.f;

    GR_GL(MatrixMode(GR_GL_PROJECTION));
    GR_GL(LoadMatrixf(mat));
}

bool GrGpuGLFixed::flushGraphicsState(GrPrimitiveType type) {

    bool usingTextures[kNumStages];

    for (int s = 0; s < kNumStages; ++s) {
        usingTextures[s] = this->isStageEnabled(s);
        if (usingTextures[s] && fCurrDrawState.fSamplerStates[s].isGradient()) {
            unimpl("Fixed pipe doesn't support radial/sweep gradients");
            return false;
        }
    }

    if (GR_GL_SUPPORT_ES1) {
        if (BlendCoeffReferencesConstant(fCurrDrawState.fSrcBlend) ||
            BlendCoeffReferencesConstant(fCurrDrawState.fDstBlend)) {
            unimpl("ES1 doesn't support blend constant");
            return false;
        }
    }

    if (!flushGLStateCommon(type)) {
        return false;
    }

    this->flushBlend(type, fCurrDrawState.fSrcBlend, fCurrDrawState.fDstBlend);

    if (fDirtyFlags.fRenderTargetChanged) {
        flushProjectionMatrix();
    }

    for (int s = 0; s < kNumStages; ++s) {
        bool wasUsingTexture = StageWillBeUsed(s, fHWGeometryState.fVertexLayout, fHWDrawState);
        if (usingTextures[s] != wasUsingTexture) {
            setTextureUnit(s);
            if (usingTextures[s]) {
                GR_GL(Enable(GR_GL_TEXTURE_2D));
            } else {
                GR_GL(Disable(GR_GL_TEXTURE_2D));
            }
        }
    }

    uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
    uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
                              kColor_VertexLayoutBit);

    if (vertColor != prevVertColor) {
        if (vertColor) {
            GR_GL(ShadeModel(GR_GL_SMOOTH));
            // invalidate the immediate mode color
            fHWDrawState.fColor = GrColor_ILLEGAL;
        } else {
            GR_GL(ShadeModel(GR_GL_FLAT));
        }
    }


    if (!vertColor && fHWDrawState.fColor != fCurrDrawState.fColor) {
        GR_GL(Color4ub(GrColorUnpackR(fCurrDrawState.fColor),
                       GrColorUnpackG(fCurrDrawState.fColor),
                       GrColorUnpackB(fCurrDrawState.fColor),
                       GrColorUnpackA(fCurrDrawState.fColor)));
        fHWDrawState.fColor = fCurrDrawState.fColor;
    }

    // set texture environment, decide whether we are modulating by RGB or A.
    for (int s = 0; s < kNumStages; ++s) {
        if (usingTextures[s]) {
            GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTextures[s];
            if (NULL != texture) {
                TextureEnvRGBOperands nextRGBOperand0 =
                    (GrPixelConfigIsAlphaOnly(texture->config())) ?
                        kAlpha_TextureEnvRGBOperand :
                        kColor_TextureEnvRGBOperand;
                if (fHWRGBOperand0[s] != nextRGBOperand0) {
                    setTextureUnit(s);
                    GR_GL(TexEnvi(GR_GL_TEXTURE_ENV,
                                  GR_GL_OPERAND0_RGB,
                                  (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ?
                                    GR_GL_SRC_ALPHA :
                                    GR_GL_SRC_COLOR));
                    fHWRGBOperand0[s] = nextRGBOperand0;
                }

                if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
                    (fHWDrawState.fSamplerStates[s].getMatrix() !=
                     getSamplerMatrix(s))) {

                    GrMatrix texMat = getSamplerMatrix(s);
                    AdjustTextureMatrix(texture,
                                        GrSamplerState::kNormal_SampleMode,
                                        &texMat);
                    GrGpuMatrix glm;
                    glm.set(texMat);
                    setTextureUnit(s);
                    GR_GL(MatrixMode(GR_GL_TEXTURE));
                    GR_GL(LoadMatrixf(glm.fMat));
                    recordHWSamplerMatrix(s, getSamplerMatrix(s));
                }
            } else {
                GrAssert(!"Rendering with texture vert flag set but no bound texture");
                return false;
            }
        }
    }

    if (fHWDrawState.fViewMatrix != fCurrDrawState.fViewMatrix) {
        GrGpuMatrix glm;
        glm.set(fCurrDrawState.fViewMatrix);
        GR_GL(MatrixMode(GR_GL_MODELVIEW));
        GR_GL(LoadMatrixf(glm.fMat));
        fHWDrawState.fViewMatrix =
        fCurrDrawState.fViewMatrix;
    }
    resetDirtyFlags();
    return true;
}

void GrGpuGLFixed::setupGeometry(int* startVertex,
                                 int* startIndex,
                                 int vertexCount,
                                 int indexCount) {

    int newColorOffset;
    int newTexCoordOffsets[kNumStages];

    GrGLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
                                                      newTexCoordOffsets,
                                                      &newColorOffset);
    int oldColorOffset;
    int oldTexCoordOffsets[kNumStages];
    GrGLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
                                                      oldTexCoordOffsets,
                                                      &oldColorOffset);

    bool indexed = NULL != startIndex;

    int extraVertexOffset;
    int extraIndexOffset;
    setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);

    GrGLenum scalarType;
    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
        scalarType = GrGLTextType;
    } else {
        scalarType = GrGLType;
    }

    size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
    *startVertex = 0;
    if (indexed) {
        *startIndex += extraIndexOffset;
    }

    // all the Pointers must be set if any of these are true
    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
                             vertexOffset != fHWGeometryState.fVertexOffset ||
                             newStride != oldStride;

    // position and tex coord offsets change if above conditions are true
    // or the type changed based on text vs nontext type coords.
    bool posAndTexChange = allOffsetsChange ||
                           ((GrGLTextType != GrGLType) &&
                                (kTextFormat_VertexLayoutBit &
                                  (fHWGeometryState.fVertexLayout ^
                                   fGeometrySrc.fVertexLayout)));

    if (posAndTexChange) {
        GR_GL(VertexPointer(2, scalarType, newStride, (GrGLvoid*)vertexOffset));
        fHWGeometryState.fVertexOffset = vertexOffset;
    }

    for (int s = 0; s < kNumStages; ++s) {
        // need to enable array if tex coord offset is 0
        // (using positions as coords)
        if (newTexCoordOffsets[s] >= 0) {
            GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[s]);
            if (oldTexCoordOffsets[s] < 0) {
                GR_GL(ClientActiveTexture(GR_GL_TEXTURE0+s));
                GR_GL(EnableClientState(GR_GL_TEXTURE_COORD_ARRAY));
                GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
            } else if (posAndTexChange ||
                       newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
                GR_GL(ClientActiveTexture(GR_GL_TEXTURE0+s));
                GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
            }
        } else if (oldTexCoordOffsets[s] >= 0) {
            GR_GL(ClientActiveTexture(GR_GL_TEXTURE0+s));
            GR_GL(DisableClientState(GR_GL_TEXTURE_COORD_ARRAY));
        }
    }

    if (newColorOffset > 0) {
        GrGLvoid* colorOffset = (GrGLvoid*)(vertexOffset + newColorOffset);
        if (oldColorOffset <= 0) {
            GR_GL(EnableClientState(GR_GL_COLOR_ARRAY));
            GR_GL(ColorPointer(4, GR_GL_UNSIGNED_BYTE, newStride, colorOffset));
        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
            GR_GL(ColorPointer(4, GR_GL_UNSIGNED_BYTE, newStride, colorOffset));
        }
    } else if (oldColorOffset > 0) {
        GR_GL(DisableClientState(GR_GL_COLOR_ARRAY));
    }

    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
    fHWGeometryState.fArrayPtrsDirty = false;
}
