/*
    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"

#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP

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

#define SKIP_CACHE_CHECK    true

struct GrGpuMatrix {
    GrScalar    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]  = m[GrMatrix::kScaleX];
        fMat[4]  = m[GrMatrix::kSkewX];
        fMat[12] = m[GrMatrix::kTransX];
        
        fMat[1]  = m[GrMatrix::kSkewY];
        fMat[5]  = m[GrMatrix::kScaleY];
        fMat[13] = m[GrMatrix::kTransY];
        
        fMat[3]  = m[GrMatrix::kPersp0];
        fMat[7]  = m[GrMatrix::kPersp1];
        fMat[15] = m[GrMatrix::kPersp2];
        
        fMat[10] = GR_Scalar1;    // z-scale
    }
};

// these must match the order in the corresponding enum in GrGpu.h
static const GLenum gMatrixMode2Enum[] = {
    GL_MODELVIEW, GL_TEXTURE
};

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

GrGpuGLFixed::GrGpuGLFixed() {
    resetContextHelper();
}

GrGpuGLFixed::~GrGpuGLFixed() {
}

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

void GrGpuGLFixed::resetContextHelper() {
    GR_GL(Disable(GL_TEXTURE_2D));

    for (int s = 0; s < kNumStages; ++s) {
        setTextureUnit(s);
        GR_GL(EnableClientState(GL_VERTEX_ARRAY));    
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,   GL_MODULATE));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,      GL_TEXTURE0+s));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,      GL_PREVIOUS));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,  GL_SRC_COLOR));

        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0+s));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS));
        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, 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.fPositionPtr  = (void*) ~0;
    GR_GL(EnableClientState(GL_VERTEX_ARRAY));
    GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
    GR_GL(ShadeModel(GL_FLAT));
    GR_GL(DisableClientState(GL_COLOR_ARRAY));
    
    GrGLClearErr();
    fTextVerts = false;

    fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal    
    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(GL_PROJECTION));
    GR_GL(LoadMatrixf(mat));
}

bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
    
    bool usingTextures[kNumStages];
    
    for (int s = 0; s < kNumStages; ++s) {
        usingTextures[s] = VertexUsesStage(s, fGeometrySrc.fVertexLayout);

        if (usingTextures[s] && fCurrDrawState.fSamplerStates[s].isGradient()) {
            unimpl("Fixed pipe doesn't support radial/sweep gradients");
            return false;
        }
    }
    
    flushGLStateCommon(type);

    if (fRenderTargetChanged) {    
        flushProjectionMatrix();
        fRenderTargetChanged = false;
    }
    
    for (int s = 0; s < kNumStages; ++s) {
        bool wasUsingTexture = VertexUsesStage(s, fHWGeometryState.fVertexLayout);
        if (usingTextures[s] != wasUsingTexture) {
            setTextureUnit(s);
            if (usingTextures[s]) {
                GR_GL(Enable(GL_TEXTURE_2D));
            } else {
                GR_GL(Disable(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(GL_SMOOTH));
            // invalidate the immediate mode color
            fHWDrawState.fColor = GrColor_ILLEGAL;
        } else {
            GR_GL(ShadeModel(GL_FLAT));
        }
    }

    if (kPoints_PrimitiveType == type &&
        fHWDrawState.fPointSize != fCurrDrawState.fPointSize) {
        GR_GL(PointSize(fCurrDrawState.fPointSize));
        fHWDrawState.fPointSize = fCurrDrawState.fPointSize;
    }
    
    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 = 
                    (texture->config() == GrTexture::kAlpha_8_PixelConfig) ? 
                        kAlpha_TextureEnvRGBOperand : 
                        kColor_TextureEnvRGBOperand;
                if (fHWRGBOperand0[s] != nextRGBOperand0) {
                    setTextureUnit(s);
                    GR_GL(TexEnvi(GL_TEXTURE_ENV, 
                                  GL_OPERAND0_RGB,
                                  (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ? 
                                    GL_SRC_ALPHA : 
                                    GL_SRC_COLOR));
                    fHWRGBOperand0[s] = nextRGBOperand0;
                }
                
                if (fHWTextureOrientation != texture->orientation() ||
                    fHWDrawState.fTextureMatrices[s] != 
                    fCurrDrawState.fTextureMatrices[s]) {
                    GrGpuMatrix glm;
                    if (GrGLTexture::kBottomUp_Orientation == 
                        texture->orientation()) {
                        GrMatrix m(
                            GR_Scalar1, 0, 0,
                            0, -GR_Scalar1, GR_Scalar1,
                            0, 0, GrMatrix::I()[8]
                        );
                        m.preConcat(fCurrDrawState.fTextureMatrices[s]);
                        glm.set(m);
                    } else {
                        glm.set(fCurrDrawState.fTextureMatrices[s]);
                    }
                    setTextureUnit(s);
                    GR_GL(MatrixMode(GL_TEXTURE));
                    GR_GL(LoadMatrixf(glm.fMat));
                    fHWDrawState.fTextureMatrices[s] = 
                                            fCurrDrawState.fTextureMatrices[s];
                    fHWTextureOrientation = texture->orientation();
                }
            } 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(GL_MODELVIEW));
        GR_GL(LoadMatrixf(glm.fMat));
        fHWDrawState.fViewMatrix = 
        fCurrDrawState.fViewMatrix;
    }
    return true;
}

void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
                                 uint32_t startIndex,
                                 uint32_t vertexCount,
                                 uint32_t indexCount) {
    
    int newColorOffset;
    int newTexCoordOffsets[kNumStages];
    
    GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
                                                    newTexCoordOffsets, 
                                                    &newColorOffset);
    int oldColorOffset;
    int oldTexCoordOffsets[kNumStages];
    GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
                                                    oldTexCoordOffsets, 
                                                    &oldColorOffset);
    
    const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
    
    if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
        GrAssert(NULL != fGeometrySrc.fVertexBuffer);
        GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
        if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
            GrGLVertexBuffer* buf = 
                            (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
            GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
            fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
        }
    } else { 
        if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
            posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray + 
                             (intptr_t)posPtr);
        } else {
            GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
            posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);            
        }
        if (NULL != fHWGeometryState.fVertexBuffer) {
            GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
            fHWGeometryState.fVertexBuffer = NULL;
        }
    }
    
    if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
        GrAssert(NULL != fGeometrySrc.fIndexBuffer);
        GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
        if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
            GrGLIndexBuffer* buf = 
            (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
            GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
            fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
        }
    } else if (NULL != fHWGeometryState.fIndexBuffer) {
        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
        fHWGeometryState.fIndexBuffer = NULL;
    }
    
    GLenum scalarType;
    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
        scalarType = GrGLTextType;
    } else {
        scalarType = GrGLType;
    }
    
    bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
    bool scalarChange = 
        (GrGLTextType != GrGLType) &&
        (kTextFormat_VertexLayoutBit &
         (fHWGeometryState.fVertexLayout ^ fGeometrySrc.fVertexLayout));
    bool strideChange = newStride != oldStride;
    bool posChange = baseChange || scalarChange || strideChange;
    
    if (posChange) {
        GR_GL(VertexPointer(2, scalarType, newStride, posPtr));
        fHWGeometryState.fPositionPtr = posPtr;
    }
    
    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) {
            GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[s];
            if (oldTexCoordOffsets[s] < 0) {
                GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
                GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
            }
            if (posChange || newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
                GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
                GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordPtr));
            }
        } else if (oldTexCoordOffsets[s] >= 0) {
            GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
            GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
        }
    }
    
    if (newColorOffset > 0) {
        GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
        if (oldColorOffset <= 0) {
            GR_GL(EnableClientState(GL_COLOR_ARRAY));
        }
        if (posChange || newColorOffset != oldColorOffset) {
            GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorPtr));
        }
    } else if (oldColorOffset > 0) {
        GR_GL(DisableClientState(GL_COLOR_ARRAY));
    }
    
    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
}

#endif

