Emulator's GLES translator implementation.

This is the GLESv1 on top of OpenGL implementation on the host.
GLDispatch - dispatch table to host OpenGL implementation.
GLESimp - includes GLES entry points implementation.

Change-Id: Ief5eac2253a5a98b75a5d76363a36b7587d17391
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk b/tools/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk
new file mode 100644
index 0000000..8c94670
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk
@@ -0,0 +1,35 @@
+LOCAL_PATH := $(call my-dir)
+
+### GLES_CM host implementation (On top of OpenGL) ########################
+include $(CLEAR_VARS)
+
+translator_path := $(LOCAL_PATH)/..
+#exclude darwin builds
+ifeq (, $(findstring $(HOST_OS), darwin))
+
+LOCAL_SRC_FILES :=    \
+     GLDispatch.cpp   \
+     GLEScontext.cpp  \
+     GLESimp.cpp      \
+     GLESpointer.cpp  \
+     GLESvalidate.cpp \
+     GLESutils.cpp    \
+     GLESbuffer.cpp   \
+     TextureUtils.cpp \
+     RangeManip.cpp
+
+LOCAL_C_INCLUDES += \
+                 $(translator_path)/include
+
+LOCAL_STATIC_LIBRARIES := \
+    libGLcommon           \
+    libcutils
+
+LOCAL_CFLAGS := -g -O0
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := libGLES_CM_translator
+LOCAL_LDLIBS := -lGL
+
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp
new file mode 100644
index 0000000..27bc98b
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp
@@ -0,0 +1,171 @@
+/*
+* 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 "GLDispatch.h"
+#include <stdio.h>
+
+#ifdef __linux__
+#include <GL/glx.h>
+#elif defined(WIN32)
+#include <windows.h>
+#endif
+
+typedef void (*GL_FUNC_PTR)();
+
+static GL_FUNC_PTR getGLFuncAddress(const char *funcName) {
+#ifdef __linux__
+    return  (GL_FUNC_PTR)glXGetProcAddress((const GLubyte*)funcName);
+#elif defined(WIN32)
+    return  (GL_FUNC_PTR)wglGetProcAddress(funcName);
+#endif
+}
+
+#define LOAD_GL_FUNC(name)  {   void * funcAddrs = NULL;              \
+                funcAddrs = (void *)getGLFuncAddress(#name);      \
+                if(funcAddrs)                     \
+                    *(void**)(&name) = funcAddrs;         \
+                else                          \
+                    fprintf(stderr,"could not load func %s\n",#name); }
+
+GLDispatch::GLDispatch():m_isLoaded(false){};
+
+
+void GLDispatch::dispatchFuncs() {
+    android::Mutex::Autolock mutex(m_lock);
+    if(m_isLoaded)
+        return;
+
+    LOAD_GL_FUNC(glActiveTexture);
+    LOAD_GL_FUNC(glAlphaFunc);
+    LOAD_GL_FUNC(glBegin);
+    LOAD_GL_FUNC(glBindBuffer);
+    LOAD_GL_FUNC(glBindTexture);
+    LOAD_GL_FUNC(glBlendFunc);
+    LOAD_GL_FUNC(glBufferData);
+    LOAD_GL_FUNC(glBufferSubData);
+    LOAD_GL_FUNC(glClear);
+    LOAD_GL_FUNC(glClearColor);
+    LOAD_GL_FUNC(glClearDepthf);
+    LOAD_GL_FUNC(glClearStencil);
+    LOAD_GL_FUNC(glClientActiveTexture);
+    LOAD_GL_FUNC(glClipPlane);
+    LOAD_GL_FUNC(glColor4d);
+    LOAD_GL_FUNC(glColor4f);
+    LOAD_GL_FUNC(glColor4fv);
+    LOAD_GL_FUNC(glColor4ub);
+    LOAD_GL_FUNC(glColor4ubv);
+    LOAD_GL_FUNC(glColorMask);
+    LOAD_GL_FUNC(glColorPointer);
+    LOAD_GL_FUNC(glCompressedTexImage2D);
+    LOAD_GL_FUNC(glCompressedTexSubImage2D);
+    LOAD_GL_FUNC(glCopyTexImage2D);
+    LOAD_GL_FUNC(glCopyTexSubImage2D);
+    LOAD_GL_FUNC(glCullFace);
+    LOAD_GL_FUNC(glDeleteBuffers);
+    LOAD_GL_FUNC(glDeleteTextures);
+    LOAD_GL_FUNC(glDepthFunc);
+    LOAD_GL_FUNC(glDepthMask);
+    LOAD_GL_FUNC(glDepthRange);
+    LOAD_GL_FUNC(glDisable);
+    LOAD_GL_FUNC(glDisableClientState);
+    LOAD_GL_FUNC(glDrawArrays);
+    LOAD_GL_FUNC(glDrawElements);
+    LOAD_GL_FUNC(glEnable);
+    LOAD_GL_FUNC(glEnableClientState);
+    LOAD_GL_FUNC(glEnd);
+    LOAD_GL_FUNC(glFinish);
+    LOAD_GL_FUNC(glFlush);
+    LOAD_GL_FUNC(glFogf);
+    LOAD_GL_FUNC(glFogfv);
+    LOAD_GL_FUNC(glFrontFace);
+    LOAD_GL_FUNC(glFrustum);
+    LOAD_GL_FUNC(glGenBuffers);
+    LOAD_GL_FUNC(glGenTextures);
+    LOAD_GL_FUNC(glGetBooleanv);
+    LOAD_GL_FUNC(glGetBufferParameteriv);
+    LOAD_GL_FUNC(glGetClipPlane);
+    LOAD_GL_FUNC(glGetDoublev);
+    LOAD_GL_FUNC(glGetError);
+    LOAD_GL_FUNC(glGetFloatv);
+    LOAD_GL_FUNC(glGetIntegerv);
+    LOAD_GL_FUNC(glGetLightfv);
+    LOAD_GL_FUNC(glGetMaterialfv);
+    LOAD_GL_FUNC(glGetPointerv);
+    LOAD_GL_FUNC(glGetString);
+    LOAD_GL_FUNC(glGetTexEnvfv);
+    LOAD_GL_FUNC(glGetTexEnviv);
+    LOAD_GL_FUNC(glGetTexParameterfv);
+    LOAD_GL_FUNC(glGetTexParameteriv);
+    LOAD_GL_FUNC(glHint);
+    LOAD_GL_FUNC(glIsBuffer);
+    LOAD_GL_FUNC(glIsEnabled);
+    LOAD_GL_FUNC(glIsTexture);
+    LOAD_GL_FUNC(glLightf);
+    LOAD_GL_FUNC(glLightfv);
+    LOAD_GL_FUNC(glLightModelf);
+    LOAD_GL_FUNC(glLightModelfv);
+    LOAD_GL_FUNC(glLineWidth);
+    LOAD_GL_FUNC(glLoadIdentity);
+    LOAD_GL_FUNC(glLoadMatrixf);
+    LOAD_GL_FUNC(glLogicOp);
+    LOAD_GL_FUNC(glMaterialf);
+    LOAD_GL_FUNC(glMaterialfv);
+    LOAD_GL_FUNC(glMultiTexCoord2fv);
+    LOAD_GL_FUNC(glMultiTexCoord2sv);
+    LOAD_GL_FUNC(glMultiTexCoord3fv);
+    LOAD_GL_FUNC(glMultiTexCoord3sv);
+    LOAD_GL_FUNC(glMultiTexCoord4fv);
+    LOAD_GL_FUNC(glMultiTexCoord4sv);
+    LOAD_GL_FUNC(glMultiTexCoord4f);
+    LOAD_GL_FUNC(glMultMatrixf);
+    LOAD_GL_FUNC(glNormal3f);
+    LOAD_GL_FUNC(glNormal3fv);
+    LOAD_GL_FUNC(glNormal3sv);
+    LOAD_GL_FUNC(glOrtho);
+    LOAD_GL_FUNC(glPointParameterf);
+    LOAD_GL_FUNC(glPointParameterfv);
+    LOAD_GL_FUNC(glPointSize);
+    LOAD_GL_FUNC(glPolygonOffset);
+    LOAD_GL_FUNC(glRotatef);
+    LOAD_GL_FUNC(glScalef);
+    LOAD_GL_FUNC(glTexEnvf);
+    LOAD_GL_FUNC(glTexEnvfv);
+    LOAD_GL_FUNC(glTexParameterf);
+    LOAD_GL_FUNC(glTexParameterfv);
+    LOAD_GL_FUNC(glMatrixMode);
+    LOAD_GL_FUNC(glNormalPointer);
+    LOAD_GL_FUNC(glPixelStorei);
+    LOAD_GL_FUNC(glPopMatrix);
+    LOAD_GL_FUNC(glPushMatrix);
+    LOAD_GL_FUNC(glReadPixels);
+    LOAD_GL_FUNC(glSampleCoverage);
+    LOAD_GL_FUNC(glScissor);
+    LOAD_GL_FUNC(glShadeModel);
+    LOAD_GL_FUNC(glStencilFunc);
+    LOAD_GL_FUNC(glStencilMask);
+    LOAD_GL_FUNC(glStencilOp);
+    LOAD_GL_FUNC(glTexCoordPointer);
+    LOAD_GL_FUNC(glTexEnvi);
+    LOAD_GL_FUNC(glTexEnviv);
+    LOAD_GL_FUNC(glTexImage2D);
+    LOAD_GL_FUNC(glTexParameteri);
+    LOAD_GL_FUNC(glTexParameteriv);
+    LOAD_GL_FUNC(glTexSubImage2D);
+    LOAD_GL_FUNC(glTranslatef);
+    LOAD_GL_FUNC(glVertexPointer);
+    LOAD_GL_FUNC(glViewport);
+
+    m_isLoaded = true;
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h
new file mode 100644
index 0000000..af15183
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h
@@ -0,0 +1,158 @@
+/*
+* 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.
+*/
+#ifndef GLDISPATCHH
+#define GLDISPATCHH
+
+#include <GLES/gl.h>
+#include <utils/threads.h>
+
+#define GLAPIENTRY GL_APIENTRY
+
+typedef double      GLclampd;   /* double precision float in [0,1] */
+typedef double      GLdouble;   /* double precision float */
+
+class GLDispatch
+{
+public:
+
+    GLDispatch();
+    void dispatchFuncs();
+
+    void (GLAPIENTRY *glActiveTexture) ( GLenum texture );
+    void (GLAPIENTRY *glAlphaFunc) (GLenum func, GLclampf ref);
+    void (GLAPIENTRY *glBegin)( GLenum mode );
+    void (GLAPIENTRY *glBindBuffer) (GLenum target, GLuint buffer);
+    void (GLAPIENTRY *glBindTexture) (GLenum target, GLuint texture);
+    void (GLAPIENTRY *glBlendFunc) (GLenum sfactor, GLenum dfactor);
+    void (GLAPIENTRY *glBufferData) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+    void (GLAPIENTRY *glBufferSubData) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+    void (GLAPIENTRY *glClear) (GLbitfield mask);
+    void (GLAPIENTRY *glClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+    void (GLAPIENTRY *glClearDepthf) (GLclampd depth);
+    void (GLAPIENTRY *glClearStencil) (GLint s);
+    void (GLAPIENTRY *glClientActiveTexture) ( GLenum texture );
+    void (GLAPIENTRY *glClipPlane) (GLenum plane, const GLdouble *equation);
+    void (GLAPIENTRY *glColor4d) (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+    void (GLAPIENTRY *glColor4f) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+    void (GLAPIENTRY *glColor4fv) ( const GLfloat *v );
+    void (GLAPIENTRY *glColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+    void (GLAPIENTRY *glColor4ubv) ( const GLubyte *v );
+    void (GLAPIENTRY *glColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+    void (GLAPIENTRY *glColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+    void (GLAPIENTRY *glCompressedTexImage2D) ( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data );
+    void (GLAPIENTRY *glCompressedTexSubImage2D) ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data );
+    void (GLAPIENTRY *glCopyTexImage2D) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+    void (GLAPIENTRY *glCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+    void (GLAPIENTRY *glCullFace) (GLenum mode);
+    void (GLAPIENTRY *glDeleteBuffers) (GLsizei n, const GLuint *buffers);
+    void (GLAPIENTRY *glDeleteTextures) (GLsizei n, const GLuint *textures);
+    void (GLAPIENTRY *glDepthFunc) (GLenum func);
+    void (GLAPIENTRY *glDepthMask) (GLboolean flag);
+    void (GLAPIENTRY *glDepthRange) (GLclampd zNear, GLclampd zFar);
+    void (GLAPIENTRY *glDisable) (GLenum cap);
+    void (GLAPIENTRY *glDisableClientState) (GLenum array);
+    void (GLAPIENTRY *glDrawArrays) (GLenum mode, GLint first, GLsizei count);
+    void (GLAPIENTRY *glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+    void (GLAPIENTRY *glEnable) (GLenum cap);
+    void (GLAPIENTRY *glEnableClientState) (GLenum array);
+    void (GLAPIENTRY *glEnd) ( void );
+    void (GLAPIENTRY *glFinish) (void);
+    void (GLAPIENTRY *glFlush) (void);
+    void (GLAPIENTRY *glFogf) (GLenum pname, GLfloat param);
+    void (GLAPIENTRY *glFogfv) (GLenum pname, const GLfloat *params);
+    void (GLAPIENTRY *glFrontFace) (GLenum mode);
+    void (GLAPIENTRY *glFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+    void (GLAPIENTRY *glGenBuffers) (GLsizei n, GLuint *buffers);
+    void (GLAPIENTRY *glGenTextures) (GLsizei n, GLuint *textures);
+    void (GLAPIENTRY *glGetBooleanv) (GLenum pname, GLboolean *params);
+    void (GLAPIENTRY *glGetBufferParameteriv) (GLenum, GLenum, GLint *);
+    void (GLAPIENTRY *glGetClipPlane) (GLenum plane, GLdouble *equation);
+    void (GLAPIENTRY *glGetDoublev) ( GLenum pname, GLdouble *params );
+    GLenum (GLAPIENTRY *glGetError) (void);
+    void (GLAPIENTRY *glGetFloatv) (GLenum pname, GLfloat *params);
+    void (GLAPIENTRY *glGetIntegerv) (GLenum pname, GLint *params);
+    void (GLAPIENTRY *glGetLightfv) (GLenum light, GLenum pname, GLfloat *params);
+    void (GLAPIENTRY *glGetMaterialfv) (GLenum face, GLenum pname, GLfloat *params);
+    void (GLAPIENTRY *glGetPointerv) (GLenum pname, GLvoid* *params);
+    const GLubyte * (GLAPIENTRY *glGetString) (GLenum name);
+    void (GLAPIENTRY *glGetTexEnvfv) (GLenum target, GLenum pname, GLfloat *params);
+    void (GLAPIENTRY *glGetTexEnviv) (GLenum target, GLenum pname, GLint *params);
+    void (GLAPIENTRY *glGetTexParameterfv) (GLenum target, GLenum pname, GLfloat *params);
+    void (GLAPIENTRY *glGetTexParameteriv) (GLenum target, GLenum pname, GLint *params);
+    void (GLAPIENTRY *glHint) (GLenum target, GLenum mode);
+    GLboolean (GLAPIENTRY *glIsBuffer) (GLuint);
+    GLboolean (GLAPIENTRY *glIsEnabled) (GLenum cap);
+    GLboolean (GLAPIENTRY *glIsTexture) (GLuint texture);
+    void (GLAPIENTRY *glLightf) (GLenum light, GLenum pname, GLfloat param);
+    void (GLAPIENTRY *glLightfv) (GLenum light, GLenum pname, const GLfloat *params);
+    void (GLAPIENTRY *glLightModelf) (GLenum pname, GLfloat param);
+    void (GLAPIENTRY *glLightModelfv) (GLenum pname, const GLfloat *params);
+    void (GLAPIENTRY *glLineWidth) (GLfloat width);
+    void (GLAPIENTRY *glLoadIdentity) (void);
+    void (GLAPIENTRY *glLoadMatrixf) (const GLfloat *m);
+    void (GLAPIENTRY *glLogicOp) (GLenum opcode);
+    void (GLAPIENTRY *glMaterialf) (GLenum face, GLenum pname, GLfloat param);
+    void (GLAPIENTRY *glMaterialfv) (GLenum face, GLenum pname, const GLfloat *params);
+    void (GLAPIENTRY *glMultiTexCoord2fv) ( GLenum target, const GLfloat *v );
+    void (GLAPIENTRY *glMultiTexCoord2sv) ( GLenum target, const GLshort *v );
+    void (GLAPIENTRY *glMultiTexCoord3fv) ( GLenum target, const GLfloat *v );
+    void (GLAPIENTRY *glMultiTexCoord3sv) ( GLenum target, const GLshort *v );
+    void (GLAPIENTRY *glMultiTexCoord4f) ( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q );
+    void (GLAPIENTRY *glMultiTexCoord4fv) ( GLenum target, const GLfloat *v );
+    void (GLAPIENTRY *glMultiTexCoord4sv) ( GLenum target, const GLshort *v );
+    void (GLAPIENTRY *glMultMatrixf) (const GLfloat *m);
+    void (GLAPIENTRY *glNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz);
+    void (GLAPIENTRY *glNormal3fv) ( const GLfloat *v );
+    void (GLAPIENTRY *glNormal3sv) ( const GLshort *v );
+    void (GLAPIENTRY *glOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+    void (GLAPIENTRY *glPointParameterf) (GLenum, GLfloat);
+    void (GLAPIENTRY *glPointParameterfv) (GLenum, const GLfloat *);
+    void (GLAPIENTRY *glPointSize) (GLfloat size);
+    void (GLAPIENTRY *glPolygonOffset) (GLfloat factor, GLfloat units);
+    void (GLAPIENTRY *glRotatef) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+    void (GLAPIENTRY *glScalef) (GLfloat x, GLfloat y, GLfloat z);
+    void (GLAPIENTRY *glTexEnvf) (GLenum target, GLenum pname, GLfloat param);
+    void (GLAPIENTRY *glTexEnvfv) (GLenum target, GLenum pname, const GLfloat *params);
+    void (GLAPIENTRY *glTexParameterf) (GLenum target, GLenum pname, GLfloat param);
+    void (GLAPIENTRY *glTexParameterfv) (GLenum target, GLenum pname, const GLfloat *params);
+    void (GLAPIENTRY *glMatrixMode) (GLenum mode);
+    void (GLAPIENTRY *glNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
+    void (GLAPIENTRY *glPixelStorei) (GLenum pname, GLint param);
+    void (GLAPIENTRY *glPopMatrix) (void);
+    void (GLAPIENTRY *glPushMatrix) (void);
+    void (GLAPIENTRY *glReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+    void (GLAPIENTRY *glSampleCoverage) ( GLclampf value, GLboolean invert );
+    void (GLAPIENTRY *glScissor) (GLint x, GLint y, GLsizei width, GLsizei height);
+    void (GLAPIENTRY *glShadeModel) (GLenum mode);
+    void (GLAPIENTRY *glStencilFunc) (GLenum func, GLint ref, GLuint mask);
+    void (GLAPIENTRY *glStencilMask) (GLuint mask);
+    void (GLAPIENTRY *glStencilOp) (GLenum fail, GLenum zfail, GLenum zpass);
+    void (GLAPIENTRY *glTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+    void (GLAPIENTRY *glTexEnvi) (GLenum target, GLenum pname, GLint param);
+    void (GLAPIENTRY *glTexEnviv) (GLenum target, GLenum pname, const GLint *params);
+    void (GLAPIENTRY *glTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+    void (GLAPIENTRY *glTexParameteri) (GLenum target, GLenum pname, GLint param);
+    void (GLAPIENTRY *glTexParameteriv) (GLenum target, GLenum pname, const GLint *params);
+    void (GLAPIENTRY *glTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+    void (GLAPIENTRY *glTranslatef) (GLfloat x, GLfloat y, GLfloat z);
+    void (GLAPIENTRY *glVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+    void (GLAPIENTRY *glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
+private:
+    bool             m_isLoaded;
+    android::Mutex   m_lock;
+};
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.cpp
new file mode 100644
index 0000000..531e79d
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.cpp
@@ -0,0 +1,53 @@
+/*
+* 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 "GLESbuffer.h"
+#include <string.h>
+
+bool  GLESbuffer::setBuffer(GLuint size,GLuint usage,const GLvoid* data) {
+    m_size = size;
+    m_usage = usage;
+    if(m_data) {
+        delete [] m_data;
+        m_data = NULL;
+    }
+    m_data = new unsigned char[size];
+    if(m_data) {
+        memcpy(m_data,data,size);
+        m_conversionManager.clear();
+        m_conversionManager.addRange(Range(0,m_size));
+        return true;
+    }
+    return false;
+}
+
+bool  GLESbuffer::setSubBuffer(GLint offset,GLuint size,const GLvoid* data) {
+    if(offset + size > m_size) return false;
+    memcpy(m_data+offset,data,size);
+    m_conversionManager.addRange(Range(offset,size));
+    m_conversionManager.merge();
+    return true;
+}
+
+void  GLESbuffer::getConversions(const RangeList& rIn,RangeList& rOut) {
+        m_conversionManager.delRanges(rIn,rOut);
+        rOut.merge();
+}
+
+GLESbuffer::~GLESbuffer() {
+    if(m_data) {
+        delete [] m_data;
+    }
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h
new file mode 100644
index 0000000..e1326fc
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h
@@ -0,0 +1,42 @@
+/*
+* 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.
+*/
+#ifndef GLES_BUFFER_H
+#define GLES_BUFFER_H
+
+#include <stdio.h>
+#include <GLES/gl.h>
+#include "RangeManip.h"
+
+class GLESbuffer {
+public:
+   GLESbuffer():m_size(0),m_usage(GL_STATIC_DRAW),m_data(NULL){}
+   GLuint getSize(){return m_size;};
+   GLuint getUsage(){return m_usage;};
+   GLvoid* getData(){ return m_data;}
+   bool  setBuffer(GLuint size,GLuint usage,const GLvoid* data);
+   bool  setSubBuffer(GLint offset,GLuint size,const GLvoid* data);
+   void  getConversions(const RangeList& rIn,RangeList& rOut);
+   bool  fullyConverted(){return m_conversionManager.size() == 0;};
+   ~GLESbuffer();
+
+private:
+    GLuint         m_size;
+    GLuint         m_usage;
+    unsigned char* m_data;
+    RangeList      m_conversionManager;
+};
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp
new file mode 100644
index 0000000..1f9a1e5
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp
@@ -0,0 +1,528 @@
+/*
+* 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 "GLEScontext.h"
+#include "GLESutils.h"
+#include "GLfixed_ops.h"
+#include "RangeManip.h"
+#include <GLcommon/GLutils.h>
+#include <string.h>
+#include <GLES/gl.h>
+
+//declerations
+static void convertDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize);
+static void convertIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize);
+static int findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices);
+
+
+GLDispatch     GLEScontext::s_glDispatch;
+GLsupport      GLEScontext::s_glSupport;
+android::Mutex GLEScontext::s_lock;
+
+GLESFloatArrays::~GLESFloatArrays() {
+    for(std::map<GLenum,GLfloat*>::iterator it = arrays.begin(); it != arrays.end();it++) {
+        GLfloat* p = (*it).second;
+        if(p) {
+            delete[] p;
+        }
+    }
+}
+
+GLEScontext::~GLEScontext() {
+    for(ArraysMap::iterator it = m_map.begin(); it != m_map.end();it++) {
+        GLESpointer* p = (*it).second;
+        if(p) {
+            delete[] p;
+        }
+    }
+}
+
+void GLEScontext::init() {
+    android::Mutex::Autolock mutex(s_lock);
+    if(!m_initialized) {
+        int maxTexUnits;
+        s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane);
+        s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights);
+        s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize);
+        s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTexUnits);
+        s_glSupport.maxTexUnits = maxTexUnits < MAX_TEX_UNITS ? maxTexUnits:MAX_TEX_UNITS;
+    }
+
+    m_texCoords = new GLESpointer[s_glSupport.maxTexUnits];
+    m_map[GL_TEXTURE_COORD_ARRAY]  = &m_texCoords[m_activeTexture];
+    m_initialized = true;
+}
+
+GLEScontext::GLEScontext():m_glError(GL_NO_ERROR),m_activeTexture(0),m_arrayBuffer(0),m_elementBuffer(0),m_minAvailableBuffer(1),m_pointsIndex(-1),m_initialized(false) {
+
+    s_glDispatch.dispatchFuncs();
+
+    m_map[GL_COLOR_ARRAY]          = new GLESpointer();
+    m_map[GL_NORMAL_ARRAY]         = new GLESpointer();
+    m_map[GL_VERTEX_ARRAY]         = new GLESpointer();
+    m_map[GL_POINT_SIZE_ARRAY_OES] = new GLESpointer();
+}
+
+GLDispatch& GLEScontext::dispatcher() {
+    return s_glDispatch;
+}
+
+GLenum GLEScontext::getGLerror() {
+    return m_glError;
+}
+
+void GLEScontext::setGLerror(GLenum err) {
+    m_glError = err;
+}
+
+void GLEScontext::setActiveTexture(GLenum tex) {
+   m_activeTexture = tex - GL_TEXTURE0;
+   m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_activeTexture];
+}
+
+const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data) {
+    GLuint bufferName = m_arrayBuffer;
+    if(bufferName) {
+        unsigned int offset = reinterpret_cast<unsigned int>(data);
+        m_map[arrType]->setBuffer(size,type,stride,m_vbos[bufferName],offset);
+        return  static_cast<const unsigned char*>(m_vbos[bufferName]->getData()) +  offset;
+    }
+    m_map[arrType]->setArray(size,type,stride,data);
+    return data;
+}
+
+
+void GLEScontext::enableArr(GLenum arr,bool enable) {
+    m_map[arr]->enable(enable);
+}
+
+bool GLEScontext::isArrEnabled(GLenum arr) {
+    return m_map[arr]->isEnable();
+}
+
+const GLESpointer* GLEScontext::getPointer(GLenum arrType) {
+    if(m_map.find(arrType) != m_map.end()) return m_map[arrType];
+    return NULL;
+}
+
+//sending data to server side
+void GLEScontext::sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int index) {
+    switch(arrayType) {
+        case GL_VERTEX_ARRAY:
+            s_glDispatch.glVertexPointer(size,GL_FLOAT,stride,arr);
+            break;
+        case GL_NORMAL_ARRAY:
+            s_glDispatch.glNormalPointer(GL_FLOAT,stride,arr);
+            break;
+        case GL_TEXTURE_COORD_ARRAY:
+            s_glDispatch.glTexCoordPointer(size,GL_FLOAT,stride,arr);
+            break;
+        case GL_COLOR_ARRAY:
+            s_glDispatch.glColorPointer(size,GL_FLOAT,stride,arr);
+            break;
+        case GL_POINT_SIZE_ARRAY_OES:
+            m_pointsIndex = index;
+            break;
+    }
+}
+
+static void convertDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
+
+    for(unsigned int i = 0; i < nBytes;i+=strideOut) {
+        const GLfixed* fixed_data = (const GLfixed *)dataIn;
+        //filling attrib
+        for(int j=0;j<attribSize;j++) {
+            reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(dataOut)[i])[j] = X2F(fixed_data[j]);
+        }
+        dataIn += strideIn;
+    }
+}
+
+static void convertIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
+    for(int i = 0 ;i < count ;i++) {
+        unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]:
+                                                             ((GLushort *)indices)[i];
+        const GLfixed* fixed_data = (GLfixed *)(dataIn  + index*strideIn);
+        GLfloat* float_data = reinterpret_cast<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
+
+        for(int j=0;j<attribSize;j++) {
+            float_data[j] = X2F(fixed_data[j]);
+         }
+    }
+}
+
+static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) {
+
+    int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes
+    int stride = p->getStride()?p->getStride():attribSize;
+    int start  = p->getBufferOffset()+first*attribSize;
+    if(!p->getStride()) {
+        list.addRange(Range(start,count*attribSize));
+    } else {
+        for(int i = 0 ;i < count; i++,start+=stride) {
+            list.addRange(Range(start,attribSize));
+        }
+    }
+}
+
+static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) {
+
+    int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
+    int stride = p->getStride()?p->getStride():attribSize;
+    int start  = p->getBufferOffset();
+    for(int i=0 ; i < count; i++) {
+        GLushort index = (indices_type == GL_UNSIGNED_SHORT?
+                         static_cast<const GLushort*>(indices)[i]:
+                         static_cast<const GLubyte*>(indices)[i]);
+        list.addRange(Range(start+index*stride,attribSize));
+
+    }
+}
+
+int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLushort* indices) {
+
+    int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
+    int stride = p->getStride()?p->getStride():attribSize;
+    int offset = p->getBufferOffset();
+
+    int n = 0;
+    for(int i=0;i<ranges.size();i++) {
+        int startIndex = (ranges[i].getStart() - offset) / stride;
+        int nElements = ranges[i].getSize()/attribSize;
+        for(int j=0;j<nElements;j++) {
+            indices[n++] = startIndex+j;
+        }
+    }
+    return n;
+}
+
+void GLEScontext::convertDirect(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p,unsigned int& index) {
+    GLenum type    = p->getType();
+    if(isArrEnabled(array_id) && type == GL_FIXED) {
+        int attribSize = p->getSize();
+        unsigned int size = attribSize*count + first;
+        fArrs.arrays[index] = new GLfloat[size];
+        int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
+        const char* data = (const char*)p->getArrayData() + (first*stride);
+
+        convertDirectLoop(data,stride,fArrs.arrays[index],size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize);
+        sendArr(fArrs.arrays[index],array_id,attribSize,0,index);
+        index++;
+    }
+}
+
+void GLEScontext::convertDirectVBO(GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
+    GLenum type    = p->getType();
+    if(isArrEnabled(array_id) && type == GL_FIXED) {
+        RangeList ranges;
+        RangeList conversions;
+        GLushort* indices = NULL;
+        int attribSize = p->getSize();
+        int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
+        unsigned int size = p->getStride()?p->getStride()*count:attribSize*count*sizeof(GLfixed);
+        char* data = (char*)p->getBufferData() + (first*stride);
+
+        if(p->bufferNeedConversion()) {
+            directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset
+            p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
+
+            if(conversions.size()) { // there are some elements to convert
+               indices = new GLushort[count];
+               int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array
+               convertIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,indices,stride,attribSize);
+            }
+        }
+
+        sendArr(data,array_id,attribSize,p->getStride());
+        if(indices) delete[] indices;
+    }
+}
+
+void GLEScontext::convertIndirect(GLESFloatArrays& fArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p,unsigned int& index_out) {
+    GLenum type    = p->getType();
+    int maxElements = findMaxIndex(count,type,indices) + 1;
+
+    if(isArrEnabled(array_id) && type == GL_FIXED) {
+        int attribSize = p->getSize();
+        int size = attribSize * maxElements;
+        fArrs.arrays[index_out] = new GLfloat[size];
+        int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
+
+        const char* data = (const char*)p->getArrayData();
+        convertIndirectLoop(data,stride,fArrs.arrays[index_out],count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize);
+        sendArr(fArrs.arrays[index_out],array_id,attribSize,0,index_out);
+        index_out++;
+    }
+}
+
+void GLEScontext::convertIndirectVBO(GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
+    GLenum type    = p->getType();
+
+    if(isArrEnabled(array_id) && type == GL_FIXED) {
+        RangeList ranges;
+        RangeList conversions;
+        GLushort* conversionIndices = NULL;
+        int attribSize = p->getSize();
+        int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
+        char* data = static_cast<char*>(p->getBufferData());
+        if(p->bufferNeedConversion()) {
+            indirectToBytesRanges(indices,indices_type,count,p,ranges); //converting indices range to buffer bytes ranges by offset
+            p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
+            if(conversions.size()) { // there are some elements to convert
+                conversionIndices = new GLushort[count];
+                int nIndices = bytesRangesToIndices(conversions,p,conversionIndices); //converting bytes ranges by offset to indices in this array
+                convertIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,conversionIndices,stride,attribSize);
+            }
+        }
+        sendArr(data,array_id,attribSize,p->getStride());
+        if(conversionIndices) delete[] conversionIndices;
+    }
+}
+
+void GLEScontext::chooseConvertMethod(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id, unsigned int& index) {
+
+    bool vertexVBO = m_arrayBuffer!= 0;
+    if(direct) {
+        if(vertexVBO) {
+            convertDirectVBO(first,count,array_id,p);
+        } else {
+            convertDirect(fArrs,first,count,array_id,p,index);
+        }
+    } else {
+        if(vertexVBO) {
+            convertIndirectVBO(count,type,indices,array_id,p);
+        } else {
+            convertIndirect(fArrs,count,type,indices,array_id,p,index);
+        }
+    }
+}
+
+void GLEScontext::convertArrs(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct) {
+    ArraysMap::iterator it;
+    unsigned int index = 0;
+    m_pointsIndex = -1;
+
+    //going over all clients arrays Pointers
+    for ( it=m_map.begin() ; it != m_map.end(); it++ ) {
+        GLenum array_id   = (*it).first;
+        GLESpointer* p = (*it).second;
+
+        if(array_id == GL_TEXTURE_COORD_ARRAY) continue; //handling textures later
+        chooseConvertMethod(fArrs,first,count,type,indices,direct,p,array_id,index);
+    }
+
+    unsigned int activeTexture = m_activeTexture + GL_TEXTURE0;
+
+    s_lock.lock();
+    int maxTexUnits = s_glSupport.maxTexUnits;
+    s_lock.unlock();
+
+    //converting all texture coords arrays
+    for(int i=0; i< maxTexUnits;i++) {
+
+        unsigned int tex = GL_TEXTURE0+i;
+        setActiveTexture(tex);
+        s_glDispatch.glClientActiveTexture(tex);
+
+        GLenum array_id   = GL_TEXTURE_COORD_ARRAY;
+        GLESpointer* p = m_map[array_id];
+        chooseConvertMethod(fArrs,first,count,type,indices,direct,p,array_id,index);
+    }
+
+    setActiveTexture(activeTexture);
+    s_glDispatch.glClientActiveTexture(activeTexture);
+}
+
+
+static int findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) {
+    //finding max index
+    int max = 0;
+    if(type == GL_UNSIGNED_BYTE) {
+        GLubyte*  b_indices  =(GLubyte *)indices;
+        for(int i=0;i<count;i++) {
+            if(b_indices[i] > max) max = b_indices[i];
+        }
+    } else {
+        GLushort* us_indices =(GLushort *)indices;
+        for(int i=0;i<count;i++) {
+            if(us_indices[i] > max) max = us_indices[i];
+        }
+    }
+    return max;
+}
+
+//TODO change it into merge sort to work in O(nlogn)
+void sortPoints(GLfloat* sortedPoints,GLushort* sortedIndices,int size) {
+
+    int flag = 1;    // set flag to 1 to start first pass
+    for(int i = 1; (i <= size) && flag; i++) {
+        flag = 0;
+        for (int j=0; j < (size -1); j++) {
+            if (sortedPoints[j+1] < sortedPoints[j]) {
+                swap<GLfloat>(sortedPoints[j],sortedPoints[j+1]);
+                swap<GLushort>(sortedIndices[j],sortedIndices[j+1]);
+                flag = 1;               // indicates that a swap occurred.
+            }
+        }
+    }
+}
+
+
+void GLEScontext::drawPoints(PointSizeIndices* points) {
+
+    GLushort* indices = NULL;
+    int last_size = 0;
+
+    //drawing each group of vertices by the points size
+    for(PointSizeIndices::iterator it = points->begin();it != points->end(); it++) {
+            int count = (*it).second.size();
+            int pointSize = (*it).first;
+            std::vector<int>& arr = (*it).second;
+
+            if(count > last_size) {
+             if(indices) delete [] indices;
+             indices = new GLushort[count];
+            }
+            int i = 0 ;
+            for(std::vector<int>::iterator it2 = arr.begin();it2 != arr.end();it2++) {
+                indices[i++] = (*it2);
+            }
+            s_glDispatch.glPointSize(pointSize);
+            s_glDispatch.glDrawElements(GL_POINTS,count,GL_UNSIGNED_SHORT,indices);
+    }
+    if(indices) delete [] indices;
+}
+
+void  GLEScontext::drawPointsData(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw) {
+    const GLfloat  *pointsArr =  NULL;
+    int stride = 0; //steps in GLfloats
+
+    //choosing the right points sizes array source
+    if(m_pointsIndex >= 0) { //point size array was converted
+        pointsArr=fArrs.arrays[m_pointsIndex];
+        stride = 1;
+    } else {
+        GLESpointer* p = m_map[GL_POINT_SIZE_ARRAY_OES];
+        pointsArr = static_cast<const GLfloat*>(isBindedBuffer(GL_ARRAY_BUFFER)?p->getBufferData():p->getArrayData());
+        stride = p->getStride()?p->getStride()/sizeof(GLfloat):1;
+    }
+
+    //filling  arrays before sorting them
+    PointSizeIndices  points;
+    if(isElemsDraw) {
+        for(int i=0; i< count; i++) {
+            GLushort index = (type == GL_UNSIGNED_SHORT?
+                    static_cast<const GLushort*>(indices_in)[i]:
+                    static_cast<const GLubyte*>(indices_in)[i]);
+            points[pointsArr[index*stride]].push_back(index);
+        }
+    } else {
+        for(int i=0; i< count; i++) {
+            points[pointsArr[first+i*stride]].push_back(i+first);
+        }
+    }
+    drawPoints(&points);
+}
+
+void  GLEScontext::drawPointsArrs(GLESFloatArrays& arrs,GLint first,GLsizei count) {
+    drawPointsData(arrs,first,count,0,NULL,false);
+}
+
+void GLEScontext::drawPointsElems(GLESFloatArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices_in) {
+    drawPointsData(arrs,0,count,type,indices_in,true);
+}
+
+void GLEScontext:: genBuffers(GLsizei n,GLuint* buffers)
+{
+    int i = 0;
+    while(i < n) {
+        if(m_vbos.find(m_minAvailableBuffer) == m_vbos.end()) {
+           buffers[i++] = m_minAvailableBuffer;;
+           m_vbos[m_minAvailableBuffer] = new GLESbuffer();
+        }
+        m_minAvailableBuffer++;
+    }
+}
+
+void GLEScontext::deleteBuffers(GLsizei n,const GLuint* buffers) {
+    for(int i = 0; i < n ;i++) {
+       if(m_vbos.find(buffers[i]) != m_vbos.end()) {
+           if(m_vbos[buffers[i]]) delete m_vbos[buffers[i]];
+           if(buffers[i] < m_minAvailableBuffer) m_minAvailableBuffer = buffers[i];
+           m_vbos.erase(buffers[i]);
+       }
+    }
+}
+
+void GLEScontext::bindBuffer(GLenum target,GLuint buffer) {
+    if(target == GL_ARRAY_BUFFER) {
+        m_arrayBuffer = buffer;
+    } else {
+       m_elementBuffer = buffer;
+    }
+    if(m_vbos.find(buffer) == m_vbos.end()) { // buffer name wasn't generated before
+        m_vbos[buffer] = new GLESbuffer();
+    }
+}
+
+//checks if there is buffer named "buffer" and if this buffer is binded
+bool GLEScontext::isBuffer(GLuint buffer) {
+    if(m_vbos.find(buffer) != m_vbos.end()) {
+       if(m_elementBuffer == buffer || m_arrayBuffer == buffer) return true;
+    }
+    return false;
+}
+
+//checks if any buffer is binded to target
+bool GLEScontext::isBindedBuffer(GLenum target) {
+    if(target == GL_ARRAY_BUFFER) {
+        return m_arrayBuffer != 0;
+    } else {
+        return m_elementBuffer != 0;
+    }
+}
+
+GLuint GLEScontext::getBuffer(GLenum target) {
+    return target == GL_ARRAY_BUFFER ? m_arrayBuffer:m_elementBuffer;
+}
+
+GLvoid* GLEScontext::getBindedBuffer(GLenum target) {
+    GLuint bufferName = getBuffer(target);
+    if(!bufferName) return NULL;
+    return m_vbos[bufferName]->getData();
+}
+
+void GLEScontext::getBufferSize(GLenum target,GLint* param) {
+    GLuint bufferName = getBuffer(target);
+    *param = m_vbos[bufferName]->getSize();
+}
+
+void GLEScontext::getBufferUsage(GLenum target,GLint* param) {
+    GLuint bufferName = getBuffer(target);
+    *param = m_vbos[bufferName]->getUsage();
+}
+
+bool GLEScontext::setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage) {
+    GLuint bufferName = getBuffer(target);
+    if(!bufferName) return false;
+    return m_vbos[bufferName]->setBuffer(size,usage,data);
+}
+
+bool GLEScontext::setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data) {
+
+    GLuint bufferName = getBuffer(target);
+    if(!bufferName) return false;
+    return m_vbos[bufferName]->setSubBuffer(offset,size,data);
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h
new file mode 100644
index 0000000..7322609
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h
@@ -0,0 +1,116 @@
+/*
+* 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.
+*/
+#ifndef GLES_CONTEX_H
+#define GLES_CONTEX_H
+
+#include "GLDispatch.h"
+#include "GLESpointer.h"
+#include "GLESbuffer.h"
+#include <map>
+#include <vector>
+#include <utils/threads.h>
+
+#define MAX_TEX_UNITS 8
+
+typedef std::map<GLenum,GLESpointer*>  ArraysMap;
+typedef std::map<GLuint,GLESbuffer*>   BuffersMap;
+typedef std::map<GLfloat,std::vector<int> > PointSizeIndices;
+
+struct GLESFloatArrays
+{
+    GLESFloatArrays(){};
+    ~GLESFloatArrays();
+    std::map<GLenum,GLfloat*> arrays;
+};
+
+
+struct GLsupport {
+    GLsupport():maxLights(0),maxClipPlane(0),maxTexUnits(0),maxTexSize(0){};
+    int  maxLights;
+    int  maxClipPlane;
+    int  maxTexUnits;
+    int  maxTexSize;
+};
+
+class GLEScontext
+{
+public:
+    void init();
+    GLEScontext();
+    GLenum getGLerror();
+
+    bool  isArrEnabled(GLenum);
+    void  enableArr(GLenum arr,bool enable);
+    void  setGLerror(GLenum err);
+    void  setActiveTexture(GLenum tex);
+    const GLvoid* setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data);
+    const GLESpointer* getPointer(GLenum arrType);
+
+    void convertArrs(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct);
+    void drawPointsArrs(GLESFloatArrays& arrs,GLint first,GLsizei count);
+    void drawPointsElems(GLESFloatArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices);
+
+    void genBuffers(GLsizei n,GLuint* buffers);
+    void deleteBuffers(GLsizei n,const GLuint* buffers);
+    void bindBuffer(GLenum target,GLuint buffer);
+    bool isBuffer(GLuint buffer);
+    bool isBindedBuffer(GLenum target);
+    GLvoid* getBindedBuffer(GLenum target);
+    void getBufferSize(GLenum target,GLint* param);
+    void getBufferUsage(GLenum target,GLint* param);
+    bool setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage);
+    bool setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data);
+
+    static GLDispatch& dispatcher();
+    static int getMaxLights(){return s_glSupport.maxLights;}
+    static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;}
+    static int getMaxTexUnits(){return s_glSupport.maxTexUnits;}
+    static int getMaxTexSize(){return s_glSupport.maxTexSize;}
+
+    ~GLEScontext();
+private:
+
+    GLuint getBuffer(GLenum target);
+    void sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int pointsIndex = -1);
+    void drawPoints(PointSizeIndices* points);
+    void drawPointsData(GLESFloatArrays& arrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw);
+
+    void chooseConvertMethod(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id,unsigned int& index);
+    void convertDirect(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p,unsigned int& index);
+    void convertDirectVBO(GLint first,GLsizei count,GLenum array_id,GLESpointer* p);
+    void convertIndirect(GLESFloatArrays& fArrs,GLsizei count,GLenum type,const GLvoid* indices,GLenum array_id,GLESpointer* p,unsigned int& index);
+    void convertIndirectVBO(GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p);
+
+    static GLDispatch     s_glDispatch;
+    static GLsupport      s_glSupport;
+    static android::Mutex s_lock;
+
+    ArraysMap             m_map;
+    GLESpointer*          m_texCoords;
+    GLenum                m_glError;
+    unsigned int          m_activeTexture;
+    unsigned int          m_arrayBuffer;
+    unsigned int          m_elementBuffer;
+
+    unsigned int          m_minAvailableBuffer;
+    BuffersMap            m_vbos;
+
+    int                   m_pointsIndex;
+    bool                  m_initialized;
+};
+
+#endif
+
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp
new file mode 100644
index 0000000..ab10a04
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp
@@ -0,0 +1,1128 @@
+/*
+* 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 <stdio.h>
+#include "GLDispatch.h"
+#include "GLEScontext.h"
+#include "GLESvalidate.h"
+#include "GLESutils.h"
+#include "GLfixed_ops.h"
+#include "TextureUtils.h"
+
+#include <GLcommon/TranslatorIfaces.h>
+#include <GLcommon/ThreadInfo.h>
+#include <GLES/gl.h>
+#include <cmath>
+
+
+extern "C" {
+
+//decleration
+static void initContext(GLEScontext* ctx);
+static GLEScontext* createGLESContext();
+static void deleteGLESContext(GLEScontext* ctx);
+
+}
+
+static EGLiface*  s_eglIface = NULL;
+static GLESiface  s_glesIface = {
+    createGLESContext:createGLESContext,
+    initContext      :initContext,
+    deleteGLESContext:deleteGLESContext,
+    flush            :glFlush,
+    finish           :glFinish
+};
+
+extern "C" {
+
+static void initContext(GLEScontext* ctx) {
+    ctx->init();
+}
+static GLEScontext* createGLESContext() {
+    GLEScontext* ctx = new GLEScontext();
+    return ctx;
+}
+
+static void deleteGLESContext(GLEScontext* ctx) {
+    if(ctx) delete ctx;
+}
+
+GLESiface* __translator_getIfaces(EGLiface* eglIface){
+    s_eglIface = eglIface;
+    return & s_glesIface;
+}
+
+}
+
+#define GET_THREAD()                                                         \
+            ThreadInfo* thrd = NULL;                                         \
+            if(s_eglIface) {                                                 \
+                thrd = s_eglIface->getThreadInfo();                          \
+            } else {                                                         \
+                fprintf(stderr,"Context wasn't initialized yet \n");         \
+            }
+ 
+
+#define GET_CTX()                                                            \
+            GET_THREAD();                                                    \
+            if(!thrd) return;                                                \
+            GLEScontext *ctx = static_cast<GLEScontext*>(thrd->glesContext);
+
+#define GET_CTX_RET(failure_ret)                                             \
+            GET_THREAD();                                                    \
+            if(!thrd) return failure_ret;                                    \
+            GLEScontext *ctx = static_cast<GLEScontext*>(thrd->glesContext);
+
+
+#define SET_ERROR_IF(condition,err) if((condition)) {                        \
+                        ctx->setGLerror(err);                                \
+                        return;                                              \
+                    }
+
+
+#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {            \
+                        ctx->setGLerror(err);                                \
+                        return ret;                                          \
+                    }
+
+
+GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) {
+    GET_CTX_RET(GL_FALSE)
+    return ctx->isBuffer(buffer);
+}
+
+GL_API GLboolean GL_APIENTRY  glIsEnabled( GLenum cap) {
+    GET_CTX_RET(GL_FALSE)
+    RET_AND_SET_ERROR_IF(!GLESvalidate::capability(cap,ctx->getMaxLights(),ctx->getMaxClipPlanes()),GL_INVALID_ENUM,GL_FALSE);
+
+    if(cap == GL_POINT_SIZE_ARRAY_OES) return ctx->isArrEnabled(cap);
+    return ctx->dispatcher().glIsEnabled(cap);
+}
+
+GL_API GLboolean GL_APIENTRY  glIsTexture( GLuint texture) {
+    GET_CTX_RET(GL_FALSE)
+    return ctx->dispatcher().glIsTexture(texture);
+}
+
+GL_API GLenum GL_APIENTRY  glGetError(void) {
+    GET_CTX_RET(GL_NO_ERROR)
+    GLenum err = ctx->getGLerror();
+    if(err != GL_NO_ERROR) {
+        ctx->setGLerror(GL_NO_ERROR);
+        return err;
+    }
+
+    return ctx->dispatcher().glGetError();
+}
+
+GL_API const GLubyte * GL_APIENTRY  glGetString( GLenum name) {
+
+    GET_CTX_RET(NULL)
+    static GLubyte VENDOR[]     = "Google";
+    static GLubyte RENDERER[]   = "OpenGL ES-CM 1.1";
+    static GLubyte VERSION[]    = "OpenGL ES-CM 1.1";
+    static GLubyte EXTENSIONS[] = "GL_OES_compressed_paletted_texture "
+                                  "GL_OES_point_size_array";
+    switch(name) {
+        case GL_VENDOR:
+            return VENDOR;
+        case GL_RENDERER:
+            return RENDERER;
+        case GL_VERSION:
+            return VERSION;
+        case GL_EXTENSIONS:
+            return EXTENSIONS;
+        default:
+            RET_AND_SET_ERROR_IF(true,GL_INVALID_ENUM,NULL);
+    }
+}
+
+GL_API void GL_APIENTRY  glActiveTexture( GLenum texture) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::textureEnum(texture,ctx->getMaxTexUnits()),GL_INVALID_ENUM);
+    ctx->dispatcher().glActiveTexture(texture);
+}
+
+GL_API void GL_APIENTRY  glAlphaFunc( GLenum func, GLclampf ref) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::alphaFunc(func),GL_INVALID_ENUM);
+    ctx->dispatcher().glAlphaFunc(func,ref);
+}
+
+
+GL_API void GL_APIENTRY  glAlphaFuncx( GLenum func, GLclampx ref) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::alphaFunc(func),GL_INVALID_ENUM);
+    ctx->dispatcher().glAlphaFunc(func,X2F(ref));
+}
+
+
+GL_API void GL_APIENTRY  glBindBuffer( GLenum target, GLuint buffer) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::bufferTarget(target),GL_INVALID_ENUM);
+    ctx->bindBuffer(target,buffer);
+}
+
+GL_API void GL_APIENTRY  glBindTexture( GLenum target, GLuint texture) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::textureTarget(target),GL_INVALID_ENUM)
+    ctx->dispatcher().glBindTexture(target,texture);
+}
+
+GL_API void GL_APIENTRY  glBlendFunc( GLenum sfactor, GLenum dfactor) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::blendSrc(sfactor) || !GLESvalidate::blendDst(dfactor),GL_INVALID_ENUM)
+    ctx->dispatcher().glBlendFunc(sfactor,dfactor);
+}
+
+GL_API void GL_APIENTRY  glBufferData( GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::bufferTarget(target),GL_INVALID_ENUM);
+    SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
+    ctx->setBufferData(target,size,data,usage);
+}
+
+GL_API void GL_APIENTRY  glBufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) {
+    GET_CTX()
+    SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
+    SET_ERROR_IF(!GLESvalidate::bufferTarget(target),GL_INVALID_ENUM);
+    SET_ERROR_IF(!ctx->setBufferSubData(target,offset,size,data),GL_INVALID_VALUE);
+}
+
+GL_API void GL_APIENTRY  glClear( GLbitfield mask) {
+    GET_CTX()
+    ctx->dispatcher().glClear(mask);
+}
+
+GL_API void GL_APIENTRY  glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+    GET_CTX()
+    ctx->dispatcher().glClearColor(red,green,blue,alpha);
+}
+
+GL_API void GL_APIENTRY  glClearColorx( GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+    GET_CTX()
+    ctx->dispatcher().glClearColor(X2F(red),X2F(green),X2F(blue),X2F(alpha));
+}
+
+
+GL_API void GL_APIENTRY  glClearDepthf( GLclampf depth) {
+    GET_CTX()
+    ctx->dispatcher().glClearDepthf(depth);
+}
+
+GL_API void GL_APIENTRY  glClearDepthx( GLclampx depth) {
+    GET_CTX()
+    ctx->dispatcher().glClearDepthf(X2F(depth));
+}
+
+GL_API void GL_APIENTRY  glClearStencil( GLint s) {
+    GET_CTX()
+    ctx->dispatcher().glClearStencil(s);
+}
+
+GL_API void GL_APIENTRY  glClientActiveTexture( GLenum texture) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::textureEnum(texture,ctx->getMaxTexUnits()),GL_INVALID_ENUM);
+    ctx->setActiveTexture(texture);
+    ctx->dispatcher().glClientActiveTexture(texture);
+
+}
+
+GL_API void GL_APIENTRY  glClipPlanef( GLenum plane, const GLfloat *equation) {
+    GET_CTX()
+    GLdouble tmpEquation[4];
+
+    for(int i = 0; i < 4; i++) {
+         tmpEquation[i] = static_cast<GLdouble>(equation[i]);
+    }
+    ctx->dispatcher().glClipPlane(plane,tmpEquation);
+}
+
+GL_API void GL_APIENTRY  glClipPlanex( GLenum plane, const GLfixed *equation) {
+    GET_CTX()
+    GLdouble tmpEquation[4];
+    for(int i = 0; i < 4; i++) {
+        tmpEquation[i] = X2D(equation[i]);
+    }
+    ctx->dispatcher().glClipPlane(plane,tmpEquation);
+}
+
+GL_API void GL_APIENTRY  glColor4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
+    GET_CTX()
+    ctx->dispatcher().glColor4f(red,green,blue,alpha);
+}
+
+GL_API void GL_APIENTRY  glColor4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
+    GET_CTX()
+    ctx->dispatcher().glColor4ub(red,green,blue,alpha);
+}
+
+GL_API void GL_APIENTRY  glColor4x( GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
+    GET_CTX()
+    ctx->dispatcher().glColor4f(X2F(red),X2F(green),X2F(blue),X2F(alpha));
+}
+
+GL_API void GL_APIENTRY  glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
+    GET_CTX()
+    ctx->dispatcher().glColorMask(red,green,blue,alpha);
+}
+
+GL_API void GL_APIENTRY  glColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::colorPointerParams(size,stride),GL_INVALID_VALUE);
+
+    const GLvoid* data = ctx->setPointer(GL_COLOR_ARRAY,size,type,stride,pointer);
+    if(type != GL_FIXED) ctx->dispatcher().glColorPointer(size,type,stride,data);
+}
+
+GL_API void GL_APIENTRY  glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) {
+    GET_CTX()
+    SET_ERROR_IF(!(GLESvalidate::texCompImgFrmt(internalformat) && GLESvalidate::textureTarget(target)),GL_INVALID_ENUM);
+    SET_ERROR_IF(level > log2(ctx->getMaxTexSize())|| border !=0 || level > 0 || !GLESvalidate::texImgDim(width,height,ctx->getMaxTexSize()+2),GL_INVALID_VALUE)
+
+    int nMipmaps = -level + 1;
+    GLsizei tmpWidth  = width;
+    GLsizei tmpHeight = height;
+
+    for(int i = 0; i < nMipmaps ; i++)
+    {
+       GLenum uncompressedFrmt;
+       unsigned char* uncompressed = uncompressTexture(internalformat,uncompressedFrmt,width,height,imageSize,data,i);
+       ctx->dispatcher().glTexImage2D(target,i,uncompressedFrmt,width,height,border,uncompressedFrmt,GL_UNSIGNED_BYTE,uncompressed);
+       tmpWidth/=2;
+       tmpHeight/=2;
+       delete uncompressed;
+    }
+    ctx->dispatcher().glCompressedTexImage2D(target,level,internalformat,width,height,border,imageSize,data);
+}
+
+GL_API void GL_APIENTRY  glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) {
+    GET_CTX()
+    SET_ERROR_IF(!(GLESvalidate::texCompImgFrmt(format) && GLESvalidate::textureTarget(target)),GL_INVALID_ENUM);
+    SET_ERROR_IF(level < 0 || level > log2(ctx->getMaxTexSize()),GL_INVALID_VALUE)
+
+    GLenum uncompressedFrmt;
+    unsigned char* uncompressed = uncompressTexture(format,uncompressedFrmt,width,height,imageSize,data,level);
+    ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,uncompressedFrmt,GL_UNSIGNED_BYTE,uncompressed);
+    delete uncompressed;
+}
+
+GL_API void GL_APIENTRY  glCopyTexImage2D( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
+    GET_CTX()
+    SET_ERROR_IF(!(GLESvalidate::pixelFrmt(internalformat) && GLESvalidate::textureTarget(target)),GL_INVALID_ENUM);
+    SET_ERROR_IF(border != 0,GL_INVALID_VALUE);
+    ctx->dispatcher().glCopyTexImage2D(target,level,internalformat,x,y,width,height,border);
+}
+
+GL_API void GL_APIENTRY  glCopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::textureTarget(target),GL_INVALID_ENUM);
+    ctx->dispatcher().glCopyTexSubImage2D(target,level,xoffset,yoffset,x,y,width,height);
+}
+
+GL_API void GL_APIENTRY  glCullFace( GLenum mode) {
+    GET_CTX()
+    ctx->dispatcher().glCullFace(mode);
+}
+
+GL_API void GL_APIENTRY  glDeleteBuffers( GLsizei n, const GLuint *buffers) {
+    GET_CTX()
+    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
+    ctx->deleteBuffers(n,buffers);
+}
+
+GL_API void GL_APIENTRY  glDeleteTextures( GLsizei n, const GLuint *textures) {
+    GET_CTX()
+    ctx->dispatcher().glDeleteTextures(n,textures);
+}
+
+GL_API void GL_APIENTRY  glDepthFunc( GLenum func) {
+    GET_CTX()
+    ctx->dispatcher().glDepthFunc(func);
+}
+
+GL_API void GL_APIENTRY  glDepthMask( GLboolean flag) {
+    GET_CTX()
+    ctx->dispatcher().glDepthMask(flag);
+}
+
+GL_API void GL_APIENTRY  glDepthRangef( GLclampf zNear, GLclampf zFar) {
+    GET_CTX()
+    ctx->dispatcher().glDepthRange(zNear,zFar);
+}
+
+GL_API void GL_APIENTRY  glDepthRangex( GLclampx zNear, GLclampx zFar) {
+    GET_CTX()
+    ctx->dispatcher().glDepthRange(X2F(zNear),X2F(zFar));
+}
+
+GL_API void GL_APIENTRY  glDisable( GLenum cap) {
+    GET_CTX()
+    ctx->dispatcher().glDisable(cap);
+}
+
+GL_API void GL_APIENTRY  glDisableClientState( GLenum array) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::supportedArrays(array),GL_INVALID_ENUM)
+
+    ctx->enableArr(array,false);
+    if(array != GL_POINT_SIZE_ARRAY_OES) ctx->dispatcher().glDisableClientState(array);
+}
+
+
+GL_API void GL_APIENTRY  glDrawArrays( GLenum mode, GLint first, GLsizei count) {
+    GET_CTX()
+    SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
+    SET_ERROR_IF(!GLESvalidate::drawMode(mode),GL_INVALID_ENUM)
+
+    if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return;
+
+    GLESFloatArrays tmpArrs;
+    ctx->convertArrs(tmpArrs,first,count,0,NULL,true);
+    if(mode != GL_POINTS || !ctx->isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
+        ctx->dispatcher().glDrawArrays(mode,first,count);
+    }
+    else{
+        ctx->drawPointsArrs(tmpArrs,first,count);
+    }
+}
+
+GL_API void GL_APIENTRY  glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *elementsIndices) {
+    GET_CTX()
+    SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
+    SET_ERROR_IF((!GLESvalidate::drawMode(mode) || !GLESvalidate::drawType(type)),GL_INVALID_ENUM)
+    const GLvoid* indices = elementsIndices;
+    GLESFloatArrays tmpArrs;
+    if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
+        const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
+        indices = buf+reinterpret_cast<unsigned int>(elementsIndices);
+    }
+
+    ctx->convertArrs(tmpArrs,0,count,type,indices,false);
+    if(mode != GL_POINTS || !ctx->isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
+        ctx->dispatcher().glDrawElements(mode,count,type,indices);
+    }
+    else{
+        ctx->drawPointsElems(tmpArrs,count,type,indices);
+    }
+}
+
+GL_API void GL_APIENTRY  glEnable( GLenum cap) {
+    GET_CTX()
+    ctx->dispatcher().glEnable(cap);
+}
+
+GL_API void GL_APIENTRY  glEnableClientState( GLenum array) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::supportedArrays(array),GL_INVALID_ENUM)
+
+    ctx->enableArr(array,true);
+    if(array != GL_POINT_SIZE_ARRAY_OES) ctx->dispatcher().glEnableClientState(array);
+}
+
+GL_API void GL_APIENTRY  glFinish( void) {
+    GET_CTX()
+    ctx->dispatcher().glFinish();
+}
+
+GL_API void GL_APIENTRY  glFlush( void) {
+    GET_CTX()
+    ctx->dispatcher().glFlush();
+}
+
+GL_API void GL_APIENTRY  glFogf( GLenum pname, GLfloat param) {
+    GET_CTX()
+    ctx->dispatcher().glFogf(pname,param);
+}
+
+GL_API void GL_APIENTRY  glFogfv( GLenum pname, const GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glFogfv(pname,params);
+}
+
+GL_API void GL_APIENTRY  glFogx( GLenum pname, GLfixed param) {
+    GET_CTX()
+    ctx->dispatcher().glFogf(pname,(pname == GL_FOG_MODE)? static_cast<GLfloat>(param):X2F(param));
+}
+
+GL_API void GL_APIENTRY  glFogxv( GLenum pname, const GLfixed *params) {
+    GET_CTX()
+    if(pname == GL_FOG_MODE) {
+        GLfloat tmpParam = static_cast<GLfloat>(params[0]);
+        ctx->dispatcher().glFogfv(pname,&tmpParam);
+    } else {
+        GLfloat tmpParams[4];
+        for(int i=0; i< 4; i++) {
+            tmpParams[i] = X2F(params[i]);
+        }
+        ctx->dispatcher().glFogfv(pname,tmpParams);
+    }
+
+}
+
+GL_API void GL_APIENTRY  glFrontFace( GLenum mode) {
+    GET_CTX()
+    ctx->dispatcher().glFrontFace(mode);
+}
+
+GL_API void GL_APIENTRY  glFrustumf( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+    GET_CTX()
+    ctx->dispatcher().glFrustum(left,right,bottom,top,zNear,zFar);
+}
+
+GL_API void GL_APIENTRY  glFrustumx( GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+    GET_CTX()
+    ctx->dispatcher().glFrustum(X2F(left),X2F(right),X2F(bottom),X2F(top),X2F(zNear),X2F(zFar));
+}
+
+GL_API void GL_APIENTRY  glGenBuffers( GLsizei n, GLuint *buffers) {
+    GET_CTX()
+    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
+    ctx->genBuffers(n,buffers);
+}
+
+GL_API void GL_APIENTRY  glGenTextures( GLsizei n, GLuint *textures) {
+    GET_CTX()
+    ctx->dispatcher().glGenTextures(n,textures);
+}
+
+GL_API void GL_APIENTRY  glGetBooleanv( GLenum pname, GLboolean *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetBooleanv(pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetBufferParameteriv( GLenum target, GLenum pname, GLint *params) {
+    GET_CTX()
+    SET_ERROR_IF(!(GLESvalidate::bufferTarget(target) && GLESvalidate::bufferParam(pname)),GL_INVALID_ENUM);
+    SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
+    bool ret = true;
+    switch(pname) {
+    case GL_BUFFER_SIZE:
+        ctx->getBufferSize(target,params);
+        break;
+    case GL_BUFFER_USAGE:
+        ctx->getBufferUsage(target,params);
+        break;
+    }
+
+}
+
+GL_API void GL_APIENTRY  glGetClipPlanef( GLenum pname, GLfloat eqn[4]) {
+    GET_CTX()
+    GLdouble tmpEqn[4];
+
+    ctx->dispatcher().glGetClipPlane(pname,tmpEqn);
+    for(int i =0 ;i < 4; i++){
+        eqn[i] = static_cast<GLfloat>(tmpEqn[i]);
+    }
+}
+
+GL_API void GL_APIENTRY  glGetClipPlanex( GLenum pname, GLfixed eqn[4]) {
+    GET_CTX()
+    GLdouble tmpEqn[4];
+
+    ctx->dispatcher().glGetClipPlane(pname,tmpEqn);
+    for(int i =0 ;i < 4; i++){
+        eqn[i] = F2X(tmpEqn[i]);
+    }
+}
+
+GL_API void GL_APIENTRY  glGetFixedv( GLenum pname, GLfixed *params) {
+    GET_CTX()
+    size_t nParams = glParamSize(pname);
+    GLfloat fParams[16];
+    ctx->dispatcher().glGetFloatv(pname,fParams);
+    for(size_t i =0 ; i < nParams;i++) {
+        params[i] = F2X(fParams[i]);
+    }
+}
+
+GL_API void GL_APIENTRY  glGetFloatv( GLenum pname, GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetFloatv(pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetIntegerv( GLenum pname, GLint *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetIntegerv(pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetLightfv( GLenum light, GLenum pname, GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetLightfv(light,pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetLightxv( GLenum light, GLenum pname, GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParams[4];
+
+    ctx->dispatcher().glGetLightfv(light,pname,tmpParams);
+    switch (pname){
+        case GL_AMBIENT:
+        case GL_DIFFUSE:
+        case GL_SPECULAR:
+        case GL_POSITION:
+            params[3] = F2X(tmpParams[3]);
+        case GL_SPOT_DIRECTION:
+            params[2] = F2X(tmpParams[2]);
+            params[1] = F2X(tmpParams[1]);
+            break;
+        default:{
+            ctx->setGLerror(GL_INVALID_ENUM);
+            return;
+        }
+
+    }
+    params[0] = F2X(tmpParams[0]);
+}
+
+GL_API void GL_APIENTRY  glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetMaterialfv(face,pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetMaterialxv( GLenum face, GLenum pname, GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParams[4];
+    ctx->dispatcher().glGetMaterialfv(face,pname,tmpParams);
+    switch(pname){
+    case GL_AMBIENT:
+    case GL_DIFFUSE:
+    case GL_SPECULAR:
+    case GL_EMISSION:
+    case GL_AMBIENT_AND_DIFFUSE:
+        params[3] = tmpParams[3];
+        params[2] = tmpParams[2];
+        params[1] = tmpParams[1];
+    case GL_SHININESS:
+        params[0] = tmpParams[0];
+    default:{
+            ctx->setGLerror(GL_INVALID_ENUM);
+            return;
+        }
+    }
+}
+
+GL_API void GL_APIENTRY  glGetPointerv( GLenum pname, void **params) {
+    GET_CTX()
+    const GLESpointer* p = ctx->getPointer(pname);
+    if(p) {
+        *params = const_cast<void *>( p->getArrayData());
+    } else {
+        ctx->setGLerror(GL_INVALID_ENUM);
+    }
+
+}
+
+GL_API void GL_APIENTRY  glGetTexEnvfv( GLenum env, GLenum pname, GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetTexEnvfv(env,pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetTexEnviv( GLenum env, GLenum pname, GLint *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetTexEnviv(env,pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetTexEnvxv( GLenum env, GLenum pname, GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParams[4];
+
+    ctx->dispatcher().glGetTexEnvfv(env,pname,tmpParams);
+    if(pname == GL_TEXTURE_ENV_MODE) {
+        params[0] = static_cast<GLfixed>(tmpParams[0]);
+    } else {
+        for(int i=0 ; i < 4 ; i++)
+            params[i] = F2X(tmpParams[i]);
+    }
+}
+
+GL_API void GL_APIENTRY  glGetTexParameterfv( GLenum target, GLenum pname, GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetTexParameterfv(target,pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetTexParameteriv( GLenum target, GLenum pname, GLint *params) {
+    GET_CTX()
+    ctx->dispatcher().glGetTexParameteriv(target,pname,params);
+}
+
+GL_API void GL_APIENTRY  glGetTexParameterxv( GLenum target, GLenum pname, GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParam;
+    ctx->dispatcher().glGetTexParameterfv(target,pname,&tmpParam);
+    params[0] = static_cast<GLfixed>(tmpParam);
+}
+
+GL_API void GL_APIENTRY  glHint( GLenum target, GLenum mode) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::hintTargetMode(target,mode),GL_INVALID_ENUM);
+    ctx->dispatcher().glHint(target,mode);
+}
+
+GL_API void GL_APIENTRY  glLightModelf( GLenum pname, GLfloat param) {
+    GET_CTX()
+    ctx->dispatcher().glLightModelf(pname,param);
+}
+
+GL_API void GL_APIENTRY  glLightModelfv( GLenum pname, const GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glLightModelfv(pname,params);
+}
+
+GL_API void GL_APIENTRY  glLightModelx( GLenum pname, GLfixed param) {
+    GET_CTX()
+    GLfloat tmpParam = static_cast<GLfloat>(param);
+    ctx->dispatcher().glLightModelf(pname,tmpParam);
+}
+
+GL_API void GL_APIENTRY  glLightModelxv( GLenum pname, const GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParams[4];
+    if(pname == GL_LIGHT_MODEL_TWO_SIDE) {
+        tmpParams[0] = X2F(params[0]);
+    } else if (pname == GL_LIGHT_MODEL_AMBIENT) {
+        for(int i=0;i<4;i++) {
+            tmpParams[i] = X2F(params[i]);
+        }
+    }
+
+    ctx->dispatcher().glLightModelfv(pname,tmpParams);
+}
+
+GL_API void GL_APIENTRY  glLightf( GLenum light, GLenum pname, GLfloat param) {
+    GET_CTX()
+    ctx->dispatcher().glLightf(light,pname,param);
+}
+
+GL_API void GL_APIENTRY  glLightfv( GLenum light, GLenum pname, const GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glLightfv(light,pname,params);
+}
+
+GL_API void GL_APIENTRY  glLightx( GLenum light, GLenum pname, GLfixed param) {
+    GET_CTX()
+    ctx->dispatcher().glLightf(light,pname,X2F(param));
+}
+
+GL_API void GL_APIENTRY  glLightxv( GLenum light, GLenum pname, const GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParams[4];
+
+    switch (pname) {
+        case GL_AMBIENT:
+        case GL_DIFFUSE:
+        case GL_SPECULAR:
+        case GL_POSITION:
+            tmpParams[3] = X2F(params[3]);
+        case GL_SPOT_DIRECTION:
+            tmpParams[2] = X2F(params[2]);
+            tmpParams[1] = X2F(params[1]);
+            break;
+        default: {
+                ctx->setGLerror(GL_INVALID_ENUM);
+                return;
+            }
+    }
+    tmpParams[0] = X2F(params[0]);
+    ctx->dispatcher().glLightfv(light,pname,tmpParams);
+}
+
+GL_API void GL_APIENTRY  glLineWidth( GLfloat width) {
+    GET_CTX()
+    ctx->dispatcher().glLineWidth(width);
+}
+
+GL_API void GL_APIENTRY  glLineWidthx( GLfixed width) {
+    GET_CTX()
+    ctx->dispatcher().glLineWidth(X2F(width));
+}
+
+GL_API void GL_APIENTRY  glLoadIdentity( void) {
+    GET_CTX()
+    ctx->dispatcher().glLoadIdentity();
+}
+
+GL_API void GL_APIENTRY  glLoadMatrixf( const GLfloat *m) {
+    GET_CTX()
+    ctx->dispatcher().glLoadMatrixf(m);
+}
+
+GL_API void GL_APIENTRY  glLoadMatrixx( const GLfixed *m) {
+    GET_CTX()
+    GLfloat mat[16];
+    for(int i=0; i< 16 ; i++) {
+        mat[i] = X2F(m[i]);
+    }
+    ctx->dispatcher().glLoadMatrixf(mat);
+}
+
+GL_API void GL_APIENTRY  glLogicOp( GLenum opcode) {
+    GET_CTX()
+    ctx->dispatcher().glLogicOp(opcode);
+}
+
+GL_API void GL_APIENTRY  glMaterialf( GLenum face, GLenum pname, GLfloat param) {
+    GET_CTX()
+    ctx->dispatcher().glMaterialf(face,pname,param);
+}
+
+GL_API void GL_APIENTRY  glMaterialfv( GLenum face, GLenum pname, const GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glMaterialfv(face,pname,params);
+}
+
+GL_API void GL_APIENTRY  glMaterialx( GLenum face, GLenum pname, GLfixed param) {
+    GET_CTX()
+    ctx->dispatcher().glMaterialf(face,pname,X2F(param));
+}
+
+GL_API void GL_APIENTRY  glMaterialxv( GLenum face, GLenum pname, const GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParams[4];
+
+    for(int i=0; i< 4; i++) {
+        tmpParams[i] = X2F(params[i]);
+    }
+    ctx->dispatcher().glMaterialfv(face,pname,tmpParams);
+}
+
+GL_API void GL_APIENTRY  glMatrixMode( GLenum mode) {
+    GET_CTX()
+    ctx->dispatcher().glMatrixMode(mode);
+}
+
+GL_API void GL_APIENTRY  glMultMatrixf( const GLfloat *m) {
+    GET_CTX()
+    ctx->dispatcher().glMultMatrixf(m);
+}
+
+GL_API void GL_APIENTRY  glMultMatrixx( const GLfixed *m) {
+    GET_CTX()
+    GLfloat mat[16];
+    for(int i=0; i< 16 ; i++) {
+        mat[i] = X2F(m[i]);
+    }
+    ctx->dispatcher().glMultMatrixf(mat);
+}
+
+GL_API void GL_APIENTRY  glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::textureEnum(target,ctx->getMaxTexUnits()),GL_INVALID_ENUM);
+    ctx->dispatcher().glMultiTexCoord4f(target,s,t,r,q);
+}
+
+GL_API void GL_APIENTRY  glMultiTexCoord4x( GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::textureEnum(target,ctx->getMaxTexUnits()),GL_INVALID_ENUM);
+    ctx->dispatcher().glMultiTexCoord4f(target,X2F(s),X2F(t),X2F(r),X2F(q));
+}
+
+GL_API void GL_APIENTRY  glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz) {
+    GET_CTX()
+    ctx->dispatcher().glNormal3f(nx,ny,nz);
+}
+
+GL_API void GL_APIENTRY  glNormal3x( GLfixed nx, GLfixed ny, GLfixed nz) {
+    GET_CTX()
+    ctx->dispatcher().glNormal3f(X2F(nx),X2F(ny),X2F(nz));
+}
+
+GL_API void GL_APIENTRY  glNormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GET_CTX()
+    SET_ERROR_IF(stride < 0,GL_INVALID_VALUE);
+    const GLvoid* data = ctx->setPointer(GL_NORMAL_ARRAY,3,type,stride,pointer);//3 normal verctor
+    if(type != GL_FIXED) ctx->dispatcher().glNormalPointer(type,stride,data);
+}
+
+GL_API void GL_APIENTRY  glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+    GET_CTX()
+    ctx->dispatcher().glOrtho(left,right,bottom,top,zNear,zFar);
+}
+
+GL_API void GL_APIENTRY  glOrthox( GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+    GET_CTX()
+    ctx->dispatcher().glOrtho(X2F(left),X2F(right),X2F(bottom),X2F(top),X2F(zNear),X2F(zFar));
+}
+
+GL_API void GL_APIENTRY  glPixelStorei( GLenum pname, GLint param) {
+    GET_CTX()
+    ctx->dispatcher().glPixelStorei(pname,param);
+}
+
+GL_API void GL_APIENTRY  glPointParameterf( GLenum pname, GLfloat param) {
+    GET_CTX()
+    ctx->dispatcher().glPointParameterf(pname,param);
+}
+
+GL_API void GL_APIENTRY  glPointParameterfv( GLenum pname, const GLfloat *params) {
+    GET_CTX()
+    ctx->dispatcher().glPointParameterfv(pname,params);
+}
+
+GL_API void GL_APIENTRY  glPointParameterx( GLenum pname, GLfixed param)
+{
+    GET_CTX()
+    ctx->dispatcher().glPointParameterf(pname,X2F(param));
+}
+
+GL_API void GL_APIENTRY  glPointParameterxv( GLenum pname, const GLfixed *params) {
+    GET_CTX()
+    GLfloat tmpParams[3];
+    int i = 0;
+
+    do {
+        tmpParams[i] = X2F(params[i]);
+        i++;
+    }while(pname != GL_POINT_DISTANCE_ATTENUATION);
+    ctx->dispatcher().glPointParameterfv(pname,tmpParams);
+}
+
+GL_API void GL_APIENTRY  glPointSize( GLfloat size) {
+    GET_CTX()
+    ctx->dispatcher().glPointSize(size);
+}
+
+GL_API void GL_APIENTRY  glPointSizePointerOES( GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GET_CTX()
+    SET_ERROR_IF(stride < 0,GL_INVALID_VALUE);
+    ctx->setPointer(GL_POINT_SIZE_ARRAY_OES,1,type,stride,pointer);
+}
+
+GL_API void GL_APIENTRY  glPointSizex( GLfixed size) {
+    GET_CTX()
+    ctx->dispatcher().glPointSize(X2F(size));
+}
+
+GL_API void GL_APIENTRY  glPolygonOffset( GLfloat factor, GLfloat units) {
+    GET_CTX()
+    ctx->dispatcher().glPolygonOffset(factor,units);
+}
+
+GL_API void GL_APIENTRY  glPolygonOffsetx( GLfixed factor, GLfixed units) {
+    GET_CTX()
+    ctx->dispatcher().glPolygonOffset(X2F(factor),X2F(units));
+}
+
+GL_API void GL_APIENTRY  glPopMatrix(void) {
+    GET_CTX()
+    ctx->dispatcher().glPopMatrix();
+}
+
+GL_API void GL_APIENTRY  glPushMatrix(void) {
+    GET_CTX()
+    ctx->dispatcher().glPushMatrix();
+}
+
+GL_API void GL_APIENTRY  glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
+    GET_CTX()
+    SET_ERROR_IF(!(GLESvalidate::pixelFrmt(format) && GLESvalidate::pixelType(type)),GL_INVALID_ENUM);
+    SET_ERROR_IF(!(GLESvalidate::pixelOp(format,type)),GL_INVALID_OPERATION);
+
+    ctx->dispatcher().glReadPixels(x,y,width,height,format,type,pixels);
+}
+
+GL_API void GL_APIENTRY  glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
+    GET_CTX()
+    ctx->dispatcher().glRotatef(angle,x,y,z);
+}
+
+GL_API void GL_APIENTRY  glRotatex( GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
+    GET_CTX()
+    ctx->dispatcher().glRotatef(angle,X2F(x),X2F(y),X2F(z));
+}
+
+GL_API void GL_APIENTRY  glSampleCoverage( GLclampf value, GLboolean invert) {
+    GET_CTX()
+    ctx->dispatcher().glSampleCoverage(value,invert);
+}
+
+GL_API void GL_APIENTRY  glSampleCoveragex( GLclampx value, GLboolean invert) {
+    GET_CTX()
+    ctx->dispatcher().glSampleCoverage(X2F(value),invert);
+}
+
+GL_API void GL_APIENTRY  glScalef( GLfloat x, GLfloat y, GLfloat z) {
+    GET_CTX()
+    ctx->dispatcher().glScalef(x,y,z);
+}
+
+GL_API void GL_APIENTRY  glScalex( GLfixed x, GLfixed y, GLfixed z) {
+    GET_CTX()
+    ctx->dispatcher().glScalef(X2F(x),X2F(y),X2F(z));
+}
+
+GL_API void GL_APIENTRY  glScissor( GLint x, GLint y, GLsizei width, GLsizei height) {
+    GET_CTX()
+    ctx->dispatcher().glScissor(x,y,width,height);
+}
+
+GL_API void GL_APIENTRY  glShadeModel( GLenum mode) {
+    GET_CTX()
+    ctx->dispatcher().glShadeModel(mode);
+}
+
+GL_API void GL_APIENTRY  glStencilFunc( GLenum func, GLint ref, GLuint mask) {
+    GET_CTX()
+    ctx->dispatcher().glStencilFunc(func,ref,mask);
+}
+
+GL_API void GL_APIENTRY  glStencilMask( GLuint mask) {
+    GET_CTX()
+    ctx->dispatcher().glStencilMask(mask);
+}
+
+GL_API void GL_APIENTRY  glStencilOp( GLenum fail, GLenum zfail, GLenum zpass) {
+    GET_CTX()
+    ctx->dispatcher().glStencilOp(fail,zfail,zpass);
+}
+
+GL_API void GL_APIENTRY  glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texCoordPointerParams(size,stride),GL_INVALID_VALUE);
+
+    const GLvoid* data = ctx->setPointer(GL_TEXTURE_COORD_ARRAY,size,type,stride,pointer);
+    if(type != GL_FIXED) ctx->dispatcher().glTexCoordPointer(size,type,stride,data);
+}
+
+GL_API void GL_APIENTRY  glTexEnvf( GLenum target, GLenum pname, GLfloat param) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexEnvf(target,pname,param);
+}
+
+GL_API void GL_APIENTRY  glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexEnvfv(target,pname,params);
+}
+
+GL_API void GL_APIENTRY  glTexEnvi( GLenum target, GLenum pname, GLint param) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexEnvi(target,pname,param);
+}
+
+GL_API void GL_APIENTRY  glTexEnviv( GLenum target, GLenum pname, const GLint *params) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexEnviv(target,pname,params);
+}
+
+GL_API void GL_APIENTRY  glTexEnvx( GLenum target, GLenum pname, GLfixed param) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM);
+    GLfloat tmpParam = static_cast<GLfloat>(param);
+    ctx->dispatcher().glTexEnvf(target,pname,tmpParam);
+}
+
+GL_API void GL_APIENTRY  glTexEnvxv( GLenum target, GLenum pname, const GLfixed *params) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM);
+
+    GLfloat tmpParams[4];
+    if(pname == GL_TEXTURE_ENV_COLOR) {
+        for(int i =0;i<4;i++) {
+            tmpParams[i] = X2F(params[i]);
+        }
+    } else {
+        tmpParams[0] = static_cast<GLfloat>(params[0]);
+    }
+    ctx->dispatcher().glTexEnvfv(target,pname,tmpParams);
+}
+
+GL_API void GL_APIENTRY  glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
+    GET_CTX()
+
+    SET_ERROR_IF(!(GLESvalidate::textureTarget(target) &&
+                   GLESvalidate::pixelFrmt(internalformat) &&
+                   GLESvalidate::pixelFrmt(format)&&
+                   GLESvalidate::pixelType(type)),GL_INVALID_ENUM);
+
+    //SET_ERROR_IF(level < 0 || border !=0 || level > log2(ctx->getMaxTexSize()) || !GLESvalidate::texImgDim(width,height,ctx->getMaxTexSize()),GL_INVALID_VALUE);
+    SET_ERROR_IF(!(GLESvalidate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION);
+
+    ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels);
+}
+
+GL_API void GL_APIENTRY  glTexParameterf( GLenum target, GLenum pname, GLfloat param) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexParameterf(target,pname,param);
+}
+
+GL_API void GL_APIENTRY  glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexParameterfv(target,pname,params);
+}
+
+GL_API void GL_APIENTRY  glTexParameteri( GLenum target, GLenum pname, GLint param) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexParameteri(target,pname,param);
+}
+
+GL_API void GL_APIENTRY  glTexParameteriv( GLenum target, GLenum pname, const GLint *params) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexParameteriv(target,pname,params);
+}
+
+GL_API void GL_APIENTRY  glTexParameterx( GLenum target, GLenum pname, GLfixed param) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM);
+    ctx->dispatcher().glTexParameterf(target,pname,static_cast<GLfloat>(param));
+}
+
+GL_API void GL_APIENTRY  glTexParameterxv( GLenum target, GLenum pname, const GLfixed *params) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM);
+    GLfloat param = static_cast<GLfloat>(params[0]);
+    ctx->dispatcher().glTexParameterfv(target,pname,&param);
+}
+
+GL_API void GL_APIENTRY  glTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
+    GET_CTX()
+    SET_ERROR_IF(!(GLESvalidate::textureTarget(target) &&
+                   GLESvalidate::pixelFrmt(format)&&
+                   GLESvalidate::pixelType(type)),GL_INVALID_ENUM);
+    SET_ERROR_IF(!GLESvalidate::pixelOp(format,type),GL_INVALID_OPERATION);
+
+    ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);
+}
+
+GL_API void GL_APIENTRY  glTranslatef( GLfloat x, GLfloat y, GLfloat z) {
+    GET_CTX()
+    ctx->dispatcher().glTranslatef(x,y,z);
+}
+
+GL_API void GL_APIENTRY  glTranslatex( GLfixed x, GLfixed y, GLfixed z) {
+    GET_CTX()
+    ctx->dispatcher().glTranslatef(x,y,z);
+}
+
+GL_API void GL_APIENTRY  glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GET_CTX()
+    SET_ERROR_IF(!GLESvalidate::vertexPointerParams(size,stride),GL_INVALID_VALUE);
+
+    const GLvoid* data = ctx->setPointer(GL_VERTEX_ARRAY,size,type,stride,pointer);
+    if(type != GL_FIXED) ctx->dispatcher().glVertexPointer(size,type,stride,data);
+}
+
+GL_API void GL_APIENTRY  glViewport( GLint x, GLint y, GLsizei width, GLsizei height) {
+    GET_CTX()
+    ctx->dispatcher().glViewport(x,y,width,height);
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.cpp
new file mode 100644
index 0000000..55b4dcd
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.cpp
@@ -0,0 +1,75 @@
+/*
+* 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 "GLESpointer.h"
+#include <stdlib.h>
+
+GLESpointer::GLESpointer():m_size(0),m_type(0),m_stride(0),m_enabled(false),m_data(NULL),m_buffer(NULL),m_buffOffset(0){};
+
+
+GLenum GLESpointer:: getType() const {
+    return m_type;
+}
+
+GLint GLESpointer::getSize() const  {
+    return m_size;
+}
+
+GLsizei GLESpointer::getStride() const {
+    return m_stride;
+}
+
+const GLvoid* GLESpointer::getArrayData() const {
+    return m_data;
+}
+
+GLvoid* GLESpointer::getBufferData() const {
+
+    return static_cast<unsigned char*>(m_buffer->getData()) + m_buffOffset;
+}
+
+unsigned int GLESpointer::getBufferOffset() const {
+
+    return  m_buffOffset;
+}
+
+bool GLESpointer::isEnable() const {
+    return m_enabled;
+}
+
+void GLESpointer::enable(bool b) {
+    m_enabled = b;
+}
+
+void GLESpointer::setArray(GLint size,GLenum type,GLsizei stride,const GLvoid* data) {
+    m_size   = size;
+    m_type   = type;
+    m_stride = stride;
+    m_data   = data;
+    m_buffer = NULL;
+}
+
+void GLESpointer::setBuffer(GLint size,GLenum type,GLsizei stride,GLESbuffer* buf,int offset) {
+    m_size   = size;
+    m_type   = type;
+    m_stride = stride;
+    m_data   = NULL;
+    m_buffer = buf;
+    m_buffOffset = offset;
+}
+
+void GLESpointer::getBufferConversions(const RangeList& rl,RangeList& rlOut) {
+    m_buffer->getConversions(rl,rlOut);
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.h
new file mode 100644
index 0000000..9d897e4
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.h
@@ -0,0 +1,49 @@
+/*
+* 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.
+*/
+#ifndef GLES_POINTER_H
+#define GLES_POINTER_H
+
+#include <GLES/gl.h>
+#include "GLESbuffer.h"
+
+class GLESpointer
+{
+
+public:
+    GLESpointer();
+    GLenum        getType() const;
+    GLint         getSize() const;
+    GLsizei       getStride() const;
+    const GLvoid* getArrayData() const;
+    GLvoid*       getBufferData() const;
+    unsigned int  getBufferOffset() const;
+    void          getBufferConversions(const RangeList& rl,RangeList& rlOut);
+    bool          bufferNeedConversion(){ return !m_buffer->fullyConverted();}
+    void          setArray (GLint size,GLenum type,GLsizei stride,const GLvoid* data);
+    void          setBuffer(GLint size,GLenum type,GLsizei stride,GLESbuffer* buf,int offset);
+    bool          isEnable() const;
+    void          enable(bool b);
+
+private:
+    GLint         m_size;
+    GLenum        m_type;
+    GLsizei       m_stride;
+    bool          m_enabled;
+    const GLvoid* m_data;
+    GLESbuffer*   m_buffer;
+    unsigned int  m_buffOffset;
+};
+#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.cpp
new file mode 100644
index 0000000..08c2d6a
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.cpp
@@ -0,0 +1,101 @@
+/*
+* 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 "GLESutils.h"
+
+
+size_t glParamSize(GLenum param)
+{
+    size_t s = 0;
+
+    switch(param)
+    {
+    case GL_MAX_TEXTURE_SIZE:
+    //case GL_TEXTURE_GEN_MODE_OES:
+    case GL_TEXTURE_ENV_MODE:
+    case GL_FOG_MODE:
+    case GL_FOG_DENSITY:
+    case GL_FOG_START:
+    case GL_FOG_END:
+    case GL_SPOT_EXPONENT:
+    case GL_CONSTANT_ATTENUATION:
+    case GL_LINEAR_ATTENUATION:
+    case GL_QUADRATIC_ATTENUATION:
+    case GL_SHININESS:
+    case GL_LIGHT_MODEL_TWO_SIDE:
+    case GL_POINT_SIZE:
+    case GL_POINT_SIZE_MIN:
+    case GL_POINT_SIZE_MAX:
+    case GL_POINT_FADE_THRESHOLD_SIZE:
+    case GL_CULL_FACE_MODE:
+    case GL_FRONT_FACE:
+    case GL_SHADE_MODEL:
+    case GL_DEPTH_WRITEMASK:
+    case GL_DEPTH_CLEAR_VALUE:
+    case GL_STENCIL_FAIL:
+    case GL_STENCIL_PASS_DEPTH_FAIL:
+    case GL_STENCIL_PASS_DEPTH_PASS:
+    case GL_STENCIL_REF:
+    case GL_STENCIL_WRITEMASK:
+    case GL_MATRIX_MODE:
+    case GL_MODELVIEW_STACK_DEPTH:
+    case GL_PROJECTION_STACK_DEPTH:
+    case GL_TEXTURE_STACK_DEPTH:
+    case GL_ALPHA_TEST_FUNC:
+    case GL_ALPHA_TEST_REF:
+    case GL_BLEND_DST:
+    case GL_BLEND_SRC:
+    case GL_LOGIC_OP_MODE:
+    case GL_SCISSOR_TEST:
+    case GL_MAX_TEXTURE_UNITS:
+        s = 1;
+        break;
+    case GL_ALIASED_LINE_WIDTH_RANGE:
+    case GL_ALIASED_POINT_SIZE_RANGE:
+    case GL_DEPTH_RANGE:
+    case GL_MAX_VIEWPORT_DIMS:
+    case GL_SMOOTH_POINT_SIZE_RANGE:
+    case GL_SMOOTH_LINE_WIDTH_RANGE:
+        s= 2;
+        break;
+    case GL_SPOT_DIRECTION:
+    case GL_POINT_DISTANCE_ATTENUATION:
+    case GL_CURRENT_NORMAL:
+        s =  3;
+        break;
+    case GL_CURRENT_TEXTURE_COORDS:
+    case GL_CURRENT_COLOR:
+    case GL_FOG_COLOR:
+    case GL_AMBIENT:
+    case GL_DIFFUSE:
+    case GL_SPECULAR:
+    case GL_EMISSION:
+    case GL_POSITION:
+    case GL_LIGHT_MODEL_AMBIENT:
+    case GL_TEXTURE_ENV_COLOR:
+    case GL_SCISSOR_BOX:
+    case GL_VIEWPORT:
+    //case GL_TEXTURE_CROP_RECT_OES:
+        s =  4;
+        break;
+    case GL_MODELVIEW_MATRIX:
+    case GL_PROJECTION_MATRIX:
+    case GL_TEXTURE_MATRIX:
+        s = 16;
+    default:
+        s = 1; // assume 1
+    }
+    return s;
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.h
new file mode 100644
index 0000000..38ad6bc
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.h
@@ -0,0 +1,22 @@
+/*
+* 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.
+*/
+#ifndef GLES_UTILS_H
+#define GLES_UTILS_H
+#include <GLES/gl.h>
+#include <stdlib.h>
+
+size_t glParamSize(GLenum param);
+#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.cpp
new file mode 100644
index 0000000..6bc211f
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.cpp
@@ -0,0 +1,281 @@
+/*
+* 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 "GLESvalidate.h"
+#include <GLcommon/GLutils.h>
+
+bool  GLESvalidate::textureEnum(GLenum e,unsigned int maxTex) {
+    return e >= GL_TEXTURE0 && e <= (GL_TEXTURE0 + maxTex);
+}
+
+bool GLESvalidate::lightEnum(GLenum e,unsigned int maxLights) {
+    return  e >=GL_LIGHT0 && e <= (GL_LIGHT0+maxLights);
+}
+
+bool GLESvalidate::clipPlaneEnum(GLenum e,unsigned int maxClipPlanes) {
+    return  e >=GL_CLIP_PLANE0 && e <= (GL_CLIP_PLANE0+maxClipPlanes);
+}
+
+bool GLESvalidate::textureTarget(GLenum target) {
+    return target == GL_TEXTURE_2D;
+}
+
+
+bool GLESvalidate::alphaFunc(GLenum f) {
+    switch(f) {
+    case GL_NEVER:
+    case GL_LESS:
+    case GL_EQUAL:
+    case GL_LEQUAL:
+    case GL_GREATER:
+    case GL_NOTEQUAL:
+    case GL_GEQUAL:
+    case GL_ALWAYS:
+        return true;
+    }
+    return false;
+}
+
+bool GLESvalidate::blendSrc(GLenum s) {
+   switch(s) {
+    case GL_ZERO:
+    case GL_ONE:
+    case GL_DST_COLOR:
+    case GL_ONE_MINUS_DST_COLOR:
+    case GL_SRC_ALPHA:
+    case GL_ONE_MINUS_SRC_ALPHA:
+    case GL_DST_ALPHA:
+    case GL_ONE_MINUS_DST_ALPHA:
+        return true;
+  }
+  return false;
+}
+
+bool GLESvalidate::blendDst(GLenum d) {
+   switch(d) {
+    case GL_ZERO:
+    case GL_ONE:
+    case GL_SRC_COLOR:
+    case GL_ONE_MINUS_SRC_COLOR:
+    case GL_SRC_ALPHA:
+    case GL_ONE_MINUS_SRC_ALPHA:
+    case GL_DST_ALPHA:
+    case GL_ONE_MINUS_DST_ALPHA:
+        return true;
+   }
+   return false;
+}
+
+bool GLESvalidate::vertexPointerParams(GLint size,GLsizei stride) {
+    return ((size >=2) && (size <= 4)) && (stride >=0) ;
+}
+
+bool GLESvalidate::colorPointerParams(GLint size,GLsizei stride) {
+    return ((size >=3) && (size <= 4)) && (stride >=0) ;
+}
+
+bool GLESvalidate::texCoordPointerParams(GLint size,GLsizei stride) {
+    return ((size >=1) && (size <= 4)) && (stride >=0) ;
+}
+
+bool GLESvalidate::supportedArrays(GLenum arr) {
+    switch(arr) {
+    case GL_COLOR_ARRAY:
+    case GL_NORMAL_ARRAY:
+    case GL_POINT_SIZE_ARRAY_OES:
+    case GL_TEXTURE_COORD_ARRAY:
+    case GL_VERTEX_ARRAY:
+        return true;
+    }
+    return false;
+}
+
+bool GLESvalidate::drawMode(GLenum mode) {
+    switch(mode) {
+    case GL_POINTS:
+    case GL_LINE_STRIP:
+    case GL_LINE_LOOP:
+    case GL_LINES:
+    case GL_TRIANGLE_STRIP:
+    case GL_TRIANGLE_FAN:
+    case GL_TRIANGLES:
+        return true;
+    }
+    return false;
+}
+
+bool GLESvalidate::drawType(GLenum mode) {
+    return mode == GL_UNSIGNED_BYTE || mode == GL_UNSIGNED_SHORT;
+}
+
+bool GLESvalidate::hintTargetMode(GLenum target,GLenum mode) {
+   switch(target) {
+   case GL_FOG_HINT:
+   case GL_GENERATE_MIPMAP_HINT:
+   case GL_LINE_SMOOTH_HINT:
+   case GL_PERSPECTIVE_CORRECTION_HINT:
+   case GL_POINT_SMOOTH_HINT:
+       break;
+   default: return false;
+   }
+   switch(mode) {
+   case GL_FASTEST:
+   case GL_NICEST:
+   case GL_DONT_CARE:
+       break;
+   default: return false;
+   }
+   return true;
+}
+
+bool GLESvalidate::texParams(GLenum target,GLenum pname) {
+    switch(pname) {
+    case GL_TEXTURE_MIN_FILTER:
+    case GL_TEXTURE_MAG_FILTER:
+    case GL_TEXTURE_WRAP_S:
+    case GL_TEXTURE_WRAP_T:
+        break;
+    default:
+        return false;
+    }
+    return target == GL_TEXTURE_2D;
+}
+
+bool GLESvalidate::texEnv(GLenum target,GLenum pname) {
+    switch(pname) {
+    case GL_TEXTURE_ENV_MODE:
+    case GL_COMBINE_RGB:
+    case GL_COMBINE_ALPHA:
+    case GL_SRC0_RGB:
+    case GL_SRC1_RGB:
+    case GL_SRC2_RGB:
+    case GL_SRC0_ALPHA:
+    case GL_SRC1_ALPHA:
+    case GL_SRC2_ALPHA:
+    case GL_OPERAND0_RGB:
+    case GL_OPERAND1_RGB:
+    case GL_OPERAND2_RGB:
+    case GL_OPERAND0_ALPHA:
+    case GL_OPERAND1_ALPHA:
+    case GL_OPERAND2_ALPHA:
+    case GL_RGB_SCALE:
+    case GL_ALPHA_SCALE:
+    case GL_COORD_REPLACE_OES:
+        break;
+    default:
+        return false;
+    }
+    return (target == GL_TEXTURE_ENV || target == GL_POINT_SPRITE_OES);
+}
+
+bool GLESvalidate::capability(GLenum cap,int maxLights,int maxClipPlanes) {
+    switch(cap) {
+    case GL_ALPHA_TEST:
+    case GL_BLEND:
+    case GL_COLOR_ARRAY:
+    case GL_COLOR_LOGIC_OP:
+    case GL_COLOR_MATERIAL:
+    case GL_CULL_FACE:
+    case GL_DEPTH_TEST:
+    case GL_DITHER:
+    case GL_FOG:
+    case GL_LIGHTING:
+    case GL_LINE_SMOOTH:
+    case GL_MULTISAMPLE:
+    case GL_NORMAL_ARRAY:
+    case GL_NORMALIZE:
+    case GL_POINT_SIZE_ARRAY_OES:
+    case GL_POINT_SMOOTH:
+    case GL_POINT_SPRITE_OES:
+    case GL_POLYGON_OFFSET_FILL:
+    case GL_RESCALE_NORMAL:
+    case GL_SAMPLE_ALPHA_TO_COVERAGE:
+    case GL_SAMPLE_ALPHA_TO_ONE:
+    case GL_SAMPLE_COVERAGE:
+    case GL_SCISSOR_TEST:
+    case GL_STENCIL_TEST:
+    case GL_TEXTURE_2D:
+    case GL_TEXTURE_COORD_ARRAY:
+    case GL_VERTEX_ARRAY:
+        return true;
+    }
+    return GLESvalidate::lightEnum(cap,maxLights) || GLESvalidate::clipPlaneEnum(cap,maxClipPlanes);
+}
+
+bool GLESvalidate::pixelType(GLenum type) {
+    switch(type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_UNSIGNED_SHORT_5_6_5:
+    case GL_UNSIGNED_SHORT_4_4_4_4:
+    case GL_UNSIGNED_SHORT_5_5_5_1:
+        return true;
+    }
+    return false;
+}
+
+bool GLESvalidate::pixelFrmt(GLenum format) {
+    switch(format) {
+    case GL_ALPHA:
+    case GL_RGB:
+    case GL_RGBA:
+    case GL_LUMINANCE:
+    case GL_LUMINANCE_ALPHA:
+        return true;
+    }
+    return false;
+}
+
+bool GLESvalidate::texCompImgFrmt(GLenum format) {
+    switch(format) {
+    case GL_PALETTE4_RGB8_OES:
+    case GL_PALETTE4_RGBA8_OES:
+    case GL_PALETTE4_R5_G6_B5_OES:
+    case GL_PALETTE4_RGBA4_OES:
+    case GL_PALETTE4_RGB5_A1_OES:
+    case GL_PALETTE8_RGB8_OES:
+    case GL_PALETTE8_RGBA8_OES:
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE8_RGBA4_OES:
+    case GL_PALETTE8_RGB5_A1_OES:
+        return true;
+    }
+    return false;
+}
+
+bool GLESvalidate::pixelOp(GLenum format,GLenum type) {
+     switch(type) {
+     case GL_UNSIGNED_SHORT_4_4_4_4:
+     case GL_UNSIGNED_SHORT_5_5_5_1:
+         return format == GL_RGBA;
+     case GL_UNSIGNED_SHORT_5_6_5:
+         return format == GL_RGB;
+     }
+     return true;
+}
+
+bool GLESvalidate::texImgDim(GLsizei width,GLsizei height,int maxTexSize) {
+
+ if( width < 0 || height < 0 || width > maxTexSize || height > maxTexSize)
+    return false;
+ return isPowerOf2(width) && isPowerOf2(height);
+}
+
+bool GLESvalidate::bufferTarget(GLenum target) {
+    return target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER;
+}
+
+bool GLESvalidate::bufferParam(GLenum param) {
+ return  (param == GL_BUFFER_SIZE) || (param == GL_BUFFER_USAGE);
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.h
new file mode 100644
index 0000000..a4f785b
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.h
@@ -0,0 +1,50 @@
+/*
+* 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.
+*/
+#ifndef GLES_VALIDATE_H
+#define GLES_VALIDATE_H
+
+#include <GLES/gl.h>
+
+struct GLESvalidate
+{
+
+static bool lightEnum(GLenum e,unsigned int maxLIghts);
+static bool clipPlaneEnum(GLenum e,unsigned int maxClipPlanes);
+static bool alphaFunc(GLenum f);
+static bool blendSrc(GLenum s);
+static bool blendDst(GLenum d);
+static bool vertexPointerParams(GLint size,GLsizei stride);
+static bool colorPointerParams(GLint size,GLsizei stride);
+static bool supportedArrays(GLenum arr);
+static bool drawMode(GLenum mode);
+static bool drawType(GLenum mode);
+static bool hintTargetMode(GLenum target,GLenum mode);
+static bool capability(GLenum cap,int maxLights,int maxClipPlanes);
+static bool texParams(GLenum target,GLenum pname);
+static bool texCoordPointerParams(GLint size,GLsizei stride);
+static bool textureTarget(GLenum target);
+static bool textureEnum(GLenum e,unsigned int maxTex);
+static bool texEnv(GLenum target,GLenum pname);
+static bool pixelFrmt(GLenum format);
+static bool pixelType(GLenum type);
+static bool pixelOp(GLenum format,GLenum type);
+static bool texCompImgFrmt(GLenum format);
+static bool texImgDim(GLsizei width,GLsizei height,int maxTexSize);
+static bool bufferTarget(GLenum target);
+static bool bufferParam(GLenum param);
+};
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLfixed_ops.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLfixed_ops.h
new file mode 100644
index 0000000..824bb94
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLfixed_ops.h
@@ -0,0 +1,29 @@
+/*
+* 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.
+*/
+#ifndef _GL_FIXED_OPS_H
+#define _GL_FIXED_OPS_H
+
+#define X2F(x)  (((float)(x))/65536.0f)
+#define X2D(x)  (((double)(x))/65536.0)
+#define X2I(x)             ((x) /65536)
+
+
+#define F2X(d) ((d) > 32767.65535 ? 32767 * 65536 + 65535 :  \
+               (d) < -32768.65535 ? -32768 * 65536 + 65535 : \
+               ((GLfixed) ((d) * 65536)))
+
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.cpp
new file mode 100644
index 0000000..6c41e6f
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.cpp
@@ -0,0 +1,126 @@
+/*
+* 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 "RangeManip.h"
+
+
+bool Range::rangeIntersection(const Range& r,Range& rOut) const {
+    if(m_start > r.getEnd() || r.getStart() > m_end) return false;
+    int max_start = (m_start > r.getStart())? m_start:r.getStart();
+    int min_end = (m_end < r.getEnd())?m_end:r.getEnd();
+    int size = min_end - max_start;
+    if(size) {
+        rOut.setRange(max_start,min_end-max_start);
+        return true;
+    }
+    return false;
+}
+
+bool Range::rangeUnion(const Range& r,Range& rOut) const {
+    if(m_start > r.getEnd() || r.getStart() > m_end) return false;
+    int min_start = (m_start < r.getStart())?m_start:r.getStart();
+    int max_end = (m_end > r.getEnd())?m_end:r.getEnd();
+    int size =  max_end - min_start;
+    if(size) {
+        rOut.setRange(min_start,max_end-min_start);
+        return false;
+    }
+    return false;
+}
+
+void RangeList::addRange(const Range& r) {
+    list.push_back(r);
+}
+
+void RangeList::addRanges(const RangeList& rl) {
+    for(int i =0; i< rl.size();i++) {
+       addRange(rl.list[i]);
+    }
+}
+
+void RangeList::delRanges(const RangeList& rl,RangeList& deleted) {
+    for(int i =0; i< rl.size();i++) {
+       delRange(rl.list[i],deleted);
+    }
+}
+
+bool RangeList::empty() const{
+    return list.empty();
+}
+
+int  RangeList::size() const{
+    return list.size();
+}
+void RangeList::clear() {
+    return list.clear();
+}
+
+void RangeList::erase(unsigned int i) {
+    if(i > list.size()) return;
+    list.erase(list.begin() +i);
+}
+
+void RangeList::delRange(const Range& r,RangeList& deleted) {
+    if(r.getSize() == 0) return;
+
+    Range intersection;
+    Range temp;
+    // compare new rect to each and any of the rects on the list
+    for (int i=0;i<(int)list.size();i++) { // i must be signed for i-- below
+     // if there is intersection
+     if (r.rangeIntersection(list[i],intersection)) {
+             Range old=list[i];
+         // remove old as it is about to be split
+         erase(i);
+         i--;
+         if (intersection!=old) { // otherwise split:
+                 //intersection on right side
+                 if(old.getStart() != intersection.getStart()) {
+                     list.insert(list.begin(),Range(old.getStart(),intersection.getStart() - old.getStart()));
+                 }
+
+                 //intersection on left side
+                 if(old.getEnd() != intersection.getEnd()) {
+                     list.insert(list.begin(),Range(intersection.getEnd(),old.getEnd() - intersection.getEnd()));
+                 }
+                 deleted.addRange(intersection);
+             }
+     }
+ }
+}
+
+void RangeList::merge() {
+    if(list.empty()) return;
+
+    Range temp;
+    bool changed;
+
+    do { // re-run if changed in last run
+        changed=0;
+        // run for each combinations of two rects in the list
+        for (int i=0;i<(((int)list.size())-1) && !changed ;i++)
+        {
+            for (int j=i+1;j<(int)list.size() && !changed ;j++)
+            {
+               if (list[i].rangeUnion(list[j],temp)) {
+                    // are them exactly one on left of the other
+                    list[i] = temp;
+                    erase(j);
+                    changed=1;
+               }
+            }
+        }
+    } while (changed);
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.h
new file mode 100644
index 0000000..e3162b8
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.h
@@ -0,0 +1,69 @@
+/*
+* 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.
+*/
+#ifndef RANGE_H
+#define RANGE_H
+
+#include <vector>
+
+class Range {
+
+public:
+    Range():m_start(0),m_end(0),m_size(0){};
+    Range(int start,int size):m_start(start),m_end(start+size),m_size(size){};
+    Range(const Range& r):m_start(r.m_start),m_end(r.m_end),m_size(r.m_size){};
+    void setRange(int start,int size){m_start = start; m_end = start+size; m_size = size;};
+    inline int getStart() const{return m_start;};
+    inline int getEnd() const{return m_end;};
+    inline int getSize() const{return m_size;};
+    Range& operator=(const Range& r) {
+        m_start = r.m_start;
+        m_end = r.m_end;
+        m_size = r.m_size;
+        return *this;
+    }
+    bool operator ==(const Range& r) const {
+        return m_start == r.m_start && m_size == r.m_size && m_end == r.m_end;
+    }
+    bool operator !=(const Range& r) const {return !((*this) == r);};
+    bool rangeIntersection(const Range& r,Range& rOut) const ;
+    bool rangeUnion(const Range& r,Range& rOut) const ;
+
+private:
+    int m_start;
+    int m_end;
+    int m_size;
+};
+
+class RangeList {
+public:
+      void addRange(const Range& r);
+      void addRanges(const RangeList& rl);
+      void delRange(const Range& r,RangeList& deleted);
+      void delRanges(const RangeList& rl,RangeList& deleted);
+      bool empty() const;
+      void merge();
+      int  size() const;
+      void clear();
+      Range& operator[](unsigned int i){return list[i];};
+private:
+  void erase(unsigned int i);
+  std::vector<Range> list;
+};
+
+
+
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.cpp
new file mode 100644
index 0000000..28dff1c
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.cpp
@@ -0,0 +1,158 @@
+/*
+* 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 "TextureUtils.h"
+#include <stdio.h>
+
+
+struct Color
+{
+  Color(unsigned char r, unsigned char g,unsigned char b, unsigned char a):red(r),green(g),blue(b),alpha(a){};
+  unsigned char red;
+  unsigned char green;
+  unsigned char blue;
+  unsigned char alpha;
+};
+
+void getPaletteInfo(GLenum internalFormat,unsigned int& indexSizeBits,unsigned int& colorSizeBytes,GLenum& colorFrmt) {
+
+        colorFrmt = GL_RGB;
+        switch(internalFormat)
+    {
+    case GL_PALETTE4_RGB8_OES:
+        indexSizeBits = 4;
+        colorSizeBytes = 3;
+        break;
+
+    case GL_PALETTE4_RGBA8_OES:
+        indexSizeBits = 4;
+        colorSizeBytes = 4;
+            colorFrmt = GL_RGBA;
+        break;
+
+    case GL_PALETTE4_RGBA4_OES:
+            colorFrmt = GL_RGBA;
+    case GL_PALETTE4_R5_G6_B5_OES:
+    case GL_PALETTE4_RGB5_A1_OES:
+        indexSizeBits = 4;
+        colorSizeBytes = 2;
+        break;
+
+    case GL_PALETTE8_RGB8_OES:
+        indexSizeBits = 8;
+        colorSizeBytes = 3;
+        break;
+
+    case GL_PALETTE8_RGBA8_OES:
+        indexSizeBits = 8;
+        colorSizeBytes = 4;
+            colorFrmt = GL_RGBA;
+        break;
+
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE8_RGB5_A1_OES:
+        indexSizeBits = 8;
+        colorSizeBytes = 2;
+        break;
+    }
+}
+
+
+Color paletteColor(const unsigned char* pallete,unsigned int index,GLenum format)
+{
+        short s;
+        switch(format) {
+        //RGB
+    case GL_PALETTE4_RGB8_OES:
+    case GL_PALETTE8_RGB8_OES:
+            return Color(pallete[index],pallete[index+1],pallete[index+2],0);
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE4_R5_G6_B5_OES:
+            s = *((short *)(pallete+index));
+            return Color(s >> 10,(s >> 5) & 0x3f ,s & 0x1f,0);
+
+        //RGBA
+    case GL_PALETTE4_RGBA8_OES:
+    case GL_PALETTE8_RGBA8_OES:
+            return Color(pallete[index],pallete[index+1],pallete[index+2],pallete[index+3]);
+    case GL_PALETTE4_RGBA4_OES:
+            s = *((short *)(pallete+index));
+            return Color((s >> 12) & 0xf,(s >> 8) & 0xf,(s >> 4) & 0xf ,s & 0xf);
+    case GL_PALETTE4_RGB5_A1_OES:
+    case GL_PALETTE8_RGB5_A1_OES:
+            s = *((short *)(pallete+index));
+            return Color((s >> 11) & 0x1f,(s >> 6) & 0x1f,(s >> 1) & 0x1f ,s & 0x1 * 255);
+        default:
+            return Color(255,255,255,255);
+    }
+}
+
+unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level) {
+
+    unsigned int indexSizeBits;  //the size of the color index in the pallete
+    unsigned int colorSizeBytes; //the size of each color cell in the pallete
+
+    const unsigned char* palette = static_cast<const unsigned char *>(data);
+
+    getPaletteInfo(internalformat,indexSizeBits,colorSizeBytes,formatOut);
+
+    //the pallete positioned in the begininng of the data
+    // so we jump over it to get to the colos indices in the palette
+
+    int nColors = 2 << (indexSizeBits -1); //2^indexSizeBits
+    int paletteSizeBytes = nColors*colorSizeBytes;
+    const unsigned char* imageIndices =  palette + paletteSizeBytes;
+
+    //jumping to the the correct mipmap level
+    for(int i=0;i<level;i++) {
+        imageIndices+= (width*height*indexSizeBits)/8;
+        width  = width  >> 1;
+        height = height >> 1;
+    }
+
+    int colorSizeOut = (formatOut == GL_RGB? 3:4);
+    int nPixels = width*height;
+    unsigned char* pixelsOut = new unsigned char[nPixels*colorSizeOut];
+    if(!pixelsOut) return NULL;
+
+    int leftBytes = ((palette + imageSize) /* the end of data pointer*/
+                      - imageIndices);
+    int leftPixels = (leftBytes * 8 )/indexSizeBits;
+
+    int maxIndices = (leftPixels < nPixels) ? leftPixels:nPixels;
+
+    //filling the pixels array
+    for(int i =0 ; i < maxIndices ; i++) {
+        int paletteIndex = 0;
+        int indexOut = i*colorSizeOut;
+        if(indexSizeBits == 4) {
+            paletteIndex = (i%2)? imageIndices[i/2] >> 4:  //upper bits
+                           imageIndices[i/2] & 0xf; //lower bits
+        } else {
+            paletteIndex = imageIndices[i];
+        }
+
+        paletteIndex*=colorSizeBytes;
+        Color c = paletteColor(palette,paletteIndex,internalformat);
+
+        pixelsOut[indexOut] = c.red;
+        pixelsOut[indexOut+1] = c.green;
+        pixelsOut[indexOut+2] = c.blue;
+        if(formatOut == GL_RGBA) {
+            pixelsOut[indexOut+3] = c.alpha;
+        }
+    }
+    return pixelsOut;
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.h
new file mode 100644
index 0000000..21094af
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.h
@@ -0,0 +1,23 @@
+/*
+* 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.
+*/
+#ifndef _TEXTURE_UTILS_H
+#define _TEXTURE_UTILS_H
+
+#include <GLES/gl.h>
+
+unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level);
+
+#endif