/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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 "GLEncoder.h"
#include "glUtils.h"
#include <log/log.h>
#include <assert.h>
#include <vector>

using gfxstream::guest::IOStream;

#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif

static GLubyte *gVendorString= (GLubyte *) "Android";
static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0";
static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0";
static GLubyte *gExtensionsString= (GLubyte *) "GL_OES_EGL_image_external ";

#define SET_ERROR_IF(condition,err) if((condition)) {                            \
        ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
        ctx->setError(err);                                    \
        return;                                                  \
    }


#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {                \
        ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
        ctx->setError(err);                                    \
        return ret;                                              \
    }

GLenum GLEncoder::s_glGetError(void * self)
{
    GLEncoder *ctx = (GLEncoder *)self;
    GLenum err = ctx->getError();
    if(err != GL_NO_ERROR) {
        ctx->setError(GL_NO_ERROR);
        return err;
    }

    return ctx->m_glGetError_enc(self);

}

GLint * GLEncoder::getCompressedTextureFormats()
{
    if (m_compressedTextureFormats == NULL) {
        this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
                            &m_num_compressedTextureFormats);
        if (m_num_compressedTextureFormats > 0) {
            // get number of texture formats;
            m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
            this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
        }
    }
    return m_compressedTextureFormats;
}

void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    GLClientState* state = ctx->m_state;

    switch (param) {
    case GL_COMPRESSED_TEXTURE_FORMATS: {
        GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
        if (ctx->m_num_compressedTextureFormats > 0 &&
                compressedTextureFormats != NULL) {
            memcpy(ptr, compressedTextureFormats,
                   ctx->m_num_compressedTextureFormats * sizeof(GLint));
        }
        break;
    }

    case GL_MAX_TEXTURE_UNITS:
        ctx->m_glGetIntegerv_enc(self, param, ptr);
        *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
        break;

    case GL_TEXTURE_BINDING_2D:
        *ptr = state->getBoundTexture(GL_TEXTURE_2D);
        break;

    case GL_TEXTURE_BINDING_EXTERNAL_OES:
        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
        break;

    case GL_RESET_NOTIFICATION_STRATEGY_EXT:
        // BUG: 121414786
        *ptr = GL_LOSE_CONTEXT_ON_RESET_EXT;
        break;

    default:
        if (!state->getClientStateParameter<GLint>(param,ptr)) {
            ctx->m_glGetIntegerv_enc(self, param, ptr);
        }
        break;
    }
}

void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    GLClientState* state = ctx->m_state;

    switch (param) {
    case GL_COMPRESSED_TEXTURE_FORMATS: {
        GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
        if (ctx->m_num_compressedTextureFormats > 0 &&
                compressedTextureFormats != NULL) {
            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
                ptr[i] = (GLfloat) compressedTextureFormats[i];
            }
        }
        break;
    }

    case GL_MAX_TEXTURE_UNITS:
        ctx->m_glGetFloatv_enc(self, param, ptr);
        *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
        break;

    case GL_TEXTURE_BINDING_2D:
        *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
        break;

    case GL_TEXTURE_BINDING_EXTERNAL_OES:
        *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
        break;

    default:
        if (!state->getClientStateParameter<GLfloat>(param,ptr)) {
            ctx->m_glGetFloatv_enc(self, param, ptr);
        }
        break;
    }
}

void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    GLClientState* state = ctx->m_state;

    switch (param) {
    case GL_COMPRESSED_TEXTURE_FORMATS: {
        GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
        if (ctx->m_num_compressedTextureFormats > 0 &&
                compressedTextureFormats != NULL) {
            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
                ptr[i] =  compressedTextureFormats[i] << 16;
            }
        }
        break;
    }

    case GL_MAX_TEXTURE_UNITS:
        ctx->m_glGetFixedv_enc(self, param, ptr);
        *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16);
        break;

    case GL_TEXTURE_BINDING_2D:
        *ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16;
        break;

    case GL_TEXTURE_BINDING_EXTERNAL_OES:
        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16;
        break;

    default:
        if (!state->getClientStateParameter<GLfixed>(param,ptr)) {
            ctx->m_glGetFixedv_enc(self, param, ptr);
        }
        break;
    }
}

void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    GLClientState* state = ctx->m_state;

    switch (param) {
    case GL_COMPRESSED_TEXTURE_FORMATS: {
        GLint* compressedTextureFormats = ctx->getCompressedTextureFormats();
        if (ctx->m_num_compressedTextureFormats > 0 &&
                compressedTextureFormats != NULL) {
            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
                ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
            }
        }
        break;
    }

    case GL_TEXTURE_BINDING_2D:
        *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
        break;

    case GL_TEXTURE_BINDING_EXTERNAL_OES:
        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
                ? GL_TRUE : GL_FALSE;
        break;

    default:
        if (!state->getClientStateParameter<GLboolean>(param,ptr)) {
            ctx->m_glGetBooleanv_enc(self, param, ptr);
        }
        break;
    }
}

void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params)
{
    GLEncoder * ctx = (GLEncoder *) self;
    assert(ctx->m_state != NULL);
    ctx->m_state->getClientStatePointer(param,params);
}

void GLEncoder::s_glFlush(void *self)
{
    GLEncoder *ctx = (GLEncoder *)self;
    ctx->m_glFlush_enc(self);
    ctx->m_stream->flush();
}

const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name)
{
    (void)self;

    GLubyte *retval =  (GLubyte *) "";
    switch(name) {
    case GL_VENDOR:
        retval = gVendorString;
        break;
    case GL_RENDERER:
        retval = gRendererString;
        break;
    case GL_VERSION:
        retval = gVersionString;
        break;
    case GL_EXTENSIONS:
        retval = gExtensionsString;
        break;
    }
    return retval;
}

void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value)
{
    GLEncoder *ctx = (GLEncoder *)self;
    ctx->m_glPixelStorei_enc(ctx, param, value);
    ALOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei");
    ctx->m_state->setPixelStore(param, value);
}

void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    ctx->m_state->setVertexAttribState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data);
}

void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    ctx->m_state->setVertexAttribState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data);
}

void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    ctx->m_state->setVertexAttribState(GLClientState::COLOR_LOCATION, size, type, false, stride, data);
}

void GLEncoder::s_glPointSizePointerOES(void *self, GLenum type, GLsizei stride, const void *data)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    ctx->m_state->setVertexAttribState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data);
}

void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    ctx->m_state->setActiveTexture(texture - GL_TEXTURE0);
}

void GLEncoder::s_glTexCoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY);
    ctx->m_state->setVertexAttribState(loc, size, type, false, stride, data);
}

void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES);
    ctx->m_state->setVertexAttribState(loc, size, type, false, stride, data);
}

void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data)
{
    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES);
    ctx->m_state->setVertexAttribState(loc, size, type, false, stride, data);
}

void GLEncoder::s_glEnableClientState(void *self, GLenum state)
{
    GLEncoder *ctx = (GLEncoder *) self;
    assert(ctx->m_state != NULL);
    int loc = ctx->m_state->getLocation(state);
    ctx->m_state->enable(loc, 1);
}

void GLEncoder::s_glDisableClientState(void *self, GLenum state)
{
    GLEncoder *ctx = (GLEncoder *) self;
    assert(ctx->m_state != NULL);
    int loc = ctx->m_state->getLocation(state);
    ctx->m_state->enable(loc, 0);
}

GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap)
{
    GLEncoder *ctx = (GLEncoder *) self;
    assert(ctx->m_state != NULL);
    int loc = ctx->m_state->getLocation(cap);
    const GLClientState::VertexAttribState& state = ctx->m_state->getState(loc);
    return state.enabled;
}

void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
{
    GLEncoder *ctx = (GLEncoder *) self;
    assert(ctx->m_state != NULL);
    ctx->m_state->bindBuffer(target, id);
    // TODO set error state if needed;
    ctx->m_glBindBuffer_enc(self, target, id);
}

void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
{
    GLEncoder *ctx = (GLEncoder *) self;
    GLuint bufferId = ctx->m_state->getBuffer(target);
    SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
    SET_ERROR_IF(size<0, GL_INVALID_VALUE);

    ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
    ctx->m_glBufferData_enc(self, target, size, data, usage);
}

void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
{
    GLEncoder *ctx = (GLEncoder *) self;
    GLuint bufferId = ctx->m_state->getBuffer(target);
    SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);

    GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
    SET_ERROR_IF(res, res);

    ctx->m_glBufferSubData_enc(self, target, offset, size, data);
}

void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
{
    GLEncoder *ctx = (GLEncoder *) self;
    SET_ERROR_IF(n<0, GL_INVALID_VALUE);
    for (int i=0; i<n; i++) {
        ctx->m_shared->deleteBufferData(buffers[i]);
        ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
    }
}

void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
{
    assert(m_state != NULL);
    GLenum prevActiveTexUnit = m_state->getActiveTextureUnit();
    for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
        bool enableDirty;
        const GLClientState::VertexAttribState& state = m_state->getStateAndEnableDirty(i, &enableDirty);

        // do not send disable state if state was already disabled
        if (!enableDirty && !state.enabled) continue;

        if ( i >= GLClientState::TEXCOORD0_LOCATION &&
            i <= GLClientState::TEXCOORD7_LOCATION ) {
            m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION);
        }

        if (state.enabled) {
            if (enableDirty)
                m_glEnableClientState_enc(this, state.glConst);

            unsigned int datalen = state.elementSize * count;
            int stride = state.stride;
            if (stride == 0) stride = state.elementSize;
            int firstIndex = stride * first;

            this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state.bufferObject);
            if (state.bufferObject == 0) {

                switch(i) {
                case GLClientState::VERTEX_LOCATION:
                    this->glVertexPointerData(this, state.size, state.type, state.stride,
                                              (unsigned char *)state.data + firstIndex, datalen);
                    break;
                case GLClientState::NORMAL_LOCATION:
                    this->glNormalPointerData(this, state.type, state.stride,
                                              (unsigned char *)state.data + firstIndex, datalen);
                    break;
                case GLClientState::COLOR_LOCATION:
                    this->glColorPointerData(this, state.size, state.type, state.stride,
                                             (unsigned char *)state.data + firstIndex, datalen);
                    break;
                case GLClientState::TEXCOORD0_LOCATION:
                case GLClientState::TEXCOORD1_LOCATION:
                case GLClientState::TEXCOORD2_LOCATION:
                case GLClientState::TEXCOORD3_LOCATION:
                case GLClientState::TEXCOORD4_LOCATION:
                case GLClientState::TEXCOORD5_LOCATION:
                case GLClientState::TEXCOORD6_LOCATION:
                case GLClientState::TEXCOORD7_LOCATION:
                    m_state->setActiveTextureUnit(i - GLClientState::TEXCOORD0_LOCATION + GL_TEXTURE0);
                    if (m_state->getPriorityEnabledTarget(GL_INVALID_ENUM) != GL_INVALID_ENUM) {
                        this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state.size, state.type, state.stride,
                                                (unsigned char *)state.data + firstIndex, datalen);
                    }
                    break;
                case GLClientState::POINTSIZE_LOCATION:
                    this->glPointSizePointerData(this, state.type, state.stride,
                                                 (unsigned char *) state.data + firstIndex, datalen);
                    break;
                case GLClientState::WEIGHT_LOCATION:
                    this->glWeightPointerData(this, state.size, state.type, state.stride,
                                              (unsigned char * ) state.data + firstIndex, datalen);
                    break;
                case GLClientState::MATRIXINDEX_LOCATION:
                    this->glMatrixIndexPointerData(this, state.size, state.type, state.stride,
                                                  (unsigned char *)state.data + firstIndex, datalen);
                    break;
                }
            } else {

                switch(i) {
                case GLClientState::VERTEX_LOCATION:
                    this->glVertexPointerOffset(this, state.size, state.type, state.stride,
                                                (uintptr_t)state.data + firstIndex);
                    break;
                case GLClientState::NORMAL_LOCATION:
                    this->glNormalPointerOffset(this, state.type, state.stride,
                                                (uintptr_t)state.data + firstIndex);
                    break;
                case GLClientState::POINTSIZE_LOCATION:
                    this->glPointSizePointerOffset(this, state.type, state.stride,
                                                   (uintptr_t)state.data + firstIndex);
                    break;
                case GLClientState::COLOR_LOCATION:
                    this->glColorPointerOffset(this, state.size, state.type, state.stride,
                                               (uintptr_t)state.data + firstIndex);
                    break;
                case GLClientState::TEXCOORD0_LOCATION:
                case GLClientState::TEXCOORD1_LOCATION:
                case GLClientState::TEXCOORD2_LOCATION:
                case GLClientState::TEXCOORD3_LOCATION:
                case GLClientState::TEXCOORD4_LOCATION:
                case GLClientState::TEXCOORD5_LOCATION:
                case GLClientState::TEXCOORD6_LOCATION:
                case GLClientState::TEXCOORD7_LOCATION:
                    this->glTexCoordPointerOffset(this, state.size, state.type, state.stride,
                                                  (uintptr_t)state.data + firstIndex);
                    break;
                case GLClientState::WEIGHT_LOCATION:
                    this->glWeightPointerOffset(this,state.size,state.type,state.stride,
                                                (uintptr_t)state.data+firstIndex);
                    break;
                case GLClientState::MATRIXINDEX_LOCATION:
                    this->glMatrixIndexPointerOffset(this,state.size,state.type,state.stride,
                                              (uintptr_t)state.data+firstIndex);
                    break;
                }
            }
            this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
        } else {
            this->m_glDisableClientState_enc(this, state.glConst);
        }
    }
    m_state->setActiveTextureUnit(prevActiveTexUnit);
}

void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
{
    GLEncoder *ctx = (GLEncoder *)self;

    bool has_arrays = false;
    for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
        const GLClientState::VertexAttribState& state = ctx->m_state->getState(i);
        if (state.enabled) {
            if (state.bufferObject || state.data) {
                has_arrays = true;
            } else {
                ALOGE("glDrawArrays: a vertex attribute array is enabled with no data bound\n");
                ctx->setError(GL_INVALID_OPERATION);
                return;
            }
        }
    }
    if (!has_arrays) {
        ALOGE("glDrawArrays: no data bound to the command - ignoring\n");
        return;
    }

    ctx->sendVertexData(first, count);
    ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count);
    ctx->m_stream->flush();
}

void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
{

    GLEncoder *ctx = (GLEncoder *)self;
    assert(ctx->m_state != NULL);
    SET_ERROR_IF(count<0, GL_INVALID_VALUE);

    bool has_immediate_arrays = false;
    bool has_indirect_arrays = false;

    for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
        const GLClientState::VertexAttribState& state = ctx->m_state->getState(i);
        if (state.enabled) {
            if (state.bufferObject != 0) {
                has_indirect_arrays = true;
            } else if (state.data) {
                has_immediate_arrays = true;
            } else {
                ALOGE("glDrawElements: a vertex attribute array is enabled with no data bound\n");
                ctx->setError(GL_INVALID_OPERATION);
                return;
            }
        }
    }

    if (!has_immediate_arrays && !has_indirect_arrays) {
        ALOGE("glDrawElements: no data bound to the command - ignoring\n");
        return;
    }

    bool adjustIndices = true;
    if (ctx->m_state->currentIndexVbo() != 0) {
        if (!has_immediate_arrays) {
            ctx->sendVertexData(0, count);
            ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
            ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices);
            ctx->m_stream->flush();
            adjustIndices = false;
        } else {
            BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
            ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
            indices = &buf->m_fixedBuffer[(GLintptr)indices];
        }
    }
    if (adjustIndices) {
        void *adjustedIndices = (void*)indices;
        int minIndex = 0, maxIndex = 0;

        switch(type) {
        case GL_BYTE:
        case GL_UNSIGNED_BYTE:
            GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
            if (minIndex != 0) {
                ctx->m_fixedBuffer.resize(glSizeof(type) * count);
                adjustedIndices = ctx->m_fixedBuffer.data();
                GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
                                                 (unsigned char *)adjustedIndices,
                                                 count, -minIndex);
            }
            break;
        case GL_SHORT:
        case GL_UNSIGNED_SHORT:
            GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
            if (minIndex != 0) {
                ctx->m_fixedBuffer.resize(glSizeof(type) * count);
                adjustedIndices = ctx->m_fixedBuffer.data();
                GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
                                                 (unsigned short *)adjustedIndices,
                                                 count, -minIndex);
            }
            break;
        case GL_INT:
        case GL_UNSIGNED_INT:
            GLUtils::minmax<unsigned int>((unsigned int *)indices, count, &minIndex, &maxIndex);
            if (minIndex != 0) {
                ctx->m_fixedBuffer.resize(glSizeof(type) * count);
                adjustedIndices = ctx->m_fixedBuffer.data();
                GLUtils::shiftIndices<unsigned int>((unsigned int *)indices,
                                                 (unsigned int *)adjustedIndices,
                                                 count, -minIndex);
            }
            break;
        default:
            ALOGE("unsupported index buffer type %d\n", type);
        }
        if (has_indirect_arrays || 1) {
            ctx->sendVertexData(minIndex, maxIndex - minIndex + 1);
            ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
                                      count * glSizeof(type));
            ctx->m_stream->flush();
            // XXX - OPTIMIZATION (see the other else branch) should be implemented
            if(!has_indirect_arrays) {
                //ALOGD("unoptimized drawelements !!!\n");
            }
        } else {
            // we are all direct arrays and immidate mode index array -
            // rebuild the arrays and the index array;
            ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
        }
    }
}

void GLEncoder::s_glActiveTexture(void* self, GLenum texture)
{
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;
    GLenum err;

    if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) {
        ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
        ctx->setError(err);
        return;
    }

    ctx->m_glActiveTexture_enc(ctx, texture);
}

void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
{
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;
    GLenum err;

    GLboolean firstUse;
    if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) {
        ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
        ctx->setError(err);
        return;
    }

    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
        ctx->m_glBindTexture_enc(ctx, target, texture);
        return;
    }

    GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);

    if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
        // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D
        ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
                GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
                GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
                GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        if (target != priorityTarget) {
            ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
                    state->getBoundTexture(GL_TEXTURE_2D));
        }
    }

    if (target == priorityTarget) {
        ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
    }
}

void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
{
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    state->deleteTextures(n, textures);
    ctx->m_glDeleteTextures_enc(ctx, n, textures);
}

void GLEncoder::s_glDisable(void* self, GLenum cap)
{
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
        GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
        state->disableTextureTarget(cap);
        GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);

        if (prevTarget != currTarget) {
            if (currTarget == GL_INVALID_ENUM) {
                ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D);
                currTarget = GL_TEXTURE_2D;
            }
            // maintain the invariant that when TEXTURE_EXTERNAL_OES is
            // disabled, the TEXTURE_2D binding is active, even if
            // TEXTURE_2D is also disabled.
            ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
                    state->getBoundTexture(currTarget));
        }

    } else {
        ctx->m_glDisable_enc(ctx, cap);
    }
}

void GLEncoder::s_glEnable(void* self, GLenum cap)
{
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
        GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
        state->enableTextureTarget(cap);
        GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);

        if (prevTarget != currTarget) {
            if (prevTarget == GL_INVALID_ENUM) {
                ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D);
            }
            if (currTarget == GL_TEXTURE_EXTERNAL_OES) {
                ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
                        state->getBoundTexture(currTarget));
            }
        }

    } else {
        ctx->m_glEnable_enc(ctx, cap);
    }
}

void GLEncoder::s_glGetTexParameterfv(void* self,
        GLenum target, GLenum pname, GLfloat* params)
{
    GLEncoder* ctx = (GLEncoder*)self;
    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
    }
}

void GLEncoder::s_glGetTexParameteriv(void* self,
        GLenum target, GLenum pname, GLint* params)
{
    GLEncoder* ctx = (GLEncoder*)self;

    switch (pname) {
    case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
        *params = 1;
        break;

    default:
        if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
            ctx->override2DTextureTarget(target);
            ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
            ctx->restore2DTextureTarget();
        } else {
            ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
        }
        break;
    }
}

void GLEncoder::s_glGetTexParameterxv(void* self,
        GLenum target, GLenum pname, GLfixed* params)
{
    GLEncoder* ctx = (GLEncoder*)self;

    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params);
    }
}

static bool isValidTextureExternalParam(GLenum pname, GLenum param)
{
    switch (pname) {
    case GL_TEXTURE_MIN_FILTER:
    case GL_TEXTURE_MAG_FILTER:
        return param == GL_NEAREST || param == GL_LINEAR;

    case GL_TEXTURE_WRAP_S:
    case GL_TEXTURE_WRAP_T:
        return param == GL_CLAMP_TO_EDGE;

    case GL_GENERATE_MIPMAP:
        return param == GL_FALSE;

    default:
        return true;
    }
}

void GLEncoder::s_glTexParameterf(void* self,
        GLenum target, GLenum pname, GLfloat param)
{
    GLEncoder* ctx = (GLEncoder*)self;

    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
            !isValidTextureExternalParam(pname, (GLenum)param)),
            GL_INVALID_ENUM);

    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glTexParameterf_enc(ctx, target, pname, param);
    }
}

void GLEncoder::s_glTexParameterfv(void* self,
        GLenum target, GLenum pname, const GLfloat* params)
{
    GLEncoder* ctx = (GLEncoder*)self;

    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
            !isValidTextureExternalParam(pname, (GLenum)params[0])),
            GL_INVALID_ENUM);

    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
    }
}

void GLEncoder::s_glTexParameteri(void* self,
        GLenum target, GLenum pname, GLint param)
{
    GLEncoder* ctx = (GLEncoder*)self;

    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
            !isValidTextureExternalParam(pname, (GLenum)param)),
            GL_INVALID_ENUM);

    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glTexParameteri_enc(ctx, target, pname, param);
    }
}

void GLEncoder::s_glTexParameterx(void* self,
        GLenum target, GLenum pname, GLfixed param)
{
    GLEncoder* ctx = (GLEncoder*)self;

    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
            !isValidTextureExternalParam(pname, (GLenum)param)),
            GL_INVALID_ENUM);

    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glTexParameterx_enc(ctx, target, pname, param);
    }
}

void GLEncoder::s_glTexParameteriv(void* self,
        GLenum target, GLenum pname, const GLint* params)
{
    GLEncoder* ctx = (GLEncoder*)self;

    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
            !isValidTextureExternalParam(pname, (GLenum)params[0])),
            GL_INVALID_ENUM);

    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
    }
}

void GLEncoder::s_glTexParameterxv(void* self,
        GLenum target, GLenum pname, const GLfixed* params)
{
    GLEncoder* ctx = (GLEncoder*)self;

    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
            !isValidTextureExternalParam(pname, (GLenum)params[0])),
            GL_INVALID_ENUM);

    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
        ctx->override2DTextureTarget(target);
        ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
        ctx->restore2DTextureTarget();
    } else {
        ctx->m_glTexParameterxv_enc(ctx, target, pname, params);
    }
}

void GLEncoder::override2DTextureTarget(GLenum target)
{
    if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
        target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
            m_glBindTexture_enc(this, GL_TEXTURE_2D,
                    m_state->getBoundTexture(target));
    }
}

void GLEncoder::restore2DTextureTarget()
{
    GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
    m_glBindTexture_enc(this, GL_TEXTURE_2D,
            m_state->getBoundTexture(priorityTarget));
}

void GLEncoder::s_glGenFramebuffersOES(void* self,
        GLsizei n, GLuint* framebuffers) {
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    SET_ERROR_IF(n < 0, GL_INVALID_VALUE);

    ctx->m_glGenFramebuffersOES_enc(self, n, framebuffers);
    state->addFramebuffers(n, framebuffers);
}

void GLEncoder::s_glDeleteFramebuffersOES(void* self,
        GLsizei n, const GLuint* framebuffers) {
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    SET_ERROR_IF(n < 0, GL_INVALID_VALUE);

    ctx->m_glDeleteFramebuffersOES_enc(self, n, framebuffers);
    state->removeFramebuffers(n, framebuffers);
}

void GLEncoder::s_glBindFramebufferOES(void* self,
        GLenum target, GLuint framebuffer) {
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    SET_ERROR_IF((target != GL_FRAMEBUFFER),
                 GL_INVALID_ENUM);

    state->bindFramebuffer(target, framebuffer);

    ctx->m_glBindFramebufferOES_enc(self, target, framebuffer);
}

void GLEncoder::s_glFramebufferTexture2DOES(void*self,
        GLenum target, GLenum attachment,
        GLenum textarget, GLuint texture, GLint level) {
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    state->attachTextureObject(target, attachment, texture, level, 0);

    ctx->m_glFramebufferTexture2DOES_enc(self, target, attachment, textarget, texture, level);
}

void GLEncoder::s_glFramebufferTexture2DMultisampleIMG(void* self,
        GLenum target, GLenum attachment,
        GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
    GLEncoder* ctx = (GLEncoder*)self;
    GLClientState* state = ctx->m_state;

    state->attachTextureObject(target, attachment, texture, level, 0);

    ctx->m_glFramebufferTexture2DMultisampleIMG_enc(self, target, attachment, textarget, texture, level, samples);
}

void GLEncoder::s_glGetFramebufferAttachmentParameterivOES(void* self,
        GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
    GLEncoder* ctx = (GLEncoder*)self;
    const GLClientState* state = ctx->m_state;

    SET_ERROR_IF(state->boundFramebuffer(GL_FRAMEBUFFER) == 0,
                 GL_INVALID_OPERATION);
    SET_ERROR_IF((pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) &&
                 (!state->attachmentHasObject(GL_FRAMEBUFFER, attachment)),
                 GL_INVALID_ENUM);

    ctx->m_glGetFramebufferAttachmentParameterivOES_enc(self, target, attachment, pname, params);
}

GLEncoder::GLEncoder(IOStream *stream, ChecksumCalculator *protocol)
        : gl_encoder_context_t(stream, protocol)
{
    m_initialized = false;
    m_state = NULL;
    m_error = GL_NO_ERROR;
    m_num_compressedTextureFormats = 0;
    m_compressedTextureFormats = NULL;

    // overrides;
#define OVERRIDE(name)  m_##name##_enc = this-> name ; this-> name = &s_##name

    OVERRIDE(glFlush);
    OVERRIDE(glPixelStorei);
    OVERRIDE(glVertexPointer);
    OVERRIDE(glNormalPointer);
    OVERRIDE(glColorPointer);
    OVERRIDE(glPointSizePointerOES);
    OVERRIDE(glClientActiveTexture);
    OVERRIDE(glTexCoordPointer);
    OVERRIDE(glMatrixIndexPointerOES);
    OVERRIDE(glWeightPointerOES);

    OVERRIDE(glGetIntegerv);
    OVERRIDE(glGetFloatv);
    OVERRIDE(glGetBooleanv);
    OVERRIDE(glGetFixedv);
    OVERRIDE(glGetPointerv);

    OVERRIDE(glBindBuffer);
    OVERRIDE(glBufferData);
    OVERRIDE(glBufferSubData);
    OVERRIDE(glDeleteBuffers);

    OVERRIDE(glEnableClientState);
    OVERRIDE(glDisableClientState);
    OVERRIDE(glIsEnabled);
    OVERRIDE(glDrawArrays);
    OVERRIDE(glDrawElements);

    this->glGetString = s_glGetString;
    this->glFinish = s_glFinish;

    OVERRIDE(glGetError);

    OVERRIDE(glActiveTexture);
    OVERRIDE(glBindTexture);
    OVERRIDE(glDeleteTextures);
    OVERRIDE(glDisable);
    OVERRIDE(glEnable);
    OVERRIDE(glGetTexParameterfv);
    OVERRIDE(glGetTexParameteriv);
    OVERRIDE(glGetTexParameterxv);
    OVERRIDE(glTexParameterf);
    OVERRIDE(glTexParameterfv);
    OVERRIDE(glTexParameteri);
    OVERRIDE(glTexParameterx);
    OVERRIDE(glTexParameteriv);
    OVERRIDE(glTexParameterxv);

    OVERRIDE(glGenFramebuffersOES);
    OVERRIDE(glDeleteFramebuffersOES);
    OVERRIDE(glBindFramebufferOES);
    OVERRIDE(glFramebufferTexture2DOES);
    OVERRIDE(glFramebufferTexture2DMultisampleIMG);
    OVERRIDE(glGetFramebufferAttachmentParameterivOES);

    this->glReadnPixelsEXT = s_glReadnPixelsEXT;
}

GLEncoder::~GLEncoder()
{
    delete [] m_compressedTextureFormats;
}

size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
{
    assert(m_state != NULL);
    return m_state->pixelDataSize(width, height, 1, format, type, pack);
}

void GLEncoder::s_glFinish(void *self)
{
    GLEncoder *ctx = (GLEncoder *)self;
    ctx->glFinishRoundTrip(self);
}

void GLEncoder::s_glReadnPixelsEXT(void* self, GLint x, GLint y, GLsizei width,
        GLsizei height, GLenum format, GLenum type, GLsizei bufSize,
        GLvoid* pixels) {
    GLEncoder *ctx = (GLEncoder*)self;
    SET_ERROR_IF(bufSize < ctx->pixelDataSize(width, height, format,
        type, 1), GL_INVALID_OPERATION);
    ctx->glReadPixels(self, x, y, width, height, format, type, pixels);
}
