emulatgor opengl: First commit of the host renderer library.

This is a library which includes all the OpenGL renderer functionality,
it is packaged in a library so that both the renderer process and the emulator
program will be able to use that functionality.

NOTES:
   1) gl_proc.h and GLDispatch.{h,cpp} in this commit will be replaced
      with the decoder auto-generated dispatch in a later commit, the
      auto-generated dispatch is currently missing some extension functions
      required for the renderer.
   2) look at host/include/libOpenglRender/render_api.h for the external
      interface defined for this library (to be used by the emulator).

The following is a description of each component:

FrameBuffer - The main object which manages the framebuffer and color buffers.
              This is a singleton which get initialized through its initialize
              static function. It initializes the OpenGL renderer and must be
              called first. This initialization function is not thread safe so
              it must be called before any thread that is calling to this
              library is created.

FBConfig - Includes a static set of configs supported by the renderer which get
           initialized during FrameBuffer initialization phase. Also,
           an instance of this class includes the a description of one frame
           buffer configuration supported by the renderer.

RenderContext - encapsulate a rendering context state.

ColorBuffer - implements a color buffer object as a texture which can be bind
              as render target or source.

WindowSurface - implements the functionality of a native window which can be
                bound to a rendering context and its target ColorBuffer can
                be specified and replaced.

ThreadInfo - holds per-thread information.

EGLDispatch - loads the EGL plugin library, all egl calls are made through
              this dispatch table which get initialized during initialization
              phase.

GLDispatch - loads the GLES plugin library, all GLES calls are made through
             this dispatch table which get initialized during initialization
             phase - This will be replaced by the auto-generated code of the
             decoder ...

RenderThread - implements a thread that reads command tokens from an IOStream
               and decode it.

RenderControl - implements the host side implementation of the renderControl
                API, when a renderControl token is decoded from the stream
                it is dispatched to this implementation.

RenderServer - implements a TCP server which listens to port number and
               launcges a RenderThread for each new connection.

Change-Id: I9f34d17bdfcb715893a13cd30086c767f499df87
diff --git a/tools/emulator/opengl/host/include/libOpenglRender/render_api.h b/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
new file mode 100644
index 0000000..c46f11d
--- /dev/null
+++ b/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
@@ -0,0 +1,71 @@
+/*
+* 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 _OPENGL_RENDERER_RENDER_API_H
+#define _OPENGL_RENDERER_RENDER_API_H
+
+#include "IOStream.h"
+
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#include <windows.h>
+
+typedef HDC     FBNativeDisplayType;
+typedef HWND    FBNativeWindowType;
+
+#elif defined(__linux__)
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+typedef Window   FBNativeWindowType;
+
+#else
+#error "Unsupported platform"
+#endif
+
+
+//
+// initOpenGLRenderer - initialize the OpenGL renderer process.
+//     window is the native window to be used as the framebuffer.
+//     x,y,width,height are the dimensions of the rendering subwindow.
+//     portNum is the tcp port number the renderer is listening to.
+//
+// returns true if renderer has been starter successfully;
+//
+// This function is *NOT* thread safe and should be called first
+// to initialize the renderer.
+//
+bool initOpenGLRenderer(FBNativeWindowType window,
+                        int x, int y, int width, int height,
+                        int portNum);
+
+//
+// stopOpenGLRenderer - stops the OpenGL renderer process.
+//     This functions is *NOT* thread safe and should be called
+//     only if previous initOpenGLRenderer has returned true.
+//
+bool stopOpenGLRenderer();
+
+//
+// createRenderThread - opens a new communication channel to the renderer
+//   process and creates new rendering thread.
+//   returns a pointer to IOStream through which command tokens are being sent
+//   to the render thread for execution. 'p_stream_buffer_size' is the internal
+//   stream buffer size.
+//   The thread is destroyed when deleting the IOStream object.
+//
+IOStream *createRenderThread(int p_stream_buffer_size);
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk b/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk
new file mode 100644
index 0000000..7d60fee
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk
@@ -0,0 +1,65 @@
+LOCAL_PATH := $(call my-dir)
+
+### libOpenglRender #################################################
+include $(CLEAR_VARS)
+
+emulatorOpengl := $(LOCAL_PATH)/../../..
+
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := libOpenglRender
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+	$(HOST_OUT_SHARED_LIBRARIES)/lib_renderControl_dec$(HOST_SHLIB_SUFFIX) \
+	$(HOST_OUT_SHARED_LIBRARIES)/libGLESv1_dec$(HOST_SHLIB_SUFFIX)
+
+LOCAL_SRC_FILES := \
+    render_api.cpp \
+    ColorBuffer.cpp \
+    EGLDispatch.cpp \
+    FBConfig.cpp \
+    FrameBuffer.cpp \
+    GLDispatch.cpp \
+    GL2Dispatch.cpp \
+    RenderContext.cpp \
+    WindowSurface.cpp \
+    RenderControl.cpp \
+    ThreadInfo.cpp \
+    RenderThread.cpp \
+    ReadBuffer.cpp \
+    RenderServer.cpp
+
+LOCAL_C_INCLUDES += \
+    $(emulatorOpengl)/host/include \
+    $(emulatorOpengl)/shared/OpenglCodecCommon \
+    $(emulatorOpengl)/shared/OpenglOsUtils \
+    $(emulatorOpengl)/host/include/libOpenglRender \
+    $(emulatorOpengl)/host/libs/GLESv1_dec \
+    $(emulatorOpengl)/system/GLESv1_enc \
+    $(emulatorOpengl)/system/renderControl_enc \
+	$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_dec, HOST) \
+	$(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_dec, HOST)
+
+LOCAL_STATIC_LIBRARIES := \
+        libOpenglCodecCommon \
+        libOpenglOsUtils \
+        libcutils \
+        libutils \
+        liblog
+
+LOCAL_SHARED_LIBRARIES := \
+        libGLESv1_dec \
+        lib_renderControl_dec
+
+ifeq ($(HOST_OS),windows)
+    LOCAL_LDLIBS := -lws2_32
+endif
+
+ifeq ($(HOST_OS),linux)
+    LOCAL_LDLIBS := -ldl -lpthread -lrt
+endif
+
+# XXX - uncomment for debug
+#LOCAL_CFLAGS := -O0 -g
+
+include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
new file mode 100644
index 0000000..774ad02
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
@@ -0,0 +1,189 @@
+/*
+* 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 "ColorBuffer.h"
+#include "FrameBuffer.h"
+#include "EGLDispatch.h"
+#include "GLDispatch.h"
+#include <stdio.h>
+
+ColorBuffer *ColorBuffer::create(int p_width, int p_height,
+                                 GLenum p_internalFormat)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+
+    if (!fb->bind_locked()) {
+        return NULL;
+    }
+
+    ColorBuffer *cb = new ColorBuffer();
+
+    s_gl.glGenTextures(1, &cb->m_tex);
+    s_gl.glBindTexture(GL_TEXTURE_2D, cb->m_tex);
+    s_gl.glTexImage2D(GL_TEXTURE_2D, 0, p_internalFormat,
+                      p_width, p_height, 0,
+                      GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    cb->m_width = p_width;
+    cb->m_height = p_height;
+
+    if (fb->getCaps().has_eglimage_texture_2d) {
+        cb->m_eglImage = s_egl.eglCreateImageKHR(fb->getDisplay(),
+                                                 fb->getContext(),
+                                                 EGL_GL_TEXTURE_2D_KHR,
+                                                 (EGLClientBuffer)cb->m_tex,
+                                                 NULL);
+    }
+
+    fb->unbind_locked();
+    return cb;
+}
+
+ColorBuffer::ColorBuffer() :
+    m_tex(0),
+    m_eglImage(NULL),
+    m_fbo(0)
+{
+}
+
+ColorBuffer::~ColorBuffer()
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    fb->bind_locked();
+    s_gl.glDeleteTextures(1, &m_tex);
+    if (m_eglImage) {
+        s_egl.eglDestroyImageKHR(fb->getDisplay(), m_eglImage);
+    }
+    if (m_fbo) {
+        s_gl.glDeleteFramebuffersOES(1, &m_fbo);
+    }
+    fb->unbind_locked();
+}
+
+void ColorBuffer::update(GLenum p_format, GLenum p_type, void *pixels)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb->bind_locked()) return;
+    s_gl.glBindTexture(GL_TEXTURE_2D, m_tex);
+    s_gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    s_gl.glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+                         m_width, m_height, p_format, p_type, pixels);
+    fb->unbind_locked();
+}
+
+bool ColorBuffer::blitFromPbuffer(EGLSurface p_pbufSurface)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb->bind_locked()) return false;
+
+    //
+    // bind FBO object which has this colorbuffer as render target
+    //
+    if (!bind_fbo()) {
+        fb->unbind_locked();
+        return false;
+    }
+
+    //
+    // bind the pbuffer to a temporary texture object
+    //
+    GLuint tempTex;
+    s_gl.glGenTextures(1, &tempTex);
+    s_gl.glBindTexture(GL_TEXTURE_2D, tempTex);
+    if (!s_egl.eglBindTexImage(fb->getDisplay(), p_pbufSurface, EGL_BACK_BUFFER)) {
+        printf("eglBindTexImage failed 0x%x\n", s_egl.eglGetError());
+        s_gl.glDeleteTextures(1, &tempTex);
+        fb->unbind_locked();
+        return false;
+    }
+
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    s_gl.glEnable(GL_TEXTURE_2D);
+
+    drawTexQuad();
+
+    //
+    // unbind FBO, release the pbuffer and delete the temp texture object
+    //
+    s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+    s_egl.eglReleaseTexImage(fb->getDisplay(), p_pbufSurface, EGL_BACK_BUFFER);
+    s_gl.glDeleteTextures(1, &tempTex);
+
+    fb->unbind_locked();
+    return true;
+}
+
+bool ColorBuffer::bind_fbo()
+{
+    if (m_fbo) {
+        // fbo already exist - just bind
+        s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_fbo);
+        return true;
+    }
+
+    s_gl.glGenFramebuffersOES(1, &m_fbo);
+    s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_fbo);
+    s_gl.glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
+                                   GL_COLOR_ATTACHMENT0_OES,
+                                   GL_TEXTURE_2D, m_tex, 0);
+    GLenum status = s_gl.glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+    if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
+        s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+        s_gl.glDeleteFramebuffersOES(1, &m_fbo);
+        m_fbo = 0;
+        return false;
+    }
+
+    return true;
+}
+
+bool ColorBuffer::post()
+{
+    s_gl.glBindTexture(GL_TEXTURE_2D, m_tex);
+    s_gl.glEnable(GL_TEXTURE_2D);
+    drawTexQuad();
+
+    return true;
+}
+
+void ColorBuffer::drawTexQuad()
+{
+    GLfloat verts[] = { -1.0f, -1.0f, 0.0f,
+                         -1.0f, +1.0f, 0.0f,
+                         +1.0f, -1.0f, 0.0f,
+                         +1.0f, +1.0f, 0.0f };
+
+    GLfloat tcoords[] = { 0.0f, 0.0f,
+                           0.0f, 1.0f,
+                           1.0f, 0.0f,
+                           1.0f, 1.0f };
+
+    s_gl.glClientActiveTexture(GL_TEXTURE0);
+    s_gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    s_gl.glTexCoordPointer(2, GL_FLOAT, 0, tcoords);
+
+    s_gl.glEnableClientState(GL_VERTEX_ARRAY);
+    s_gl.glVertexPointer(3, GL_FLOAT, 0, verts);
+    s_gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
new file mode 100644
index 0000000..550c6d1
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
@@ -0,0 +1,54 @@
+/*
+* 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 _LIBRENDER_COLORBUFFER_H
+#define _LIBRENDER_COLORBUFFER_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <SmartPtr.h>
+
+class ColorBuffer
+{
+public:
+    static ColorBuffer *create(int p_width, int p_height,
+                               GLenum p_internalFormat);
+    ~ColorBuffer();
+
+    GLuint getGLTextureName() const { return m_tex; }
+    GLuint getWidth() const { return m_width; }
+    GLuint getHeight() const { return m_height; }
+
+    void update(GLenum p_format, GLenum p_type, void *pixels);
+    bool blitFromPbuffer(EGLSurface p_pbufSurface);
+    bool post();
+
+private:
+    ColorBuffer();
+    void drawTexQuad();
+    bool bind_fbo();  // binds a fbo which have this texture as render target
+
+private:
+    GLuint m_tex;
+    EGLImageKHR m_eglImage;
+    GLuint m_width;
+    GLuint m_height;
+    GLuint m_fbo;
+};
+
+typedef SmartPtr<ColorBuffer> ColorBufferPtr;
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
new file mode 100644
index 0000000..635f94a
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
@@ -0,0 +1,79 @@
+/*
+* 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 "EGLDispatch.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "osDynLibrary.h"
+
+EGLDispatch s_egl;
+
+bool init_egl_dispatch()
+{
+    const char *libName = getenv("ANDROID_EGL_LIB");
+    if (!libName) libName = "libEGL.so";
+
+    osUtils::dynLibrary *lib = osUtils::dynLibrary::open(libName);
+    if (!lib) {
+        return NULL;
+    }
+
+    s_egl.eglGetError = (eglGetError_t) lib->findSymbol("eglGetError");
+    s_egl.eglGetDisplay = (eglGetDisplay_t) lib->findSymbol("eglGetDisplay");
+    s_egl.eglInitialize = (eglInitialize_t) lib->findSymbol("eglInitialize");
+    s_egl.eglTerminate = (eglTerminate_t) lib->findSymbol("eglTerminate");
+    s_egl.eglQueryString = (eglQueryString_t) lib->findSymbol("eglQueryString");
+    s_egl.eglGetConfigs = (eglGetConfigs_t) lib->findSymbol("eglGetConfigs");
+    s_egl.eglChooseConfig = (eglChooseConfig_t) lib->findSymbol("eglChooseConfig");
+    s_egl.eglGetConfigAttrib = (eglGetConfigAttrib_t) lib->findSymbol("eglGetConfigAttrib");
+    s_egl.eglCreateWindowSurface = (eglCreateWindowSurface_t) lib->findSymbol("eglCreateWindowSurface");
+    s_egl.eglCreatePbufferSurface = (eglCreatePbufferSurface_t) lib->findSymbol("eglCreatePbufferSurface");
+    s_egl.eglCreatePixmapSurface = (eglCreatePixmapSurface_t) lib->findSymbol("eglCreatePixmapSurface");
+    s_egl.eglDestroySurface = (eglDestroySurface_t) lib->findSymbol("eglDestroySurface");
+    s_egl.eglQuerySurface = (eglQuerySurface_t) lib->findSymbol("eglQuerySurface");
+    s_egl.eglBindAPI = (eglBindAPI_t) lib->findSymbol("eglBindAPI");
+    s_egl.eglQueryAPI = (eglQueryAPI_t) lib->findSymbol("eglQueryAPI");
+    s_egl.eglWaitClient = (eglWaitClient_t) lib->findSymbol("eglWaitClient");
+    s_egl.eglReleaseThread = (eglReleaseThread_t) lib->findSymbol("eglReleaseThread");
+    s_egl.eglCreatePbufferFromClientBuffer = (eglCreatePbufferFromClientBuffer_t) lib->findSymbol("eglCreatePbufferFromClientBuffer");
+    s_egl.eglSurfaceAttrib = (eglSurfaceAttrib_t) lib->findSymbol("eglSurfaceAttrib");
+    s_egl.eglBindTexImage = (eglBindTexImage_t) lib->findSymbol("eglBindTexImage");
+    s_egl.eglReleaseTexImage = (eglReleaseTexImage_t) lib->findSymbol("eglReleaseTexImage");
+    s_egl.eglSwapInterval = (eglSwapInterval_t) lib->findSymbol("eglSwapInterval");
+    s_egl.eglCreateContext = (eglCreateContext_t) lib->findSymbol("eglCreateContext");
+    s_egl.eglDestroyContext = (eglDestroyContext_t) lib->findSymbol("eglDestroyContext");
+    s_egl.eglMakeCurrent = (eglMakeCurrent_t) lib->findSymbol("eglMakeCurrent");
+    s_egl.eglGetCurrentContext = (eglGetCurrentContext_t) lib->findSymbol("eglGetCurrentContext");
+    s_egl.eglGetCurrentSurface = (eglGetCurrentSurface_t) lib->findSymbol("eglGetCurrentSurface");
+    s_egl.eglGetCurrentDisplay = (eglGetCurrentDisplay_t) lib->findSymbol("eglGetCurrentDisplay");
+    s_egl.eglQueryContext = (eglQueryContext_t) lib->findSymbol("eglQueryContext");
+    s_egl.eglWaitGL = (eglWaitGL_t) lib->findSymbol("eglWaitGL");
+    s_egl.eglWaitNative = (eglWaitNative_t) lib->findSymbol("eglWaitNative");
+    s_egl.eglSwapBuffers = (eglSwapBuffers_t) lib->findSymbol("eglSwapBuffers");
+    s_egl.eglCopyBuffers = (eglCopyBuffers_t) lib->findSymbol("eglCopyBuffers");
+    s_egl.eglGetProcAddress = (eglGetProcAddress_t) lib->findSymbol("eglGetProcAddress");
+    s_egl.eglLockSurfaceKHR = (eglLockSurfaceKHR_t) lib->findSymbol("eglLockSurfaceKHR");
+    s_egl.eglUnlockSurfaceKHR = (eglUnlockSurfaceKHR_t) lib->findSymbol("eglUnlockSurfaceKHR");
+    s_egl.eglCreateImageKHR = (eglCreateImageKHR_t) lib->findSymbol("eglCreateImageKHR");
+    s_egl.eglDestroyImageKHR = (eglDestroyImageKHR_t) lib->findSymbol("eglDestroyImageKHR");
+    s_egl.eglCreateSyncKHR = (eglCreateSyncKHR_t) lib->findSymbol("eglCreateSyncKHR");
+    s_egl.eglDestroySyncKHR = (eglDestroySyncKHR_t) lib->findSymbol("eglDestroySyncKHR");
+    s_egl.eglClientWaitSyncKHR = (eglClientWaitSyncKHR_t) lib->findSymbol("eglClientWaitSyncKHR");
+    s_egl.eglSignalSyncKHR = (eglSignalSyncKHR_t) lib->findSymbol("eglSignalSyncKHR");
+    s_egl.eglGetSyncAttribKHR = (eglGetSyncAttribKHR_t) lib->findSymbol("eglGetSyncAttribKHR");
+    s_egl.eglSetSwapRectangleANDROID = (eglSetSwapRectangleANDROID_t) lib->findSymbol("eglSetSwapRectangleANDROID");
+
+    return true;
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.h b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.h
new file mode 100644
index 0000000..f74acba
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.h
@@ -0,0 +1,72 @@
+/*
+* 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 _EGL_DISPATCH_H
+#define _EGL_DISPATCH_H
+
+#include "egl_proc.h"
+
+struct EGLDispatch {
+    eglGetError_t eglGetError;
+    eglGetDisplay_t eglGetDisplay;
+    eglInitialize_t eglInitialize;
+    eglTerminate_t eglTerminate;
+    eglQueryString_t eglQueryString;
+    eglGetConfigs_t eglGetConfigs;
+    eglChooseConfig_t eglChooseConfig;
+    eglGetConfigAttrib_t eglGetConfigAttrib;
+    eglCreateWindowSurface_t eglCreateWindowSurface;
+    eglCreatePbufferSurface_t eglCreatePbufferSurface;
+    eglCreatePixmapSurface_t eglCreatePixmapSurface;
+    eglDestroySurface_t eglDestroySurface;
+    eglQuerySurface_t eglQuerySurface;
+    eglBindAPI_t eglBindAPI;
+    eglQueryAPI_t eglQueryAPI;
+    eglWaitClient_t eglWaitClient;
+    eglReleaseThread_t eglReleaseThread;
+    eglCreatePbufferFromClientBuffer_t eglCreatePbufferFromClientBuffer;
+    eglSurfaceAttrib_t eglSurfaceAttrib;
+    eglBindTexImage_t eglBindTexImage;
+    eglReleaseTexImage_t eglReleaseTexImage;
+    eglSwapInterval_t eglSwapInterval;
+    eglCreateContext_t eglCreateContext;
+    eglDestroyContext_t eglDestroyContext;
+    eglMakeCurrent_t eglMakeCurrent;
+    eglGetCurrentContext_t eglGetCurrentContext;
+    eglGetCurrentSurface_t eglGetCurrentSurface;
+    eglGetCurrentDisplay_t eglGetCurrentDisplay;
+    eglQueryContext_t eglQueryContext;
+    eglWaitGL_t eglWaitGL;
+    eglWaitNative_t eglWaitNative;
+    eglSwapBuffers_t eglSwapBuffers;
+    eglCopyBuffers_t eglCopyBuffers;
+    eglGetProcAddress_t eglGetProcAddress;
+    eglLockSurfaceKHR_t eglLockSurfaceKHR;
+    eglUnlockSurfaceKHR_t eglUnlockSurfaceKHR;
+    eglCreateImageKHR_t eglCreateImageKHR;
+    eglDestroyImageKHR_t eglDestroyImageKHR;
+    eglCreateSyncKHR_t eglCreateSyncKHR;
+    eglDestroySyncKHR_t eglDestroySyncKHR;
+    eglClientWaitSyncKHR_t eglClientWaitSyncKHR;
+    eglSignalSyncKHR_t eglSignalSyncKHR;
+    eglGetSyncAttribKHR_t eglGetSyncAttribKHR;
+    eglSetSwapRectangleANDROID_t eglSetSwapRectangleANDROID;
+};
+
+bool init_egl_dispatch();
+
+extern EGLDispatch s_egl;
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
new file mode 100644
index 0000000..14e84b9
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
@@ -0,0 +1,225 @@
+/*
+* 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 "FBConfig.h"
+#include "FrameBuffer.h"
+#include "EGLDispatch.h"
+#include <stdio.h>
+
+FBConfig **FBConfig::s_fbConfigs = NULL;
+int FBConfig::s_numConfigs = 0;
+
+const GLuint FBConfig::s_configAttribs[] = {
+    EGL_DEPTH_SIZE,     // must be first - see getDepthSize()
+    EGL_STENCIL_SIZE,   // must be second - see getStencilSize()
+    EGL_RENDERABLE_TYPE, // must be third - see getRenderableType()
+    EGL_SURFACE_TYPE,  // must be fourth - see getSurfaceType()
+    EGL_BUFFER_SIZE,
+    EGL_ALPHA_SIZE,
+    EGL_BLUE_SIZE,
+    EGL_GREEN_SIZE,
+    EGL_RED_SIZE,
+    EGL_CONFIG_CAVEAT,
+    EGL_CONFIG_ID,
+    EGL_LEVEL,
+    EGL_MAX_PBUFFER_HEIGHT,
+    EGL_MAX_PBUFFER_PIXELS,
+    EGL_MAX_PBUFFER_WIDTH,
+    EGL_NATIVE_RENDERABLE,
+    EGL_NATIVE_VISUAL_ID,
+    EGL_NATIVE_VISUAL_TYPE,
+    EGL_SAMPLES,
+    EGL_SAMPLE_BUFFERS,
+    EGL_TRANSPARENT_TYPE,
+    EGL_TRANSPARENT_BLUE_VALUE,
+    EGL_TRANSPARENT_GREEN_VALUE,
+    EGL_TRANSPARENT_RED_VALUE,
+    EGL_BIND_TO_TEXTURE_RGB,
+    EGL_BIND_TO_TEXTURE_RGBA,
+    EGL_MIN_SWAP_INTERVAL,
+    EGL_MAX_SWAP_INTERVAL,
+    EGL_LUMINANCE_SIZE,
+    EGL_ALPHA_MASK_SIZE,
+    EGL_COLOR_BUFFER_TYPE,
+    //EGL_MATCH_NATIVE_PIXMAP,
+    EGL_CONFORMANT
+};
+
+const int FBConfig::s_numConfigAttribs = sizeof(FBConfig::s_configAttribs) / sizeof(GLuint);
+
+InitConfigStatus FBConfig::initConfigList(FrameBuffer *fb)
+{
+    InitConfigStatus ret = INIT_CONFIG_FAILED;
+
+    if (!fb) {
+        return ret;
+    }
+
+    const FrameBufferCaps &caps = fb->getCaps();
+    EGLDisplay dpy = fb->getDisplay();
+
+    if (dpy == EGL_NO_DISPLAY) {
+        fprintf(stderr,"Could not get EGL Display\n");
+        return ret;
+    }
+
+    //
+    // Query the set of configs in the EGL backend
+    //
+    EGLint nConfigs;
+    if (!s_egl.eglGetConfigs(dpy, NULL, 0, &nConfigs)) {
+        fprintf(stderr, "Could not get number of available configs\n");
+        return ret;
+    }
+    EGLConfig *configs = new EGLConfig[nConfigs];
+    s_egl.eglGetConfigs(dpy, configs, nConfigs, &nConfigs);
+
+    //
+    // Find number of usable configs which support pbuffer rendering
+    // for each ES and ES2 as well as number of configs supporting
+    // EGL_BIND_TO_TEXTURE_RGBA for each of ES and ES2.
+    //
+    const int GL = 0;
+    const int GL1 = 1;
+    const int GL2 = 2;
+    int numPbuf[3] = {0, 0, 0};
+    int numBindToTexture[3] = {0, 0, 0};
+    for (int i=0; i<nConfigs; i++) {
+        GLint depthSize, stencilSize;
+        GLint renderType, surfaceType;
+        GLint bindToTexture;
+
+        s_egl.eglGetConfigAttrib(dpy, configs[i], EGL_DEPTH_SIZE, &depthSize);
+        s_egl.eglGetConfigAttrib(dpy, configs[i], EGL_STENCIL_SIZE, &stencilSize);
+        s_egl.eglGetConfigAttrib(dpy, configs[i], EGL_RENDERABLE_TYPE, &renderType);
+        s_egl.eglGetConfigAttrib(dpy, configs[i], EGL_SURFACE_TYPE, &surfaceType);
+        if (depthSize > 0 && stencilSize > 0 &&
+            (surfaceType & EGL_PBUFFER_BIT) != 0) {
+
+            numPbuf[GL]++;
+
+            if ((renderType & EGL_OPENGL_ES_BIT) != 0) {
+                numPbuf[GL1]++;
+            }
+
+            if ((renderType & EGL_OPENGL_ES2_BIT) != 0) {
+                numPbuf[GL2]++;
+            }
+
+            s_egl.eglGetConfigAttrib(dpy, configs[i],
+                                     EGL_BIND_TO_TEXTURE_RGBA, &bindToTexture);
+            if (bindToTexture) {
+                numBindToTexture[GL]++;
+                if ((renderType & EGL_OPENGL_ES_BIT) != 0) {
+                    numBindToTexture[GL1]++;
+                }
+
+                if ((renderType & EGL_OPENGL_ES2_BIT) != 0) {
+                    numBindToTexture[GL2]++;
+                }
+            }
+        }
+    }
+
+    bool useOnlyPbuf = false;
+    bool useOnlyBindToTexture = false;
+    int numConfigs = nConfigs;
+    if ( numPbuf[GL1] > 0 &&
+        (!caps.hasGL2 || numPbuf[GL2] > 0)) {
+        useOnlyPbuf = true;
+        numConfigs = numPbuf[GL];
+    }
+    if (useOnlyPbuf &&
+        !(caps.has_eglimage_texture_2d &&
+          caps.has_eglimage_renderbuffer) &&
+        numBindToTexture[GL1] > 0 &&
+        (!caps.hasGL2 || numBindToTexture[GL2] > 0)) {
+        useOnlyBindToTexture = true;
+        numConfigs = numBindToTexture[GL];
+        ret = INIT_CONFIG_HAS_BIND_TO_TEXTURE;
+    }
+    else {
+        ret = INIT_CONFIG_PASSED;
+    }
+
+    int j = 0;
+    s_fbConfigs = new FBConfig*[nConfigs];
+    for (int i=0; i<nConfigs; i++) {
+        if (useOnlyBindToTexture) {
+            EGLint bindToTexture;
+            s_egl.eglGetConfigAttrib(dpy, configs[i],
+                                     EGL_BIND_TO_TEXTURE_RGBA, &bindToTexture);
+            if (!bindToTexture) continue;
+        }
+        else if (useOnlyPbuf) {
+            EGLint surfaceType;
+            s_egl.eglGetConfigAttrib(dpy, configs[i],
+                                     EGL_SURFACE_TYPE, &surfaceType);
+            if (!(surfaceType & EGL_PBUFFER_BIT)) continue;
+        }
+
+        s_fbConfigs[j++] = new FBConfig(dpy, configs[i]);
+    }
+    s_numConfigs = j;
+
+    delete configs;
+    return ret;
+}
+
+const FBConfig *FBConfig::get(int p_config)
+{
+    if (p_config >= 0 && p_config < s_numConfigs) {
+        return s_fbConfigs[p_config];
+    }
+    return NULL;
+}
+
+int FBConfig::getNumConfigs()
+{
+    return s_numConfigs;
+}
+
+void FBConfig::packConfigsInfo(GLuint *buffer)
+{
+    memcpy(buffer, s_configAttribs, s_numConfigAttribs * sizeof(GLuint));
+    for (int i=0; i<s_numConfigs; i++) {
+        memcpy(buffer+(i+1)*s_numConfigAttribs,
+               &s_fbConfigs[i]->m_attribValues,
+               s_numConfigAttribs * sizeof(GLuint));
+    }
+}
+
+FBConfig::FBConfig(EGLDisplay p_eglDpy, EGLConfig p_eglCfg)
+{
+    m_eglConfig = p_eglCfg;
+    m_attribValues = new GLint[s_numConfigAttribs];
+    for (int i=0; i<s_numConfigAttribs; i++) {
+        s_egl.eglGetConfigAttrib(p_eglDpy, p_eglCfg, s_configAttribs[i], &m_attribValues[i]);
+
+        //
+        // All exported configs supports android native window rendering
+        //
+        if (s_configAttribs[i] == EGL_SURFACE_TYPE) {
+            m_attribValues[i] |= EGL_WINDOW_BIT;
+        }
+    }
+}
+
+FBConfig::~FBConfig()
+{
+    if (m_attribValues) {
+        delete m_attribValues;
+    }
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.h b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.h
new file mode 100644
index 0000000..b898b37
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.h
@@ -0,0 +1,60 @@
+/*
+* 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 _LIBRENDER_FBCONFIG_H
+#define _LIBRENDER_FBCONFIG_H
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+class FrameBuffer;
+
+enum InitConfigStatus {
+    INIT_CONFIG_FAILED = 0,
+    INIT_CONFIG_PASSED = 1,
+    INIT_CONFIG_HAS_BIND_TO_TEXTURE = 2
+};
+
+class FBConfig
+{
+public:
+    static InitConfigStatus initConfigList(FrameBuffer *fb);
+    static const FBConfig *get(int p_config);
+    static int getNumConfigs();
+    static int getNumAttribs() { return s_numConfigAttribs; }
+    static void packConfigsInfo(GLuint *buffer);
+    ~FBConfig();
+
+    EGLConfig getEGLConfig() const { return m_eglConfig; }
+    GLuint  getDepthSize() const { return (m_attribValues ? m_attribValues[0] : 0); }
+    GLuint  getStencilSize() const { return (m_attribValues ? m_attribValues[1] : 0); }
+    GLuint  getRenderableType() const { return (m_attribValues ? m_attribValues[2] : 0); }
+    GLuint getSurfaceType() const { return (m_attribValues ? m_attribValues[3] : 0); }
+
+private:
+    FBConfig(EGLDisplay p_eglDpy, EGLConfig p_eglCfg);
+
+private:
+    static FBConfig **s_fbConfigs;
+    static int s_numConfigs;
+    static const int s_numConfigAttribs;
+    static const GLuint s_configAttribs[];
+
+private:
+    EGLConfig m_eglConfig;
+    GLint *m_attribValues;
+};
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
new file mode 100644
index 0000000..a0f32c8
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
@@ -0,0 +1,553 @@
+/*
+* 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 "FrameBuffer.h"
+#include "FBConfig.h"
+#include "EGLDispatch.h"
+#include "GLDispatch.h"
+#include "GL2Dispatch.h"
+#include "ThreadInfo.h"
+#include <stdio.h>
+
+FrameBuffer *FrameBuffer::s_theFrameBuffer = NULL;
+HandleType FrameBuffer::s_nextHandle = 0;
+
+#ifdef WITH_GLES2
+static const char *getGLES2ExtensionString(EGLDisplay p_dpy,
+                                 FBNativeWindowType p_window)
+{
+    EGLConfig config;
+    EGLSurface surface;
+
+    GLint configAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_NONE
+    };
+
+    int n;
+    if (!s_egl.eglChooseConfig(p_dpy, configAttribs,
+                               &config, 1, &n)) {
+        return NULL;
+    }
+
+#if defined(__linux__) || defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__)
+    surface = s_egl.eglCreateWindowSurface(p_dpy, config,
+                                              (EGLNativeWindowType)p_window,
+                                              NULL);
+    if (surface == EGL_NO_SURFACE) {
+        return NULL;
+    }
+#endif
+
+    GLint gl2ContextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE
+    };
+
+    EGLContext ctx = s_egl.eglCreateContext(p_dpy, config,
+                                            EGL_NO_CONTEXT,
+                                            gl2ContextAttribs);
+    if (ctx == EGL_NO_CONTEXT) {
+        s_egl.eglDestroySurface(p_dpy, surface);
+        return NULL;
+    }
+
+    if (!s_egl.eglMakeCurrent(p_dpy, surface, surface, ctx)) {
+        s_egl.eglDestroySurface(p_dpy, surface);
+        s_egl.eglDestroyContext(p_dpy, ctx);
+        return NULL;
+    }
+
+    const char *extString = (const char *)s_gl2.glGetString(GL_EXTENSIONS);
+    if (!extString) {
+        extString = "";
+    }
+
+    s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL);
+    s_egl.eglDestroySurface(p_dpy, surface);
+    s_egl.eglDestroyContext(p_dpy, ctx);
+
+    return extString;
+}
+#endif
+
+bool FrameBuffer::initialize(FBNativeWindowType p_window,
+                             int p_x, int p_y,
+                             int p_width, int p_height)
+{
+    if (s_theFrameBuffer != NULL) {
+        return true;
+    }
+
+    //
+    // Load EGL Plugin
+    //
+    if (!init_egl_dispatch()) {
+        // Failed to load EGL
+        return false;
+    }
+
+    //
+    // Load GLES Plugin
+    //
+    if (!init_gl_dispatch()) {
+        // Failed to load GLES
+        return false;
+    }
+
+    //
+    // allocate space for the FrameBuffer object
+    //
+    FrameBuffer *fb = new FrameBuffer(p_x, p_y, p_width, p_height);
+    if (!fb) {
+        return false;
+    }
+
+#ifdef WITH_GLES2
+    //
+    // Try to load GLES2 Plugin, not mandatory
+    //
+    if (getenv("ANDROID_NO_GLES2")) {
+        fb->m_caps.hasGL2 = false;
+    }
+    else {
+        fb->m_caps.hasGL2 = init_gl2_dispatch();
+    }
+#else
+    fb->m_caps.hasGL2 = false;
+#endif
+
+    //
+    // Initialize backend EGL display
+    //
+    fb->m_eglDisplay = s_egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (fb->m_eglDisplay == EGL_NO_DISPLAY) {
+        delete fb;
+        return false;
+    }
+    s_egl.eglInitialize(fb->m_eglDisplay, &fb->m_caps.eglMajor, &fb->m_caps.eglMinor);
+    s_egl.eglBindAPI(EGL_OPENGL_ES_API);
+
+    fb->m_nativeWindow = p_window;
+
+    //
+    // if GLES2 plugin has loaded - try to make GLES2 context and
+    // get GLES2 extension string
+    //
+    const char *gl2Extensions = NULL;
+#ifdef WITH_GLES2
+    if (fb->m_caps.hasGL2) {
+        gl2Extensions = getGLES2ExtensionString(fb->m_eglDisplay, p_window);
+        if (!gl2Extensions) {
+            // Could not create GLES2 context - drop GL2 capability
+            fb->m_caps.hasGL2 = false;
+        }
+    }
+#endif
+
+    //
+    // Create EGL context and Surface attached to the native window, for
+    // framebuffer post rendering.
+    //
+    GLint configAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+        EGL_NONE
+    };
+
+    EGLConfig eglConfig;
+    int n;
+    if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs,
+                               &eglConfig, 1, &n)) {
+        delete fb;
+        return false;
+    }
+
+#if defined(__linux__) || defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__)
+    fb->m_eglSurface = s_egl.eglCreateWindowSurface(fb->m_eglDisplay, eglConfig,
+                                                  (EGLNativeWindowType)p_window,
+                                                  NULL);
+    if (fb->m_eglSurface == EGL_NO_SURFACE) {
+        delete fb;
+        return false;
+    }
+#endif
+
+    GLint glContextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 1,
+        EGL_NONE
+    };
+
+    fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay, eglConfig,
+                                              EGL_NO_CONTEXT,
+                                              glContextAttribs);
+    if (fb->m_eglContext == EGL_NO_CONTEXT) {
+        printf("Failed to create Context 0x%x\n", s_egl.eglGetError());
+        delete fb;
+        return false;
+    }
+
+    // Make the context current
+    if (!fb->bind_locked()) {
+        delete fb;
+        return false;
+    }
+
+    //
+    // Initilize framebuffer capabilities
+    //
+    const char *glExtensions = (const char *)s_gl.glGetString(GL_EXTENSIONS);
+    bool has_gl_oes_image = false;
+    if (glExtensions) {
+        has_gl_oes_image = strstr(glExtensions, "GL_OES_EGL_image") != NULL;
+    }
+
+    if (fb->m_caps.hasGL2 && has_gl_oes_image) {
+        has_gl_oes_image &= (strstr(gl2Extensions, "GL_OES_EGL_image") != NULL);
+    }
+
+    const char *eglExtensions = s_egl.eglQueryString(fb->m_eglDisplay,
+                                                     EGL_EXTENSIONS);
+
+    if (eglExtensions && has_gl_oes_image) {
+        fb->m_caps.has_eglimage_texture_2d =
+             strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") != NULL;
+        fb->m_caps.has_eglimage_renderbuffer =
+             strstr(eglExtensions, "EGL_KHR_gl_renderbuffer_image") != NULL;
+    }
+    else {
+        fb->m_caps.has_eglimage_texture_2d = false;
+        fb->m_caps.has_eglimage_renderbuffer = false;
+    }
+
+    //
+    // Initialize set of configs
+    //
+    InitConfigStatus configStatus = FBConfig::initConfigList(fb);
+    if (configStatus == INIT_CONFIG_FAILED) {
+        delete fb;
+        return false;
+    }
+
+    //
+    // Check that we have config for each GLES and GLES2
+    //
+    int nConfigs = FBConfig::getNumConfigs();
+    int nGLConfigs = 0;
+    int nGL2Configs = 0;
+    for (int i=0; i<nConfigs; i++) {
+        GLint rtype = FBConfig::get(i)->getRenderableType();
+        if (0 != (rtype & EGL_OPENGL_ES_BIT)) {
+            nGLConfigs++;
+        }
+        if (0 != (rtype & EGL_OPENGL_ES2_BIT)) {
+            nGL2Configs++;
+        }
+    }
+
+    //
+    // Fail initialization if no GLES configs exist
+    //
+    if (nGLConfigs == 0) {
+        delete fb;
+        return false;
+    }
+
+    //
+    // If no GLES2 configs exist - not GLES2 capability
+    //
+    if (nGL2Configs == 0) {
+        fb->m_caps.hasGL2 = false;
+    }
+
+    //
+    // update Pbuffer bind to texture capability based on configs
+    //
+    fb->m_caps.has_BindToTexture =
+        (configStatus == INIT_CONFIG_HAS_BIND_TO_TEXTURE);
+
+
+    //
+    // Initialize some GL state
+    //
+    s_gl.glMatrixMode(GL_PROJECTION);
+    s_gl.glLoadIdentity();
+    s_gl.glOrthof(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
+    s_gl.glMatrixMode(GL_MODELVIEW);
+    s_gl.glLoadIdentity();
+
+    // release the FB context
+    fb->unbind_locked();
+
+    //
+    // Keep the singleton framebuffer pointer
+    //
+    s_theFrameBuffer = fb;
+    return true;
+}
+
+FrameBuffer::FrameBuffer(int p_x, int p_y, int p_width, int p_height) :
+    m_x(p_x),
+    m_y(p_y),
+    m_width(p_width),
+    m_height(p_height),
+    m_eglDisplay(EGL_NO_DISPLAY),
+    m_eglSurface(EGL_NO_SURFACE),
+    m_eglContext(EGL_NO_CONTEXT),
+    m_prevContext(EGL_NO_CONTEXT),
+    m_prevReadSurf(EGL_NO_SURFACE),
+    m_prevDrawSurf(EGL_NO_SURFACE)
+{
+}
+
+FrameBuffer::~FrameBuffer()
+{
+}
+
+HandleType FrameBuffer::genHandle()
+{
+    HandleType id;
+    do {
+        id = ++s_nextHandle;
+    } while( id == 0 ||
+             m_contexts.find(id) != m_contexts.end() ||
+             m_windows.find(id) != m_windows.end() );
+
+    return id;
+}
+
+HandleType FrameBuffer::createColorBuffer(int p_width, int p_height,
+                                          GLenum p_internalFormat)
+{
+    android::Mutex::Autolock mutex(m_lock);
+    HandleType ret = 0;
+
+    ColorBufferPtr cb( ColorBuffer::create(p_width, p_height, p_internalFormat) );
+    if (cb.Ptr() != NULL) {
+        ret = genHandle();
+        m_colorbuffers[ret] = cb;
+    }
+    return ret;
+}
+
+HandleType FrameBuffer::createRenderContext(int p_config, HandleType p_share,
+                                            bool p_isGL2)
+{
+    android::Mutex::Autolock mutex(m_lock);
+    HandleType ret = 0;
+
+    RenderContextPtr share(NULL);
+    if (p_share != 0) {
+        RenderContextMap::iterator s( m_contexts.find(p_share) );
+        if (s == m_contexts.end()) {
+            return 0;
+        }
+        share = (*s).second;
+    }
+
+    RenderContextPtr rctx( RenderContext::create(p_config, share, p_isGL2) );
+    if (rctx.Ptr() != NULL) {
+        ret = genHandle();
+        m_contexts[ret] = rctx;
+    }
+    return ret;
+}
+
+HandleType FrameBuffer::createWindowSurface(int p_config, int p_width, int p_height)
+{
+    android::Mutex::Autolock mutex(m_lock);
+
+    HandleType ret = 0;
+    WindowSurfacePtr win( WindowSurface::create(p_config, p_width, p_height) );
+    if (win.Ptr() != NULL) {
+        ret = genHandle();
+        m_windows[ret] = win;
+    }
+
+    return ret;
+}
+
+void FrameBuffer::DestroyRenderContext(HandleType p_context)
+{
+    android::Mutex::Autolock mutex(m_lock);
+    m_contexts.erase(p_context);
+}
+
+void FrameBuffer::DestroyWindowSurface(HandleType p_surface)
+{
+    android::Mutex::Autolock mutex(m_lock);
+    m_windows.erase(p_surface);
+}
+
+void FrameBuffer::DestroyColorBuffer(HandleType p_colorbuffer)
+{
+    android::Mutex::Autolock mutex(m_lock);
+    m_colorbuffers.erase(p_colorbuffer);
+}
+
+bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface,
+                                              HandleType p_colorbuffer)
+{
+    android::Mutex::Autolock mutex(m_lock);
+
+    WindowSurfaceMap::iterator w( m_windows.find(p_surface) );
+    if (w == m_windows.end()) {
+        // bad surface handle
+        return false;
+    }
+
+    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
+    if (c == m_colorbuffers.end()) {
+        // bad colorbuffer handle
+        return false;
+    }
+
+    (*w).second->setColorBuffer( (*c).second );
+
+    return true;
+}
+
+bool FrameBuffer::bindContext(HandleType p_context,
+                              HandleType p_drawSurface,
+                              HandleType p_readSurface)
+{
+    android::Mutex::Autolock mutex(m_lock);
+
+    WindowSurfacePtr draw(NULL), read(NULL);
+    RenderContextPtr ctx(NULL);
+
+    //
+    // if this is not an unbind operation - make sure all handles are good
+    //
+    if (p_context || p_drawSurface || p_readSurface) {
+        RenderContextMap::iterator r( m_contexts.find(p_context) );
+        if (r == m_contexts.end()) {
+            // bad context handle
+            return false;
+        }
+
+        ctx = (*r).second;
+        WindowSurfaceMap::iterator w( m_windows.find(p_drawSurface) );
+        if (w == m_windows.end()) {
+            // bad surface handle
+            return false;
+        }
+        draw = (*w).second;
+
+        if (p_readSurface != p_drawSurface) {
+            WindowSurfaceMap::iterator w( m_windows.find(p_readSurface) );
+            if (w == m_windows.end()) {
+                // bad surface handle
+                return false;
+            }
+            read = (*w).second;
+        }
+        else {
+            read = draw;
+        }
+    }
+
+    if (!s_egl.eglMakeCurrent(m_eglDisplay,
+                              draw ? draw->getEGLSurface() : EGL_NO_SURFACE,
+                              read ? read->getEGLSurface() : EGL_NO_SURFACE,
+                              ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT)) {
+        // MakeCurrent failed
+        return false;
+    }
+
+    //
+    // Bind the surface(s) to the context
+    //
+    RenderThreadInfo *tinfo = getRenderThreadInfo();
+    if (draw.Ptr() == NULL && read.Ptr() == NULL) {
+        // if this is an unbind operation - make sure the current bound
+        // surfaces get unbound from the context.
+        draw = tinfo->currDrawSurf;
+        read = tinfo->currReadSurf;
+    }
+
+    if (draw.Ptr() != NULL && read.Ptr() != NULL) {
+        if (p_readSurface != p_drawSurface) {
+            draw->bind( ctx, SURFACE_BIND_DRAW );
+            read->bind( ctx, SURFACE_BIND_READ );
+        }
+        else {
+            draw->bind( ctx, SURFACE_BIND_READDRAW );
+        }
+    }
+
+    //
+    // update thread info with current bound context
+    //
+    tinfo->currContext = ctx;
+    tinfo->currDrawSurf = draw;
+    tinfo->currReadSurf = read;
+
+    return true;
+}
+
+//
+// The framebuffer lock should be held when calling this function !
+//
+bool FrameBuffer::bind_locked()
+{
+    EGLContext prevContext = s_egl.eglGetCurrentContext();
+    EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
+    EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
+
+    if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface,
+                              m_eglSurface, m_eglContext)) {
+        return false;
+    }
+
+    m_prevContext = prevContext;
+    m_prevReadSurf = prevReadSurf;
+    m_prevDrawSurf = prevDrawSurf;
+    return true;
+}
+
+bool FrameBuffer::unbind_locked()
+{
+    if (!s_egl.eglMakeCurrent(m_eglDisplay, m_prevDrawSurf,
+                              m_prevReadSurf, m_prevContext)) {
+        return false;
+    }
+
+    m_prevContext = EGL_NO_CONTEXT;
+    m_prevReadSurf = EGL_NO_SURFACE;
+    m_prevDrawSurf = EGL_NO_SURFACE;
+    return true;
+}
+
+bool FrameBuffer::post(HandleType p_colorbuffer)
+{
+    android::Mutex::Autolock mutex(m_lock);
+    bool ret = false;
+
+    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
+    if (c != m_colorbuffers.end()) {
+        if (!bind_locked()) {
+            return false;
+        }
+        ret = (*c).second->post();
+        if (ret) {
+            s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface);
+        }
+        unbind_locked();
+    }
+
+    return ret;
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
new file mode 100644
index 0000000..f1ae0d3
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
@@ -0,0 +1,106 @@
+/*
+* 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 _LIBRENDER_FRAMEBUFFER_H
+#define _LIBRENDER_FRAMEBUFFER_H
+
+#include "libOpenglRender/render_api.h"
+#include "ColorBuffer.h"
+#include "RenderContext.h"
+#include "WindowSurface.h"
+#include <utils/threads.h>
+#include <map>
+#include <EGL/egl.h>
+#include <stdint.h>
+
+#if defined(__linux__) || defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__)
+#else
+#error "Unsupported Platform"
+#endif
+
+typedef uint32_t HandleType;
+typedef std::map<HandleType, RenderContextPtr> RenderContextMap;
+typedef std::map<HandleType, WindowSurfacePtr> WindowSurfaceMap;
+typedef std::map<HandleType, ColorBufferPtr> ColorBufferMap;
+
+struct FrameBufferCaps
+{
+    bool hasGL2;
+    bool has_eglimage_texture_2d;
+    bool has_eglimage_renderbuffer;
+    bool has_BindToTexture;
+    EGLint eglMajor;
+    EGLint eglMinor;
+};
+
+class FrameBuffer
+{
+public:
+    static bool initialize(FBNativeWindowType p_window,
+                           int x, int y,
+                           int width, int height);
+    static FrameBuffer *getFB() { return s_theFrameBuffer; }
+
+    const FrameBufferCaps &getCaps() const { return m_caps; }
+
+    int getWidth() const { return m_width; }
+    int getHeight() const { return m_height; }
+
+    HandleType createRenderContext(int p_config, HandleType p_share, bool p_isGL2 = false);
+    HandleType createWindowSurface(int p_config, int p_width, int p_height);
+    HandleType createColorBuffer(int p_width, int p_height, GLenum p_internalFormat);
+    void DestroyRenderContext(HandleType p_context);
+    void DestroyWindowSurface(HandleType p_surface);
+    void DestroyColorBuffer(HandleType p_colorbuffer);
+
+    bool  bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface);
+    bool  setWindowSurfaceColorBuffer(HandleType p_surface, HandleType p_colorbuffer);
+
+    bool post(HandleType p_colorbuffer);
+
+    EGLDisplay getDisplay() const { return m_eglDisplay; }
+    EGLContext getContext() const { return m_eglContext; }
+
+    bool bind_locked();
+    bool unbind_locked();
+
+private:
+    FrameBuffer(int p_x, int p_y, int p_width, int p_height);
+    ~FrameBuffer();
+    HandleType genHandle();
+
+private:
+    static FrameBuffer *s_theFrameBuffer;
+    static HandleType s_nextHandle;
+    int m_x;
+    int m_y;
+    int m_width;
+    int m_height;
+    android::Mutex m_lock;
+    FBNativeWindowType m_nativeWindow;
+    FrameBufferCaps m_caps;
+    EGLDisplay m_eglDisplay;
+    RenderContextMap m_contexts;
+    WindowSurfaceMap m_windows;
+    ColorBufferMap m_colorbuffers;
+
+    EGLSurface m_eglSurface;
+    EGLContext m_eglContext;
+
+    EGLContext m_prevContext;
+    EGLSurface m_prevReadSurf;
+    EGLSurface m_prevDrawSurf;
+};
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
new file mode 100644
index 0000000..0989d37
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
@@ -0,0 +1,59 @@
+/*
+* 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.
+*/
+#ifdef WITH_GLES2
+#include "GL2Dispatch.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "osDynLibrary.h"
+
+gl2_decoder_context_t s_gl2;
+
+static osUtils::dynLibrary *s_gles2_lib = NULL;
+
+//
+// This function is called only once during initialiation before
+// any thread has been created - hence it should NOT be thread safe.
+//
+bool init_gl2_dispatch()
+{
+    const char *libName = getenv("ANDROID_GLESv2_LIB");
+    if (!libName) libName = "libGLESv2.so";
+
+    //
+    // Load the GLES library
+    //
+    s_gles2_lib = osUtils::dynLibrary::open(libName);
+    if (!s_gles2_lib) return false;
+
+    //
+    // init the GLES dispatch table
+    //
+    return s_gl2.initDispatchByName( gl2_dispatch_get_proc_func, NULL );
+}
+
+//
+// This function is called only during initialiation before
+// any thread has been created - hence it should NOT be thread safe.
+//
+void *gl2_dispatch_get_proc_func(const char *name, void *userData)
+{
+    if (!s_gles2_lib) {
+        return NULL;
+    }
+    return (void *)s_gles2_lib->findSymbol(name);
+}
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h
new file mode 100644
index 0000000..6d1415b
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.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 _GLES2_DISPATCH_H
+#define _GLES2_DISPATCH_H
+
+#ifdef WITH_GLES2
+
+#include "gl2_dec.h"
+
+bool init_gl2_dispatch();
+void *gl2_dispatch_get_proc_func(const char *name, void *userData);
+
+extern gl2_decoder_context_t s_gl;
+
+#endif
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp
new file mode 100644
index 0000000..f438cd9
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp
@@ -0,0 +1,322 @@
+/*
+* 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>
+#include <stdlib.h>
+#include "osDynLibrary.h"
+
+GLDispatch s_gl;
+
+static osUtils::dynLibrary *s_gles_lib = NULL;
+
+//
+// This function is called only once during initialiation before
+// any thread has been created - hence it should NOT be thread safe.
+//
+bool init_gl_dispatch()
+{
+    const char *libName = getenv("ANDROID_GLESv1_LIB");
+    if (!libName) libName = "libGLES_CM.so";
+
+    s_gles_lib = osUtils::dynLibrary::open(libName);
+    if (!s_gles_lib) return false;
+
+    s_gl.glAlphaFunc = (glAlphaFunc_t) s_gles_lib->findSymbol("glAlphaFunc");
+    s_gl.glClearColor = (glClearColor_t) s_gles_lib->findSymbol("glClearColor");
+    s_gl.glClearDepthf = (glClearDepthf_t) s_gles_lib->findSymbol("glClearDepthf");
+    s_gl.glClipPlanef = (glClipPlanef_t) s_gles_lib->findSymbol("glClipPlanef");
+    s_gl.glColor4f = (glColor4f_t) s_gles_lib->findSymbol("glColor4f");
+    s_gl.glDepthRangef = (glDepthRangef_t) s_gles_lib->findSymbol("glDepthRangef");
+    s_gl.glFogf = (glFogf_t) s_gles_lib->findSymbol("glFogf");
+    s_gl.glFogfv = (glFogfv_t) s_gles_lib->findSymbol("glFogfv");
+    s_gl.glFrustumf = (glFrustumf_t) s_gles_lib->findSymbol("glFrustumf");
+    s_gl.glGetClipPlanef = (glGetClipPlanef_t) s_gles_lib->findSymbol("glGetClipPlanef");
+    s_gl.glGetFloatv = (glGetFloatv_t) s_gles_lib->findSymbol("glGetFloatv");
+    s_gl.glGetLightfv = (glGetLightfv_t) s_gles_lib->findSymbol("glGetLightfv");
+    s_gl.glGetMaterialfv = (glGetMaterialfv_t) s_gles_lib->findSymbol("glGetMaterialfv");
+    s_gl.glGetTexEnvfv = (glGetTexEnvfv_t) s_gles_lib->findSymbol("glGetTexEnvfv");
+    s_gl.glGetTexParameterfv = (glGetTexParameterfv_t) s_gles_lib->findSymbol("glGetTexParameterfv");
+    s_gl.glLightModelf = (glLightModelf_t) s_gles_lib->findSymbol("glLightModelf");
+    s_gl.glLightModelfv = (glLightModelfv_t) s_gles_lib->findSymbol("glLightModelfv");
+    s_gl.glLightf = (glLightf_t) s_gles_lib->findSymbol("glLightf");
+    s_gl.glLightfv = (glLightfv_t) s_gles_lib->findSymbol("glLightfv");
+    s_gl.glLineWidth = (glLineWidth_t) s_gles_lib->findSymbol("glLineWidth");
+    s_gl.glLoadMatrixf = (glLoadMatrixf_t) s_gles_lib->findSymbol("glLoadMatrixf");
+    s_gl.glMaterialf = (glMaterialf_t) s_gles_lib->findSymbol("glMaterialf");
+    s_gl.glMaterialfv = (glMaterialfv_t) s_gles_lib->findSymbol("glMaterialfv");
+    s_gl.glMultMatrixf = (glMultMatrixf_t) s_gles_lib->findSymbol("glMultMatrixf");
+    s_gl.glMultiTexCoord4f = (glMultiTexCoord4f_t) s_gles_lib->findSymbol("glMultiTexCoord4f");
+    s_gl.glNormal3f = (glNormal3f_t) s_gles_lib->findSymbol("glNormal3f");
+    s_gl.glOrthof = (glOrthof_t) s_gles_lib->findSymbol("glOrthof");
+    s_gl.glPointParameterf = (glPointParameterf_t) s_gles_lib->findSymbol("glPointParameterf");
+    s_gl.glPointParameterfv = (glPointParameterfv_t) s_gles_lib->findSymbol("glPointParameterfv");
+    s_gl.glPointSize = (glPointSize_t) s_gles_lib->findSymbol("glPointSize");
+    s_gl.glPolygonOffset = (glPolygonOffset_t) s_gles_lib->findSymbol("glPolygonOffset");
+    s_gl.glRotatef = (glRotatef_t) s_gles_lib->findSymbol("glRotatef");
+    s_gl.glScalef = (glScalef_t) s_gles_lib->findSymbol("glScalef");
+    s_gl.glTexEnvf = (glTexEnvf_t) s_gles_lib->findSymbol("glTexEnvf");
+    s_gl.glTexEnvfv = (glTexEnvfv_t) s_gles_lib->findSymbol("glTexEnvfv");
+    s_gl.glTexParameterf = (glTexParameterf_t) s_gles_lib->findSymbol("glTexParameterf");
+    s_gl.glTexParameterfv = (glTexParameterfv_t) s_gles_lib->findSymbol("glTexParameterfv");
+    s_gl.glTranslatef = (glTranslatef_t) s_gles_lib->findSymbol("glTranslatef");
+    s_gl.glActiveTexture = (glActiveTexture_t) s_gles_lib->findSymbol("glActiveTexture");
+    s_gl.glAlphaFuncx = (glAlphaFuncx_t) s_gles_lib->findSymbol("glAlphaFuncx");
+    s_gl.glBindBuffer = (glBindBuffer_t) s_gles_lib->findSymbol("glBindBuffer");
+    s_gl.glBindTexture = (glBindTexture_t) s_gles_lib->findSymbol("glBindTexture");
+    s_gl.glBlendFunc = (glBlendFunc_t) s_gles_lib->findSymbol("glBlendFunc");
+    s_gl.glBufferData = (glBufferData_t) s_gles_lib->findSymbol("glBufferData");
+    s_gl.glBufferSubData = (glBufferSubData_t) s_gles_lib->findSymbol("glBufferSubData");
+    s_gl.glClear = (glClear_t) s_gles_lib->findSymbol("glClear");
+    s_gl.glClearColorx = (glClearColorx_t) s_gles_lib->findSymbol("glClearColorx");
+    s_gl.glClearDepthx = (glClearDepthx_t) s_gles_lib->findSymbol("glClearDepthx");
+    s_gl.glClearStencil = (glClearStencil_t) s_gles_lib->findSymbol("glClearStencil");
+    s_gl.glClientActiveTexture = (glClientActiveTexture_t) s_gles_lib->findSymbol("glClientActiveTexture");
+    s_gl.glClipPlanex = (glClipPlanex_t) s_gles_lib->findSymbol("glClipPlanex");
+    s_gl.glColor4ub = (glColor4ub_t) s_gles_lib->findSymbol("glColor4ub");
+    s_gl.glColor4x = (glColor4x_t) s_gles_lib->findSymbol("glColor4x");
+    s_gl.glColorMask = (glColorMask_t) s_gles_lib->findSymbol("glColorMask");
+    s_gl.glColorPointer = (glColorPointer_t) s_gles_lib->findSymbol("glColorPointer");
+    s_gl.glCompressedTexImage2D = (glCompressedTexImage2D_t) s_gles_lib->findSymbol("glCompressedTexImage2D");
+    s_gl.glCompressedTexSubImage2D = (glCompressedTexSubImage2D_t) s_gles_lib->findSymbol("glCompressedTexSubImage2D");
+    s_gl.glCopyTexImage2D = (glCopyTexImage2D_t) s_gles_lib->findSymbol("glCopyTexImage2D");
+    s_gl.glCopyTexSubImage2D = (glCopyTexSubImage2D_t) s_gles_lib->findSymbol("glCopyTexSubImage2D");
+    s_gl.glCullFace = (glCullFace_t) s_gles_lib->findSymbol("glCullFace");
+    s_gl.glDeleteBuffers = (glDeleteBuffers_t) s_gles_lib->findSymbol("glDeleteBuffers");
+    s_gl.glDeleteTextures = (glDeleteTextures_t) s_gles_lib->findSymbol("glDeleteTextures");
+    s_gl.glDepthFunc = (glDepthFunc_t) s_gles_lib->findSymbol("glDepthFunc");
+    s_gl.glDepthMask = (glDepthMask_t) s_gles_lib->findSymbol("glDepthMask");
+    s_gl.glDepthRangex = (glDepthRangex_t) s_gles_lib->findSymbol("glDepthRangex");
+    s_gl.glDisable = (glDisable_t) s_gles_lib->findSymbol("glDisable");
+    s_gl.glDisableClientState = (glDisableClientState_t) s_gles_lib->findSymbol("glDisableClientState");
+    s_gl.glDrawArrays = (glDrawArrays_t) s_gles_lib->findSymbol("glDrawArrays");
+    s_gl.glDrawElements = (glDrawElements_t) s_gles_lib->findSymbol("glDrawElements");
+    s_gl.glEnable = (glEnable_t) s_gles_lib->findSymbol("glEnable");
+    s_gl.glEnableClientState = (glEnableClientState_t) s_gles_lib->findSymbol("glEnableClientState");
+    s_gl.glFinish = (glFinish_t) s_gles_lib->findSymbol("glFinish");
+    s_gl.glFlush = (glFlush_t) s_gles_lib->findSymbol("glFlush");
+    s_gl.glFogx = (glFogx_t) s_gles_lib->findSymbol("glFogx");
+    s_gl.glFogxv = (glFogxv_t) s_gles_lib->findSymbol("glFogxv");
+    s_gl.glFrontFace = (glFrontFace_t) s_gles_lib->findSymbol("glFrontFace");
+    s_gl.glFrustumx = (glFrustumx_t) s_gles_lib->findSymbol("glFrustumx");
+    s_gl.glGetBooleanv = (glGetBooleanv_t) s_gles_lib->findSymbol("glGetBooleanv");
+    s_gl.glGetBufferParameteriv = (glGetBufferParameteriv_t) s_gles_lib->findSymbol("glGetBufferParameteriv");
+    s_gl.glGetClipPlanex = (glGetClipPlanex_t) s_gles_lib->findSymbol("glGetClipPlanex");
+    s_gl.glGenBuffers = (glGenBuffers_t) s_gles_lib->findSymbol("glGenBuffers");
+    s_gl.glGenTextures = (glGenTextures_t) s_gles_lib->findSymbol("glGenTextures");
+    s_gl.glGetError = (glGetError_t) s_gles_lib->findSymbol("glGetError");
+    s_gl.glGetFixedv = (glGetFixedv_t) s_gles_lib->findSymbol("glGetFixedv");
+    s_gl.glGetIntegerv = (glGetIntegerv_t) s_gles_lib->findSymbol("glGetIntegerv");
+    s_gl.glGetLightxv = (glGetLightxv_t) s_gles_lib->findSymbol("glGetLightxv");
+    s_gl.glGetMaterialxv = (glGetMaterialxv_t) s_gles_lib->findSymbol("glGetMaterialxv");
+    s_gl.glGetPointerv = (glGetPointerv_t) s_gles_lib->findSymbol("glGetPointerv");
+    s_gl.glGetString = (glGetString_t) s_gles_lib->findSymbol("glGetString");
+    s_gl.glGetTexEnviv = (glGetTexEnviv_t) s_gles_lib->findSymbol("glGetTexEnviv");
+    s_gl.glGetTexEnvxv = (glGetTexEnvxv_t) s_gles_lib->findSymbol("glGetTexEnvxv");
+    s_gl.glGetTexParameteriv = (glGetTexParameteriv_t) s_gles_lib->findSymbol("glGetTexParameteriv");
+    s_gl.glGetTexParameterxv = (glGetTexParameterxv_t) s_gles_lib->findSymbol("glGetTexParameterxv");
+    s_gl.glHint = (glHint_t) s_gles_lib->findSymbol("glHint");
+    s_gl.glIsBuffer = (glIsBuffer_t) s_gles_lib->findSymbol("glIsBuffer");
+    s_gl.glIsEnabled = (glIsEnabled_t) s_gles_lib->findSymbol("glIsEnabled");
+    s_gl.glIsTexture = (glIsTexture_t) s_gles_lib->findSymbol("glIsTexture");
+    s_gl.glLightModelx = (glLightModelx_t) s_gles_lib->findSymbol("glLightModelx");
+    s_gl.glLightModelxv = (glLightModelxv_t) s_gles_lib->findSymbol("glLightModelxv");
+    s_gl.glLightx = (glLightx_t) s_gles_lib->findSymbol("glLightx");
+    s_gl.glLightxv = (glLightxv_t) s_gles_lib->findSymbol("glLightxv");
+    s_gl.glLineWidthx = (glLineWidthx_t) s_gles_lib->findSymbol("glLineWidthx");
+    s_gl.glLoadIdentity = (glLoadIdentity_t) s_gles_lib->findSymbol("glLoadIdentity");
+    s_gl.glLoadMatrixx = (glLoadMatrixx_t) s_gles_lib->findSymbol("glLoadMatrixx");
+    s_gl.glLogicOp = (glLogicOp_t) s_gles_lib->findSymbol("glLogicOp");
+    s_gl.glMaterialx = (glMaterialx_t) s_gles_lib->findSymbol("glMaterialx");
+    s_gl.glMaterialxv = (glMaterialxv_t) s_gles_lib->findSymbol("glMaterialxv");
+    s_gl.glMatrixMode = (glMatrixMode_t) s_gles_lib->findSymbol("glMatrixMode");
+    s_gl.glMultMatrixx = (glMultMatrixx_t) s_gles_lib->findSymbol("glMultMatrixx");
+    s_gl.glMultiTexCoord4x = (glMultiTexCoord4x_t) s_gles_lib->findSymbol("glMultiTexCoord4x");
+    s_gl.glNormal3x = (glNormal3x_t) s_gles_lib->findSymbol("glNormal3x");
+    s_gl.glNormalPointer = (glNormalPointer_t) s_gles_lib->findSymbol("glNormalPointer");
+    s_gl.glOrthox = (glOrthox_t) s_gles_lib->findSymbol("glOrthox");
+    s_gl.glPixelStorei = (glPixelStorei_t) s_gles_lib->findSymbol("glPixelStorei");
+    s_gl.glPointParameterx = (glPointParameterx_t) s_gles_lib->findSymbol("glPointParameterx");
+    s_gl.glPointParameterxv = (glPointParameterxv_t) s_gles_lib->findSymbol("glPointParameterxv");
+    s_gl.glPointSizex = (glPointSizex_t) s_gles_lib->findSymbol("glPointSizex");
+    s_gl.glPolygonOffsetx = (glPolygonOffsetx_t) s_gles_lib->findSymbol("glPolygonOffsetx");
+    s_gl.glPopMatrix = (glPopMatrix_t) s_gles_lib->findSymbol("glPopMatrix");
+    s_gl.glPushMatrix = (glPushMatrix_t) s_gles_lib->findSymbol("glPushMatrix");
+    s_gl.glReadPixels = (glReadPixels_t) s_gles_lib->findSymbol("glReadPixels");
+    s_gl.glRotatex = (glRotatex_t) s_gles_lib->findSymbol("glRotatex");
+    s_gl.glSampleCoverage = (glSampleCoverage_t) s_gles_lib->findSymbol("glSampleCoverage");
+    s_gl.glSampleCoveragex = (glSampleCoveragex_t) s_gles_lib->findSymbol("glSampleCoveragex");
+    s_gl.glScalex = (glScalex_t) s_gles_lib->findSymbol("glScalex");
+    s_gl.glScissor = (glScissor_t) s_gles_lib->findSymbol("glScissor");
+    s_gl.glShadeModel = (glShadeModel_t) s_gles_lib->findSymbol("glShadeModel");
+    s_gl.glStencilFunc = (glStencilFunc_t) s_gles_lib->findSymbol("glStencilFunc");
+    s_gl.glStencilMask = (glStencilMask_t) s_gles_lib->findSymbol("glStencilMask");
+    s_gl.glStencilOp = (glStencilOp_t) s_gles_lib->findSymbol("glStencilOp");
+    s_gl.glTexCoordPointer = (glTexCoordPointer_t) s_gles_lib->findSymbol("glTexCoordPointer");
+    s_gl.glTexEnvi = (glTexEnvi_t) s_gles_lib->findSymbol("glTexEnvi");
+    s_gl.glTexEnvx = (glTexEnvx_t) s_gles_lib->findSymbol("glTexEnvx");
+    s_gl.glTexEnviv = (glTexEnviv_t) s_gles_lib->findSymbol("glTexEnviv");
+    s_gl.glTexEnvxv = (glTexEnvxv_t) s_gles_lib->findSymbol("glTexEnvxv");
+    s_gl.glTexImage2D = (glTexImage2D_t) s_gles_lib->findSymbol("glTexImage2D");
+    s_gl.glTexParameteri = (glTexParameteri_t) s_gles_lib->findSymbol("glTexParameteri");
+    s_gl.glTexParameterx = (glTexParameterx_t) s_gles_lib->findSymbol("glTexParameterx");
+    s_gl.glTexParameteriv = (glTexParameteriv_t) s_gles_lib->findSymbol("glTexParameteriv");
+    s_gl.glTexParameterxv = (glTexParameterxv_t) s_gles_lib->findSymbol("glTexParameterxv");
+    s_gl.glTexSubImage2D = (glTexSubImage2D_t) s_gles_lib->findSymbol("glTexSubImage2D");
+    s_gl.glTranslatex = (glTranslatex_t) s_gles_lib->findSymbol("glTranslatex");
+    s_gl.glVertexPointer = (glVertexPointer_t) s_gles_lib->findSymbol("glVertexPointer");
+    s_gl.glViewport = (glViewport_t) s_gles_lib->findSymbol("glViewport");
+    s_gl.glPointSizePointerOES = (glPointSizePointerOES_t) s_gles_lib->findSymbol("glPointSizePointerOES");
+    s_gl.glBlendEquationSeparateOES = (glBlendEquationSeparateOES_t) s_gles_lib->findSymbol("glBlendEquationSeparateOES");
+    s_gl.glBlendFuncSeparateOES = (glBlendFuncSeparateOES_t) s_gles_lib->findSymbol("glBlendFuncSeparateOES");
+    s_gl.glBlendEquationOES = (glBlendEquationOES_t) s_gles_lib->findSymbol("glBlendEquationOES");
+    s_gl.glDrawTexsOES = (glDrawTexsOES_t) s_gles_lib->findSymbol("glDrawTexsOES");
+    s_gl.glDrawTexiOES = (glDrawTexiOES_t) s_gles_lib->findSymbol("glDrawTexiOES");
+    s_gl.glDrawTexxOES = (glDrawTexxOES_t) s_gles_lib->findSymbol("glDrawTexxOES");
+    s_gl.glDrawTexsvOES = (glDrawTexsvOES_t) s_gles_lib->findSymbol("glDrawTexsvOES");
+    s_gl.glDrawTexivOES = (glDrawTexivOES_t) s_gles_lib->findSymbol("glDrawTexivOES");
+    s_gl.glDrawTexxvOES = (glDrawTexxvOES_t) s_gles_lib->findSymbol("glDrawTexxvOES");
+    s_gl.glDrawTexfOES = (glDrawTexfOES_t) s_gles_lib->findSymbol("glDrawTexfOES");
+    s_gl.glDrawTexfvOES = (glDrawTexfvOES_t) s_gles_lib->findSymbol("glDrawTexfvOES");
+    s_gl.glEGLImageTargetTexture2DOES = (glEGLImageTargetTexture2DOES_t) s_gles_lib->findSymbol("glEGLImageTargetTexture2DOES");
+    s_gl.glEGLImageTargetRenderbufferStorageOES = (glEGLImageTargetRenderbufferStorageOES_t) s_gles_lib->findSymbol("glEGLImageTargetRenderbufferStorageOES");
+    s_gl.glAlphaFuncxOES = (glAlphaFuncxOES_t) s_gles_lib->findSymbol("glAlphaFuncxOES");
+    s_gl.glClearColorxOES = (glClearColorxOES_t) s_gles_lib->findSymbol("glClearColorxOES");
+    s_gl.glClearDepthxOES = (glClearDepthxOES_t) s_gles_lib->findSymbol("glClearDepthxOES");
+    s_gl.glClipPlanexOES = (glClipPlanexOES_t) s_gles_lib->findSymbol("glClipPlanexOES");
+    s_gl.glColor4xOES = (glColor4xOES_t) s_gles_lib->findSymbol("glColor4xOES");
+    s_gl.glDepthRangexOES = (glDepthRangexOES_t) s_gles_lib->findSymbol("glDepthRangexOES");
+    s_gl.glFogxOES = (glFogxOES_t) s_gles_lib->findSymbol("glFogxOES");
+    s_gl.glFogxvOES = (glFogxvOES_t) s_gles_lib->findSymbol("glFogxvOES");
+    s_gl.glFrustumxOES = (glFrustumxOES_t) s_gles_lib->findSymbol("glFrustumxOES");
+    s_gl.glGetClipPlanexOES = (glGetClipPlanexOES_t) s_gles_lib->findSymbol("glGetClipPlanexOES");
+    s_gl.glGetFixedvOES = (glGetFixedvOES_t) s_gles_lib->findSymbol("glGetFixedvOES");
+    s_gl.glGetLightxvOES = (glGetLightxvOES_t) s_gles_lib->findSymbol("glGetLightxvOES");
+    s_gl.glGetMaterialxvOES = (glGetMaterialxvOES_t) s_gles_lib->findSymbol("glGetMaterialxvOES");
+    s_gl.glGetTexEnvxvOES = (glGetTexEnvxvOES_t) s_gles_lib->findSymbol("glGetTexEnvxvOES");
+    s_gl.glGetTexParameterxvOES = (glGetTexParameterxvOES_t) s_gles_lib->findSymbol("glGetTexParameterxvOES");
+    s_gl.glLightModelxOES = (glLightModelxOES_t) s_gles_lib->findSymbol("glLightModelxOES");
+    s_gl.glLightModelxvOES = (glLightModelxvOES_t) s_gles_lib->findSymbol("glLightModelxvOES");
+    s_gl.glLightxOES = (glLightxOES_t) s_gles_lib->findSymbol("glLightxOES");
+    s_gl.glLightxvOES = (glLightxvOES_t) s_gles_lib->findSymbol("glLightxvOES");
+    s_gl.glLineWidthxOES = (glLineWidthxOES_t) s_gles_lib->findSymbol("glLineWidthxOES");
+    s_gl.glLoadMatrixxOES = (glLoadMatrixxOES_t) s_gles_lib->findSymbol("glLoadMatrixxOES");
+    s_gl.glMaterialxOES = (glMaterialxOES_t) s_gles_lib->findSymbol("glMaterialxOES");
+    s_gl.glMaterialxvOES = (glMaterialxvOES_t) s_gles_lib->findSymbol("glMaterialxvOES");
+    s_gl.glMultMatrixxOES = (glMultMatrixxOES_t) s_gles_lib->findSymbol("glMultMatrixxOES");
+    s_gl.glMultiTexCoord4xOES = (glMultiTexCoord4xOES_t) s_gles_lib->findSymbol("glMultiTexCoord4xOES");
+    s_gl.glNormal3xOES = (glNormal3xOES_t) s_gles_lib->findSymbol("glNormal3xOES");
+    s_gl.glOrthoxOES = (glOrthoxOES_t) s_gles_lib->findSymbol("glOrthoxOES");
+    s_gl.glPointParameterxOES = (glPointParameterxOES_t) s_gles_lib->findSymbol("glPointParameterxOES");
+    s_gl.glPointParameterxvOES = (glPointParameterxvOES_t) s_gles_lib->findSymbol("glPointParameterxvOES");
+    s_gl.glPointSizexOES = (glPointSizexOES_t) s_gles_lib->findSymbol("glPointSizexOES");
+    s_gl.glPolygonOffsetxOES = (glPolygonOffsetxOES_t) s_gles_lib->findSymbol("glPolygonOffsetxOES");
+    s_gl.glRotatexOES = (glRotatexOES_t) s_gles_lib->findSymbol("glRotatexOES");
+    s_gl.glSampleCoveragexOES = (glSampleCoveragexOES_t) s_gles_lib->findSymbol("glSampleCoveragexOES");
+    s_gl.glScalexOES = (glScalexOES_t) s_gles_lib->findSymbol("glScalexOES");
+    s_gl.glTexEnvxOES = (glTexEnvxOES_t) s_gles_lib->findSymbol("glTexEnvxOES");
+    s_gl.glTexEnvxvOES = (glTexEnvxvOES_t) s_gles_lib->findSymbol("glTexEnvxvOES");
+    s_gl.glTexParameterxOES = (glTexParameterxOES_t) s_gles_lib->findSymbol("glTexParameterxOES");
+    s_gl.glTexParameterxvOES = (glTexParameterxvOES_t) s_gles_lib->findSymbol("glTexParameterxvOES");
+    s_gl.glTranslatexOES = (glTranslatexOES_t) s_gles_lib->findSymbol("glTranslatexOES");
+    s_gl.glIsRenderbufferOES = (glIsRenderbufferOES_t) s_gles_lib->findSymbol("glIsRenderbufferOES");
+    s_gl.glBindRenderbufferOES = (glBindRenderbufferOES_t) s_gles_lib->findSymbol("glBindRenderbufferOES");
+    s_gl.glDeleteRenderbuffersOES = (glDeleteRenderbuffersOES_t) s_gles_lib->findSymbol("glDeleteRenderbuffersOES");
+    s_gl.glGenRenderbuffersOES = (glGenRenderbuffersOES_t) s_gles_lib->findSymbol("glGenRenderbuffersOES");
+    s_gl.glRenderbufferStorageOES = (glRenderbufferStorageOES_t) s_gles_lib->findSymbol("glRenderbufferStorageOES");
+    s_gl.glGetRenderbufferParameterivOES = (glGetRenderbufferParameterivOES_t) s_gles_lib->findSymbol("glGetRenderbufferParameterivOES");
+    s_gl.glIsFramebufferOES = (glIsFramebufferOES_t) s_gles_lib->findSymbol("glIsFramebufferOES");
+    s_gl.glBindFramebufferOES = (glBindFramebufferOES_t) s_gles_lib->findSymbol("glBindFramebufferOES");
+    s_gl.glDeleteFramebuffersOES = (glDeleteFramebuffersOES_t) s_gles_lib->findSymbol("glDeleteFramebuffersOES");
+    s_gl.glGenFramebuffersOES = (glGenFramebuffersOES_t) s_gles_lib->findSymbol("glGenFramebuffersOES");
+    s_gl.glCheckFramebufferStatusOES = (glCheckFramebufferStatusOES_t) s_gles_lib->findSymbol("glCheckFramebufferStatusOES");
+    s_gl.glFramebufferRenderbufferOES = (glFramebufferRenderbufferOES_t) s_gles_lib->findSymbol("glFramebufferRenderbufferOES");
+    s_gl.glFramebufferTexture2DOES = (glFramebufferTexture2DOES_t) s_gles_lib->findSymbol("glFramebufferTexture2DOES");
+    s_gl.glGetFramebufferAttachmentParameterivOES = (glGetFramebufferAttachmentParameterivOES_t) s_gles_lib->findSymbol("glGetFramebufferAttachmentParameterivOES");
+    s_gl.glGenerateMipmapOES = (glGenerateMipmapOES_t) s_gles_lib->findSymbol("glGenerateMipmapOES");
+    s_gl.glMapBufferOES = (glMapBufferOES_t) s_gles_lib->findSymbol("glMapBufferOES");
+    s_gl.glUnmapBufferOES = (glUnmapBufferOES_t) s_gles_lib->findSymbol("glUnmapBufferOES");
+    s_gl.glGetBufferPointervOES = (glGetBufferPointervOES_t) s_gles_lib->findSymbol("glGetBufferPointervOES");
+    s_gl.glCurrentPaletteMatrixOES = (glCurrentPaletteMatrixOES_t) s_gles_lib->findSymbol("glCurrentPaletteMatrixOES");
+    s_gl.glLoadPaletteFromModelViewMatrixOES = (glLoadPaletteFromModelViewMatrixOES_t) s_gles_lib->findSymbol("glLoadPaletteFromModelViewMatrixOES");
+    s_gl.glMatrixIndexPointerOES = (glMatrixIndexPointerOES_t) s_gles_lib->findSymbol("glMatrixIndexPointerOES");
+    s_gl.glWeightPointerOES = (glWeightPointerOES_t) s_gles_lib->findSymbol("glWeightPointerOES");
+    s_gl.glQueryMatrixxOES = (glQueryMatrixxOES_t) s_gles_lib->findSymbol("glQueryMatrixxOES");
+    s_gl.glDepthRangefOES = (glDepthRangefOES_t) s_gles_lib->findSymbol("glDepthRangefOES");
+    s_gl.glFrustumfOES = (glFrustumfOES_t) s_gles_lib->findSymbol("glFrustumfOES");
+    s_gl.glOrthofOES = (glOrthofOES_t) s_gles_lib->findSymbol("glOrthofOES");
+    s_gl.glClipPlanefOES = (glClipPlanefOES_t) s_gles_lib->findSymbol("glClipPlanefOES");
+    s_gl.glGetClipPlanefOES = (glGetClipPlanefOES_t) s_gles_lib->findSymbol("glGetClipPlanefOES");
+    s_gl.glClearDepthfOES = (glClearDepthfOES_t) s_gles_lib->findSymbol("glClearDepthfOES");
+    s_gl.glTexGenfOES = (glTexGenfOES_t) s_gles_lib->findSymbol("glTexGenfOES");
+    s_gl.glTexGenfvOES = (glTexGenfvOES_t) s_gles_lib->findSymbol("glTexGenfvOES");
+    s_gl.glTexGeniOES = (glTexGeniOES_t) s_gles_lib->findSymbol("glTexGeniOES");
+    s_gl.glTexGenivOES = (glTexGenivOES_t) s_gles_lib->findSymbol("glTexGenivOES");
+    s_gl.glTexGenxOES = (glTexGenxOES_t) s_gles_lib->findSymbol("glTexGenxOES");
+    s_gl.glTexGenxvOES = (glTexGenxvOES_t) s_gles_lib->findSymbol("glTexGenxvOES");
+    s_gl.glGetTexGenfvOES = (glGetTexGenfvOES_t) s_gles_lib->findSymbol("glGetTexGenfvOES");
+    s_gl.glGetTexGenivOES = (glGetTexGenivOES_t) s_gles_lib->findSymbol("glGetTexGenivOES");
+    s_gl.glGetTexGenxvOES = (glGetTexGenxvOES_t) s_gles_lib->findSymbol("glGetTexGenxvOES");
+    s_gl.glBindVertexArrayOES = (glBindVertexArrayOES_t) s_gles_lib->findSymbol("glBindVertexArrayOES");
+    s_gl.glDeleteVertexArraysOES = (glDeleteVertexArraysOES_t) s_gles_lib->findSymbol("glDeleteVertexArraysOES");
+    s_gl.glGenVertexArraysOES = (glGenVertexArraysOES_t) s_gles_lib->findSymbol("glGenVertexArraysOES");
+    s_gl.glIsVertexArrayOES = (glIsVertexArrayOES_t) s_gles_lib->findSymbol("glIsVertexArrayOES");
+    s_gl.glDiscardFramebufferEXT = (glDiscardFramebufferEXT_t) s_gles_lib->findSymbol("glDiscardFramebufferEXT");
+    s_gl.glMultiDrawArraysEXT = (glMultiDrawArraysEXT_t) s_gles_lib->findSymbol("glMultiDrawArraysEXT");
+    s_gl.glMultiDrawElementsEXT = (glMultiDrawElementsEXT_t) s_gles_lib->findSymbol("glMultiDrawElementsEXT");
+    s_gl.glClipPlanefIMG = (glClipPlanefIMG_t) s_gles_lib->findSymbol("glClipPlanefIMG");
+    s_gl.glClipPlanexIMG = (glClipPlanexIMG_t) s_gles_lib->findSymbol("glClipPlanexIMG");
+    s_gl.glRenderbufferStorageMultisampleIMG = (glRenderbufferStorageMultisampleIMG_t) s_gles_lib->findSymbol("glRenderbufferStorageMultisampleIMG");
+    s_gl.glFramebufferTexture2DMultisampleIMG = (glFramebufferTexture2DMultisampleIMG_t) s_gles_lib->findSymbol("glFramebufferTexture2DMultisampleIMG");
+    s_gl.glDeleteFencesNV = (glDeleteFencesNV_t) s_gles_lib->findSymbol("glDeleteFencesNV");
+    s_gl.glGenFencesNV = (glGenFencesNV_t) s_gles_lib->findSymbol("glGenFencesNV");
+    s_gl.glIsFenceNV = (glIsFenceNV_t) s_gles_lib->findSymbol("glIsFenceNV");
+    s_gl.glTestFenceNV = (glTestFenceNV_t) s_gles_lib->findSymbol("glTestFenceNV");
+    s_gl.glGetFenceivNV = (glGetFenceivNV_t) s_gles_lib->findSymbol("glGetFenceivNV");
+    s_gl.glFinishFenceNV = (glFinishFenceNV_t) s_gles_lib->findSymbol("glFinishFenceNV");
+    s_gl.glSetFenceNV = (glSetFenceNV_t) s_gles_lib->findSymbol("glSetFenceNV");
+    s_gl.glGetDriverControlsQCOM = (glGetDriverControlsQCOM_t) s_gles_lib->findSymbol("glGetDriverControlsQCOM");
+    s_gl.glGetDriverControlStringQCOM = (glGetDriverControlStringQCOM_t) s_gles_lib->findSymbol("glGetDriverControlStringQCOM");
+    s_gl.glEnableDriverControlQCOM = (glEnableDriverControlQCOM_t) s_gles_lib->findSymbol("glEnableDriverControlQCOM");
+    s_gl.glDisableDriverControlQCOM = (glDisableDriverControlQCOM_t) s_gles_lib->findSymbol("glDisableDriverControlQCOM");
+    s_gl.glExtGetTexturesQCOM = (glExtGetTexturesQCOM_t) s_gles_lib->findSymbol("glExtGetTexturesQCOM");
+    s_gl.glExtGetBuffersQCOM = (glExtGetBuffersQCOM_t) s_gles_lib->findSymbol("glExtGetBuffersQCOM");
+    s_gl.glExtGetRenderbuffersQCOM = (glExtGetRenderbuffersQCOM_t) s_gles_lib->findSymbol("glExtGetRenderbuffersQCOM");
+    s_gl.glExtGetFramebuffersQCOM = (glExtGetFramebuffersQCOM_t) s_gles_lib->findSymbol("glExtGetFramebuffersQCOM");
+    s_gl.glExtGetTexLevelParameterivQCOM = (glExtGetTexLevelParameterivQCOM_t) s_gles_lib->findSymbol("glExtGetTexLevelParameterivQCOM");
+    s_gl.glExtTexObjectStateOverrideiQCOM = (glExtTexObjectStateOverrideiQCOM_t) s_gles_lib->findSymbol("glExtTexObjectStateOverrideiQCOM");
+    s_gl.glExtGetTexSubImageQCOM = (glExtGetTexSubImageQCOM_t) s_gles_lib->findSymbol("glExtGetTexSubImageQCOM");
+    s_gl.glExtGetBufferPointervQCOM = (glExtGetBufferPointervQCOM_t) s_gles_lib->findSymbol("glExtGetBufferPointervQCOM");
+    s_gl.glExtGetShadersQCOM = (glExtGetShadersQCOM_t) s_gles_lib->findSymbol("glExtGetShadersQCOM");
+    s_gl.glExtGetProgramsQCOM = (glExtGetProgramsQCOM_t) s_gles_lib->findSymbol("glExtGetProgramsQCOM");
+    s_gl.glExtIsProgramBinaryQCOM = (glExtIsProgramBinaryQCOM_t) s_gles_lib->findSymbol("glExtIsProgramBinaryQCOM");
+    s_gl.glExtGetProgramBinarySourceQCOM = (glExtGetProgramBinarySourceQCOM_t) s_gles_lib->findSymbol("glExtGetProgramBinarySourceQCOM");
+    s_gl.glStartTilingQCOM = (glStartTilingQCOM_t) s_gles_lib->findSymbol("glStartTilingQCOM");
+    s_gl.glEndTilingQCOM = (glEndTilingQCOM_t) s_gles_lib->findSymbol("glEndTilingQCOM");
+
+    return true;
+}
+
+//
+// This function is called only during initialiation before
+// any thread has been created - hence it should NOT be thread safe.
+//
+void *gl_dispatch_get_proc_func(const char *name, void *userData)
+{
+    if (!s_gles_lib) {
+        return NULL;
+    }
+    return (void *)s_gles_lib->findSymbol(name);
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/GLDispatch.h b/tools/emulator/opengl/host/libs/libOpenglRender/GLDispatch.h
new file mode 100644
index 0000000..5fe98f1
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/GLDispatch.h
@@ -0,0 +1,300 @@
+/*
+* 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_DISPATCH_H
+#define _GLES_DISPATCH_H
+
+#include "gl_proc.h"
+
+
+struct GLDispatch {
+    glAlphaFunc_t glAlphaFunc;
+    glClearColor_t glClearColor;
+    glClearDepthf_t glClearDepthf;
+    glClipPlanef_t glClipPlanef;
+    glColor4f_t glColor4f;
+    glDepthRangef_t glDepthRangef;
+    glFogf_t glFogf;
+    glFogfv_t glFogfv;
+    glFrustumf_t glFrustumf;
+    glGetClipPlanef_t glGetClipPlanef;
+    glGetFloatv_t glGetFloatv;
+    glGetLightfv_t glGetLightfv;
+    glGetMaterialfv_t glGetMaterialfv;
+    glGetTexEnvfv_t glGetTexEnvfv;
+    glGetTexParameterfv_t glGetTexParameterfv;
+    glLightModelf_t glLightModelf;
+    glLightModelfv_t glLightModelfv;
+    glLightf_t glLightf;
+    glLightfv_t glLightfv;
+    glLineWidth_t glLineWidth;
+    glLoadMatrixf_t glLoadMatrixf;
+    glMaterialf_t glMaterialf;
+    glMaterialfv_t glMaterialfv;
+    glMultMatrixf_t glMultMatrixf;
+    glMultiTexCoord4f_t glMultiTexCoord4f;
+    glNormal3f_t glNormal3f;
+    glOrthof_t glOrthof;
+    glPointParameterf_t glPointParameterf;
+    glPointParameterfv_t glPointParameterfv;
+    glPointSize_t glPointSize;
+    glPolygonOffset_t glPolygonOffset;
+    glRotatef_t glRotatef;
+    glScalef_t glScalef;
+    glTexEnvf_t glTexEnvf;
+    glTexEnvfv_t glTexEnvfv;
+    glTexParameterf_t glTexParameterf;
+    glTexParameterfv_t glTexParameterfv;
+    glTranslatef_t glTranslatef;
+    glActiveTexture_t glActiveTexture;
+    glAlphaFuncx_t glAlphaFuncx;
+    glBindBuffer_t glBindBuffer;
+    glBindTexture_t glBindTexture;
+    glBlendFunc_t glBlendFunc;
+    glBufferData_t glBufferData;
+    glBufferSubData_t glBufferSubData;
+    glClear_t glClear;
+    glClearColorx_t glClearColorx;
+    glClearDepthx_t glClearDepthx;
+    glClearStencil_t glClearStencil;
+    glClientActiveTexture_t glClientActiveTexture;
+    glClipPlanex_t glClipPlanex;
+    glColor4ub_t glColor4ub;
+    glColor4x_t glColor4x;
+    glColorMask_t glColorMask;
+    glColorPointer_t glColorPointer;
+    glCompressedTexImage2D_t glCompressedTexImage2D;
+    glCompressedTexSubImage2D_t glCompressedTexSubImage2D;
+    glCopyTexImage2D_t glCopyTexImage2D;
+    glCopyTexSubImage2D_t glCopyTexSubImage2D;
+    glCullFace_t glCullFace;
+    glDeleteBuffers_t glDeleteBuffers;
+    glDeleteTextures_t glDeleteTextures;
+    glDepthFunc_t glDepthFunc;
+    glDepthMask_t glDepthMask;
+    glDepthRangex_t glDepthRangex;
+    glDisable_t glDisable;
+    glDisableClientState_t glDisableClientState;
+    glDrawArrays_t glDrawArrays;
+    glDrawElements_t glDrawElements;
+    glEnable_t glEnable;
+    glEnableClientState_t glEnableClientState;
+    glFinish_t glFinish;
+    glFlush_t glFlush;
+    glFogx_t glFogx;
+    glFogxv_t glFogxv;
+    glFrontFace_t glFrontFace;
+    glFrustumx_t glFrustumx;
+    glGetBooleanv_t glGetBooleanv;
+    glGetBufferParameteriv_t glGetBufferParameteriv;
+    glGetClipPlanex_t glGetClipPlanex;
+    glGenBuffers_t glGenBuffers;
+    glGenTextures_t glGenTextures;
+    glGetError_t glGetError;
+    glGetFixedv_t glGetFixedv;
+    glGetIntegerv_t glGetIntegerv;
+    glGetLightxv_t glGetLightxv;
+    glGetMaterialxv_t glGetMaterialxv;
+    glGetPointerv_t glGetPointerv;
+    glGetString_t glGetString;
+    glGetTexEnviv_t glGetTexEnviv;
+    glGetTexEnvxv_t glGetTexEnvxv;
+    glGetTexParameteriv_t glGetTexParameteriv;
+    glGetTexParameterxv_t glGetTexParameterxv;
+    glHint_t glHint;
+    glIsBuffer_t glIsBuffer;
+    glIsEnabled_t glIsEnabled;
+    glIsTexture_t glIsTexture;
+    glLightModelx_t glLightModelx;
+    glLightModelxv_t glLightModelxv;
+    glLightx_t glLightx;
+    glLightxv_t glLightxv;
+    glLineWidthx_t glLineWidthx;
+    glLoadIdentity_t glLoadIdentity;
+    glLoadMatrixx_t glLoadMatrixx;
+    glLogicOp_t glLogicOp;
+    glMaterialx_t glMaterialx;
+    glMaterialxv_t glMaterialxv;
+    glMatrixMode_t glMatrixMode;
+    glMultMatrixx_t glMultMatrixx;
+    glMultiTexCoord4x_t glMultiTexCoord4x;
+    glNormal3x_t glNormal3x;
+    glNormalPointer_t glNormalPointer;
+    glOrthox_t glOrthox;
+    glPixelStorei_t glPixelStorei;
+    glPointParameterx_t glPointParameterx;
+    glPointParameterxv_t glPointParameterxv;
+    glPointSizex_t glPointSizex;
+    glPolygonOffsetx_t glPolygonOffsetx;
+    glPopMatrix_t glPopMatrix;
+    glPushMatrix_t glPushMatrix;
+    glReadPixels_t glReadPixels;
+    glRotatex_t glRotatex;
+    glSampleCoverage_t glSampleCoverage;
+    glSampleCoveragex_t glSampleCoveragex;
+    glScalex_t glScalex;
+    glScissor_t glScissor;
+    glShadeModel_t glShadeModel;
+    glStencilFunc_t glStencilFunc;
+    glStencilMask_t glStencilMask;
+    glStencilOp_t glStencilOp;
+    glTexCoordPointer_t glTexCoordPointer;
+    glTexEnvi_t glTexEnvi;
+    glTexEnvx_t glTexEnvx;
+    glTexEnviv_t glTexEnviv;
+    glTexEnvxv_t glTexEnvxv;
+    glTexImage2D_t glTexImage2D;
+    glTexParameteri_t glTexParameteri;
+    glTexParameterx_t glTexParameterx;
+    glTexParameteriv_t glTexParameteriv;
+    glTexParameterxv_t glTexParameterxv;
+    glTexSubImage2D_t glTexSubImage2D;
+    glTranslatex_t glTranslatex;
+    glVertexPointer_t glVertexPointer;
+    glViewport_t glViewport;
+    glPointSizePointerOES_t glPointSizePointerOES;
+    glBlendEquationSeparateOES_t glBlendEquationSeparateOES;
+    glBlendFuncSeparateOES_t glBlendFuncSeparateOES;
+    glBlendEquationOES_t glBlendEquationOES;
+    glDrawTexsOES_t glDrawTexsOES;
+    glDrawTexiOES_t glDrawTexiOES;
+    glDrawTexxOES_t glDrawTexxOES;
+    glDrawTexsvOES_t glDrawTexsvOES;
+    glDrawTexivOES_t glDrawTexivOES;
+    glDrawTexxvOES_t glDrawTexxvOES;
+    glDrawTexfOES_t glDrawTexfOES;
+    glDrawTexfvOES_t glDrawTexfvOES;
+    glEGLImageTargetTexture2DOES_t glEGLImageTargetTexture2DOES;
+    glEGLImageTargetRenderbufferStorageOES_t glEGLImageTargetRenderbufferStorageOES;
+    glAlphaFuncxOES_t glAlphaFuncxOES;
+    glClearColorxOES_t glClearColorxOES;
+    glClearDepthxOES_t glClearDepthxOES;
+    glClipPlanexOES_t glClipPlanexOES;
+    glColor4xOES_t glColor4xOES;
+    glDepthRangexOES_t glDepthRangexOES;
+    glFogxOES_t glFogxOES;
+    glFogxvOES_t glFogxvOES;
+    glFrustumxOES_t glFrustumxOES;
+    glGetClipPlanexOES_t glGetClipPlanexOES;
+    glGetFixedvOES_t glGetFixedvOES;
+    glGetLightxvOES_t glGetLightxvOES;
+    glGetMaterialxvOES_t glGetMaterialxvOES;
+    glGetTexEnvxvOES_t glGetTexEnvxvOES;
+    glGetTexParameterxvOES_t glGetTexParameterxvOES;
+    glLightModelxOES_t glLightModelxOES;
+    glLightModelxvOES_t glLightModelxvOES;
+    glLightxOES_t glLightxOES;
+    glLightxvOES_t glLightxvOES;
+    glLineWidthxOES_t glLineWidthxOES;
+    glLoadMatrixxOES_t glLoadMatrixxOES;
+    glMaterialxOES_t glMaterialxOES;
+    glMaterialxvOES_t glMaterialxvOES;
+    glMultMatrixxOES_t glMultMatrixxOES;
+    glMultiTexCoord4xOES_t glMultiTexCoord4xOES;
+    glNormal3xOES_t glNormal3xOES;
+    glOrthoxOES_t glOrthoxOES;
+    glPointParameterxOES_t glPointParameterxOES;
+    glPointParameterxvOES_t glPointParameterxvOES;
+    glPointSizexOES_t glPointSizexOES;
+    glPolygonOffsetxOES_t glPolygonOffsetxOES;
+    glRotatexOES_t glRotatexOES;
+    glSampleCoveragexOES_t glSampleCoveragexOES;
+    glScalexOES_t glScalexOES;
+    glTexEnvxOES_t glTexEnvxOES;
+    glTexEnvxvOES_t glTexEnvxvOES;
+    glTexParameterxOES_t glTexParameterxOES;
+    glTexParameterxvOES_t glTexParameterxvOES;
+    glTranslatexOES_t glTranslatexOES;
+    glIsRenderbufferOES_t glIsRenderbufferOES;
+    glBindRenderbufferOES_t glBindRenderbufferOES;
+    glDeleteRenderbuffersOES_t glDeleteRenderbuffersOES;
+    glGenRenderbuffersOES_t glGenRenderbuffersOES;
+    glRenderbufferStorageOES_t glRenderbufferStorageOES;
+    glGetRenderbufferParameterivOES_t glGetRenderbufferParameterivOES;
+    glIsFramebufferOES_t glIsFramebufferOES;
+    glBindFramebufferOES_t glBindFramebufferOES;
+    glDeleteFramebuffersOES_t glDeleteFramebuffersOES;
+    glGenFramebuffersOES_t glGenFramebuffersOES;
+    glCheckFramebufferStatusOES_t glCheckFramebufferStatusOES;
+    glFramebufferRenderbufferOES_t glFramebufferRenderbufferOES;
+    glFramebufferTexture2DOES_t glFramebufferTexture2DOES;
+    glGetFramebufferAttachmentParameterivOES_t glGetFramebufferAttachmentParameterivOES;
+    glGenerateMipmapOES_t glGenerateMipmapOES;
+    glMapBufferOES_t glMapBufferOES;
+    glUnmapBufferOES_t glUnmapBufferOES;
+    glGetBufferPointervOES_t glGetBufferPointervOES;
+    glCurrentPaletteMatrixOES_t glCurrentPaletteMatrixOES;
+    glLoadPaletteFromModelViewMatrixOES_t glLoadPaletteFromModelViewMatrixOES;
+    glMatrixIndexPointerOES_t glMatrixIndexPointerOES;
+    glWeightPointerOES_t glWeightPointerOES;
+    glQueryMatrixxOES_t glQueryMatrixxOES;
+    glDepthRangefOES_t glDepthRangefOES;
+    glFrustumfOES_t glFrustumfOES;
+    glOrthofOES_t glOrthofOES;
+    glClipPlanefOES_t glClipPlanefOES;
+    glGetClipPlanefOES_t glGetClipPlanefOES;
+    glClearDepthfOES_t glClearDepthfOES;
+    glTexGenfOES_t glTexGenfOES;
+    glTexGenfvOES_t glTexGenfvOES;
+    glTexGeniOES_t glTexGeniOES;
+    glTexGenivOES_t glTexGenivOES;
+    glTexGenxOES_t glTexGenxOES;
+    glTexGenxvOES_t glTexGenxvOES;
+    glGetTexGenfvOES_t glGetTexGenfvOES;
+    glGetTexGenivOES_t glGetTexGenivOES;
+    glGetTexGenxvOES_t glGetTexGenxvOES;
+    glBindVertexArrayOES_t glBindVertexArrayOES;
+    glDeleteVertexArraysOES_t glDeleteVertexArraysOES;
+    glGenVertexArraysOES_t glGenVertexArraysOES;
+    glIsVertexArrayOES_t glIsVertexArrayOES;
+    glDiscardFramebufferEXT_t glDiscardFramebufferEXT;
+    glMultiDrawArraysEXT_t glMultiDrawArraysEXT;
+    glMultiDrawElementsEXT_t glMultiDrawElementsEXT;
+    glClipPlanefIMG_t glClipPlanefIMG;
+    glClipPlanexIMG_t glClipPlanexIMG;
+    glRenderbufferStorageMultisampleIMG_t glRenderbufferStorageMultisampleIMG;
+    glFramebufferTexture2DMultisampleIMG_t glFramebufferTexture2DMultisampleIMG;
+    glDeleteFencesNV_t glDeleteFencesNV;
+    glGenFencesNV_t glGenFencesNV;
+    glIsFenceNV_t glIsFenceNV;
+    glTestFenceNV_t glTestFenceNV;
+    glGetFenceivNV_t glGetFenceivNV;
+    glFinishFenceNV_t glFinishFenceNV;
+    glSetFenceNV_t glSetFenceNV;
+    glGetDriverControlsQCOM_t glGetDriverControlsQCOM;
+    glGetDriverControlStringQCOM_t glGetDriverControlStringQCOM;
+    glEnableDriverControlQCOM_t glEnableDriverControlQCOM;
+    glDisableDriverControlQCOM_t glDisableDriverControlQCOM;
+    glExtGetTexturesQCOM_t glExtGetTexturesQCOM;
+    glExtGetBuffersQCOM_t glExtGetBuffersQCOM;
+    glExtGetRenderbuffersQCOM_t glExtGetRenderbuffersQCOM;
+    glExtGetFramebuffersQCOM_t glExtGetFramebuffersQCOM;
+    glExtGetTexLevelParameterivQCOM_t glExtGetTexLevelParameterivQCOM;
+    glExtTexObjectStateOverrideiQCOM_t glExtTexObjectStateOverrideiQCOM;
+    glExtGetTexSubImageQCOM_t glExtGetTexSubImageQCOM;
+    glExtGetBufferPointervQCOM_t glExtGetBufferPointervQCOM;
+    glExtGetShadersQCOM_t glExtGetShadersQCOM;
+    glExtGetProgramsQCOM_t glExtGetProgramsQCOM;
+    glExtIsProgramBinaryQCOM_t glExtIsProgramBinaryQCOM;
+    glExtGetProgramBinarySourceQCOM_t glExtGetProgramBinarySourceQCOM;
+    glStartTilingQCOM_t glStartTilingQCOM;
+    glEndTilingQCOM_t glEndTilingQCOM;
+};
+
+bool init_gl_dispatch();
+void *gl_dispatch_get_proc_func(const char *name, void *userData);
+
+extern GLDispatch s_gl;
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.cpp
new file mode 100644
index 0000000..a08d601
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.cpp
@@ -0,0 +1,54 @@
+/*
+* 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 "ReadBuffer.h"
+#include <string.h>
+#include <assert.h>
+
+ReadBuffer::ReadBuffer(IOStream *stream, size_t bufsize)
+{
+    m_size = bufsize;
+    m_stream = stream;
+    m_buf = new unsigned char[m_size];
+    m_validData = 0;
+    m_readPtr = m_buf;
+}
+
+ReadBuffer::~ReadBuffer()
+{
+    delete m_buf;
+}
+
+int ReadBuffer::getData()
+{
+    if (m_validData > 0) {
+        memcpy(m_buf, m_readPtr, m_validData);
+    }
+    m_readPtr = m_buf;
+    // get fresh data into the buffer;
+    size_t len = m_size - m_validData;
+    if (NULL != m_stream->read(m_buf + m_validData, &len)) {
+        m_validData += len;
+        return len;
+    }
+    return -1;
+}
+
+void ReadBuffer::consume(size_t amount)
+{
+    assert(amount <= m_validData);
+    m_validData -= amount;
+    m_readPtr += amount;
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.h
new file mode 100644
index 0000000..f2dfbce
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.h
@@ -0,0 +1,36 @@
+/*
+* 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 _READ_BUFFER_H
+#define _READ_BUFFER_H
+
+#include "IOStream.h"
+
+class ReadBuffer {
+public:
+    ReadBuffer(IOStream *stream, size_t bufSize);
+    ~ReadBuffer();
+    int getData(); // get fresh data from the stream
+    unsigned char *buf() { return m_readPtr; } // return the next read location
+    size_t validData() { return m_validData; } // return the amount of valid data in readptr
+    void consume(size_t amount); // notify that 'amount' data has been consumed;
+private:
+    unsigned char *m_buf;
+    unsigned char *m_readPtr;
+    size_t m_size;
+    size_t m_validData;
+    IOStream *m_stream;
+};
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.cpp
new file mode 100644
index 0000000..f5cbd67
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.cpp
@@ -0,0 +1,76 @@
+/*
+* 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 "RenderContext.h"
+#include "FBConfig.h"
+#include "FrameBuffer.h"
+#include "EGLDispatch.h"
+#include "GLDispatch.h"
+
+RenderContext *RenderContext::create(int p_config,
+                                     RenderContextPtr p_shareContext,
+                                     bool p_isGL2)
+{
+    const FBConfig *fbconf = FBConfig::get(p_config);
+    if (!fbconf) {
+        return NULL;
+    }
+
+    RenderContext *c = new RenderContext();
+    if (!c) {
+        return NULL;
+    }
+
+    EGLContext share = EGL_NO_CONTEXT;
+    if (p_shareContext.Ptr() != NULL) {
+        share = p_shareContext->getEGLContext();
+    }
+
+    GLint glContextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 1,
+        EGL_NONE
+    };
+
+    if (p_isGL2) {
+        glContextAttribs[1] = 2;
+        c->m_isGL2 = true;
+    }
+
+    c->m_ctx = s_egl.eglCreateContext(FrameBuffer::getFB()->getDisplay(),
+                                      fbconf->getEGLConfig(), share,
+                                      glContextAttribs);
+
+    if (c->m_ctx == EGL_NO_CONTEXT) {
+        delete c;
+        return NULL;
+    }
+
+    c->m_config = p_config;
+    return c;
+}
+
+RenderContext::RenderContext() :
+    m_ctx(EGL_NO_CONTEXT),
+    m_config(0),
+    m_isGL2(false)
+{
+}
+
+RenderContext::~RenderContext()
+{
+    if (m_ctx != EGL_NO_CONTEXT) {
+        s_egl.eglDestroyContext(FrameBuffer::getFB()->getDisplay(), m_ctx);
+    }
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h
new file mode 100644
index 0000000..3962ada
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h
@@ -0,0 +1,45 @@
+/*
+* 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 _LIBRENDER_RENDERCONTEXT_H
+#define _LIBRENDER_RENDERCONTEXT_H
+
+#include "SmartPtr.h"
+#include <EGL/egl.h>
+
+class RenderContext;
+typedef SmartPtr<RenderContext> RenderContextPtr;
+
+class RenderContext
+{
+public:
+    static RenderContext *create(int p_config, RenderContextPtr p_shareContext,
+                                 bool p_isGL2 = false);
+    ~RenderContext();
+    int getConfig() const { return m_config; }
+
+    EGLContext getEGLContext() const { return m_ctx; }
+    bool isGL2() const { return m_isGL2; }
+
+private:
+    RenderContext();
+
+private:
+    EGLContext m_ctx;
+    int        m_config;
+    bool       m_isGL2;
+};
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
new file mode 100644
index 0000000..504d792
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
@@ -0,0 +1,270 @@
+/*
+* 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 "renderControl_dec.h"
+#include "FrameBuffer.h"
+#include "FBConfig.h"
+#include "EGLDispatch.h"
+
+static const GLint rendererVersion = 1;
+
+static GLint rcGetRendererVersion()
+{
+    return rendererVersion;
+}
+
+static EGLint rcGetEGLVersion(EGLint* major, EGLint* minor)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return EGL_FALSE;
+    }
+    *major = (EGLint)fb->getCaps().eglMajor;
+    *minor = (EGLint)fb->getCaps().eglMinor;
+
+    return EGL_TRUE;
+}
+
+static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return 0;
+    }
+
+    const char *str = s_egl.eglQueryString(fb->getDisplay(), name);
+    if (!str) {
+        return 0;
+    }
+
+    int len = strlen(str) + 1;
+    if (!buffer || len > bufferSize) {
+        return -len;
+    }
+
+    strcpy((char *)buffer, str);
+    return len;
+}
+
+static EGLint rcGetNumConfigs(uint32_t* numAttribs)
+{
+    if (numAttribs) {
+        *numAttribs = FBConfig::getNumAttribs();
+    }
+    return FBConfig::getNumConfigs();
+}
+
+static EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer)
+{
+    int configSize = FBConfig::getNumAttribs();
+    int nConfigs = FBConfig::getNumConfigs();
+    uint32_t neededSize = (nConfigs + 1) * configSize * sizeof(GLuint);
+    if (!buffer || bufSize < neededSize) {
+        return -neededSize;
+    }
+    FBConfig::packConfigsInfo(buffer);
+    return nConfigs;
+}
+
+static EGLint rcGetFBParam(EGLint param)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return 0;
+    }
+
+    EGLint ret = 0;
+
+    switch(param) {
+        case FB_WIDTH:
+            ret = fb->getWidth();
+            break;
+        case FB_HEIGHT:
+            ret = fb->getHeight();
+            break;
+        case FB_XDPI:
+            ret = 72; // XXX: should be implemented
+            break;
+        case FB_YDPI:
+            ret = 72; // XXX: should be implemented
+            break;
+        case FB_FPS:
+            ret = 60;
+            break;
+        case FB_MIN_SWAP_INTERVAL:
+            ret = 1; // XXX: should be implemented
+            break;
+        case FB_MAX_SWAP_INTERVAL:
+            ret = 1; // XXX: should be implemented
+            break;
+        default:
+            break;
+    }
+
+    return ret;
+}
+
+static uint32_t rcCreateContext(uint32_t config,
+                                uint32_t share, uint32_t glVersion)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return 0;
+    }
+
+    HandleType ret = fb->createRenderContext(config, share, glVersion == 2);
+    return ret;
+}
+
+static void rcDestroyContext(uint32_t context)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return;
+    }
+
+    fb->DestroyRenderContext(context);
+}
+
+static uint32_t rcCreateWindowSurface(uint32_t config,
+                                      uint32_t width, uint32_t height)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return 0;
+    }
+
+    return fb->createWindowSurface(config, width, height);
+}
+
+static void rcDestroyWindowSurface(uint32_t windowSurface)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return;
+    }
+
+    fb->DestroyWindowSurface( windowSurface );
+}
+
+static uint32_t rcCreateColorBuffer(uint32_t width,
+                                    uint32_t height, GLenum internalFormat)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return 0;
+    }
+
+    return fb->createColorBuffer(width, height, internalFormat);
+}
+
+static void rcDestroyColorBuffer(uint32_t colorbuffer)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return;
+    }
+    fb->DestroyColorBuffer( colorbuffer );
+}
+
+static void rcSetWindowColorBuffer(uint32_t windowSurface,
+                                   uint32_t colorBuffer)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return;
+    }
+    fb->setWindowSurfaceColorBuffer(windowSurface, colorBuffer);
+}
+
+static EGLint rcMakeCurrent(uint32_t context,
+                            uint32_t drawSurf, uint32_t readSurf)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return EGL_FALSE;
+    }
+
+    bool ret = fb->bindContext(context, drawSurf, readSurf);
+
+    return (ret ? EGL_TRUE : EGL_FALSE);
+}
+
+static void rcFBPost(uint32_t colorBuffer)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return;
+    }
+
+    fb->post(colorBuffer);
+}
+
+static void rcFBSetSwapInterval(EGLint interval)
+{
+   // XXX: TBD - should be implemented
+}
+
+static void rcBindTexture(uint32_t colorBuffer)
+{
+   // XXX: TBD - should be implemented
+}
+
+static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer,
+                                      EGLint postCount, int forRead)
+{
+   // XXX: TBD - should be implemented
+   return 0;
+}
+
+static void rcReadColorBuffer(uint32_t colorBuffer,
+                              GLint x, GLint y,
+                              GLint width, GLint height,
+                              GLenum format, GLenum type, void* pixels)
+{
+   // XXX: TBD - should be implemented
+}
+
+static void rcUpdateColorBuffer(uint32_t colorBuffer,
+                                GLint x, GLint y,
+                                GLint width, GLint height,
+                                GLenum format, GLenum type, void* pixels)
+{
+   // XXX: TBD - should be implemented
+}
+
+void initRenderControlContext(renderControl_decoder_context_t *dec)
+{
+    dec->set_rcGetRendererVersion(rcGetRendererVersion);
+    dec->set_rcGetEGLVersion(rcGetEGLVersion);
+    dec->set_rcQueryEGLString(rcQueryEGLString);
+    dec->set_rcGetNumConfigs(rcGetNumConfigs);
+    dec->set_rcGetConfigs(rcGetConfigs);
+    dec->set_rcGetFBParam(rcGetFBParam);
+    dec->set_rcCreateContext(rcCreateContext);
+    dec->set_rcDestroyContext(rcDestroyContext);
+    dec->set_rcCreateWindowSurface(rcCreateWindowSurface);
+    dec->set_rcDestroyWindowSurface(rcDestroyWindowSurface);
+    dec->set_rcCreateColorBuffer(rcCreateColorBuffer);
+    dec->set_rcDestroyColorBuffer(rcDestroyColorBuffer);
+    dec->set_rcSetWindowColorBuffer(rcSetWindowColorBuffer);
+    dec->set_rcMakeCurrent(rcMakeCurrent);
+    dec->set_rcFBPost(rcFBPost);
+    dec->set_rcFBSetSwapInterval(rcFBSetSwapInterval);
+    dec->set_rcBindTexture(rcBindTexture);
+    dec->set_rcColorBufferCacheFlush(rcColorBufferCacheFlush);
+    dec->set_rcReadColorBuffer(rcReadColorBuffer);
+    dec->set_rcUpdateColorBuffer(rcUpdateColorBuffer);
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.h
new file mode 100644
index 0000000..233e809
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.h
@@ -0,0 +1,21 @@
+/*
+* 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 _RENDER_CONTROL_H
+#define _RENDER_CONTROL_H
+
+void initRenderControlContext(renderControl_decoder_context_t *dec);
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
new file mode 100644
index 0000000..95dbc3c
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
@@ -0,0 +1,71 @@
+/*
+* 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 "RenderServer.h"
+#include "TcpStream.h"
+#include "RenderThread.h"
+
+RenderServer::RenderServer() :
+    m_listenSock(NULL),
+    m_exit(false)
+{
+}
+
+RenderServer *RenderServer::create(int port)
+{
+    RenderServer *server = new RenderServer();
+    if (!server) {
+        return NULL;
+    }
+
+    server->m_listenSock = new TcpStream();
+    if (server->m_listenSock->listen(port) < 0) {
+        delete server;
+        return NULL;
+    }
+
+    return server;
+}
+
+int RenderServer::Main()
+{
+    while(!m_exit) {
+        TcpStream *stream = m_listenSock->accept();
+        if (!stream) {
+            fprintf(stderr,"Error accepting connection, aborting\n");
+            break;
+        }
+
+        // check if we have been requested to exit while waiting on accept
+        if (m_exit) {
+            break;
+        }
+
+        RenderThread *rt = RenderThread::create(stream);
+        if (!rt) {
+            fprintf(stderr,"Failed to create RenderThread\n");
+            delete stream;
+        }
+
+        if (!rt->start()) {
+            fprintf(stderr,"Failed to start RenderThread\n");
+            delete stream;
+        }
+
+        printf("Started new RenderThread\n");
+    }
+
+    return 0;
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
new file mode 100644
index 0000000..04b8588
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
@@ -0,0 +1,38 @@
+/*
+* 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 _LIB_OPENGL_RENDER_RENDER_SERVER_H
+#define _LIB_OPENGL_RENDER_RENDER_SERVER_H
+
+#include "TcpStream.h"
+#include "osThread.h"
+
+class RenderServer : public osUtils::Thread
+{
+public:
+    static RenderServer *create(int port);
+    virtual int Main();
+
+    void flagNeedExit() { m_exit = true; }
+
+private:
+    RenderServer();
+
+private:
+    TcpStream *m_listenSock;
+    bool m_exit;
+};
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
new file mode 100644
index 0000000..8dd60d5
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
@@ -0,0 +1,103 @@
+/*
+* 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 "RenderThread.h"
+#include "RenderControl.h"
+#include "ReadBuffer.h"
+#include "TimeUtils.h"
+#include "GLDispatch.h"
+
+#define STREAM_BUFFER_SIZE 4*1024*1024
+
+RenderThread::RenderThread() :
+    osUtils::Thread(),
+    m_stream(NULL)
+{
+}
+
+RenderThread *RenderThread::create(IOStream *p_stream)
+{
+    RenderThread *rt = new RenderThread();
+    if (!rt) {
+        return NULL;
+    }
+
+    rt->m_stream = p_stream;
+
+    return rt;
+}
+
+int RenderThread::Main()
+{
+    //
+    // initialize decoders
+    //
+    m_glDec.initGL( gl_dispatch_get_proc_func, NULL );
+    initRenderControlContext( &m_rcDec );
+
+    ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE);
+
+    int stats_totalBytes = 0;
+    long long stats_t0 = GetCurrentTimeMS();
+
+    while (1) {
+
+        int stat = readBuf.getData();
+        if (stat <= 0) {
+            fprintf(stderr, "client shutdown\n");
+            break;
+        }
+
+        //
+        // log received bandwidth statistics
+        //
+        stats_totalBytes += readBuf.validData();
+        long long dt = GetCurrentTimeMS() - stats_t0;
+        if (dt > 1000) {
+            float dts = (float)dt / 1000.0f;
+            printf("Used Bandwidth %5.3f MB/s\n", ((float)stats_totalBytes / dts) / (1024.0f*1024.0f));
+            stats_totalBytes = 0;
+            stats_t0 = GetCurrentTimeMS();
+        }
+
+        bool progress;
+        do {
+            progress = false;
+
+            //
+            // try to process some of the command buffer using the GLES decoder
+            //
+            size_t last = m_glDec.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
+            //
+            last = m_rcDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+            if (last > 0) {
+                readBuf.consume(last);
+                progress = true;
+            }
+
+        } while( progress );
+
+    }
+
+    return 0;
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
new file mode 100644
index 0000000..2ca5755
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
@@ -0,0 +1,39 @@
+/*
+* 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 _LIB_OPENGL_RENDER_RENDER_THREAD_H
+#define _LIB_OPENGL_RENDER_RENDER_THREAD_H
+
+#include "IOStream.h"
+#include "GLDecoder.h"
+#include "renderControl_dec.h"
+#include "osThread.h"
+
+class RenderThread : public osUtils::Thread
+{
+public:
+    static RenderThread *create(IOStream *p_stream);
+
+private:
+    RenderThread();
+    virtual int Main();
+
+private:
+    IOStream *m_stream;
+    GLDecoder   m_glDec;
+    renderControl_decoder_context_t m_rcDec;
+};
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp
new file mode 100644
index 0000000..2f2a962
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.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 "ThreadInfo.h"
+
+#ifdef __linux__
+
+static __thread RenderThreadInfo *tinfo = NULL;
+
+RenderThreadInfo *getRenderThreadInfo()
+{
+    if (!tinfo) {
+        tinfo = new RenderThreadInfo();
+    }
+    return tinfo;
+}
+
+#else
+
+#include <cutils/threads.h>
+static thread_store_t s_tls = THREAD_STORE_INITIALIZER;
+
+static void tlsDestruct(void *ptr)
+{
+    if (ptr) {
+        RenderThreadInfo *ti = (RenderThreadInfo *)ptr;
+        delete ti;
+    }
+}
+
+RenderThreadInfo *getRenderThreadInfo()
+{
+    RenderThreadInfo *ti = (RenderThreadInfo *)thread_store_get(&s_tls);
+    if (!ti) {
+        ti = new RenderThreadInfo();
+        thread_store_set(&s_tls, ti, tlsDestruct);
+    }
+    return ti;
+}
+#endif
+
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
new file mode 100644
index 0000000..82d2980
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
@@ -0,0 +1,31 @@
+/*
+* 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 _LIB_OPENGL_RENDER_THREAD_INFO_H
+#define _LIB_OPENGL_RENDER_THREAD_INFO_H
+
+#include "RenderContext.h"
+#include "WindowSurface.h"
+
+struct RenderThreadInfo
+{
+    RenderContextPtr currContext;
+    WindowSurfacePtr currDrawSurf;
+    WindowSurfacePtr currReadSurf;
+};
+
+RenderThreadInfo *getRenderThreadInfo();
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
new file mode 100644
index 0000000..e8d7180
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
@@ -0,0 +1,225 @@
+/*
+* 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 "WindowSurface.h"
+#include "FBConfig.h"
+#include "FrameBuffer.h"
+#include <GLES/glext.h>
+#include "EGLDispatch.h"
+#include "GLDispatch.h"
+#include "GL2Dispatch.h"
+#include <stdio.h>
+#include <string.h>
+
+WindowSurface::WindowSurface() :
+    m_fbObj(0),
+    m_depthRB(0),
+    m_stencilRB(0),
+    m_eglSurface(NULL),
+    m_attachedColorBuffer(NULL),
+    m_readContext(NULL),
+    m_drawContext(NULL),
+    m_width(0),
+    m_height(0),
+    m_useEGLImage(false),
+    m_useBindToTexture(false)
+{
+}
+
+WindowSurface::~WindowSurface()
+{
+    s_egl.eglDestroySurface(FrameBuffer::getFB()->getDisplay(), m_eglSurface);
+}
+
+WindowSurface *WindowSurface::create(int p_config, int p_width, int p_height)
+{
+    const FBConfig *fbconf = FBConfig::get(p_config);
+    if (!fbconf) {
+        return NULL;
+    }
+
+    // allocate space for the WindowSurface object
+    WindowSurface *win = new WindowSurface();
+    if (!win) {
+        return NULL;
+    }
+
+    FrameBuffer *fb = FrameBuffer::getFB();
+    const FrameBufferCaps &caps = fb->getCaps();
+
+    //
+    // We can use eglimage and prevent copies if:
+    //     GL_KHR_gl_texture_2D_image is present.
+    //     and either there is no need for depth or stencil buffer
+    //     or GL_KHR_gl_renderbuffer_image present.
+    //
+    win->m_useEGLImage =
+         (caps.has_eglimage_texture_2d &&
+          (caps.has_eglimage_renderbuffer ||
+           (fbconf->getDepthSize() + fbconf->getStencilSize() == 0)) );
+
+    if (win->m_useEGLImage) {
+    }
+    else if (0 != (fbconf->getSurfaceType() & EGL_PBUFFER_BIT)) {
+
+        //
+        // Use Pbuffer for the rendering surface, if possible
+        // set it such that it will be able to be bound to a texture
+        // later to prevent readback.
+        //
+        EGLint pbufAttribs[12];
+        pbufAttribs[0] = EGL_WIDTH;
+        pbufAttribs[1] = p_width;
+        pbufAttribs[2] = EGL_HEIGHT;
+        pbufAttribs[3] = p_height;
+
+        if (caps.has_BindToTexture) {
+            pbufAttribs[4] = EGL_TEXTURE_FORMAT;
+            pbufAttribs[5] = EGL_TEXTURE_RGBA;
+            pbufAttribs[6] = EGL_TEXTURE_TARGET;
+            pbufAttribs[7] = EGL_TEXTURE_2D;
+            pbufAttribs[8] = EGL_NONE;
+            win->m_useBindToTexture = true;
+        }
+        else {
+            pbufAttribs[4] = EGL_NONE;
+        }
+
+        win->m_eglSurface = s_egl.eglCreatePbufferSurface(fb->getDisplay(),
+                                                    fbconf->getEGLConfig(),
+                                                    pbufAttribs);
+        if (win->m_eglSurface == EGL_NO_SURFACE) {
+            delete win;
+            return NULL;
+        }
+    }
+    else {
+        // no EGLImage support and not Pbuffer support - fail
+        delete win;
+        return NULL;
+    }
+
+    win->m_width = p_width;
+    win->m_height = p_height;
+
+    return win;
+}
+
+//
+// setColorBuffer - this function is called when a new color buffer needs to
+//    be attached to the surface. The function should make sure that the
+//    previous attached color buffer is updated, if copy or blit should be done
+//    in order to update it - it is being done here.
+//
+void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer)
+{
+    if (m_attachedColorBuffer.Ptr() != NULL) {
+
+        if (!m_useEGLImage) {
+            bool copied = false;
+            if (m_useBindToTexture) {
+                copied = m_attachedColorBuffer->blitFromPbuffer(m_eglSurface);
+            }
+
+            if (!copied) {
+                copyToColorBuffer();
+            }
+        }
+        else {
+        }
+    }
+
+    m_attachedColorBuffer = p_colorBuffer;
+}
+
+//
+// This function is called after the context and eglSurface is already
+// bound in the current thread (eglMakeCurrent has been called).
+// This function should take actions required on the other surface objects
+// when being bind/unbound
+//
+void WindowSurface::bind(RenderContextPtr p_ctx, SurfaceBindType p_bindType)
+{
+    if (p_bindType == SURFACE_BIND_READ) {
+        m_readContext = p_ctx;
+    }
+    else if (p_bindType == SURFACE_BIND_DRAW) {
+        m_drawContext = p_ctx;
+    }
+    else if (p_bindType == SURFACE_BIND_READDRAW) {
+        m_readContext = p_ctx;
+        m_drawContext = p_ctx;
+    }
+    else {
+        return;  // bad param
+    }
+
+    if (m_useEGLImage) {
+        // XXX: should be implemented
+    }
+}
+
+void WindowSurface::copyToColorBuffer()
+{
+    if (!m_width && !m_height) return;
+
+    if (m_attachedColorBuffer->getWidth() != m_width ||
+        m_attachedColorBuffer->getHeight() != m_height) {
+        // XXX: should never happen - how this needs to be handled?
+        return;
+    }
+
+    void *data = m_xferBuffer.alloc(m_width * m_height * 4);
+    if (!data) {
+        fprintf(stderr,"WARNING: Failed to copy buffer data - OutOfMemory\n");
+        return;
+    }
+
+    //
+    // Make the surface current
+    //
+    EGLContext prevContext = s_egl.eglGetCurrentContext();
+    EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
+    EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!s_egl.eglMakeCurrent(fb->getDisplay(), m_eglSurface,
+                              m_eglSurface, m_drawContext->getEGLContext())) {
+        return;
+    }
+
+    if (m_drawContext->isGL2()) {
+#ifdef WITH_GLES2
+        s_gl2.glPixelStorei(GL_PACK_ALIGNMENT, 1);
+        s_gl2.glReadPixels(0, 0, m_width, m_height,
+                          GL_RGBA, GL_UNSIGNED_BYTE, data);
+#else
+        return; // should never happen, context cannot be GL2 in this case.
+#endif
+    }
+    else {
+        s_gl.glPixelStorei(GL_PACK_ALIGNMENT, 1);
+        s_gl.glReadPixels(0, 0, m_width, m_height,
+                          GL_RGBA, GL_UNSIGNED_BYTE, data);
+    }
+
+    // update the attached color buffer with the readback pixels
+    m_attachedColorBuffer->update(GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+    // restore current context/surface
+    s_egl.eglMakeCurrent(fb->getDisplay(), prevDrawSurf,
+                         prevReadSurf, prevContext);
+
+    free(data);
+}
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h
new file mode 100644
index 0000000..3a01a35
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h
@@ -0,0 +1,64 @@
+/*
+* 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 _LIBRENDER_WINDOWSURFACE_H
+#define _LIBRENDER_WINDOWSURFACE_H
+
+#include "ColorBuffer.h"
+#include "RenderContext.h"
+#include "SmartPtr.h"
+#include "FixedBuffer.h"
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+enum SurfaceBindType {
+    SURFACE_BIND_READ,
+    SURFACE_BIND_DRAW,
+    SURFACE_BIND_READDRAW
+};
+
+class WindowSurface
+{
+public:
+    static WindowSurface *create(int p_config, int p_width, int p_height);
+    ~WindowSurface();
+    EGLSurface getEGLSurface() const { return m_eglSurface; }
+
+    void setColorBuffer(ColorBufferPtr p_colorBuffer);
+    void bind(RenderContextPtr p_ctx, SurfaceBindType p_bindType);
+
+private:
+    WindowSurface();
+
+    void copyToColorBuffer();  // copy pbuffer content with readback+download
+
+private:
+    GLuint m_fbObj;   // GLES Framebuffer object (when EGLimage is used)
+    GLuint m_depthRB;
+    GLuint m_stencilRB;
+    EGLSurface m_eglSurface;
+    ColorBufferPtr m_attachedColorBuffer;
+    RenderContextPtr m_readContext;
+    RenderContextPtr m_drawContext;
+    GLuint m_width;
+    GLuint m_height;
+    bool m_useEGLImage;
+    bool m_useBindToTexture;
+    FixedBuffer m_xferBuffer;
+};
+
+typedef SmartPtr<WindowSurface> WindowSurfacePtr;
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/egl_proc.h b/tools/emulator/opengl/host/libs/libOpenglRender/egl_proc.h
new file mode 100644
index 0000000..140c030
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/egl_proc.h
@@ -0,0 +1,68 @@
+/*
+* 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 _EGL_PROC_H
+#define _EGL_PROC_H
+
+#include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+
+typedef EGLint (* eglGetError_t) ();
+typedef EGLDisplay (* eglGetDisplay_t) (EGLNativeDisplayType);
+typedef EGLBoolean (* eglInitialize_t) (EGLDisplay, EGLint*, EGLint*);
+typedef EGLBoolean (* eglTerminate_t) (EGLDisplay);
+typedef char* (* eglQueryString_t) (EGLDisplay, EGLint);
+typedef EGLBoolean (* eglGetConfigs_t) (EGLDisplay, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglChooseConfig_t) (EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglGetConfigAttrib_t) (EGLDisplay, EGLConfig, EGLint, EGLint*);
+typedef EGLSurface (* eglCreateWindowSurface_t) (EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint*);
+typedef EGLSurface (* eglCreatePbufferSurface_t) (EGLDisplay, EGLConfig, const EGLint*);
+typedef EGLSurface (* eglCreatePixmapSurface_t) (EGLDisplay, EGLConfig, EGLNativePixmapType, const EGLint*);
+typedef EGLBoolean (* eglDestroySurface_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglQuerySurface_t) (EGLDisplay, EGLSurface, EGLint, EGLint*);
+typedef EGLBoolean (* eglBindAPI_t) (EGLenum);
+typedef EGLenum (* eglQueryAPI_t) ();
+typedef EGLBoolean (* eglWaitClient_t) ();
+typedef EGLBoolean (* eglReleaseThread_t) ();
+typedef EGLSurface (* eglCreatePbufferFromClientBuffer_t) (EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint*);
+typedef EGLBoolean (* eglSurfaceAttrib_t) (EGLDisplay, EGLSurface, EGLint, EGLint);
+typedef EGLBoolean (* eglBindTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglReleaseTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglSwapInterval_t) (EGLDisplay, EGLint);
+typedef EGLContext (* eglCreateContext_t) (EGLDisplay, EGLConfig, EGLContext, const EGLint*);
+typedef EGLBoolean (* eglDestroyContext_t) (EGLDisplay, EGLContext);
+typedef EGLBoolean (* eglMakeCurrent_t) (EGLDisplay, EGLSurface, EGLSurface, EGLContext);
+typedef EGLContext (* eglGetCurrentContext_t) ();
+typedef EGLSurface (* eglGetCurrentSurface_t) (EGLint);
+typedef EGLDisplay (* eglGetCurrentDisplay_t) ();
+typedef EGLBoolean (* eglQueryContext_t) (EGLDisplay, EGLContext, EGLint, EGLint*);
+typedef EGLBoolean (* eglWaitGL_t) ();
+typedef EGLBoolean (* eglWaitNative_t) (EGLint);
+typedef EGLBoolean (* eglSwapBuffers_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglCopyBuffers_t) (EGLDisplay, EGLSurface, EGLNativePixmapType);
+typedef __eglMustCastToProperFunctionPointerType (* eglGetProcAddress_t) (const char*);
+typedef EGLBoolean (* eglLockSurfaceKHR_t) (EGLDisplay, EGLSurface, const EGLint*);
+typedef EGLBoolean (* eglUnlockSurfaceKHR_t) (EGLDisplay, EGLSurface);
+typedef EGLImageKHR (* eglCreateImageKHR_t) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
+typedef EGLBoolean (* eglDestroyImageKHR_t) (EGLDisplay, EGLImageKHR image);
+typedef EGLSyncKHR (* eglCreateSyncKHR_t) (EGLDisplay, EGLenum, const EGLint*);
+typedef EGLBoolean (* eglDestroySyncKHR_t) (EGLDisplay, EGLSyncKHR sync);
+typedef EGLint (* eglClientWaitSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR timeout);
+typedef EGLBoolean (* eglSignalSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLenum);
+typedef EGLBoolean (* eglGetSyncAttribKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLint*);
+typedef EGLBoolean (* eglSetSwapRectangleANDROID_t) (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
+
+#endif // of  _EGL_PROC_H
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/gl_proc.h b/tools/emulator/opengl/host/libs/libOpenglRender/gl_proc.h
new file mode 100644
index 0000000..612b658
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/gl_proc.h
@@ -0,0 +1,296 @@
+/*
+* 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_PROC_H
+#define _GLES_PROC_H
+
+#include <GLES/gl.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GLES/glext.h>
+
+typedef void (* glAlphaFunc_t) (GLenum, GLclampf);
+typedef void (* glClearColor_t) (GLclampf, GLclampf, GLclampf, GLclampf);
+typedef void (* glClearDepthf_t) (GLclampf);
+typedef void (* glClipPlanef_t) (GLenum, const GLfloat*);
+typedef void (* glColor4f_t) (GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glDepthRangef_t) (GLclampf, GLclampf);
+typedef void (* glFogf_t) (GLenum, GLfloat);
+typedef void (* glFogfv_t) (GLenum, const GLfloat*);
+typedef void (* glFrustumf_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glGetClipPlanef_t) (GLenum, GLfloat);
+typedef void (* glGetFloatv_t) (GLenum, GLfloat*);
+typedef void (* glGetLightfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetMaterialfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexEnvfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexParameterfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glLightModelf_t) (GLenum, GLfloat);
+typedef void (* glLightModelfv_t) (GLenum, const GLfloat*);
+typedef void (* glLightf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glLightfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glLineWidth_t) (GLfloat);
+typedef void (* glLoadMatrixf_t) (const GLfloat*);
+typedef void (* glMaterialf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glMaterialfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glMultMatrixf_t) (const GLfloat*);
+typedef void (* glMultiTexCoord4f_t) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glNormal3f_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glOrthof_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glPointParameterf_t) (GLenum, GLfloat);
+typedef void (* glPointParameterfv_t) (GLenum, const GLfloat*);
+typedef void (* glPointSize_t) (GLfloat);
+typedef void (* glPolygonOffset_t) (GLfloat, GLfloat);
+typedef void (* glRotatef_t) (GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glScalef_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glTexEnvf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexEnvfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTexParameterf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexParameterfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTranslatef_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glActiveTexture_t) (GLenum);
+typedef void (* glAlphaFuncx_t) (GLenum, GLclampx);
+typedef void (* glBindBuffer_t) (GLenum, GLuint);
+typedef void (* glBindTexture_t) (GLenum, GLuint);
+typedef void (* glBlendFunc_t) (GLenum, GLenum);
+typedef void (* glBufferData_t) (GLenum, GLsizeiptr, const GLvoid*, GLenum);
+typedef void (* glBufferSubData_t) (GLenum, GLintptr, GLsizeiptr, const GLvoid*);
+typedef void (* glClear_t) (GLbitfield);
+typedef void (* glClearColorx_t) (GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (* glClearDepthx_t) (GLclampx);
+typedef void (* glClearStencil_t) (GLint);
+typedef void (* glClientActiveTexture_t) (GLenum);
+typedef void (* glClipPlanex_t) (GLenum, const GLfixed*);
+typedef void (* glColor4ub_t) (GLubyte, GLubyte, GLubyte, GLubyte);
+typedef void (* glColor4x_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glColorMask_t) (GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (* glColorPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glCompressedTexImage2D_t) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
+typedef void (* glCompressedTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
+typedef void (* glCopyTexImage2D_t) (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+typedef void (* glCopyTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (* glCullFace_t) (GLenum);
+typedef void (* glDeleteBuffers_t) (GLsizei, const GLuint*);
+typedef void (* glDeleteTextures_t) (GLsizei, const GLuint*);
+typedef void (* glDepthFunc_t) (GLenum);
+typedef void (* glDepthMask_t) (GLboolean);
+typedef void (* glDepthRangex_t) (GLclampx, GLclampx);
+typedef void (* glDisable_t) (GLenum);
+typedef void (* glDisableClientState_t) (GLenum);
+typedef void (* glDrawArrays_t) (GLenum, GLint, GLsizei);
+typedef void (* glDrawElements_t) (GLenum, GLsizei, GLenum, const GLvoid*);
+typedef void (* glEnable_t) (GLenum);
+typedef void (* glEnableClientState_t) (GLenum);
+typedef void (* glFinish_t) ();
+typedef void (* glFlush_t) ();
+typedef void (* glFogx_t) (GLenum, GLfixed);
+typedef void (* glFogxv_t) (GLenum, const GLfixed*);
+typedef void (* glFrontFace_t) (GLenum);
+typedef void (* glFrustumx_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glGetBooleanv_t) (GLenum, GLboolean*);
+typedef void (* glGetBufferParameteriv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetClipPlanex_t) (GLenum, GLfixed);
+typedef void (* glGenBuffers_t) (GLsizei, GLuint*);
+typedef void (* glGenTextures_t) (GLsizei, GLuint*);
+typedef GLenum (* glGetError_t) ();
+typedef void (* glGetFixedv_t) (GLenum, GLfixed*);
+typedef void (* glGetIntegerv_t) (GLenum, GLint*);
+typedef void (* glGetLightxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetMaterialxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetPointerv_t) (GLenum, GLvoid*);
+typedef const GLubyte* (* glGetString_t) (GLenum);
+typedef void (* glGetTexEnviv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexEnvxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexParameteriv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexParameterxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glHint_t) (GLenum, GLenum);
+typedef GLboolean (* glIsBuffer_t) (GLuint);
+typedef GLboolean (* glIsEnabled_t) (GLenum);
+typedef GLboolean (* glIsTexture_t) (GLuint);
+typedef void (* glLightModelx_t) (GLenum, GLfixed);
+typedef void (* glLightModelxv_t) (GLenum, const GLfixed*);
+typedef void (* glLightx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glLightxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glLineWidthx_t) (GLfixed);
+typedef void (* glLoadIdentity_t) ();
+typedef void (* glLoadMatrixx_t) (const GLfixed*);
+typedef void (* glLogicOp_t) (GLenum);
+typedef void (* glMaterialx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glMaterialxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glMatrixMode_t) (GLenum);
+typedef void (* glMultMatrixx_t) (const GLfixed*);
+typedef void (* glMultiTexCoord4x_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glNormal3x_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glNormalPointer_t) (GLenum, GLsizei, const GLvoid*);
+typedef void (* glOrthox_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glPixelStorei_t) (GLenum, GLint);
+typedef void (* glPointParameterx_t) (GLenum, GLfixed);
+typedef void (* glPointParameterxv_t) (GLenum, const GLfixed*);
+typedef void (* glPointSizex_t) (GLfixed);
+typedef void (* glPolygonOffsetx_t) (GLfixed, GLfixed);
+typedef void (* glPopMatrix_t) ();
+typedef void (* glPushMatrix_t) ();
+typedef void (* glReadPixels_t) (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (* glRotatex_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glSampleCoverage_t) (GLclampf, GLboolean);
+typedef void (* glSampleCoveragex_t) (GLclampx, GLboolean);
+typedef void (* glScalex_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glScissor_t) (GLint, GLint, GLsizei, GLsizei);
+typedef void (* glShadeModel_t) (GLenum);
+typedef void (* glStencilFunc_t) (GLenum, GLint, GLuint);
+typedef void (* glStencilMask_t) (GLuint);
+typedef void (* glStencilOp_t) (GLenum, GLenum, GLenum);
+typedef void (* glTexCoordPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glTexEnvi_t) (GLenum, GLenum, GLint);
+typedef void (* glTexEnvx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexEnviv_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexEnvxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexImage2D_t) (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
+typedef void (* glTexParameteri_t) (GLenum, GLenum, GLint);
+typedef void (* glTexParameterx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexParameteriv_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexParameterxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*);
+typedef void (* glTranslatex_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glVertexPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glViewport_t) (GLint, GLint, GLsizei, GLsizei);
+typedef void (* glPointSizePointerOES_t) (GLenum, GLsizei, const GLvoid*);
+typedef void (* glBlendEquationSeparateOES_t) (GLenum, GLenum);
+typedef void (* glBlendFuncSeparateOES_t) (GLenum, GLenum, GLenum, GLenum);
+typedef void (* glBlendEquationOES_t) (GLenum);
+typedef void (* glDrawTexsOES_t) (GLshort, GLshort, GLshort, GLshort, GLshort);
+typedef void (* glDrawTexiOES_t) (GLint, GLint, GLint, GLint, GLint);
+typedef void (* glDrawTexxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glDrawTexsvOES_t) (const GLshort*);
+typedef void (* glDrawTexivOES_t) (const GLint*);
+typedef void (* glDrawTexxvOES_t) (const GLfixed*);
+typedef void (* glDrawTexfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glDrawTexfvOES_t) (const GLfloat*);
+typedef void (* glEGLImageTargetTexture2DOES_t) (GLenum, GLeglImageOES);
+typedef void (* glEGLImageTargetRenderbufferStorageOES_t) (GLenum, GLeglImageOES);
+typedef void (* glAlphaFuncxOES_t) (GLenum, GLclampx);
+typedef void (* glClearColorxOES_t) (GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (* glClearDepthxOES_t) (GLclampx);
+typedef void (* glClipPlanexOES_t) (GLenum, const GLfixed*);
+typedef void (* glColor4xOES_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glDepthRangexOES_t) (GLclampx, GLclampx);
+typedef void (* glFogxOES_t) (GLenum, GLfixed);
+typedef void (* glFogxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glFrustumxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glGetClipPlanexOES_t) (GLenum, GLfixed);
+typedef void (* glGetFixedvOES_t) (GLenum, GLfixed*);
+typedef void (* glGetLightxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetMaterialxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexEnvxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexParameterxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glLightModelxOES_t) (GLenum, GLfixed);
+typedef void (* glLightModelxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glLightxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glLightxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glLineWidthxOES_t) (GLfixed);
+typedef void (* glLoadMatrixxOES_t) (const GLfixed*);
+typedef void (* glMaterialxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glMaterialxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glMultMatrixxOES_t) (const GLfixed*);
+typedef void (* glMultiTexCoord4xOES_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glNormal3xOES_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glOrthoxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glPointParameterxOES_t) (GLenum, GLfixed);
+typedef void (* glPointParameterxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glPointSizexOES_t) (GLfixed);
+typedef void (* glPolygonOffsetxOES_t) (GLfixed, GLfixed);
+typedef void (* glRotatexOES_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glSampleCoveragexOES_t) (GLclampx, GLboolean);
+typedef void (* glScalexOES_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glTexEnvxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexEnvxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexParameterxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexParameterxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTranslatexOES_t) (GLfixed, GLfixed, GLfixed);
+typedef GLboolean (* glIsRenderbufferOES_t) (GLuint);
+typedef void (* glBindRenderbufferOES_t) (GLenum, GLuint);
+typedef void (* glDeleteRenderbuffersOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenRenderbuffersOES_t) (GLsizei, GLuint*);
+typedef void (* glRenderbufferStorageOES_t) (GLenum, GLenum, GLsizei, GLsizei);
+typedef void (* glGetRenderbufferParameterivOES_t) (GLenum, GLenum, GLint*);
+typedef GLboolean (* glIsFramebufferOES_t) (GLuint);
+typedef void (* glBindFramebufferOES_t) (GLenum, GLuint);
+typedef void (* glDeleteFramebuffersOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenFramebuffersOES_t) (GLsizei, GLuint*);
+typedef GLenum (* glCheckFramebufferStatusOES_t) (GLenum);
+typedef void (* glFramebufferRenderbufferOES_t) (GLenum, GLenum, GLenum, GLuint);
+typedef void (* glFramebufferTexture2DOES_t) (GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (* glGetFramebufferAttachmentParameterivOES_t) (GLenum, GLenum, GLenum, GLint*);
+typedef void (* glGenerateMipmapOES_t) (GLenum);
+typedef void* (* glMapBufferOES_t) (GLenum, GLenum);
+typedef GLboolean (* glUnmapBufferOES_t) (GLenum);
+typedef void (* glGetBufferPointervOES_t) (GLenum, GLenum, GLvoid*);
+typedef void (* glCurrentPaletteMatrixOES_t) (GLuint);
+typedef void (* glLoadPaletteFromModelViewMatrixOES_t) ();
+typedef void (* glMatrixIndexPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glWeightPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef GLbitfield (* glQueryMatrixxOES_t) (GLfixed, GLint);
+typedef void (* glDepthRangefOES_t) (GLclampf, GLclampf);
+typedef void (* glFrustumfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glOrthofOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glClipPlanefOES_t) (GLenum, const GLfloat*);
+typedef void (* glGetClipPlanefOES_t) (GLenum, GLfloat);
+typedef void (* glClearDepthfOES_t) (GLclampf);
+typedef void (* glTexGenfOES_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexGenfvOES_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTexGeniOES_t) (GLenum, GLenum, GLint);
+typedef void (* glTexGenivOES_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexGenxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexGenxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glGetTexGenfvOES_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexGenivOES_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexGenxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glBindVertexArrayOES_t) (GLuint);
+typedef void (* glDeleteVertexArraysOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenVertexArraysOES_t) (GLsizei, GLuint*);
+typedef GLboolean (* glIsVertexArrayOES_t) (GLuint);
+typedef void (* glDiscardFramebufferEXT_t) (GLenum, GLsizei, const GLenum*);
+typedef void (* glMultiDrawArraysEXT_t) (GLenum, GLint*, GLsizei*, GLsizei);
+typedef void (* glMultiDrawElementsEXT_t) (GLenum, const GLsizei*, GLenum, const GLvoid**, GLsizei);
+typedef void (* glClipPlanefIMG_t) (GLenum, const GLfloat*);
+typedef void (* glClipPlanexIMG_t) (GLenum, const GLfixed*);
+typedef void (* glRenderbufferStorageMultisampleIMG_t) (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (* glFramebufferTexture2DMultisampleIMG_t) (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+typedef void (* glDeleteFencesNV_t) (GLsizei, const GLuint*);
+typedef void (* glGenFencesNV_t) (GLsizei, GLuint*);
+typedef GLboolean (* glIsFenceNV_t) (GLuint);
+typedef GLboolean (* glTestFenceNV_t) (GLuint);
+typedef void (* glGetFenceivNV_t) (GLuint, GLenum, GLint*);
+typedef void (* glFinishFenceNV_t) (GLuint);
+typedef void (* glSetFenceNV_t) (GLuint, GLenum);
+typedef void (* glGetDriverControlsQCOM_t) (GLint*, GLsizei, GLuint*);
+typedef void (* glGetDriverControlStringQCOM_t) (GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (* glEnableDriverControlQCOM_t) (GLuint);
+typedef void (* glDisableDriverControlQCOM_t) (GLuint);
+typedef void (* glExtGetTexturesQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetBuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetRenderbuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetFramebuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetTexLevelParameterivQCOM_t) (GLuint, GLenum, GLint, GLenum, GLint*);
+typedef void (* glExtTexObjectStateOverrideiQCOM_t) (GLenum, GLenum, GLint);
+typedef void (* glExtGetTexSubImageQCOM_t) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (* glExtGetBufferPointervQCOM_t) (GLenum, GLvoid*);
+typedef void (* glExtGetShadersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetProgramsQCOM_t) (GLuint*, GLint, GLint*);
+typedef GLboolean (* glExtIsProgramBinaryQCOM_t) (GLuint);
+typedef void (* glExtGetProgramBinarySourceQCOM_t) (GLuint, GLenum, GLchar*, GLint*);
+typedef void (* glStartTilingQCOM_t) (GLuint, GLuint, GLuint, GLuint, GLbitfield);
+typedef void (* glEndTilingQCOM_t) (GLbitfield);
+
+
+#endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
new file mode 100644
index 0000000..2551f6f
--- /dev/null
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
@@ -0,0 +1,155 @@
+/*
+* 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 "libOpenglRender/render_api.h"
+#include "FrameBuffer.h"
+#include "RenderServer.h"
+#include "osProcess.h"
+#include "TimeUtils.h"
+
+static osUtils::childProcess *s_renderProc = NULL;
+static RenderServer *s_renderThread = NULL;
+static int s_renderPort = 0;
+
+bool initOpenGLRenderer(FBNativeWindowType window,
+                        int x, int y, int width, int height,
+                        int portNum)
+{
+
+    //
+    // Fail if renderer is already initialized
+    //
+    if (s_renderProc || s_renderThread) {
+        return false;
+    }
+
+    s_renderPort = portNum;
+
+#ifdef RENDER_API_USE_THREAD  // should be defined for mac
+    //
+    // initialize the renderer and listen to connections
+    // on a thread in the current process.
+    //
+    bool inited = FrameBuffer::initialize(window, x, y, width, height);
+    if (!inited) {
+        return false;
+    }
+
+    s_renderThread = RenderServer::create(portNum);
+    if (!s_renderThread) {
+        return false;
+    }
+
+    s_renderThread->start();
+
+#else
+    //
+    // Launch emulator_renderer
+    //
+    char cmdLine[128];
+    snprintf(cmdLine, 128, "emulator_renderer -windowid %d -port %d -x %d -y %d -width %d -height %d",
+             (int)window, portNum, x, y, width, height);
+
+    s_renderProc = osUtils::childProcess::create(cmdLine, NULL);
+    if (!s_renderProc) {
+        return false;
+    }
+
+    //
+    // try to connect to the renderer in order to check it
+    // was successfully initialized.
+    //
+    int nTrys = 0;
+    IOStream *dummy = NULL;
+    do {
+        ++nTrys;
+        TimeSleepMS(300);
+        dummy = createRenderThread(8);
+
+        if (!dummy) {
+            // stop if the process is no longer running
+            if (!osUtils::isProcessRunning(s_renderProc->getPID())) {
+                break;
+            }
+        }
+    } while(!dummy && nTrys < 10); // give up after 3 seconds, XXX: ???
+
+    if (!dummy) {
+        //
+        // Failed - make sure the process is killed
+        //
+        osUtils::KillProcess(s_renderProc->getPID(), true);
+        delete s_renderProc;
+        s_renderProc = NULL;
+        return false;
+    }
+
+    // destroy the dummy connection
+    delete dummy;
+#endif
+
+    return true;
+}
+
+bool stopOpenGLRenderer()
+{
+    bool ret = false;
+
+    if (s_renderProc) {
+        //
+        // kill the render process
+        //
+        ret = osUtils::KillProcess(s_renderProc->getPID(), true) != 0;
+        if (ret) {
+            delete s_renderProc;
+            s_renderProc = NULL;
+        }
+    }
+    else if (s_renderThread) {
+        // flag the thread it should exit
+        s_renderThread->flagNeedExit();
+
+        // open a dummy connection to the renderer to make it 
+        // realize the exit request
+        IOStream *dummy = createRenderThread(8);
+        if (dummy) {
+            // wait for the thread to exit
+            int status;
+            ret = s_renderThread->wait(&status);
+    
+            delete dummy;
+        }
+
+        delete s_renderThread;
+        s_renderThread = NULL;
+    }
+
+    return ret;
+}
+
+IOStream *createRenderThread(int p_stream_buffer_size)
+{
+    TcpStream *stream = new TcpStream(p_stream_buffer_size);
+    if (!stream) {
+        return NULL;
+    }
+
+    if (stream->connect("localhost", s_renderPort) < 0) {
+        delete stream;
+        return NULL;
+    }
+
+    return stream;
+}
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h b/tools/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h
new file mode 100644
index 0000000..4bdfbe4
--- /dev/null
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h
@@ -0,0 +1,167 @@
+/*
+* 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 __SMART_PTR_H
+#define __SMART_PTR_H
+
+#include <cutils/threads.h>
+#include <cutils/atomic.h>
+
+template <class T, bool threadSafe = false>
+class SmartPtr
+{
+public:
+    explicit SmartPtr(T* ptr = (T*)NULL) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        m_ptr = ptr;
+        if (ptr)
+           m_pRefCount = new int32_t(1);
+        else
+           m_pRefCount = NULL;
+    }
+
+    SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+    }
+
+    SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        if (rhs.m_lock) mutex_lock(rhs.m_lock);
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+    }
+
+    ~SmartPtr() {
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        if (m_lock)
+        {
+            mutex_unlock(m_lock);
+            mutex_destroy(m_lock);
+            delete m_lock;
+        }
+    }
+
+    T* Ptr() const {
+        return m_ptr;
+    }
+
+    const T* constPtr() const
+    {
+        return m_ptr;
+    }
+
+    T* operator->() const {
+        return m_ptr;
+    }
+
+    T& operator*() const {
+        return *m_ptr;
+    }
+
+    operator void*() const {
+        return (void *)m_ptr;
+    }
+
+    // This gives STL lists something to compare.
+    bool operator <(const SmartPtr<T>& t1) const {
+        return m_ptr < t1.m_ptr;
+    }
+
+    SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs)
+    {
+        if (m_ptr == rhs.m_ptr)
+            return *this;
+
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (m_lock) mutex_unlock(m_lock);
+
+        return *this;
+    }
+
+    SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs)
+    {
+        if (m_ptr == rhs.m_ptr)
+            return *this;
+
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        if (rhs.m_lock) mutex_lock(rhs.m_lock);
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+        if (m_lock) mutex_unlock(m_lock);
+
+        return *this;
+    }
+
+private:
+    int32_t  *m_pRefCount;
+    mutex_t  *m_lock;
+    T* m_ptr;
+
+    // Increment the reference count on this pointer by 1.
+    int use() {
+        if (!m_pRefCount) return 0;
+        return android_atomic_inc(m_pRefCount) + 1;
+    }
+
+    // Decrement the reference count on the pointer by 1.
+    // If the reference count goes to (or below) 0, the pointer is deleted.
+    int release() {
+        if (!m_pRefCount) return 0;
+
+        int iVal = android_atomic_dec(m_pRefCount);
+        if (iVal > 1)
+            return iVal - 1;
+
+        delete m_pRefCount;
+        m_pRefCount = NULL;
+
+        if (m_ptr) {
+            delete m_ptr;
+            m_ptr = NULL;
+        }
+        return 0;
+    }
+
+};
+
+#endif // of  __SMART_PTR_H
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp
index 000c381..e9e0461 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp
@@ -23,8 +23,10 @@
 #include <stdlib.h>
 #include <sys/time.h>
 #include <time.h>
+#include <unistd.h>
 #else
 #include <sys/time.h>
+#include <unistd.h>
 #endif
 
 long long GetCurrentTimeMS()
@@ -56,3 +58,12 @@
 
 #endif
 }
+
+void TimeSleepMS(int p_mili)
+{
+#ifdef _WIN32
+    Sleep(p_mili);
+#else
+    usleep(p_mili * 1000);
+#endif
+}
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h b/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h
index 184a13f..bc4fd1c 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h
@@ -17,5 +17,6 @@
 #define _TIME_UTILS_H
 
 long long GetCurrentTimeMS();
+void TimeSleepMS(int p_mili);
 
 #endif