/*
* 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 "GLEScmContext.h"
#include "GLEScmUtils.h"
#include <algorithm>
#include <GLcommon/GLutils.h>
#include <GLcommon/GLconversion_macros.h>
#include <string.h>
#include <GLES/gl.h>
#include <GLES/glext.h>

#include "aemu/base/synchronization/Lock.h"
#include "aemu/base/files/StreamSerializing.h"
#include "host-common/crash_reporter.h"
#include "GLEScmValidate.h"

#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

static GLESVersion s_maxGlesVersion = GLES_1_1;

void GLEScmContext::setMaxGlesVersion(GLESVersion version) {
    s_maxGlesVersion = version;
}

void GLEScmContext::init() {
    android::base::AutoLock mutex(s_lock);
    if(!m_initialized) {
        GLEScontext::init();

        addVertexArrayObject(0);
        setVertexArrayObject(0);

        m_currVaoState[GL_COLOR_ARRAY]          = new GLESpointer();
        m_currVaoState[GL_NORMAL_ARRAY]         = new GLESpointer();
        m_currVaoState[GL_VERTEX_ARRAY]         = new GLESpointer();
        m_currVaoState[GL_POINT_SIZE_ARRAY_OES] = new GLESpointer();

        m_texCoords = new GLESpointer[kMaxTextureUnits];
        m_currVaoState[GL_TEXTURE_COORD_ARRAY]  = &m_texCoords[m_clientActiveTexture];

        if (isCoreProfile()) {
            m_coreProfileEngine = new CoreProfileEngine(this);
        } else if (isGles2Gles()) {
            m_coreProfileEngine = new CoreProfileEngine(this, true /* gles2gles */);
        }
        mColor.type = GL_UNSIGNED_BYTE;
        mColor.val.ubyteVal[0] = 255;
        mColor.val.ubyteVal[1] = 255;
        mColor.val.ubyteVal[2] = 255;
        mColor.val.ubyteVal[3] = 255;
        mNormal.type = GL_FLOAT;
        mNormal.val.floatVal[0] = 0.0f;
        mNormal.val.floatVal[1] = 0.0f;
        mNormal.val.floatVal[2] = 1.0f;
    }
    m_initialized = true;
}

void GLEScmContext::initGlobal(EGLiface* eglIface) {
    s_glDispatch.dispatchFuncs(s_maxGlesVersion, eglIface->eglGetGlLibrary(), eglIface->getProcAddress);
    GLEScontext::initGlobal(eglIface);
    buildStrings( 1, 1,
                 (const char*)dispatcher().glGetString(GL_VENDOR),
                 (const char*)dispatcher().glGetString(GL_RENDERER),
                 (const char*)dispatcher().glGetString(GL_VERSION),
                 "OpenGL ES-CM 1.1");
}

void GLEScmContext::initDefaultFBO(
        GLint width, GLint height, GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
        GLuint* eglSurfaceRBColorId, GLuint* eglSurfaceRBDepthId,
        GLuint readWidth, GLint readHeight, GLint readColorFormat, GLint readDepthstencilFormat, GLint readMultisamples,
        GLuint* eglReadSurfaceRBColorId, GLuint* eglReadSurfaceRBDepthId) {
    GLEScontext::initDefaultFBO(
            width, height, colorFormat, depthstencilFormat, multisamples,
            eglSurfaceRBColorId, eglSurfaceRBDepthId,
            readWidth, readHeight, readColorFormat, readDepthstencilFormat, readMultisamples,
            eglReadSurfaceRBColorId, eglReadSurfaceRBDepthId
            );
}

GLEScmContext::GLEScmContext(int maj, int min,
        GlobalNameSpace* globalNameSpace, android::base::Stream* stream)
    : GLEScontext(globalNameSpace, stream, nullptr) {
    if (stream) {
        assert(maj == m_glesMajorVersion);
        assert(min == m_glesMinorVersion);
        android::base::loadBuffer(stream, &mProjMatrices);
        android::base::loadBuffer(stream, &mModelviewMatrices);
        android::base::loadBuffer(stream, &mTextureMatrices,
                [](android::base::Stream* stream) {
                    MatrixStack matrices;
                    android::base::loadBuffer(stream, &matrices);
                    return matrices;
                });
        android::base::loadBuffer(stream, &mTexUnitEnvs,
                [](android::base::Stream* stream) {
                    TexEnv texEnv;
                    android::base::loadCollection(stream, &texEnv,
                            [] (android::base::Stream* stream) {
                                GLenum idx = stream->getBe32();
                                GLValTyped val;
                                stream->read(&val, sizeof(GLValTyped));
                                return std::make_pair(idx, val);
                            });
                    return texEnv;
                });
        android::base::loadBuffer(stream, &mTexGens,
                [](android::base::Stream* stream) {
                    TexEnv texEnv;
                    android::base::loadCollection(stream, &texEnv,
                            [] (android::base::Stream* stream) {
                                GLenum idx = stream->getBe32();
                                GLValTyped val;
                                stream->read(&val, sizeof(GLValTyped));
                                return std::make_pair(idx, val);
                            });
                    return texEnv;
                });
        m_clientActiveTexture = stream->getBe32();
        if (m_initialized) {
            mShadeModel = stream->getBe32();
            stream->read((void*)&mColor, sizeof(mColor));
            stream->read((void*)&mNormal, sizeof(mNormal));
            uint32_t size = stream->getBe32();
            m_texCoords = new GLESpointer[size];
            for (uint32_t i = 0; i < size; i++) {
                m_texCoords[i].onLoad(stream);
            }
            m_currVaoState[GL_TEXTURE_COORD_ARRAY] =
                    &m_texCoords[m_clientActiveTexture];
        }

        android::base::loadBufferPtr<GLVal>(stream, mMultiTexCoord);
        android::base::loadBufferPtr<Material>(stream, &mMaterial);
        android::base::loadBufferPtr<LightModel>(stream, &mLightModel);
        android::base::loadBufferPtr<Light>(stream, mLights);
        android::base::loadBufferPtr<Fog>(stream, &mFog);

    } else {
        m_glesMajorVersion = maj;
        m_glesMinorVersion = min;

        mProjMatrices.resize(1, glm::mat4());
        mModelviewMatrices.resize(1, glm::mat4());
        mTextureMatrices.resize(kMaxTextureUnits, { glm::mat4() });
        mTexUnitEnvs.resize(kMaxTextureUnits, TexEnv());
        mTexGens.resize(kMaxTextureUnits, TexEnv());

        for (int i = 0; i < kMaxTextureUnits; i++) {
            mTexUnitEnvs[i][GL_TEXTURE_ENV_MODE].val.intVal[0] = GL_MODULATE;
            mTexUnitEnvs[i][GL_TEXTURE_ENV_MODE].type = GL_INT;
            mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[0] = 0.2f;
            mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[1] = 0.4f;
            mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[2] = 0.8f;
            mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[3] = 0.7f;
            mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].type = GL_FLOAT;
            mTexUnitEnvs[i][GL_COMBINE_RGB].val.intVal[0] = GL_REPLACE;
            mTexUnitEnvs[i][GL_COMBINE_RGB].type = GL_INT;
            mTexUnitEnvs[i][GL_COMBINE_ALPHA].val.intVal[0] = GL_REPLACE;
            mTexUnitEnvs[i][GL_COMBINE_ALPHA].type = GL_INT;
        }

        // GL_LIGHT0 starts off as white
        mLights[0].diffuse[0] = 1.0f;
        mLights[0].diffuse[1] = 1.0f;
        mLights[0].diffuse[2] = 1.0f;
        mLights[0].diffuse[3] = 1.0f;
        mLights[0].specular[0] = 1.0f;
        mLights[0].specular[1] = 1.0f;
        mLights[0].specular[2] = 1.0f;
        mLights[0].specular[3] = 1.0f;
    }
}


void GLEScmContext::setActiveTexture(GLenum tex) {
   m_activeTexture = tex - GL_TEXTURE0;
}

void GLEScmContext::setClientActiveTexture(GLenum tex) {
   m_clientActiveTexture = tex - GL_TEXTURE0;
   m_currVaoState[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture];
}

void GLEScmContext::setBindedTexture(GLenum target, unsigned int texture, unsigned int globalTexName) {
    GLEScontext::setBindedTexture(target, texture);
}

GLEScmContext::~GLEScmContext(){
    if(m_texCoords){
        delete[] m_texCoords;
        m_texCoords = NULL;
    }
    if (m_vaoStateMap.size()) {
        m_currVaoState[GL_TEXTURE_COORD_ARRAY] = NULL;
    }

    if (m_coreProfileEngine) {
        delete m_coreProfileEngine;
        m_coreProfileEngine = NULL;
    }
}

const GLEScmContext::Material& GLEScmContext::getMaterialInfo() {
    return mMaterial;
}

const GLEScmContext::LightModel& GLEScmContext::getLightModelInfo() {
    return mLightModel;
}

const GLEScmContext::Light& GLEScmContext::getLightInfo(uint32_t lightIndex) {
    return mLights[lightIndex];
}

const GLEScmContext::Fog& GLEScmContext::getFogInfo() {
    return mFog;
}

void GLEScmContext::onSave(android::base::Stream* stream) const {
    GLEScontext::onSave(stream);
    android::base::saveBuffer(stream, mProjMatrices);
    android::base::saveBuffer(stream, mModelviewMatrices);
    android::base::saveBuffer(stream, mTextureMatrices,
            [](android::base::Stream* stream, const MatrixStack& matrices) {
                android::base::saveBuffer(stream, matrices);
            });
    android::base::saveBuffer(stream, mTexUnitEnvs,
            [](android::base::Stream* stream, const TexEnv& texEnv) {
                android::base::saveCollection(stream, texEnv,
                        [] (android::base::Stream* stream,
                            const std::pair<GLenum, GLValTyped>& it) {
                            stream->putBe32(it.first);
                            stream->write(&it.second, sizeof(GLValTyped));
                        });
            });
    android::base::saveBuffer(stream, mTexGens,
            [](android::base::Stream* stream, const TexEnv& texEnv) {
                android::base::saveCollection(stream, texEnv,
                        [] (android::base::Stream* stream,
                            const std::pair<GLenum, GLValTyped>& it) {
                            stream->putBe32(it.first);
                            stream->write(&it.second, sizeof(GLValTyped));
                        });
            });
    stream->putBe32(m_clientActiveTexture);
    if (m_initialized) {
        stream->putBe32(mShadeModel);
        stream->write((void*)&mColor, sizeof(mColor));
        stream->write((void*)&mNormal, sizeof(mNormal));
        stream->putBe32(kMaxTextureUnits);
        for (uint32_t i = 0; i < kMaxTextureUnits; i++) {
            m_texCoords[i].onSave(stream);
        }
    }

    android::base::saveBuffer<GLVal>(stream, mMultiTexCoord, kMaxTextureUnits);
    android::base::saveBuffer<Material>(stream, &mMaterial, 1);
    android::base::saveBuffer<LightModel>(stream, &mLightModel, 1);
    android::base::saveBuffer<Light>(stream, mLights, kMaxLights);
    android::base::saveBuffer<Fog>(stream, &mFog, 1);
}

void GLEScmContext::restoreMatrixStack(const MatrixStack& matrices) {
    for (size_t i = 0; i < matrices.size(); i++) {
        if (i > 0) {
            dispatcher().glPushMatrix();
        }
        dispatcher().glLoadMatrixf(&matrices[i][0][0]);
    }
}

void GLEScmContext::postLoadRestoreCtx() {
    if (isInitialized()) {
        if (isCoreProfile()) {
            m_coreProfileEngine = new CoreProfileEngine(this);
        } else if (isGles2Gles()) {
            m_coreProfileEngine = new CoreProfileEngine(this, true);
        }
        if (!m_coreProfileEngine) {
            GLDispatch& dispatcher = GLEScontext::dispatcher();
            dispatcher.glMatrixMode(GL_PROJECTION);
            restoreMatrixStack(mProjMatrices);
            dispatcher.glMatrixMode(GL_MODELVIEW);
            restoreMatrixStack(mModelviewMatrices);
            dispatcher.glMatrixMode(GL_TEXTURE);
            for (size_t i = 0; i < mTextureMatrices.size(); i++) {
                if (mTextureMatrices[i].size() == 0) {
                    continue;
                }
                dispatcher.glActiveTexture(GL_TEXTURE0 + i);
                restoreMatrixStack(mTextureMatrices[i]);
            }
            for (const auto& array : m_currVaoState) {
                if (array.first == GL_TEXTURE_COORD_ARRAY) continue;
                array.second->restoreBufferObj(getBufferObj);
            }
            for (uint32_t i = 0; i < kMaxTextureUnits; i++) {
                m_texCoords[i].restoreBufferObj(getBufferObj);
            }
            dispatcher.glMatrixMode(mCurrMatrixMode);
            dispatcher.glActiveTexture(GL_TEXTURE0 + m_activeTexture);
            for (const auto& it : *m_currVaoState.it->second.arraysMap) {
                if (GLEScmValidate::supportedArrays(it.first) &&
                        it.first != GL_TEXTURE_COORD_ARRAY) {
                    if (it.second->isEnable()) {
                        dispatcher.glEnableClientState(it.first);
                    } else {
                        dispatcher.glDisableClientState(it.first);
                    }
                }
            }

            for (int i = 0; i < kMaxTextureUnits; i++) {
                GLESpointer* texcoord = m_texCoords + i;
                dispatcher.glClientActiveTexture(i + GL_TEXTURE0);
                if (texcoord->isEnable()) {
                    dispatcher.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                } else {
                    dispatcher.glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                dispatcher.glActiveTexture(i + GL_TEXTURE0);
                for (const auto& texEnv : mTexUnitEnvs[i]) {
                    GLenum target = texEnv.first == GL_POINT_SPRITE_OES ?
                        GL_COORD_REPLACE_OES : GL_TEXTURE_ENV;
                    if (texEnv.second.type == GL_INT) {
                        dispatcher.glTexEnviv(target, texEnv.first,
                                texEnv.second.val.intVal);
                    } else {
                        assert(texEnv.second.type == GL_FLOAT);
                        dispatcher.glTexEnvfv(target, texEnv.first,
                                texEnv.second.val.floatVal);
                    }
                }
            }
            dispatcher.glClientActiveTexture(
                    m_clientActiveTexture + GL_TEXTURE0);
            dispatcher.glActiveTexture(m_activeTexture + GL_TEXTURE0);
            dispatcher.glShadeModel(mShadeModel);
            switch (mColor.type) {
                case GL_FLOAT:
                    dispatcher.glColor4f(mColor.val.floatVal[0],
                            mColor.val.floatVal[1],
                            mColor.val.floatVal[2],
                            mColor.val.floatVal[3]);
                    break;
                case GL_UNSIGNED_BYTE:
                    dispatcher.glColor4ub(mColor.val.ubyteVal[0],
                            mColor.val.ubyteVal[1],
                            mColor.val.ubyteVal[2],
                            mColor.val.ubyteVal[3]);
                    break;
                default:
                    fprintf(stderr, "WARNING: glColor with unknown type 0x%x\n",
                            mColor.type);
                    break;
            }
            switch (mNormal.type) {
                case GL_FLOAT:
                    dispatcher.glNormal3f(mNormal.val.floatVal[0],
                            mNormal.val.floatVal[1],
                            mNormal.val.floatVal[2]);
                    break;
                default:
                    fprintf(stderr, "WARNING: glNormal with unknown type 0x%x\n",
                            mNormal.type);
                    break;
            }

            dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mMaterial.ambient);
            dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mMaterial.diffuse);
            dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mMaterial.specular);
            dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mMaterial.emissive);
            dispatcher.glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mMaterial.specularExponent);

            dispatcher.glLightModelfv(GL_LIGHT_MODEL_AMBIENT, mLightModel.color);
            dispatcher.glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, mLightModel.twoSided);

            for (int i = 0; i < kMaxLights; i++) {
                dispatcher.glLightfv(GL_LIGHT0 + i, GL_AMBIENT, mLights[i].ambient);
                dispatcher.glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, mLights[i].diffuse);
                dispatcher.glLightfv(GL_LIGHT0 + i, GL_SPECULAR, mLights[i].specular);
                dispatcher.glLightfv(GL_LIGHT0 + i, GL_POSITION, mLights[i].position);
                dispatcher.glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, mLights[i].direction);
                dispatcher.glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, mLights[i].spotlightExponent);
                dispatcher.glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, mLights[i].spotlightCutoffAngle);
                dispatcher.glLightf(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, mLights[i].attenuationConst);
                dispatcher.glLightf(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, mLights[i].attenuationLinear);
                dispatcher.glLightf(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, mLights[i].attenuationQuadratic);
            }

            dispatcher.glFogf(GL_FOG_MODE, (GLfloat)mFog.mode);
            dispatcher.glFogf(GL_FOG_DENSITY, mFog.density);
            dispatcher.glFogf(GL_FOG_START, mFog.start);
            dispatcher.glFogf(GL_FOG_END, mFog.end);
            dispatcher.glFogfv(GL_FOG_COLOR, mFog.color);
        }
    }
    GLEScontext::postLoadRestoreCtx();
}

//setting client side arr
void GLEScmContext::setupArr(const GLvoid* arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized, int index, bool isInt){
    if( arr == NULL) return;
    switch(arrayType) {
        case GL_VERTEX_ARRAY:
            s_glDispatch.glVertexPointer(size,dataType,stride,arr);
            break;
        case GL_NORMAL_ARRAY:
            s_glDispatch.glNormalPointer(dataType,stride,arr);
            break;
        case GL_TEXTURE_COORD_ARRAY:
            s_glDispatch.glTexCoordPointer(size,dataType,stride,arr);
            break;
        case GL_COLOR_ARRAY:
            s_glDispatch.glColorPointer(size,dataType,stride,arr);
            break;
        case GL_POINT_SIZE_ARRAY_OES:
            m_pointsIndex = index;
            break;
    }
}


void GLEScmContext::setupArrayPointerHelper(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLenum array_id,GLESpointer* p){
        unsigned int size = p->getSize();
        GLenum dataType = p->getType();

        if(needConvert(cArrs,first,count,type,indices,direct,p,array_id)){
            //conversion has occured
            ArrayData currentArr = cArrs.getCurrentArray();
            setupArr(currentArr.data,array_id,currentArr.type,size,currentArr.stride,GL_FALSE, cArrs.getCurrentIndex());
            ++cArrs;
        } else {
            setupArr(p->getData(),array_id,dataType,size,p->getStride(), GL_FALSE);
        }
}

void GLEScmContext::setupArraysPointers(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct, bool* needEnablingPostDraw) {
    (void)needEnablingPostDraw;
    ArraysMap::iterator it;
    m_pointsIndex = -1;

    //going over all clients arrays Pointers
    for ( it=m_currVaoState.begin() ; it != m_currVaoState.end(); ++it) {

        GLenum array_id   = (*it).first;
        GLESpointer* p = (*it).second;
        if(!p->isEnable()) continue;
        if(array_id == GL_TEXTURE_COORD_ARRAY) continue; //handling textures later
        setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
    }

    unsigned int activeTexture = m_clientActiveTexture + GL_TEXTURE0;

    //converting all texture coords arrays
    for(int i=0; i< kMaxTextureUnits;i++) {

        unsigned int tex = GL_TEXTURE0+i;
        setClientActiveTexture(tex);
        s_glDispatch.glClientActiveTexture(tex);

        GLenum array_id   = GL_TEXTURE_COORD_ARRAY;
        GLESpointer* p = m_currVaoState[array_id];
        if(!p->isEnable()) continue;
        setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
    }

    setClientActiveTexture(activeTexture);
    s_glDispatch.glClientActiveTexture(activeTexture);
}

void  GLEScmContext::drawPointsData(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw) {
    const char  *pointsArr =  NULL;
    int stride = 0;
    GLESpointer* p = m_currVaoState[GL_POINT_SIZE_ARRAY_OES];

    //choosing the right points sizes array source
    if(m_pointsIndex >= 0) { //point size array was converted
        pointsArr = (const char*)(cArrs[m_pointsIndex].data);
        stride = cArrs[m_pointsIndex].stride;
    } else {
        pointsArr = static_cast<const char*>(p->getData());
        stride = p->getStride();
    }

    if(stride == 0){
        stride = sizeof(GLfloat);
    }


    if(isElemsDraw) {
        int tSize = 0;
        switch (type) {
            case GL_UNSIGNED_BYTE:
                tSize = 1;
                break;
            case GL_UNSIGNED_SHORT:
                tSize = 2;
                break;
            case GL_UNSIGNED_INT:
                tSize = 4;
                break;
        };

        int i = 0;
        while(i<count)
        {
            int sStart = i;
            int sCount = 1;

#define INDEX \
                (type == GL_UNSIGNED_INT ? \
                static_cast<const GLuint*>(indices_in)[i]: \
                type == GL_UNSIGNED_SHORT ? \
                static_cast<const GLushort*>(indices_in)[i]: \
                static_cast<const GLubyte*>(indices_in)[i])

            GLfloat pSize = *((GLfloat*)(pointsArr+(INDEX*stride)));
            i++;

            while(i < count && pSize == *((GLfloat*)(pointsArr+(INDEX*stride))))
            {
                sCount++;
                i++;
            }

            s_glDispatch.glPointSize(pSize);
            s_glDispatch.glDrawElements(GL_POINTS, sCount, type, (char*)indices_in+sStart*tSize);
        }
    } else {
        int i = 0;
        while(i<count)
        {
            int sStart = i;
            int sCount = 1;
            GLfloat pSize = *((GLfloat*)(pointsArr+((first+i)*stride)));
            i++;

            while(i < count && pSize == *((GLfloat*)(pointsArr+((first+i)*stride))))
            {
                sCount++;
                i++;
            }

            s_glDispatch.glPointSize(pSize);
            s_glDispatch.glDrawArrays(GL_POINTS, first+sStart, sCount);
        }
    }
}

void  GLEScmContext::drawPointsArrs(GLESConversionArrays& arrs,GLint first,GLsizei count) {
    drawPointsData(arrs,first,count,0,NULL,false);
}

void GLEScmContext::drawPointsElems(GLESConversionArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices_in) {
    drawPointsData(arrs,0,count,type,indices_in,true);
}

bool GLEScmContext::doConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {
    return needConvert(cArrs, first, count, type, indices, direct, p, array_id);
}

void GLEScmContext::getColor(uint32_t count, std::vector<float>& out) const {
    std::vector<float> vec(4);
    switch (mColor.type) {
        case GL_UNSIGNED_BYTE:
            vec = { mColor.val.ubyteVal[0] / 255.0f,
                    mColor.val.ubyteVal[1] / 255.0f,
                    mColor.val.ubyteVal[2] / 255.0f,
                    mColor.val.ubyteVal[3] / 255.0f, };
        default:
            vec = { mColor.val.floatVal[0],
                    mColor.val.floatVal[1],
                    mColor.val.floatVal[2],
                    mColor.val.floatVal[3], };
    }

    appendRepeatedVector(count, vec, out);
}

void GLEScmContext::getNormal(uint32_t count, std::vector<float>& out) const {
    std::vector<float> vec = { mNormal.val.floatVal[0],
          mNormal.val.floatVal[1],
          mNormal.val.floatVal[2] };

    appendRepeatedVector(count, vec, out);
}

void GLEScmContext::getMultiTexCoord(uint32_t count, uint32_t index, std::vector<float>& out) const {
    // s, t, r, qcomponents
    std::vector<float> vec = { mMultiTexCoord[index].floatVal[0],
          mMultiTexCoord[index].floatVal[1],
          mMultiTexCoord[index].floatVal[2],
          mMultiTexCoord[index].floatVal[3] };

    appendRepeatedVector(count, vec, out);
}

void GLEScmContext::appendRepeatedVector(uint32_t count, std::vector<float>& in, std::vector<float>& out) const {
    size_t previousOutSize = out.size();
    out.resize(previousOutSize + (count * in.size()));
    auto it = out.begin() + previousOutSize;
    for (int i = 0; i < count; i++) {
        std::copy(in.begin(), in.end(), it);
        it += in.size();
    }
}

GLenum GLEScmContext::getTextureEnvMode() {
    return mTexUnitEnvs[m_activeTexture][GL_TEXTURE_ENV_MODE].val.intVal[0];
}

GLenum GLEScmContext::getTextureGenMode() {
    return mTexGens[m_activeTexture][GL_TEXTURE_GEN_MODE_OES].val.intVal[0];
}

glm::mat4 GLEScmContext::getProjMatrix() {
    return mProjMatrices.back();
}

glm::mat4 GLEScmContext::getModelviewMatrix() {
    return mModelviewMatrices.back();
}

glm::mat4 GLEScmContext::getTextureMatrix() {
    return mTextureMatrices[m_activeTexture].back();
}

glm::mat4& GLEScmContext::currMatrix() {
    return currMatrixStack().back();
}

GLEScmContext::MatrixStack& GLEScmContext::currMatrixStack() {
    switch (mCurrMatrixMode) {
    case GL_TEXTURE:
        return mTextureMatrices[m_activeTexture];
    case GL_PROJECTION:
        return mProjMatrices;
    case GL_MODELVIEW:
        return mModelviewMatrices;
    default:
        break;
        // emugl_crash_reporter("error: matrix mode set to 0x%x!", mCurrMatrixMode);
    }
    // Make compiler happy
    return mModelviewMatrices;
}

bool GLEScmContext::needConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {

    bool usingVBO = p->getAttribType() == GLESpointer::BUFFER;
    GLenum arrType = p->getType();
    /*
     conversion is not necessary in the following cases:
      (*) array type is byte but it is not vertex or texture array
      (*) array type is not fixed
    */
    if((arrType != GL_FIXED) && (arrType != GL_BYTE)) return false;
    if((arrType == GL_BYTE   && (array_id != GL_VERTEX_ARRAY)) &&
       (arrType == GL_BYTE   && (array_id != GL_TEXTURE_COORD_ARRAY)) ) return false;


    bool byteVBO = (arrType == GL_BYTE) && usingVBO;
    if(byteVBO){
        p->redirectPointerData();
    }

    if(!usingVBO || byteVBO) {
        if (direct) {
            convertDirect(cArrs,first,count,array_id,p);
        } else {
            convertIndirect(cArrs,count,type,indices,array_id,p);
        }
    } else {
        if (direct) {
            convertDirectVBO(cArrs,first,count,array_id,p) ;
        } else {
            convertIndirectVBO(cArrs,count,type,indices,array_id,p);
        }
    }
    return true;
}

const GLESpointer* GLEScmContext::getPointer(GLenum arrType) {
    GLenum type =
        arrType == GL_VERTEX_ARRAY_POINTER          ? GL_VERTEX_ARRAY :
        arrType == GL_NORMAL_ARRAY_POINTER          ? GL_NORMAL_ARRAY :
        arrType == GL_TEXTURE_COORD_ARRAY_POINTER   ? GL_TEXTURE_COORD_ARRAY :
        arrType == GL_COLOR_ARRAY_POINTER           ? GL_COLOR_ARRAY :
        arrType == GL_POINT_SIZE_ARRAY_POINTER_OES  ? GL_POINT_SIZE_ARRAY_OES :
        0;
    if(type != 0)
    {
        return GLEScontext::getPointer(type);
    }
    return NULL;
}

void GLEScmContext::initExtensionString() {
    if (s_glExtensionsGles1Initialized) return;
    initCapsLocked((const GLubyte*)getHostExtensionsString(&s_glDispatch).c_str(),
                   s_glSupportGles1);
    *s_glExtensionsGles1 = "GL_OES_blend_func_separate GL_OES_blend_equation_separate GL_OES_blend_subtract "
                      "GL_OES_byte_coordinates GL_OES_compressed_paletted_texture GL_OES_point_size_array "
                      "GL_OES_point_sprite GL_OES_single_precision GL_OES_stencil_wrap GL_OES_texture_env_crossbar "
                      "GL_OES_texture_mirored_repeat GL_OES_EGL_image GL_OES_element_index_uint GL_OES_draw_texture "
                      "GL_OES_texture_cube_map GL_OES_draw_texture ";
    if (s_glSupportGles1.GL_OES_READ_FORMAT)
        *s_glExtensionsGles1+="GL_OES_read_format ";
    if (s_glSupportGles1.GL_EXT_FRAMEBUFFER_OBJECT) {
        *s_glExtensionsGles1+="GL_OES_framebuffer_object GL_OES_depth24 GL_OES_depth32 GL_OES_fbo_render_mipmap "
                         "GL_OES_rgb8_rgba8 GL_OES_stencil1 GL_OES_stencil4 GL_OES_stencil8 ";
    }
    if (s_glSupportGles1.GL_EXT_PACKED_DEPTH_STENCIL)
        *s_glExtensionsGles1+="GL_OES_packed_depth_stencil ";
    if (s_glSupportGles1.GL_EXT_TEXTURE_FORMAT_BGRA8888)
        *s_glExtensionsGles1+="GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888 ";
    if (s_glSupportGles1.GL_ARB_MATRIX_PALETTE && s_glSupportGles1.GL_ARB_VERTEX_BLEND) {
        *s_glExtensionsGles1+="GL_OES_matrix_palette ";
        GLint max_palette_matrices=0;
        GLint max_vertex_units=0;
        dispatcher().glGetIntegerv(GL_MAX_PALETTE_MATRICES_OES,&max_palette_matrices);
        dispatcher().glGetIntegerv(GL_MAX_VERTEX_UNITS_OES,&max_vertex_units);
        if (max_palette_matrices>=32 && max_vertex_units>=4)
            *s_glExtensionsGles1+="GL_OES_extended_matrix_palette ";
    }
    *s_glExtensionsGles1+="GL_OES_compressed_ETC1_RGB8_texture ";

    s_glExtensionsGles1Initialized = true;
}

int GLEScmContext::getMaxTexUnits() {
    return kMaxTextureUnits;
}

bool GLEScmContext::glGetBooleanv(GLenum pname, GLboolean *params)
{
    GLint iParam;

    if(glGetIntegerv(pname, &iParam))
    {
        *params = (iParam != 0);
        return true;
    }

    return false;
}

bool GLEScmContext::glGetFixedv(GLenum pname, GLfixed *params)
{
    GLint iParam;

    if(glGetIntegerv(pname, &iParam))
    {
        *params = I2X(iParam);
        return true;
    }

    return false;
}

bool GLEScmContext::glGetFloatv(GLenum pname, GLfloat *params)
{
    GLint iParam;

    if(glGetIntegerv(pname, &iParam))
    {
        *params = (GLfloat)iParam;
        return true;
    }

    return false;
}

bool GLEScmContext::glGetIntegerv(GLenum pname, GLint *params)
{
    if(GLEScontext::glGetIntegerv(pname, params))
        return true;

    const GLESpointer* ptr = NULL;

    switch(pname){
        case GL_VERTEX_ARRAY_BUFFER_BINDING:
        case GL_VERTEX_ARRAY_SIZE:
        case GL_VERTEX_ARRAY_STRIDE:
        case GL_VERTEX_ARRAY_TYPE:
            ptr = getPointer(GL_VERTEX_ARRAY_POINTER);
            break;

        case GL_NORMAL_ARRAY_BUFFER_BINDING:
        case GL_NORMAL_ARRAY_STRIDE:
        case GL_NORMAL_ARRAY_TYPE:
            ptr = getPointer(GL_NORMAL_ARRAY_POINTER);
            break;

        case GL_COLOR_ARRAY_BUFFER_BINDING:
        case GL_COLOR_ARRAY_SIZE:
        case GL_COLOR_ARRAY_STRIDE:
        case GL_COLOR_ARRAY_TYPE:
            ptr = getPointer(GL_COLOR_ARRAY_POINTER);
            break;

        case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
        case GL_TEXTURE_COORD_ARRAY_SIZE:
        case GL_TEXTURE_COORD_ARRAY_STRIDE:
        case GL_TEXTURE_COORD_ARRAY_TYPE:
            ptr = getPointer(GL_TEXTURE_COORD_ARRAY_POINTER);
            break;

        case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
        case GL_POINT_SIZE_ARRAY_STRIDE_OES:
        case GL_POINT_SIZE_ARRAY_TYPE_OES:
            ptr = getPointer(GL_POINT_SIZE_ARRAY_POINTER_OES);
            break;

        default:
            return false;
    }

    switch(pname)
    {
        case GL_VERTEX_ARRAY_BUFFER_BINDING:
        case GL_NORMAL_ARRAY_BUFFER_BINDING:
        case GL_COLOR_ARRAY_BUFFER_BINDING:
        case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
        case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
            *params = ptr ? ptr->getBufferName() : 0;
            break;

        case GL_VERTEX_ARRAY_STRIDE:
        case GL_NORMAL_ARRAY_STRIDE:
        case GL_COLOR_ARRAY_STRIDE:
        case GL_TEXTURE_COORD_ARRAY_STRIDE:
        case GL_POINT_SIZE_ARRAY_STRIDE_OES:
            *params = ptr ? ptr->getStride() : 0;
            break;

        case GL_VERTEX_ARRAY_SIZE:
        case GL_COLOR_ARRAY_SIZE:
        case GL_TEXTURE_COORD_ARRAY_SIZE:
            *params = ptr ? ptr->getSize() : 0;
            break;

        case GL_VERTEX_ARRAY_TYPE:
        case GL_NORMAL_ARRAY_TYPE:
        case GL_COLOR_ARRAY_TYPE:
        case GL_TEXTURE_COORD_ARRAY_TYPE:
        case GL_POINT_SIZE_ARRAY_TYPE_OES:
            *params = ptr ? ptr->getType() : 0;
            break;
    }

    return true;
}

GLint GLEScmContext::getErrorCoreProfile() {
    return core().getAndClearLastError();
}

void GLEScmContext::enable(GLenum cap) {
    setEnable(cap, true);

    if (m_coreProfileEngine) {
        core().enable(cap);
    } else {
        if (cap==GL_TEXTURE_GEN_STR_OES) {
            dispatcher().glEnable(GL_TEXTURE_GEN_S);
            dispatcher().glEnable(GL_TEXTURE_GEN_T);
            dispatcher().glEnable(GL_TEXTURE_GEN_R);
        } else {
            dispatcher().glEnable(cap);
        }
    }
}

void GLEScmContext::disable(GLenum cap) {
    setEnable(cap, false);

    if (m_coreProfileEngine) {
        core().disable(cap);
    } else {
        if (cap==GL_TEXTURE_GEN_STR_OES) {
            dispatcher().glDisable(GL_TEXTURE_GEN_S);
            dispatcher().glDisable(GL_TEXTURE_GEN_T);
            dispatcher().glDisable(GL_TEXTURE_GEN_R);
        } else {
            dispatcher().glDisable(cap);
        }
    }
}

void GLEScmContext::shadeModel(GLenum mode) {
    mShadeModel = mode;

    if (m_coreProfileEngine) {
        core().shadeModel(mode);
    } else {
        dispatcher().glShadeModel(mode);
    }
}

void GLEScmContext::matrixMode(GLenum mode) {
    mCurrMatrixMode = mode;

    if (m_coreProfileEngine) {
        core().matrixMode(mode);
    } else {
        dispatcher().glMatrixMode(mode);
    }
}

void GLEScmContext::loadIdentity() {
    currMatrix() = glm::mat4();

    if (m_coreProfileEngine) {
        core().loadIdentity();
    } else {
        dispatcher().glLoadIdentity();
    }
}

void GLEScmContext::loadMatrixf(const GLfloat* m) {
    currMatrix() = glm::make_mat4(m);

    if (m_coreProfileEngine) {
        core().loadMatrixf(m);
    } else {
        dispatcher().glLoadMatrixf(m);
    }
}

void GLEScmContext::pushMatrix() {
    if (currMatrixStack().size() >= kMaxMatrixStackSize) {
        setGLerror(GL_STACK_OVERFLOW);
        return;
    }
    currMatrixStack().emplace_back(currMatrixStack().back());

    if (m_coreProfileEngine) {
        core().pushMatrix();
    } else {
        dispatcher().glPushMatrix();
    }
}

void GLEScmContext::popMatrix() {
    if (currMatrixStack().size() == 1) {
        setGLerror(GL_STACK_UNDERFLOW);
        return;
    }
    currMatrixStack().pop_back();

    if (m_coreProfileEngine) {
        core().popMatrix();
    } else {
        dispatcher().glPopMatrix();
    }
}

void GLEScmContext::multMatrixf(const GLfloat* m) {
    currMatrix() *= glm::make_mat4(m);

    if (m_coreProfileEngine) {
        core().multMatrixf(m);
    } else {
        dispatcher().glMultMatrixf(m);
    }
}

void GLEScmContext::orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
    currMatrix() *= glm::ortho(left, right, bottom, top, zNear, zFar);

    if (m_coreProfileEngine) {
        core().orthof(left, right, bottom, top, zNear, zFar);
    } else {
        dispatcher().glOrthof(left,right,bottom,top,zNear,zFar);
    }
}

void GLEScmContext::frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
    currMatrix() *= glm::frustum(left, right, bottom, top, zNear, zFar);

    if (m_coreProfileEngine) {
        core().frustumf(left, right, bottom, top, zNear, zFar);
    } else {
        dispatcher().glFrustumf(left,right,bottom,top,zNear,zFar);
    }
}

void GLEScmContext::texEnvf(GLenum target, GLenum pname, GLfloat param) {
    // Assume |target| is GL_TEXTURE_ENV
    if (pname == GL_TEXTURE_ENV_MODE) {
        texEnvi(target, pname, (GLint)param);
    } else {
        mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0] = param;
        mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
    }

    if (m_coreProfileEngine) {
        core().texEnvf(target, pname, param);
    } else {
        dispatcher().glTexEnvf(target, pname, param);
    }
}

void GLEScmContext::texEnvfv(GLenum target, GLenum pname, const GLfloat* params) {
    if (pname == GL_TEXTURE_ENV_COLOR) {
        for (int i = 0; i < 4; i++) {
            mTexUnitEnvs[m_activeTexture][pname].val.floatVal[i] = params[i];
            mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
        }
    } else {
        texEnvf(target, pname, params[0]);
    }

    if (m_coreProfileEngine) {
        core().texEnvfv(target, pname, params);
    } else {
        dispatcher().glTexEnvfv(target, pname, params);
    }
}

void GLEScmContext::texEnvi(GLenum target, GLenum pname, GLint param) {
    mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = param;
    mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;

    if (m_coreProfileEngine) {
        core().texEnvi(target, pname, param);
    } else {
        dispatcher().glTexEnvi(target, pname, param);
    }
}

void GLEScmContext::texEnviv(GLenum target, GLenum pname, const GLint* params) {
    mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = params[0];
    mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;

    if (m_coreProfileEngine) {
        core().texEnviv(target, pname, params);
    } else {
        dispatcher().glTexEnviv(target, pname, params);
    }
}

void GLEScmContext::getTexEnvfv(GLenum env, GLenum pname, GLfloat* params) {
    *params = mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0];

    if (m_coreProfileEngine) {
        core().getTexEnvfv(env, pname, params);
    } else {
        dispatcher().glGetTexEnvfv(env, pname, params);
    }
}

void GLEScmContext::getTexEnviv(GLenum env, GLenum pname, GLint* params) {
    *params = mTexUnitEnvs[m_activeTexture][pname].val.intVal[0];

    if (m_coreProfileEngine) {
        core().getTexEnviv(env, pname, params);
    } else {
        dispatcher().glGetTexEnviv(env, pname, params);
    }
}

void GLEScmContext::texGenf(GLenum coord, GLenum pname, GLfloat param) {
    mTexGens[m_activeTexture][pname].val.floatVal[0] = param;
    mTexGens[m_activeTexture][pname].type = GL_FLOAT;

    if (m_coreProfileEngine) {
        core().texGenf(coord, pname, param);
    } else {
        if (coord == GL_TEXTURE_GEN_STR_OES) {
            dispatcher().glTexGenf(GL_S,pname,param);
            dispatcher().glTexGenf(GL_T,pname,param);
            dispatcher().glTexGenf(GL_R,pname,param);
        } else {
            dispatcher().glTexGenf(coord,pname,param);
        }
    }
}

void GLEScmContext::texGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
    mTexGens[m_activeTexture][pname].val.floatVal[0] = params[0];
    mTexGens[m_activeTexture][pname].type = GL_FLOAT;

    if (m_coreProfileEngine) {
        core().texGenfv(coord, pname, params);
    } else {
        if (coord == GL_TEXTURE_GEN_STR_OES) {
            dispatcher().glTexGenfv(GL_S,pname,params);
            dispatcher().glTexGenfv(GL_T,pname,params);
            dispatcher().glTexGenfv(GL_R,pname,params);
        } else {
            dispatcher().glTexGenfv(coord,pname,params);
        }
    }
}

void GLEScmContext::texGeni(GLenum coord, GLenum pname, GLint param) {
    mTexGens[m_activeTexture][pname].val.intVal[0] = param;
    mTexGens[m_activeTexture][pname].type = GL_INT;

    if (m_coreProfileEngine) {
        core().texGeni(coord, pname, param);
    } else {
        if (coord == GL_TEXTURE_GEN_STR_OES) {
            dispatcher().glTexGeni(GL_S,pname,param);
            dispatcher().glTexGeni(GL_T,pname,param);
            dispatcher().glTexGeni(GL_R,pname,param);
        } else {
            dispatcher().glTexGeni(coord,pname,param);
        }
    }
}

void GLEScmContext::texGeniv(GLenum coord, GLenum pname, const GLint* params) {
    mTexGens[m_activeTexture][pname].val.intVal[0] = params[0];
    mTexGens[m_activeTexture][pname].type = GL_INT;

    if (m_coreProfileEngine) {
        core().texGeniv(coord, pname, params);
    } else {
        if (coord == GL_TEXTURE_GEN_STR_OES) {
            dispatcher().glTexGeniv(GL_S,pname,params);
            dispatcher().glTexGeniv(GL_T,pname,params);
            dispatcher().glTexGeniv(GL_R,pname,params);
        } else {
            dispatcher().glTexGeniv(coord,pname,params);
        }
    }
}

void GLEScmContext::getTexGeniv(GLenum coord, GLenum pname, GLint* params) {
    *params = mTexGens[m_activeTexture][pname].val.intVal[0];

    if (m_coreProfileEngine) {
        core().getTexGeniv(coord, pname, params);
    } else {
        if (coord == GL_TEXTURE_GEN_STR_OES) {
            GLint state_s = GL_FALSE;
            GLint state_t = GL_FALSE;
            GLint state_r = GL_FALSE;
            dispatcher().glGetTexGeniv(GL_S,pname,&state_s);
            dispatcher().glGetTexGeniv(GL_T,pname,&state_t);
            dispatcher().glGetTexGeniv(GL_R,pname,&state_r);
            *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
        } else {
            dispatcher().glGetTexGeniv(coord,pname,params);
        }
    }
}

void GLEScmContext::getTexGenfv(GLenum coord, GLenum pname, GLfloat* params) {
    params[0] = mTexGens[m_activeTexture][pname].val.floatVal[0];
    params[1] = mTexGens[m_activeTexture][pname].val.floatVal[1];
    params[2] = mTexGens[m_activeTexture][pname].val.floatVal[2];
    params[3] = mTexGens[m_activeTexture][pname].val.floatVal[3];

    if (m_coreProfileEngine) {
        core().getTexGenfv(coord, pname, params);
    } else {
        if (coord == GL_TEXTURE_GEN_STR_OES) {
            GLfloat state_s = GL_FALSE;
            GLfloat state_t = GL_FALSE;
            GLfloat state_r = GL_FALSE;
            dispatcher().glGetTexGenfv(GL_S,pname,&state_s);
            dispatcher().glGetTexGenfv(GL_T,pname,&state_t);
            dispatcher().glGetTexGenfv(GL_R,pname,&state_r);
            *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
        } else {
            dispatcher().glGetTexGenfv(coord,pname,params);
        }
    }
}

void GLEScmContext::materialf(GLenum face, GLenum pname, GLfloat param) {
    if (face != GL_FRONT_AND_BACK) {
        fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x) "
                        "only supports GL_FRONT_AND_BACK for materials.\n");
        setGLerror(GL_INVALID_ENUM);
        return;
    }
    switch (pname) {
    case GL_AMBIENT:
    case GL_DIFFUSE:
    case GL_AMBIENT_AND_DIFFUSE:
    case GL_SPECULAR:
    case GL_EMISSION:
        fprintf(stderr, "GL_INVALID_ENUM: glMaterial(f/x) only supports "
                        "GL_SHININESS for single parameter setting.\n");
        setGLerror(GL_INVALID_ENUM);
        return;
    case GL_SHININESS:
        if (param < 0.0f || param > 128.0f) {
            fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
                            "Only range [0.0, 128.0] supported.\n", param);
            setGLerror(GL_INVALID_VALUE);
            return;
        }
        mMaterial.specularExponent = param;
        break;
    default:
        fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)\n", pname);
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glMaterialf(face, pname, param);
    }
}

void GLEScmContext::materialfv(GLenum face, GLenum pname, const GLfloat* params) {
    if (face != GL_FRONT_AND_BACK) {
        fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x)v "
                        "only supports GL_FRONT_AND_BACK for materials.\n");
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    switch (pname) {
    case GL_AMBIENT:
        memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
        break;
    case GL_DIFFUSE:
        memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
        break;
    case GL_AMBIENT_AND_DIFFUSE:
        memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
        memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
        break;
    case GL_SPECULAR:
        memcpy(&mMaterial.specular, params, 4 * sizeof(GLfloat));
        break;
    case GL_EMISSION:
        memcpy(&mMaterial.emissive, params, 4 * sizeof(GLfloat));
        break;
    case GL_SHININESS:
        if (*params < 0.0f || *params > 128.0f) {
            fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
                            "Only range [0.0, 128.0] supported.\n", *params);
            setGLerror(GL_INVALID_VALUE);
            return;
        }
        mMaterial.specularExponent = *params;
        break;
    default:
        fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)v.\n", pname);
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glMaterialfv(face, pname, params);
    }
}

void GLEScmContext::getMaterialfv(GLenum face, GLenum pname, GLfloat* params) {
    if (face != GL_FRONT && face != GL_BACK) {
        fprintf(stderr, "GL_INVALID_ENUM: glGetMaterial(f/x)v "
                        "must take GL_FRONT or GL_BACK as face argument\n");
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    switch (pname) {
    case GL_AMBIENT:
        memcpy(params, &mMaterial.ambient, 4 * sizeof(GLfloat));
        break;
    case GL_DIFFUSE:
        memcpy(params, &mMaterial.diffuse, 4 * sizeof(GLfloat));
        break;
    case GL_SPECULAR:
        memcpy(params, &mMaterial.specular, 4 * sizeof(GLfloat));
        break;
    case GL_EMISSION:
        memcpy(params, &mMaterial.emissive, 4 * sizeof(GLfloat));
        break;
    case GL_SHININESS:
        *params = mMaterial.specularExponent;
        break;
    default:
        fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glGetMaterial(f/x)v.\n", pname);
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glGetMaterialfv(face, pname, params);
    }
}

void GLEScmContext::lightModelf(GLenum pname, GLfloat param) {
    switch (pname) {
        case GL_LIGHT_MODEL_AMBIENT:
            fprintf(stderr, "GL_INVALID_ENUM: glLightModelf only supports GL_LIGHT_MODEL_TWO_SIDE.\n");
            setGLerror(GL_INVALID_ENUM);
            return;
        case GL_LIGHT_MODEL_TWO_SIDE:
            if (param != 1.0f && param != 0.0f) {
                fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
                                "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", param);
                setGLerror(GL_INVALID_VALUE);
            }
            mLightModel.twoSided = param == 1.0f ? true : false;
            break;
        default:
            fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glLightModelf(pname, param);
    }
}

void GLEScmContext::lightModelfv(GLenum pname, const GLfloat* params) {
    switch (pname) {
        case GL_LIGHT_MODEL_AMBIENT:
            memcpy(&mLightModel.color, params, 4 * sizeof(GLfloat));
            break;
        case GL_LIGHT_MODEL_TWO_SIDE:
            if (*params != 1.0f && *params != 0.0f) {
                fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
                                "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", *params);
                setGLerror(GL_INVALID_VALUE);
            }
            mLightModel.twoSided = *params == 1.0f ? true : false;
            break;
        default:
            fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glLightModelfv(pname, params);
    }
}

void GLEScmContext::lightf(GLenum light, GLenum pname, GLfloat param) {
    uint32_t lightIndex = light - GL_LIGHT0;

    if (lightIndex >= kMaxLights) {
        fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for glLight(f/x) (wanted %u)\n",
                lightIndex);
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    switch (pname) {
        case GL_AMBIENT:
        case GL_DIFFUSE:
        case GL_SPECULAR:
        case GL_POSITION:
        case GL_SPOT_DIRECTION:
            fprintf(stderr, "GL_INVALID_ENUM: Invalid parameter name 0x%x "
                            "for glLight(f/x). Needs glLight(f/x)v.\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
        case GL_SPOT_EXPONENT:
            mLights[lightIndex].spotlightExponent = param;
            break;
        case GL_SPOT_CUTOFF:
            mLights[lightIndex].spotlightCutoffAngle = param;
            break;
        case GL_CONSTANT_ATTENUATION:
            mLights[lightIndex].attenuationConst = param;
            break;
        case GL_LINEAR_ATTENUATION:
            mLights[lightIndex].attenuationLinear = param;
            break;
        case GL_QUADRATIC_ATTENUATION:
            mLights[lightIndex].attenuationQuadratic = param;
            break;
        default:
            fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
                            "for glLight(f/x).\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glLightf(light, pname, param);
    }
}

void GLEScmContext::lightfv(GLenum light, GLenum pname, const GLfloat* params) {
    uint32_t lightIndex = light - GL_LIGHT0;

    if (lightIndex >= kMaxLights) {
        fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
                        "glLight(f/x)v (wanted %u)\n",
                lightIndex);
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    switch (pname) {
        case GL_AMBIENT:
            memcpy(&mLights[lightIndex].ambient, params, 4 * sizeof(GLfloat));
            break;
        case GL_DIFFUSE:
            memcpy(&mLights[lightIndex].diffuse, params, 4 * sizeof(GLfloat));
            break;
        case GL_SPECULAR:
            memcpy(&mLights[lightIndex].specular, params, 4 * sizeof(GLfloat));
            break;
        case GL_POSITION:
            memcpy(&mLights[lightIndex].position, params, 4 * sizeof(GLfloat));
            break;
        case GL_SPOT_DIRECTION:
            memcpy(&mLights[lightIndex].direction, params, 3 * sizeof(GLfloat));
            break;
        case GL_SPOT_EXPONENT:
            mLights[lightIndex].spotlightExponent = *params;
            break;
        case GL_SPOT_CUTOFF:
            mLights[lightIndex].spotlightCutoffAngle = *params;
            break;
        case GL_CONSTANT_ATTENUATION:
            mLights[lightIndex].attenuationConst = *params;
            break;
        case GL_LINEAR_ATTENUATION:
            mLights[lightIndex].attenuationLinear = *params;
            break;
        case GL_QUADRATIC_ATTENUATION:
            mLights[lightIndex].attenuationQuadratic = *params;
            break;
        default:
            fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
                            "for glLight(f/x).\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glLightfv(light, pname, params);
    }
}

void GLEScmContext::getLightfv(GLenum light, GLenum pname, GLfloat* params) {
    uint32_t lightIndex = light - GL_LIGHT0;

    if (lightIndex >= kMaxLights) {
        fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
                        "glGetLight(f/x)v (wanted %u)\n",
                lightIndex);
        setGLerror(GL_INVALID_ENUM);
        return;
    }

    switch (pname) {
        case GL_AMBIENT:
            memcpy(params, &mLights[lightIndex].ambient, 4 * sizeof(GLfloat));
            break;
        case GL_DIFFUSE:
            memcpy(params, &mLights[lightIndex].diffuse, 4 * sizeof(GLfloat));
            break;
        case GL_SPECULAR:
            memcpy(params, &mLights[lightIndex].specular, 4 * sizeof(GLfloat));
            break;
        case GL_POSITION:
            memcpy(params, &mLights[lightIndex].position, 4 * sizeof(GLfloat));
            break;
        case GL_SPOT_DIRECTION:
            memcpy(params, &mLights[lightIndex].direction, 3 * sizeof(GLfloat));
            break;
        case GL_SPOT_EXPONENT:
            *params = mLights[lightIndex].spotlightExponent;
            break;
        case GL_SPOT_CUTOFF:
            *params = mLights[lightIndex].spotlightCutoffAngle;
            break;
        case GL_CONSTANT_ATTENUATION:
            *params = mLights[lightIndex].attenuationConst;
            break;
        case GL_LINEAR_ATTENUATION:
            *params = mLights[lightIndex].attenuationLinear;
            break;
        case GL_QUADRATIC_ATTENUATION:
            *params = mLights[lightIndex].attenuationQuadratic;
            break;
        default:
            fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
                            "for glGetLight(f/x).\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glGetLightfv(light, pname, params);
    }
}

void GLEScmContext::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {

    mMultiTexCoord[target - GL_TEXTURE0].floatVal[0] = s;
    mMultiTexCoord[target - GL_TEXTURE0].floatVal[1] = t;
    mMultiTexCoord[target - GL_TEXTURE0].floatVal[2] = q;
    mMultiTexCoord[target - GL_TEXTURE0].floatVal[3] = r;

    if (!m_coreProfileEngine) {
        dispatcher().glMultiTexCoord4f(target, s, t, r, q);
    }
}

void GLEScmContext::normal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
    mNormal.type = GL_FLOAT;
    mNormal.val.floatVal[0] = nx;
    mNormal.val.floatVal[1] = ny;
    mNormal.val.floatVal[2] = nz;

    if (!m_coreProfileEngine) {
        dispatcher().glNormal3f(nx, ny, nz);
    }
}

void GLEScmContext::fogf(GLenum pname, GLfloat param) {
    switch (pname) {
        case GL_FOG_MODE: {
            GLenum mode = (GLenum)param;
            switch (mode) {
                case GL_EXP:
                case GL_EXP2:
                case GL_LINEAR:
                    mFog.mode = mode;
                    break;
                default:
                    fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
                                    "for glFog(f/x).\n", mode);
                    setGLerror(GL_INVALID_ENUM);
                    break;
            }
            break;
        }
        case GL_FOG_DENSITY:
            if (param < 0.0f) {
                fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x): GL_FOG_DENSITY "
                                "needs to be nonnegative, but got %f\n", param);
                setGLerror(GL_INVALID_VALUE);
                return;
            }
            mFog.density = param;
            break;
        case GL_FOG_START:
            mFog.start = param;
            break;
        case GL_FOG_END:
            mFog.end = param;
            break;
        case GL_FOG_COLOR:
            fprintf(stderr, "GL_INVALID_ENUM: GL_FOG_COLOR not allowed for glFog(f/x).\n");
            setGLerror(GL_INVALID_ENUM);
            break;
        default:
            fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
                            "for glFog(f/x).\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glFogf(pname, param);
    }
}

void GLEScmContext::fogfv(GLenum pname, const GLfloat* params) {
    switch (pname) {
        case GL_FOG_MODE: {
            GLenum mode = (GLenum)params[0];
            switch (mode) {
                case GL_EXP:
                case GL_EXP2:
                case GL_LINEAR:
                    mFog.mode = mode;
                    break;
                default:
                    fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
                                    "for glFog(f/x)v.\n", mode);
                    setGLerror(GL_INVALID_ENUM);
                    break;
            }
            break;
        }
        case GL_FOG_DENSITY:
            if (params[0] < 0.0f) {
                fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x)v: GL_FOG_DENSITY "
                                "needs to be nonnegative, but got %f\n", params[0]);
                setGLerror(GL_INVALID_VALUE);
                return;
            }
            mFog.density = params[0];
            break;
        case GL_FOG_START:
            mFog.start = params[0];
            break;
        case GL_FOG_END:
            mFog.end = params[0];
            break;
        case GL_FOG_COLOR:
            memcpy(&mFog.color, params, 4 * sizeof(GLfloat));
            break;
        default:
            fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
                            "for glFog(f/x)v.\n", pname);
            setGLerror(GL_INVALID_ENUM);
            return;
    }

    if (!m_coreProfileEngine) {
        dispatcher().glFogfv(pname, params);
    }
}

void GLEScmContext::enableClientState(GLenum clientState) {
    if (m_coreProfileEngine) {
        core().enableClientState(clientState);
    } else {
        dispatcher().glEnableClientState(clientState);
    }
}

void GLEScmContext::disableClientState(GLenum clientState) {
    if (m_coreProfileEngine) {
        core().disableClientState(clientState);
    } else {
        dispatcher().glDisableClientState(clientState);
    }
}

void GLEScmContext::drawTexOES(float x, float y, float z, float width, float height) {
    if (m_coreProfileEngine) {
        core().drawTexOES(x, y, z, width, height);
    } else {
        auto& gl = dispatcher();

        int numClipPlanes;

        GLint viewport[4] = {};
        z = (z>1 ? 1 : (z<0 ?  0 : z));

        float vertices[4*3] = {
            x , y, z,
            x , static_cast<float>(y+height), z,
            static_cast<float>(x+width), static_cast<float>(y+height), z,
            static_cast<float>(x+width), y, z
        };
        GLfloat texels[getMaxTexUnits()][4*2];
        memset((void*)texels, 0, getMaxTexUnits()*4*2*sizeof(GLfloat));

        gl.glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
        gl.glPushAttrib(GL_TRANSFORM_BIT);

        //setup projection matrix to draw in viewport aligned coordinates
        gl.glMatrixMode(GL_PROJECTION);
        gl.glPushMatrix();
        gl.glLoadIdentity();
        gl.glGetIntegerv(GL_VIEWPORT,viewport);
        gl.glOrtho(viewport[0],viewport[0] + viewport[2],viewport[1],viewport[1]+viewport[3],0,-1);
        //setup texture matrix
        gl.glMatrixMode(GL_TEXTURE);
        gl.glPushMatrix();
        gl.glLoadIdentity();
        //setup modelview matrix
        gl.glMatrixMode(GL_MODELVIEW);
        gl.glPushMatrix();
        gl.glLoadIdentity();
        //backup vbo's
        int array_buffer,element_array_buffer;
        gl.glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&array_buffer);
        gl.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,&element_array_buffer);
        gl.glBindBuffer(GL_ARRAY_BUFFER,0);
        gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

        //disable clip planes
        gl.glGetIntegerv(GL_MAX_CLIP_PLANES,&numClipPlanes);
        for (int i=0;i<numClipPlanes;++i)
            gl.glDisable(GL_CLIP_PLANE0+i);

        int nTexPtrs = 0;
        for (int i=0;i<getMaxTexUnits();++i) {
            if (isTextureUnitEnabled(GL_TEXTURE0+i)) {
                TextureData * texData = NULL;
                unsigned int texname = getBindedTexture(GL_TEXTURE0+i,GL_TEXTURE_2D);
                ObjectLocalName tex = getTextureLocalName(GL_TEXTURE_2D,texname);
                gl.glClientActiveTexture(GL_TEXTURE0+i);
                auto objData = shareGroup()->getObjectData(
                        NamedObjectType::TEXTURE, tex);
                if (objData) {
                    texData = (TextureData*)objData;
                    //calculate texels
                    texels[i][0] = (float)(texData->crop_rect[0])/(float)(texData->width);
                    texels[i][1] = (float)(texData->crop_rect[1])/(float)(texData->height);

                    texels[i][2] = (float)(texData->crop_rect[0])/(float)(texData->width);
                    texels[i][3] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);

                    texels[i][4] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
                    texels[i][5] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);

                    texels[i][6] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
                    texels[i][7] = (float)(texData->crop_rect[1])/(float)(texData->height);

                    gl.glTexCoordPointer(2,GL_FLOAT,0,texels[i]);
                    nTexPtrs++;
                }
            }
        }

        if (nTexPtrs>0) {
            //draw rectangle - only if we have some textures enabled & ready
            gl.glEnableClientState(GL_VERTEX_ARRAY);
            gl.glVertexPointer(3,GL_FLOAT,0,vertices);
            gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            gl.glDrawArrays(GL_TRIANGLE_FAN,0,4);
        }

        //restore vbo's
        gl.glBindBuffer(GL_ARRAY_BUFFER,array_buffer);
        gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,element_array_buffer);

        //restore matrix state

        gl.glMatrixMode(GL_MODELVIEW);
        gl.glPopMatrix();
        gl.glMatrixMode(GL_TEXTURE);
        gl.glPopMatrix();
        gl.glMatrixMode(GL_PROJECTION);
        gl.glPopMatrix();

        gl.glPopAttrib();
        gl.glPopClientAttrib();
    }
}

void GLEScmContext::rotatef(float angle, float x, float y, float z) {
    glm::mat4 rot = glm::rotate(glm::mat4(), 3.14159265358979f / 180.0f * angle, glm::vec3(x, y, z));
    currMatrix() *= rot;

    if (m_coreProfileEngine) {
        core().rotatef(angle, x, y, z);
    } else {
        dispatcher().glRotatef(angle, x, y, z);
    }
}

void GLEScmContext::scalef(float x, float y, float z) {
    glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(x, y, z));
    currMatrix() *= scale;

    if (m_coreProfileEngine) {
        core().scalef(x, y, z);
    } else {
        dispatcher().glScalef(x, y, z);
    }
}

void GLEScmContext::translatef(float x, float y, float z) {
    glm::mat4 tr = glm::translate(glm::mat4(), glm::vec3(x, y, z));
    currMatrix() *= tr;

    if (m_coreProfileEngine) {
        core().translatef(x, y, z);
    } else {
        dispatcher().glTranslatef(x, y, z);
    }
}

void GLEScmContext::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {

    mColor.type = GL_FLOAT;
    mColor.val.floatVal[0] = red;
    mColor.val.floatVal[1] = green;
    mColor.val.floatVal[2] = blue;
    mColor.val.floatVal[3] = alpha;

    if (m_coreProfileEngine) {
        core().color4f(red,green,blue,alpha);
    } else{
        dispatcher().glColor4f(red,green,blue,alpha);
    }
}

void GLEScmContext::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {

    mColor.type = GL_UNSIGNED_BYTE;
    mColor.val.ubyteVal[0] = red;
    mColor.val.ubyteVal[1] = green;
    mColor.val.ubyteVal[2] = blue;
    mColor.val.ubyteVal[3] = alpha;

    if (m_coreProfileEngine) {
        core().color4ub(red,green,blue,alpha);
    } else{
        dispatcher().glColor4ub(red,green,blue,alpha);
    }
}

void GLEScmContext::drawArrays(GLenum mode, GLint first, GLsizei count) {
    if (!isArrEnabled(GL_VERTEX_ARRAY)) return;

    drawValidate();

    GLuint prev_vbo;
    GLuint prev_ibo;
    dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
            (GLint*)&prev_vbo);
    dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
            (GLint*)&prev_ibo);
    dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
    dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    if (m_coreProfileEngine) {
        ArraysMap::iterator it;
        m_pointsIndex = -1;

        // going over all clients arrays Pointers
        for (it = m_currVaoState.begin();
             it != m_currVaoState.end(); ++it) {
            GLenum array_id = (*it).first;
            GLESpointer* p  = (*it).second;
            if (array_id == GL_VERTEX_ARRAY ||
                array_id == GL_NORMAL_ARRAY ||
                array_id == GL_COLOR_ARRAY ||
                array_id == GL_POINT_SIZE_ARRAY_OES ||
                array_id == GL_TEXTURE_COORD_ARRAY) {
                core().setupArrayForDraw(array_id, p, first, count, false, 0, nullptr);
            }
        }

        GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
        setClientActiveTexture(activeTexture);
        core().clientActiveTexture(activeTexture);
        core().drawArrays(mode, first, count);
    } else {
        GLESConversionArrays tmpArrs;

        setupArraysPointers(tmpArrs,first,count,0,NULL,true,nullptr);

        if (mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
            drawPointsArrs(tmpArrs,first,count);
        } else {
            dispatcher().glDrawArrays(mode,first,count);
        }
    }
    dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
    dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
}

void GLEScmContext::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
    if (!isArrEnabled(GL_VERTEX_ARRAY)) return;

    drawValidate();

    if(isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
        const unsigned char* buf = static_cast<unsigned char *>(getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
        indices = buf + SafeUIntFromPointer(indices);
    }

    GLuint prev_vbo;
    GLuint prev_ibo;
    dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
            (GLint*)&prev_vbo);
    dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
            (GLint*)&prev_ibo);
    dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
    dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    if (m_coreProfileEngine) {
        ArraysMap::iterator it;
        m_pointsIndex = -1;

        // going over all clients arrays Pointers
        for (it = m_currVaoState.begin();
             it != m_currVaoState.end(); ++it) {
            GLenum array_id = (*it).first;
            GLESpointer* p  = (*it).second;
            if (array_id == GL_VERTEX_ARRAY ||
                array_id == GL_NORMAL_ARRAY ||
                array_id == GL_COLOR_ARRAY ||
                array_id == GL_POINT_SIZE_ARRAY_OES ||
                array_id == GL_TEXTURE_COORD_ARRAY) {
                core().setupArrayForDraw(array_id, p, 0, count, true, type, indices);
            }
        }

        GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
        setClientActiveTexture(activeTexture);
        core().clientActiveTexture(activeTexture);
        core().drawElements(mode, count, type, indices);
    } else {
        GLESConversionArrays tmpArrs;

        setupArraysPointers(tmpArrs,0,count,type,indices,false,nullptr);
        if(mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
            drawPointsElems(tmpArrs,count,type,indices);
        }
        else{
            dispatcher().glDrawElements(mode,count,type,indices);
        }
    }
    dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
    dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
}

void GLEScmContext::clientActiveTexture(GLenum texture) {
    setClientActiveTexture(texture);
    if (m_coreProfileEngine) {
        core().clientActiveTexture(texture);
    } else {
        dispatcher().glClientActiveTexture(texture);
    }
}
