emulator opengl: add GLESv2 support to driver + renderer

Added GLESv2 library to system.
Made fixes to the host libOpenGLRender to
compile and support GLESv2 (defined WITH_GLES2).
Other fixes required to make GLESv2 to work.

Change-Id: I9eb198e6092e7fa3550342c50929dd1714282cb3
diff --git a/tools/emulator/opengl/Android.mk b/tools/emulator/opengl/Android.mk
index ba9f93a..c7f7b70 100644
--- a/tools/emulator/opengl/Android.mk
+++ b/tools/emulator/opengl/Android.mk
@@ -18,6 +18,12 @@
 #
 EMUGL_COMMON_INCLUDES := $(EMUGL_PATH)/host/include/libOpenglRender
 
+# common cflags used by several modules
+# This is always set to a module's LOCAL_CFLAGS
+# See the definition of emugl-begin-module in common.mk
+#
+EMUGL_COMMON_CFLAGS := -DWITH_GLES2
+
 # Include common definitions used by all the modules included later
 # in this build file. This contains the definition of all useful
 # emugl-xxxx functions.
@@ -55,6 +61,7 @@
 
 # System shared libraries
 include $(EMUGL_PATH)/system/GLESv1/Android.mk
+include $(EMUGL_PATH)/system/GLESv2/Android.mk
 include $(EMUGL_PATH)/system/egl/Android.mk
 include $(EMUGL_PATH)/tests/gles_android_wrapper/Android.mk
 
diff --git a/tools/emulator/opengl/common.mk b/tools/emulator/opengl/common.mk
index 012ecf1..b0b7e5c 100644
--- a/tools/emulator/opengl/common.mk
+++ b/tools/emulator/opengl/common.mk
@@ -38,6 +38,7 @@
     $(eval LOCAL_MODULE_CLASS := $(patsubst HOST_%,%,$(patsubst %EXECUTABLE,%EXECUTABLES,$(patsubst %LIBRARY,%LIBRARIES,$2)))) \
     $(eval LOCAL_IS_HOST_MODULE := $(if $3,true,))\
     $(eval LOCAL_C_INCLUDES := $(EMUGL_COMMON_INCLUDES)) \
+    $(eval LOCAL_CFLAGS := $(EMUGL_COMMON_CFLAGS)) \
     $(eval LOCAL_PRELINK_MODULE := false)\
     $(eval _EMUGL_INCLUDE_TYPE := $(BUILD_$2)) \
     $(call _emugl-init-module,$1,$2,$3)
diff --git a/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp b/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
index 8541b3d..ec6e192 100644
--- a/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
+++ b/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
@@ -108,7 +108,7 @@
     ctx->glDrawElements(mode, count, type, (void *)offset);
 }
 
-void GL2Decoder::s_glShaderString(void *self, GLuint shader, GLstr string, GLsizei len)
+void GL2Decoder::s_glShaderString(void *self, GLuint shader, const GLchar* string, GLsizei len)
 {
     GL2Decoder *ctx = (GL2Decoder *)self;
     ctx->glShaderSource(shader, 1, &string, NULL);
diff --git a/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h b/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h
index e626db3..86ad8f1 100644
--- a/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h
+++ b/tools/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h
@@ -30,6 +30,6 @@
 
     static void s_glDrawElementsOffset(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset);
     static void s_glDrawElementsData(void *self, GLenum mode, GLsizei count, GLenum type, void * data, GLuint datalen);
-    static void s_glShaderString(void *self, GLuint shader, GLstr string, GLsizei len);
+    static void s_glShaderString(void *self, GLuint shader, const GLchar* string, GLsizei len);
 };
 #endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk b/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk
index 1e133b4..9bf74b7 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk
@@ -5,7 +5,7 @@
 ### libOpenglRender #################################################
 $(call emugl-begin-host-shared-library,libOpenglRender)
 
-$(call emugl-import,libGLESv1_dec lib_renderControl_dec libOpenglCodecCommon libOpenglOsUtils)
+$(call emugl-import,libGLESv1_dec libGLESv2_dec lib_renderControl_dec libOpenglCodecCommon libOpenglOsUtils)
 
 LOCAL_SRC_FILES := \
     render_api.cpp \
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
index 1caaf10..d5f00ce 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
@@ -77,8 +77,8 @@
     }
 
     s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL);
-    s_egl.eglDestroySurface(p_dpy, surface);
     s_egl.eglDestroyContext(p_dpy, ctx);
+    s_egl.eglDestroySurface(p_dpy, surface);
 
     return extString;
 }
@@ -564,8 +564,14 @@
     tinfo->currContext = ctx;
     tinfo->currDrawSurf = draw;
     tinfo->currReadSurf = read;
-    tinfo->m_glDec.setContextData(&ctx->decoderContextData());
-
+    if (ctx) {
+        if (ctx->isGL2()) tinfo->m_gl2Dec.setContextData(&ctx->decoderContextData());
+        else tinfo->m_glDec.setContextData(&ctx->decoderContextData());
+    }
+    else {
+        tinfo->m_glDec.setContextData(NULL);
+        tinfo->m_gl2Dec.setContextData(NULL);
+    }
     return true;
 }
 
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
index 0989d37..b32385c 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
@@ -41,7 +41,8 @@
     //
     // init the GLES dispatch table
     //
-    return s_gl2.initDispatchByName( gl2_dispatch_get_proc_func, NULL );
+    s_gl2.initDispatchByName( gl2_dispatch_get_proc_func, NULL );
+    return true;
 }
 
 //
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h
index 6d1415b..7ad19bb 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h
@@ -23,7 +23,7 @@
 bool init_gl2_dispatch();
 void *gl2_dispatch_get_proc_func(const char *name, void *userData);
 
-extern gl2_decoder_context_t s_gl;
+extern gl2_decoder_context_t s_gl2;
 
 #endif
 #endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
index ad5df38..5725cde 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
@@ -19,6 +19,7 @@
 #include "ReadBuffer.h"
 #include "TimeUtils.h"
 #include "GLDispatch.h"
+#include "GL2Dispatch.h"
 
 #define STREAM_BUFFER_SIZE 4*1024*1024
 
@@ -47,6 +48,7 @@
     // initialize decoders
     //
     tInfo->m_glDec.initGL( gl_dispatch_get_proc_func, NULL );
+    tInfo->m_gl2Dec.initGL( gl2_dispatch_get_proc_func, NULL );
     initRenderControlContext( &m_rcDec );
 
     ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE);
@@ -79,7 +81,7 @@
             progress = false;
 
             //
-            // try to process some of the command buffer using the GLES decoder
+            // try to process some of the command buffer using the GLESv1 decoder
             //
             size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
             if (last > 0) {
@@ -88,6 +90,15 @@
             }
 
             //
+            // try to process some of the command buffer using the GLESv2 decoder
+            //
+            last = tInfo->m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+            if (last > 0) {
+                progress = true;
+                readBuf.consume(last);
+            }
+
+            //
             // try to process some of the command buffer using the
             // renderControl decoder
             //
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
index cabeb56..b147290 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
@@ -19,6 +19,7 @@
 #include "RenderContext.h"
 #include "WindowSurface.h"
 #include "GLDecoder.h"
+#include "GL2Decoder.h"
 
 struct RenderThreadInfo
 {
@@ -26,6 +27,7 @@
     WindowSurfacePtr currDrawSurf;
     WindowSurfacePtr currReadSurf;
     GLDecoder        m_glDec;
+    GL2Decoder       m_gl2Dec;
 };
 
 RenderThreadInfo *getRenderThreadInfo();
diff --git a/tools/emulator/opengl/host/renderer/Android.mk b/tools/emulator/opengl/host/renderer/Android.mk
index 6f26548..5535250 100644
--- a/tools/emulator/opengl/host/renderer/Android.mk
+++ b/tools/emulator/opengl/host/renderer/Android.mk
@@ -23,6 +23,7 @@
 
 LOCAL_SHARED_LIBRARIES := libOpenglRender \
         libGLESv1_dec \
+        libGLESv2_dec \
         lib_renderControl_dec
 
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
index 8cc097c..3c91dd1 100644
--- a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
+++ b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
@@ -637,7 +637,7 @@
                 }
             } else if (pass == PASS_DebugPrint) {
                 fprintf(fp, "#ifdef DEBUG_PRINTOUT\n");
-                fprintf(fp, "\t\t\tfprintf(stderr,\"%s(%s)\\n\"", e->name().c_str(), printString.c_str());
+                fprintf(fp, "\t\t\tfprintf(stderr,\"%s: %s(%s)\\n\"", m_basename.c_str(), e->name().c_str(), printString.c_str());
                 if (e->vars().size() > 0 && !e->vars()[0].isVoid()) fprintf(fp, ",");
             }
 
diff --git a/tools/emulator/opengl/system/GLESv2/Android.mk b/tools/emulator/opengl/system/GLESv2/Android.mk
new file mode 100644
index 0000000..184476a
--- /dev/null
+++ b/tools/emulator/opengl/system/GLESv2/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+### GLESv2 implementation ###########################################
+$(call emugl-begin-shared-library,libGLESv2_emulation)
+$(call emugl-import,libOpenglSystemCommon libGLESv2_enc lib_renderControl_enc)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"GLESv2_emulation\" -DGL_GLEXT_PROTOTYPES
+
+LOCAL_SRC_FILES := gl2.cpp
+LOCAL_STATIC_LIBRARIES += libqemu
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
+
+$(call emugl-end-module)
diff --git a/tools/emulator/opengl/system/GLESv2/gl2.cpp b/tools/emulator/opengl/system/GLESv2/gl2.cpp
new file mode 100644
index 0000000..abfa7ea
--- /dev/null
+++ b/tools/emulator/opengl/system/GLESv2/gl2.cpp
@@ -0,0 +1,103 @@
+#include "EGLClientIface.h"
+#include "HostConnection.h"
+#include "GL2Encoder.h"
+#include "GLES/gl.h"
+#include "GLES/glext.h"
+#include "ErrorLog.h"
+#include <private/ui/android_natives_priv.h>
+#include "gralloc_cb.h"
+
+
+//XXX: fix this macro to get the context from fast tls path
+#define GET_CONTEXT gl2_client_context_t * ctx = HostConnection::get()->gl2Encoder();
+
+#include "gl2_entry.cpp"
+
+//The functions table
+#include "gl2_ftable.h"
+
+
+static EGLClient_eglInterface * s_egl = NULL;
+static EGLClient_glesInterface * s_gl = NULL;
+
+#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
+    HostConnection *hostCon = HostConnection::get(); \
+    if (!hostCon) { \
+        LOGE("egl: Failed to get host connection\n"); \
+        return ret; \
+    } \
+    renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
+    if (!rcEnc) { \
+        LOGE("egl: Failed to get renderControl encoder context\n"); \
+        return ret; \
+    }
+
+//GL extensions
+void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image)
+{
+    DBG("glEGLImageTargetTexture2DOES");
+    //TODO: check error - we don't have a way to set gl error
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        return;
+    }
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        return;
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION();
+    rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle);
+
+    return;
+}
+
+void * getProcAddress(const char * procname)
+{
+    // search in GL function table
+    for (int i=0; i<gl2_num_funcs; i++) {
+        if (!strcmp(gl2_funcs_by_name[i].name, procname)) {
+            return gl2_funcs_by_name[i].proc;
+        }
+    }
+    return NULL;
+}
+
+void finish()
+{
+    glFinish();
+}
+
+const GLubyte *my_glGetString (void *self, GLenum name)
+{
+    if (s_egl) {
+        return (const GLubyte*)s_egl->getGLString(name);
+    }
+    return NULL;
+}
+
+void init()
+{
+    GET_CONTEXT;
+    ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES);
+    ctx->set_glGetString(my_glGetString);
+}
+
+extern "C" {
+EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface)
+{
+    s_egl = eglIface;
+
+    if (!s_gl) {
+        s_gl = new EGLClient_glesInterface();
+        s_gl->getProcAddress = getProcAddress;
+        s_gl->finish = finish;
+        s_gl->init = init;
+    }
+
+    return s_gl;
+}
+} //extern
+
+
diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp
index bdb9a42..d2075f9 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp
+++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp
@@ -325,9 +325,8 @@
     return m_compressedTextureFormats;
 }
 
-void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLstr *string, const GLint *length)
+void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **string, const GLint *length)
 {
-
     int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
     char *str = new char[len + 1];
     glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h
index 59a9100..3365d06 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h
+++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h
@@ -33,7 +33,13 @@
     void flush() {
         gl2_encoder_context_t::m_stream->flush();
     }
+
+    void setInitialized(){ m_initialized = true; };
+    bool isInitialized(){ return m_initialized; };
+
 private:
+
+    bool    m_initialized;
     GLClientState *m_state;
 
     GLint *m_compressedTextureFormats;
@@ -91,7 +97,7 @@
     glGetVertexAttribPointerv_client_proc_t m_glGetVertexAttribPointerv;
     static void s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer);
 
-    static void s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLstr *string, const GLint *length);
+    static void s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
 
     static void s_glFinish(void *self);
 };
diff --git a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
index c724405..118fe58 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
+++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
@@ -114,8 +114,8 @@
 
 #void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
 glGetFramebufferAttachmentParameteriv
-      dir params out
-      len params (sizeof(GLint))
+	dir params out
+	len params (sizeof(GLint))
 
 #void glGetIntegerv(GLenum pname, GLint *params)
 glGetIntegerv
@@ -152,6 +152,7 @@
 glGetShaderInfoLog
 	dir length out
 	len length (sizeof(GLsizei))
+	var_flag length nullAllowed
 	dir infolog out
 	len infolog bufsize
 	
@@ -521,9 +522,11 @@
 	len data datalen
 	custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen) 
 	flag custom_decoder
+	flag not_api
 
 glVertexAttribPointerOffset
 	flag custom_decoder
+	flag not_api
 
 #client-state, handled by the encoder
 #GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer)
@@ -533,20 +536,24 @@
 glDrawElementsData
 	len data datalen
 	flag custom_decoder
+	flag not_api
 
 glDrawElementsOffset
 	flag custom_decoder
+	flag not_api
 
 #GL_ENTRY(void, glGetCompressedTextureFormats, int count, GLint *formats)
 glGetCompressedTextureFormats
 	dir formats out
 	len formats (count * sizeof(GLint))
 	flag custom_decoder
+	flag not_api
 
 #GL_ENTRY(void, glShaderString, GLuint shader, GLchar *string, GLsizei len)
 glShaderString
 	len string len
 	flag custom_decoder
+	flag not_api
 	
 glFinishRoundTrip
 	flag custom_decoder
diff --git a/tools/emulator/opengl/system/GLESv2_enc/gl2.in b/tools/emulator/opengl/system/GLESv2_enc/gl2.in
index 14b9d19..916153b 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/gl2.in
+++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.in
@@ -96,7 +96,7 @@
 GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
 GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
 GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
-GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLstr* string, const GLint* length)
+GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
 GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
 GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
 GL_ENTRY(void, glStencilMask, GLuint mask)
@@ -210,5 +210,5 @@
 GL_ENTRY(void, glDrawElementsOffset, GLenum mode, GLsizei count, GLenum type, GLuint offset)
 GL_ENTRY(void, glDrawElementsData, GLenum mode, GLsizei count, GLenum type, void *data, GLuint datalen)
 GL_ENTRY(void, glGetCompressedTextureFormats, int count, GLint *formats)
-GL_ENTRY(void, glShaderString, GLuint shader, GLstr string, GLsizei len)
+GL_ENTRY(void, glShaderString, GLuint shader, const GLchar* string, GLsizei len)
 GL_ENTRY(int, glFinishRoundTrip, void)
diff --git a/tools/emulator/opengl/system/GLESv2_enc/gl2.types b/tools/emulator/opengl/system/GLESv2_enc/gl2.types
index 20f65cd..4cee99e 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/gl2.types
+++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.types
@@ -29,6 +29,7 @@
 GLuint* 32 0x%08x true
 GLvoid* 32 0x%08x true
 GLchar* 32 0x%08x true
+GLchar** 32 0x%08x true
 GLvoid** 32 0x%08x true
 void* 32 0x%08x true
 GLstr 32 %s true
diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk b/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk
index f1635ad..b397bda 100644
--- a/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk
+++ b/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk
@@ -1,7 +1,7 @@
 LOCAL_PATH := $(call my-dir)
 
 $(call emugl-begin-shared-library,libOpenglSystemCommon)
-$(call emugl-import,libGLESv1_enc lib_renderControl_enc)
+$(call emugl-import,libGLESv1_enc libGLESv2_enc lib_renderControl_enc)
 
 LOCAL_SRC_FILES := \
     HostConnection.cpp \
diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp
index 1745554..e3cdfaa 100644
--- a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp
+++ b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp
@@ -18,6 +18,8 @@
 #include "QemuPipeStream.h"
 #include "ThreadInfo.h"
 #include <cutils/log.h>
+#include "GLEncoder.h"
+#include "GL2Encoder.h"
 
 #define STREAM_BUFFER_SIZE  4*1024*1024
 #define STREAM_PORT_NUM     22468
@@ -28,6 +30,7 @@
 HostConnection::HostConnection() :
     m_stream(NULL),
     m_glEnc(NULL),
+    m_gl2Enc(NULL),
     m_rcEnc(NULL)
 {
 }
@@ -36,6 +39,7 @@
 {
     delete m_stream;
     delete m_glEnc;
+    delete m_gl2Enc;
     delete m_rcEnc;
 }
 
@@ -119,6 +123,16 @@
     return m_glEnc;
 }
 
+GL2Encoder *HostConnection::gl2Encoder()
+{
+    if (!m_gl2Enc) {
+        m_gl2Enc = new GL2Encoder(m_stream);
+        DBG("HostConnection::gl2Encoder new encoder %p, tid %d", m_gl2Enc, gettid());
+        m_gl2Enc->setContextAccessor(s_getGL2Context);
+    }
+    return m_gl2Enc;
+}
+
 renderControl_encoder_context_t *HostConnection::rcEncoder()
 {
     if (!m_rcEnc) {
@@ -135,3 +149,12 @@
     }
     return NULL;
 }
+
+gl2_client_context_t *HostConnection::s_getGL2Context()
+{
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    if (ti->hostConn) {
+        return ti->hostConn->m_gl2Enc;
+    }
+    return NULL;
+}
diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.h b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.h
index 828d8c1..e7a5ac4 100644
--- a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.h
+++ b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.h
@@ -17,9 +17,13 @@
 #define __COMMON_HOST_CONNECTION_H
 
 #include "IOStream.h"
-#include "GLEncoder.h"
 #include "renderControl_enc.h"
 
+class GLEncoder;
+class gl_client_context_t;
+class GL2Encoder;
+class gl2_client_context_t;
+
 class HostConnection
 {
 public:
@@ -27,6 +31,7 @@
     ~HostConnection();
 
     GLEncoder *glEncoder();
+    GL2Encoder *gl2Encoder();
     renderControl_encoder_context_t *rcEncoder();
 
     void flush() {
@@ -37,11 +42,13 @@
 
 private:
     HostConnection();
-    static gl_client_context_t *s_getGLContext();
+    static gl_client_context_t  *s_getGLContext();
+    static gl2_client_context_t *s_getGL2Context();
 
 private:
     IOStream *m_stream;
-    GLEncoder *m_glEnc;
+    GLEncoder   *m_glEnc;
+    GL2Encoder  *m_gl2Enc;
     renderControl_encoder_context_t *m_rcEnc;
 };
 
diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
index 3f92724..b632d84 100644
--- a/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
+++ b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
@@ -117,7 +117,7 @@
     //DBG(">> QemuPipeStream::readFully %d\n", len);
     if (!valid()) return NULL;
     if (!buf) {
-        ERR("QemuPipeStream::readFully failed, buf=NULL");
+        ERR("QemuPipeStream::readFully failed, buf=NULL, len %d", len);
         return NULL;  // do not allow NULL buf in that implementation
     }
     size_t res = len;
diff --git a/tools/emulator/opengl/system/egl/Android.mk b/tools/emulator/opengl/system/egl/Android.mk
index fb9e4d8..fd5ba18 100644
--- a/tools/emulator/opengl/system/egl/Android.mk
+++ b/tools/emulator/opengl/system/egl/Android.mk
@@ -18,15 +18,17 @@
 
 
 LOCAL_PRELINK_MODULE := false
-LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES
+LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES -DWITH_GLES2
 LOCAL_C_INCLUDES +=  \
         $(emulatorOpengl)/host/include/libOpenglRender \
         $(emulatorOpengl)/shared/OpenglCodecCommon \
         $(emulatorOpengl)/system/OpenglSystemCommon \
         $(emulatorOpengl)/system/GLESv1_enc \
+        $(emulatorOpengl)/system/GLESv2_enc \
         $(emulatorOpengl)/system/renderControl_enc \
 		$(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_enc) \
-		$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc)
+		$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc)  \
+		$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv2_enc)
 
 LOCAL_MODULE_TAGS := debug
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
@@ -43,6 +45,7 @@
 	libutils \
 	libdl	\
     libGLESv1_enc \
+    libGLESv2_enc \
     libOpenglSystemCommon \
     lib_renderControl_enc
 
diff --git a/tools/emulator/opengl/system/egl/egl.cpp b/tools/emulator/opengl/system/egl/egl.cpp
index 50fb2c5..5cc7528 100644
--- a/tools/emulator/opengl/system/egl/egl.cpp
+++ b/tools/emulator/opengl/system/egl/egl.cpp
@@ -21,6 +21,11 @@
 #include "gralloc_cb.h"
 #include "GLClientState.h"
 
+#include "GLEncoder.h"
+#ifdef WITH_GLES2
+#include "GL2Encoder.h"
+#endif
+
 #include <private/ui/android_natives_priv.h>
 
 template<typename T>
@@ -1012,7 +1017,12 @@
         context->read = read;
         context->flags |= EGLContext_t::IS_CURRENT;
         //set the client state
-        hostCon->glEncoder()->setClientState(context->getClientState());
+        if (context->version == 2) {
+            hostCon->gl2Encoder()->setClientState(context->getClientState());
+        }
+        else {
+            hostCon->glEncoder()->setClientState(context->getClientState());
+        }
     }
 
     if (tInfo->currentContext)
@@ -1023,14 +1033,17 @@
 
     //Check maybe we need to init the encoder, if it's first eglMakeCurrent
     if (tInfo->currentContext) {
-        if (!hostCon->glEncoder()->isInitialized()) {
-            if (tInfo->currentContext->version == 2) {
+        if (tInfo->currentContext->version == 2) {
+            if (!hostCon->gl2Encoder()->isInitialized()) {
                 s_display.gles2_iface()->init();
+                hostCon->gl2Encoder()->setInitialized();
             }
-            else {
+        }
+        else {
+            if (!hostCon->glEncoder()->isInitialized()) {
                 s_display.gles_iface()->init();
+                hostCon->glEncoder()->setInitialized();
             }
-            hostCon->glEncoder()->setInitialized();
         }
     }