implement GL_OES_draw_texture

Change-Id: I9f91fa63dab0cf769dd5ee609c96d1143122991c
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
index 8df721d..3c4758a 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
@@ -29,11 +29,11 @@
         initExtensionString();
     }
     m_texCoords = new GLESpointer[s_glSupport.maxTexUnits];
-    m_map[GL_TEXTURE_COORD_ARRAY]  = &m_texCoords[m_activeTexture];
+    m_map[GL_TEXTURE_COORD_ARRAY]  = &m_texCoords[m_clientActiveTexture];
     m_initialized = true;
 }
 
-GLEScmContext::GLEScmContext():GLEScontext(),m_pointsIndex(-1){
+GLEScmContext::GLEScmContext():GLEScontext(),m_pointsIndex(-1), m_clientActiveTexture(0) {
 
     m_map[GL_COLOR_ARRAY]          = new GLESpointer();
     m_map[GL_NORMAL_ARRAY]         = new GLESpointer();
@@ -44,7 +44,11 @@
 
 void GLEScmContext::setActiveTexture(GLenum tex) {
    m_activeTexture = tex - GL_TEXTURE0;
-   m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_activeTexture];
+}
+
+void GLEScmContext::setClientActiveTexture(GLenum tex) {
+   m_clientActiveTexture = tex - GL_TEXTURE0;
+   m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture];
 }
 
 GLEScmContext::~GLEScmContext(){
@@ -90,7 +94,7 @@
         chooseConvertMethod(fArrs,first,count,type,indices,direct,p,array_id,index);
     }
 
-    unsigned int activeTexture = m_activeTexture + GL_TEXTURE0;
+    unsigned int activeTexture = m_clientActiveTexture + GL_TEXTURE0;
 
     s_lock.lock();
     int maxTexUnits = s_glSupport.maxTexUnits;
@@ -100,7 +104,7 @@
     for(int i=0; i< maxTexUnits;i++) {
 
         unsigned int tex = GL_TEXTURE0+i;
-        setActiveTexture(tex);
+        setClientActiveTexture(tex);
         s_glDispatch.glClientActiveTexture(tex);
 
         GLenum array_id   = GL_TEXTURE_COORD_ARRAY;
@@ -108,7 +112,7 @@
         chooseConvertMethod(fArrs,first,count,type,indices,direct,p,array_id,index);
     }
 
-    setActiveTexture(activeTexture);
+    setClientActiveTexture(activeTexture);
     s_glDispatch.glClientActiveTexture(activeTexture);
 }
 
@@ -181,7 +185,7 @@
                       "GL_OES_byte_coordinates GL_OES_compressed_paletted_texture GL_OES_point_size_array "
                       "GL_OES_point_sprite GL_OES_single_precision GL_OES_stencil_wrap GL_OES_texture_env_crossbar "
                       "GL_OES_texture_mirored_repeat GL_OES_EGL_image GL_OES_element_index_uint GL_OES_draw_texture "
-                      "GL_OES_texture_cube_map ";
+                      "GL_OES_texture_cube_map GL_OES_draw_texture ";
     if (s_glSupport.GL_OES_READ_FORMAT)
         *s_glExtensions+="GL_OES_read_format ";
     if (s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT) {
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h
index 729e31d..d683755 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h
@@ -35,6 +35,9 @@
     GLEScmContext();
 
     void setActiveTexture(GLenum tex);
+    void  setClientActiveTexture(GLenum tex);
+    GLenum  getActiveTexture() { return GL_TEXTURE0 + m_activeTexture;};
+    GLenum  getClientActiveTexture() { return GL_TEXTURE0 + m_clientActiveTexture;};
     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);
@@ -49,6 +52,7 @@
 
     GLESpointer*          m_texCoords;
     int                   m_pointsIndex;
+    unsigned int          m_clientActiveTexture;
 };
 
 #endif
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
index 49e7df3..81be5de 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
@@ -18,6 +18,7 @@
 #undef GL_API
 #define GL_API __declspec(dllexport)
 #endif
+#define GL_GLEXT_PROTOTYPES
 #include "GLEScmContext.h"
 #include "GLEScmValidate.h"
 #include "GLEScmUtils.h"
@@ -30,7 +31,6 @@
 #include <GLcommon/TranslatorIfaces.h>
 #include <GLcommon/ThreadInfo.h>
 #include <GLES/gl.h>
-#define GL_GLEXT_PROTOTYPES
 #include <GLES/glext.h>
 #include <cmath>
 #include <map>
@@ -138,6 +138,14 @@
             (*s_glesExtensions)["glGetFramebufferAttachmentParameterivOES"] = (__translatorMustCastToProperFunctionPointerType)glGetFramebufferAttachmentParameterivOES;
             (*s_glesExtensions)["glGenerateMipmapOES"] = (__translatorMustCastToProperFunctionPointerType)glGenerateMipmapOES;
         }
+        (*s_glesExtensions)["glDrawTexsOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexsOES;
+        (*s_glesExtensions)["glDrawTexiOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexiOES;
+        (*s_glesExtensions)["glDrawTexfOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexfOES;
+        (*s_glesExtensions)["glDrawTexxOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexxOES;
+        (*s_glesExtensions)["glDrawTexsvOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexsvOES;
+        (*s_glesExtensions)["glDrawTexivOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexivOES;
+        (*s_glesExtensions)["glDrawTexfvOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexfvOES;
+        (*s_glesExtensions)["glDrawTexxvOES"] = (__translatorMustCastToProperFunctionPointerType)glDrawTexxvOES;
     }
     __translatorMustCastToProperFunctionPointerType ret=NULL;
     ProcTableMap::iterator val = s_glesExtensions->find(procName);
@@ -155,6 +163,22 @@
 
 }
 
+static TextureData* getTextureData(){
+    GET_CTX_RET(NULL);
+    unsigned int tex = ctx->getBindedTexture();
+    if (tex==0)
+        return NULL;
+    TextureData *texData = NULL;
+    ObjectDataPtr objData = thrd->shareGroup->getObjectData(TEXTURE,tex);
+    if(!objData.Ptr()){
+        texData = new TextureData();
+        thrd->shareGroup->setObjectData(TEXTURE, tex, ObjectDataPtr(texData));
+    } else {
+        texData = (TextureData*)objData.Ptr();
+    }
+    return texData;
+}
+
 GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) {
     GET_CTX_RET(GL_FALSE)
 
@@ -222,6 +246,7 @@
 GL_API void GL_APIENTRY  glActiveTexture( GLenum texture) {
     GET_CTX_CM()
     SET_ERROR_IF(!GLEScmValidate::textureEnum(texture,ctx->getMaxTexUnits()),GL_INVALID_ENUM);
+    ctx->setActiveTexture(texture);
     ctx->dispatcher().glActiveTexture(texture);
 }
 
@@ -267,7 +292,7 @@
             globalTextureName = thrd->shareGroup->getGlobalName(TEXTURE,texture);
         }
     }
-    ctx->setBindedTexture(globalTextureName);
+    ctx->setBindedTexture(texture);
     ctx->dispatcher().glBindTexture(target,globalTextureName);
 }
 
@@ -325,7 +350,7 @@
 GL_API void GL_APIENTRY  glClientActiveTexture( GLenum texture) {
     GET_CTX_CM()
     SET_ERROR_IF(!GLEScmValidate::textureEnum(texture,ctx->getMaxTexUnits()),GL_INVALID_ENUM);
-    ctx->setActiveTexture(texture);
+    ctx->setClientActiveTexture(texture);
     ctx->dispatcher().glClientActiveTexture(texture);
 
 }
@@ -476,8 +501,11 @@
         ctx->dispatcher().glDisable(GL_TEXTURE_GEN_T);
         ctx->dispatcher().glDisable(GL_TEXTURE_GEN_R);
     }
-    else
-        ctx->dispatcher().glDisable(cap);
+    ctx->dispatcher().glDisable(cap);
+    if (cap==GL_TEXTURE_2D)
+        ctx->setTextureEnabled(TEXTURE_2D,false);
+    else if (cap==GL_TEXTURE_CUBE_MAP_OES)
+        ctx->setTextureEnabled(TEXTURE_CUBE_MAP,false);
 }
 
 GL_API void GL_APIENTRY  glDisableClientState( GLenum array) {
@@ -537,6 +565,10 @@
     }
     else
         ctx->dispatcher().glEnable(cap);
+    if (cap==GL_TEXTURE_2D)
+        ctx->setTextureEnabled(TEXTURE_2D,true);
+    else if (cap==GL_TEXTURE_CUBE_MAP_OES)
+        ctx->setTextureEnabled(TEXTURE_CUBE_MAP,true);
 }
 
 GL_API void GL_APIENTRY  glEnableClientState( GLenum array) {
@@ -858,19 +890,43 @@
 
 GL_API void GL_APIENTRY  glGetTexParameterfv( GLenum target, GLenum pname, GLfloat *params) {
     GET_CTX()
-    ctx->dispatcher().glGetTexParameterfv(target,pname,params);
+   if (pname==GL_TEXTURE_CROP_RECT_OES) {
+      TextureData *texData = getTextureData();
+      SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
+      for (int i=0;i<4;++i)
+        params[i] = texData->crop_rect[i];
+    }
+    else {
+      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);
+    if (pname==GL_TEXTURE_CROP_RECT_OES) {
+      TextureData *texData = getTextureData();
+      SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
+      for (int i=0;i<4;++i)
+        params[i] = texData->crop_rect[i];
+    }
+    else {
+      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);
+    if (pname==GL_TEXTURE_CROP_RECT_OES) {
+      TextureData *texData = getTextureData();
+      SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
+      for (int i=0;i<4;++i)
+        params[i] = F2X(texData->crop_rect[i]);
+    }
+    else {
+      GLfloat tmpParam;
+      ctx->dispatcher().glGetTexParameterfv(target,pname,&tmpParam);
+      params[0] = static_cast<GLfixed>(tmpParam);
+    }
 }
 
 GL_API void GL_APIENTRY  glHint( GLenum target, GLenum mode) {
@@ -1252,20 +1308,6 @@
     ctx->dispatcher().glTexEnvfv(target,pname,tmpParams);
 }
 
-static TextureData* getTextureData(){
-    GET_CTX_RET(NULL);
-    unsigned int tex = ctx->getBindedTexture();
-    TextureData *texData = NULL;
-    ObjectDataPtr objData = thrd->shareGroup->getObjectData(TEXTURE,tex);
-    if(!objData.Ptr()){
-        texData = new TextureData();
-        thrd->shareGroup->setObjectData(TEXTURE, tex, ObjectDataPtr(texData));
-    } else {
-        texData = (TextureData*)objData.Ptr();
-    }
-    return texData;
-}
-
 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()
 
@@ -1277,8 +1319,8 @@
     SET_ERROR_IF(!(GLEScmValidate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION);
 
     if (thrd->shareGroup.Ptr()){
-        unsigned int tex = ctx->getBindedTexture();
         TextureData *texData = getTextureData();
+        SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
         if(texData) {
             texData->width = width;
             texData->height = height;
@@ -1298,7 +1340,15 @@
 GL_API void GL_APIENTRY  glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params) {
     GET_CTX()
     SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
-    ctx->dispatcher().glTexParameterfv(target,pname,params);
+    if (pname==GL_TEXTURE_CROP_RECT_OES) {
+        TextureData *texData = getTextureData();
+        SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
+        for (int i=0;i<4;++i)
+            texData->crop_rect[i] = params[i];
+    }
+    else {
+        ctx->dispatcher().glTexParameterfv(target,pname,params);
+    }
 }
 
 GL_API void GL_APIENTRY  glTexParameteri( GLenum target, GLenum pname, GLint param) {
@@ -1310,7 +1360,15 @@
 GL_API void GL_APIENTRY  glTexParameteriv( GLenum target, GLenum pname, const GLint *params) {
     GET_CTX()
     SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
-    ctx->dispatcher().glTexParameteriv(target,pname,params);
+    if (pname==GL_TEXTURE_CROP_RECT_OES) {
+        TextureData *texData = getTextureData();
+        SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
+        for (int i=0;i<4;++i)
+            texData->crop_rect[i] = params[i];
+    }
+    else {
+        ctx->dispatcher().glTexParameteriv(target,pname,params);
+    }
 }
 
 GL_API void GL_APIENTRY  glTexParameterx( GLenum target, GLenum pname, GLfixed param) {
@@ -1322,8 +1380,16 @@
 GL_API void GL_APIENTRY  glTexParameterxv( GLenum target, GLenum pname, const GLfixed *params) {
     GET_CTX()
     SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
-    GLfloat param = static_cast<GLfloat>(params[0]);
-    ctx->dispatcher().glTexParameterfv(target,pname,&param);
+    if (pname==GL_TEXTURE_CROP_RECT_OES) {
+        TextureData *texData = getTextureData();
+        SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
+        for (int i=0;i<4;++i)
+            texData->crop_rect[i] = X2F(params[i]);
+    }
+    else {
+        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) {
@@ -1379,6 +1445,7 @@
             thrd->shareGroup->replaceGlobalName(TEXTURE, tex,img->globalTexName);
             ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, img->globalTexName);
             TextureData *texData = getTextureData();
+            SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
             texData->sourceEGLImage = (unsigned int)image;
             texData->eglImageDetach = s_eglIface->eglDetachEGLImage;
         }
@@ -1702,3 +1769,127 @@
 
     params[0] = F2X(tmpParams[1]);
 }
+
+template <class T, GLenum TypeName>
+void glDrawTexOES (T x, T y, T z, T width, T height) {
+    GET_CTX()
+    int numClipPlanes;
+
+    GLint viewport[4];
+    z = (z>1 ? 1 : (z<0 ?  0 : z));
+
+    T     vertices[4*3] = {x , y, z,
+                             x , y+height, z,
+                             x+width, y+height, z,
+                             x+width, y, z};
+    GLfloat texels[ctx->getMaxTexUnits()][4*2];
+
+    ctx->dispatcher().glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+    ctx->dispatcher().glPushAttrib(GL_TRANSFORM_BIT);
+
+    //setup projection matrix to draw in viewport aligned coordinates
+    ctx->dispatcher().glMatrixMode(GL_PROJECTION);
+    ctx->dispatcher().glPushMatrix();
+    ctx->dispatcher().glLoadIdentity();
+    ctx->dispatcher().glGetIntegerv(GL_VIEWPORT,viewport);
+    ctx->dispatcher().glOrtho(viewport[0],viewport[0] + viewport[2],viewport[1],viewport[1]+viewport[3],0,-1);
+    //setup texture matrix
+    ctx->dispatcher().glMatrixMode(GL_TEXTURE);
+    ctx->dispatcher().glPushMatrix();
+    ctx->dispatcher().glLoadIdentity();
+    //setup modelview matrix
+    ctx->dispatcher().glMatrixMode(GL_MODELVIEW);
+    ctx->dispatcher().glPushMatrix();
+    ctx->dispatcher().glLoadIdentity();
+    //backup vbo's
+    int array_buffer,element_array_buffer;
+    glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&array_buffer);
+    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,&element_array_buffer);
+    ctx->dispatcher().glBindBuffer(GL_ARRAY_BUFFER,0);
+    ctx->dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+
+    //disable clip planes
+    ctx->dispatcher().glGetIntegerv(GL_MAX_CLIP_PLANES,&numClipPlanes);
+    for (int i=0;i<numClipPlanes;++i)
+        ctx->dispatcher().glDisable(GL_CLIP_PLANE0+i);
+
+    for (int i=0;i<ctx->getMaxTexUnits();++i) {
+        if (ctx->isTextureUnitEnabled(GL_TEXTURE0+i)) {
+            TextureData * texData = NULL;
+            int tex = ctx->getBindedTexture(GL_TEXTURE0+i);
+            ctx->dispatcher().glClientActiveTexture(GL_TEXTURE0+i);
+            ObjectDataPtr objData = thrd->shareGroup->getObjectData(TEXTURE,tex);
+            if (objData.Ptr()) {
+                texData = (TextureData*)objData.Ptr();
+                //calculate texels
+                texels[i][0] = (float)(texData->crop_rect[0])/(float)(texData->width);
+                texels[i][1] = (float)(texData->crop_rect[1])/(float)(texData->height);
+
+                texels[i][2] = (float)(texData->crop_rect[0])/(float)(texData->width);
+                texels[i][3] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
+
+                texels[i][4] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
+                texels[i][5] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
+                
+                texels[i][6] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
+                texels[i][7] = (float)(texData->crop_rect[1])/(float)(texData->height);
+
+                ctx->dispatcher().glTexCoordPointer(2,GL_FLOAT,0,texels[i]);
+             }
+        }
+    }
+
+    //draw rectangle
+    ctx->dispatcher().glEnableClientState(GL_VERTEX_ARRAY);
+    ctx->dispatcher().glVertexPointer(3,TypeName,0,vertices);
+    ctx->dispatcher().glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    ctx->dispatcher().glDrawArrays(GL_TRIANGLE_FAN,0,4);
+
+    //restore vbo's
+    ctx->dispatcher().glBindBuffer(GL_ARRAY_BUFFER,array_buffer);
+    ctx->dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,element_array_buffer);
+
+    //restore matrix state
+
+    ctx->dispatcher().glMatrixMode(GL_MODELVIEW);
+    ctx->dispatcher().glPopMatrix();
+    ctx->dispatcher().glMatrixMode(GL_TEXTURE);
+    ctx->dispatcher().glPopMatrix();
+    ctx->dispatcher().glMatrixMode(GL_PROJECTION);
+    ctx->dispatcher().glPopMatrix();
+
+    ctx->dispatcher().glPopAttrib();
+    ctx->dispatcher().glPopClientAttrib();
+}
+
+GL_API void GL_APIENTRY glDrawTexsOES (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) {
+    glDrawTexOES<GLshort,GL_SHORT>(x,y,z,width,height);
+}
+
+GL_API void GL_APIENTRY glDrawTexiOES (GLint x, GLint y, GLint z, GLint width, GLint height) {
+    glDrawTexOES<GLint,GL_INT>(x,y,z,width,height);
+}
+
+GL_API void GL_APIENTRY glDrawTexfOES (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) {
+    glDrawTexOES<GLfloat,GL_FLOAT>(x,y,z,width,height);
+}
+
+GL_API void GL_APIENTRY glDrawTexxOES (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) {
+    glDrawTexOES<GLfloat,GL_FLOAT>(X2F(x),X2F(y),X2F(z),X2F(width),X2F(height));
+}
+
+GL_API void GL_APIENTRY glDrawTexsvOES (const GLshort * coords) { 
+    glDrawTexOES<GLshort,GL_SHORT>(coords[0],coords[1],coords[2],coords[3],coords[4]);
+}
+
+GL_API void GL_APIENTRY glDrawTexivOES (const GLint * coords) { 
+    glDrawTexOES<GLint,GL_INT>(coords[0],coords[1],coords[2],coords[3],coords[4]);
+}
+
+GL_API void GL_APIENTRY glDrawTexfvOES (const GLfloat * coords) { 
+    glDrawTexOES<GLfloat,GL_FLOAT>(coords[0],coords[1],coords[2],coords[3],coords[4]);
+}
+
+GL_API void GL_APIENTRY glDrawTexxvOES (const GLfixed * coords) { 
+    glDrawTexOES<GLfloat,GL_FLOAT>(X2F(coords[0]),X2F(coords[1]),X2F(coords[2]),X2F(coords[3]),X2F(coords[4]));
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp
index cdf3df2..a2015db 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp
@@ -110,6 +110,7 @@
     case GL_TEXTURE_MAG_FILTER:
     case GL_TEXTURE_WRAP_S:
     case GL_TEXTURE_WRAP_T:
+    case GL_TEXTURE_CROP_RECT_OES:
         break;
     default:
         return false;
diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
index 8914ea7..b20f6e7 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
@@ -122,6 +122,10 @@
 void (GLAPIENTRY *GLDispatch::glTexParameteriv)(GLenum,GLenum,const GLint *) = NULL;
 void (GLAPIENTRY *GLDispatch::glTexSubImage2D)(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid *) = NULL;
 void (GLAPIENTRY *GLDispatch::glViewport)(GLint,GLint,GLsizei,GLsizei) = NULL;
+void (GLAPIENTRY *GLDispatch::glPushAttrib) ( GLbitfield mask ) = NULL;
+void (GLAPIENTRY *GLDispatch::glPopAttrib) ( void ) = NULL;
+void (GLAPIENTRY *GLDispatch::glPushClientAttrib) ( GLbitfield mask ) = NULL;
+void (GLAPIENTRY *GLDispatch::glPopClientAttrib) ( void ) = NULL;
 
 /*GLES 1.1*/
 void (GLAPIENTRY *GLDispatch::glAlphaFunc)(GLenum,GLclampf) = NULL;
@@ -363,6 +367,10 @@
     LOAD_GL_FUNC(glTexParameteriv);
     LOAD_GL_FUNC(glTexSubImage2D);
     LOAD_GL_FUNC(glViewport);
+    LOAD_GL_FUNC(glPushAttrib);
+    LOAD_GL_FUNC(glPushClientAttrib);
+    LOAD_GL_FUNC(glPopAttrib);
+    LOAD_GL_FUNC(glPopClientAttrib);
     
     /* Loading OpenGL functions which are needed ONLY for implementing GLES 1.1*/
     if(version == GLES_1_1){
diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
index 57d0ed2..5b78294 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
@@ -28,7 +28,11 @@
                            m_glError(GL_NO_ERROR)  ,
                            m_arrayBuffer(0)        ,
                            m_elementBuffer(0) {
-      
+    for (int i=0;i<MAX_TEX_UNITS;++i) {
+        m_tex2DBind[i].texture = 0;
+        for (int j=0;j<NUM_TEXTURE_TARGETS;++j)
+            m_tex2DBind[i].enabled[j] = GL_FALSE;
+    }  
 };
 
 GLenum GLEScontext::getGLerror() {
@@ -397,3 +401,11 @@
     s_glExtensions = new std::string("");
 }
 
+bool GLEScontext::isTextureUnitEnabled(GLenum unit) {
+    for (int i=0;i<NUM_TEXTURE_TARGETS;++i) {
+        if (m_tex2DBind[unit-GL_TEXTURE0].enabled[i])
+            return true;
+    }
+    return false;
+}
+
diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h
index 2533ef7..76027ea 100644
--- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h
+++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h
@@ -90,7 +90,10 @@
     static void (GLAPIENTRY *glTexParameteriv) (GLenum target, GLenum pname, const GLint *params);
     static void (GLAPIENTRY *glTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
     static void (GLAPIENTRY *glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
-
+    static void (GLAPIENTRY *glPushAttrib) ( GLbitfield mask );
+    static void (GLAPIENTRY *glPopAttrib) ( void );
+    static void (GLAPIENTRY *glPushClientAttrib) ( GLbitfield mask );
+    static void (GLAPIENTRY *glPopClientAttrib) ( void );
 
     /* OpenGL functions which are needed ONLY for implementing GLES 1.1*/
     static void (GLAPIENTRY *glAlphaFunc) (GLenum func, GLclampf ref);
diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
index 6b3b99c..aad88ad 100644
--- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
+++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
@@ -11,6 +11,17 @@
 
 typedef std::map<GLenum,GLESpointer*>  ArraysMap;
 
+enum TextureTarget {
+TEXTURE_2D,
+TEXTURE_CUBE_MAP,
+NUM_TEXTURE_TARGETS
+};
+
+typedef struct _textureUnitState {
+    GLuint texture;
+    GLboolean enabled[NUM_TEXTURE_TARGETS];
+} textureUnitState;
+
 struct GLSupport {
     GLSupport():maxLights(0),maxVertexAttribs(0),maxClipPlane(0),maxTexUnits(0),maxTexSize(0) , \
                 GL_EXT_TEXTURE_FORMAT_BGRA8888(false), GL_EXT_FRAMEBUFFER_OBJECT(false), \
@@ -44,8 +55,11 @@
     void setGLerror(GLenum err);
     void setShareGroup(ShareGroupPtr grp){m_shareGroup = grp;};
     virtual void setActiveTexture(GLenum tex);
-    unsigned int getBindedTexture(){return m_tex2DBind[m_activeTexture];};
-    void setBindedTexture(unsigned int tex){ m_tex2DBind[m_activeTexture] = tex;};
+    unsigned int getBindedTexture(){return m_tex2DBind[m_activeTexture].texture;};
+    unsigned int getBindedTexture(GLenum unit) { return m_tex2DBind[unit - GL_TEXTURE0].texture;};
+    void setBindedTexture(unsigned int tex){ m_tex2DBind[m_activeTexture].texture = tex;};
+    bool isTextureUnitEnabled(GLenum unit);
+    void setTextureEnabled(TextureTarget target, GLenum enable) {m_tex2DBind[m_activeTexture].enabled[target] = enable; };
 
     bool  isArrEnabled(GLenum);
     void  enableArr(GLenum arr,bool enable);
@@ -97,7 +111,7 @@
 
     ShareGroupPtr         m_shareGroup;
     GLenum                m_glError;
-    unsigned int          m_tex2DBind[MAX_TEX_UNITS];
+    textureUnitState      m_tex2DBind[MAX_TEX_UNITS];
     unsigned int          m_arrayBuffer;
     unsigned int          m_elementBuffer;
 };
diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h
index 51ad4b3..5d00ce6 100644
--- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h
+++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h
@@ -17,6 +17,7 @@
 #define TRANSLATOR_IFACES_H
 #include <GLcommon/ThreadInfo.h>
 #include <GLES/gl.h>
+#include <string.h>
 
 extern "C" {
 
@@ -36,13 +37,16 @@
     ~TextureData() {
         if (sourceEGLImage && eglImageDetach) (*eglImageDetach)(sourceEGLImage);
     }
-    TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0){};
+    TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0){ 
+        memset(crop_rect,0,4*sizeof(int)); 
+    };
 
     unsigned int width;
     unsigned int height;
     unsigned int border;
     unsigned int internalFormat;
     unsigned int sourceEGLImage;
+    int          crop_rect[4];
     void (*eglImageDetach)(unsigned int imageId);
 };
 
diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h
index b0fedad..ea8578d 100644
--- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h
+++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h
@@ -1,3 +1,18 @@
+/*
+* 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.
+*/
 
 typedef double      GLclampd;   /* double precision float in [0,1] */
 typedef double      GLdouble;   /* double precision float */
@@ -5,3 +20,6 @@
 #define GL_TEXTURE_GEN_S			0x0C60
 #define GL_TEXTURE_GEN_T			0x0C61
 #define GL_TEXTURE_GEN_R			0x0C62
+#define GL_CLIENT_VERTEX_ARRAY_BIT    0x00000002
+#define GL_TRANSFORM_BIT      0x00001000
+#define GL_INT                0x1404