emulator opengl: pool of fixups to the host side.

Those are the host side fixups required for the system to load
without failure to the point of bootanimation is run.

Change-Id: I42eebb123b05aaf6a0671e91e77a4ba6b330b852
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
index f6f15b5..b30d535 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
@@ -92,6 +92,17 @@
     fb->unbind_locked();
 }
 
+void ColorBuffer::subUpdate(int x, int y, int width, int height, 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, x, y,
+                         width, height, p_format, p_type, pixels);
+    fb->unbind_locked();
+}
+
 bool ColorBuffer::blitFromPbuffer(EGLSurface p_pbufSurface)
 {
     FrameBuffer *fb = FrameBuffer::getFB();
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
index 6829581..25761ce 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
@@ -33,6 +33,7 @@
     GLuint getHeight() const { return m_height; }
 
     void update(GLenum p_format, GLenum p_type, void *pixels);
+    void subUpdate(int x, int y, int width, int height, GLenum p_format, GLenum p_type, void *pixels);
     bool blitFromPbuffer(EGLSurface p_pbufSurface);
     bool post();
     bool bindToTexture();
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
index 635f94a..e457e5e 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
@@ -27,6 +27,7 @@
 
     osUtils::dynLibrary *lib = osUtils::dynLibrary::open(libName);
     if (!lib) {
+        printf("Failed to open %s\n", libName);
         return NULL;
     }
 
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
index 81ba067..17a0f87 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
@@ -196,7 +196,7 @@
     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_fbConfigs[i]->m_attribValues,
                s_numConfigAttribs * sizeof(GLuint));
     }
 }
@@ -222,7 +222,47 @@
     // Query the max matching configs in the backend
     //
     EGLConfig *matchedConfigs = new EGLConfig[nConfigs];
-    s_egl.eglChooseConfig(dpy, attribs, matchedConfigs, nConfigs, &nConfigs);
+
+    //
+    //Until we have EGLImage implementation, we force pbuf configs
+    //
+    bool needToAddPbufAttr = true;
+    int attribCnt = 0;
+    EGLint * attrib_p = attribs;
+    if (attribs) {
+        while (attrib_p[0] != EGL_NONE) {
+            if (attrib_p[0] == EGL_SURFACE_TYPE) {
+                attrib_p[1] = EGL_PBUFFER_BIT; //replace whatever was there before
+                needToAddPbufAttr = false;
+            }
+            attrib_p += 2;
+            attribCnt += 2;
+        }
+    }
+    EGLint * newAttribs = new EGLint[attribCnt + 1 + ((needToAddPbufAttr) ? 2 : 0)];
+    attrib_p = newAttribs;
+    if (needToAddPbufAttr) {
+        *(attrib_p++) = EGL_SURFACE_TYPE;
+        *(attrib_p++) = EGL_PBUFFER_BIT;
+    }
+    memcpy(attrib_p, attribs, attribCnt*sizeof(EGLint));
+    attrib_p += attribCnt;
+    *attrib_p = EGL_NONE;
+
+#if 1
+    DBG("EGLint %d", sizeof(EGLint));
+    if (newAttribs) {
+        EGLint * attrib_p = newAttribs;
+        while (attrib_p[0] != EGL_NONE) {
+            DBG("attr: 0x%x %d", attrib_p[0], attrib_p[1]);
+            attrib_p += 2;
+        }
+    }
+
+#endif
+    s_egl.eglChooseConfig(dpy, newAttribs, matchedConfigs, nConfigs, &nConfigs);
+
+    delete newAttribs;
 
     //
     // From all matchedConfigs we need only config_size FBConfigs, so we intersect both lists compating the CONFIG_ID attribute
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
index b0bd7ab..1caaf10 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
@@ -106,7 +106,7 @@
     //
     if (!init_gl_dispatch()) {
         // Failed to load GLES
-        printf("Failed to init_gl_dispatch\n");
+        ERR("Failed to init_gl_dispatch\n");
         return false;
     }
 
@@ -115,7 +115,7 @@
     //
     FrameBuffer *fb = new FrameBuffer(p_x, p_y, p_width, p_height);
     if (!fb) {
-        printf("Fialed to create fb\n");
+        ERR("Failed to create fb\n");
         return false;
     }
 
@@ -138,11 +138,18 @@
     //
     fb->m_eglDisplay = s_egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
     if (fb->m_eglDisplay == EGL_NO_DISPLAY) {
-        printf("Failed to Initialize backend EGL display\n");
+        ERR("Failed to Initialize backend EGL display\n");
         delete fb;
         return false;
     }
-    s_egl.eglInitialize(fb->m_eglDisplay, &fb->m_caps.eglMajor, &fb->m_caps.eglMinor);
+
+    if (!s_egl.eglInitialize(fb->m_eglDisplay, &fb->m_caps.eglMajor, &fb->m_caps.eglMinor)) {
+        ERR("Failed to eglInitialize\n");
+        delete fb;
+        return false;
+    }
+
+    DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor);
     s_egl.eglBindAPI(EGL_OPENGL_ES_API);
 
     fb->m_nativeWindow = p_window;
@@ -166,17 +173,26 @@
     // Create EGL context and Surface attached to the native window, for
     // framebuffer post rendering.
     //
+#if 0
     GLint configAttribs[] = {
         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
         EGL_NONE
     };
-
+#else
+    GLint configAttribs[] = {
+        EGL_RED_SIZE, 1,
+        EGL_GREEN_SIZE, 1,
+        EGL_BLUE_SIZE, 1,
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_NONE
+    };
+#endif
     EGLConfig eglConfig;
     int n;
     if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs,
                                &eglConfig, 1, &n)) {
-        printf("Failed on eglChooseConfig\n");
+        ERR("Failed on eglChooseConfig\n");
         delete fb;
         return false;
     }
@@ -186,6 +202,7 @@
                                                   (EGLNativeWindowType)p_window,
                                                   NULL);
     if (fb->m_eglSurface == EGL_NO_SURFACE) {
+        ERR("Failed to create surface\n");
         delete fb;
         return false;
     }
@@ -207,6 +224,7 @@
 
     // Make the context current
     if (!fb->bind_locked()) {
+        ERR("Failed to make current\n");
         delete fb;
         return false;
     }
@@ -243,6 +261,7 @@
     //
     InitConfigStatus configStatus = FBConfig::initConfigList(fb);
     if (configStatus == INIT_CONFIG_FAILED) {
+        ERR("Failed: Initialize set of configs\n");
         delete fb;
         return false;
     }
@@ -403,6 +422,21 @@
     m_colorbuffers.erase(p_colorbuffer);
 }
 
+bool FrameBuffer::flushWindowSurfaceColorBuffer(HandleType p_surface)
+{
+    android::Mutex::Autolock mutex(m_lock);
+
+    WindowSurfaceMap::iterator w( m_windows.find(p_surface) );
+    if (w == m_windows.end()) {
+        // bad surface handle
+        return false;
+    }
+
+    (*w).second->flushColorBuffer();
+
+    return true;
+}
+
 bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface,
                                               HandleType p_colorbuffer)
 {
@@ -425,6 +459,23 @@
     return true;
 }
 
+bool FrameBuffer::updateColorBuffer(HandleType p_colorbuffer,
+                                    int x, int y, int width, int height,
+                                    GLenum format, GLenum type, void *pixels)
+{
+    android::Mutex::Autolock mutex(m_lock);
+
+    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
+    if (c == m_colorbuffers.end()) {
+        // bad colorbuffer handle
+        return false;
+    }
+
+    (*c).second->subUpdate(x, y, width, height, format, type, pixels);
+
+    return true;
+}
+
 bool FrameBuffer::bindColorBufferToTexture(HandleType p_colorbuffer)
 {
     android::Mutex::Autolock mutex(m_lock);
@@ -513,6 +564,7 @@
     tinfo->currContext = ctx;
     tinfo->currDrawSurf = draw;
     tinfo->currReadSurf = read;
+    tinfo->m_glDec.setContextData(&ctx->decoderContextData());
 
     return true;
 }
@@ -528,6 +580,7 @@
 
     if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface,
                               m_eglSurface, m_eglContext)) {
+        ERR("eglMakeCurrent failed\n");
         return false;
     }
 
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
index 99e4999..128d73f 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
@@ -67,7 +67,11 @@
 
     bool  bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface);
     bool  setWindowSurfaceColorBuffer(HandleType p_surface, HandleType p_colorbuffer);
+    bool  flushWindowSurfaceColorBuffer(HandleType p_surface);
     bool  bindColorBufferToTexture(HandleType p_colorbuffer);
+    bool updateColorBuffer(HandleType p_colorbuffer,
+                           int x, int y, int width, int height,
+                           GLenum format, GLenum type, void *pixels);
 
     bool post(HandleType p_colorbuffer);
 
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h
index 3962ada..9cbb5fc 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h
@@ -18,6 +18,7 @@
 
 #include "SmartPtr.h"
 #include <EGL/egl.h>
+#include "GLDecoderContextData.h"
 
 class RenderContext;
 typedef SmartPtr<RenderContext> RenderContextPtr;
@@ -33,6 +34,8 @@
     EGLContext getEGLContext() const { return m_ctx; }
     bool isGL2() const { return m_isGL2; }
 
+    GLDecoderContextData & decoderContextData() { return m_contextData; }
+
 private:
     RenderContext();
 
@@ -40,6 +43,7 @@
     EGLContext m_ctx;
     int        m_config;
     bool       m_isGL2;
+    GLDecoderContextData    m_contextData;
 };
 
 #endif
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
index f68a153..c0f6260 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
@@ -189,6 +189,15 @@
     fb->DestroyColorBuffer( colorbuffer );
 }
 
+static void rcFlushWindowColorBuffer(uint32_t windowSurface)
+{
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return;
+    }
+    fb->flushWindowSurfaceColorBuffer(windowSurface);
+}
+
 static void rcSetWindowColorBuffer(uint32_t windowSurface,
                                    uint32_t colorBuffer)
 {
@@ -257,7 +266,12 @@
                                 GLint width, GLint height,
                                 GLenum format, GLenum type, void* pixels)
 {
-   // XXX: TBD - should be implemented
+    FrameBuffer *fb = FrameBuffer::getFB();
+    if (!fb) {
+        return;
+    }
+
+    fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
 }
 
 void initRenderControlContext(renderControl_decoder_context_t *dec)
@@ -276,6 +290,7 @@
     dec->set_rcCreateColorBuffer(rcCreateColorBuffer);
     dec->set_rcDestroyColorBuffer(rcDestroyColorBuffer);
     dec->set_rcSetWindowColorBuffer(rcSetWindowColorBuffer);
+    dec->set_rcFlushWindowColorBuffer(rcFlushWindowColorBuffer);
     dec->set_rcMakeCurrent(rcMakeCurrent);
     dec->set_rcFBPost(rcFBPost);
     dec->set_rcFBSetSwapInterval(rcFBSetSwapInterval);
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
index 95dbc3c..cc63283 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
@@ -32,6 +32,7 @@
 
     server->m_listenSock = new TcpStream();
     if (server->m_listenSock->listen(port) < 0) {
+        ERR("RenderServer::create failed to listen on port %d\n", port);
         delete server;
         return NULL;
     }
@@ -48,6 +49,7 @@
             break;
         }
 
+        DBG("\n\n\n\n Got new stream!!!! \n\n\n\n\n");
         // check if we have been requested to exit while waiting on accept
         if (m_exit) {
             break;
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
index 8dd60d5..ad5df38 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
@@ -15,6 +15,7 @@
 */
 #include "RenderThread.h"
 #include "RenderControl.h"
+#include "ThreadInfo.h"
 #include "ReadBuffer.h"
 #include "TimeUtils.h"
 #include "GLDispatch.h"
@@ -41,10 +42,11 @@
 
 int RenderThread::Main()
 {
+    RenderThreadInfo * tInfo = getRenderThreadInfo();
     //
     // initialize decoders
     //
-    m_glDec.initGL( gl_dispatch_get_proc_func, NULL );
+    tInfo->m_glDec.initGL( gl_dispatch_get_proc_func, NULL );
     initRenderControlContext( &m_rcDec );
 
     ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE);
@@ -79,7 +81,7 @@
             //
             // try to process some of the command buffer using the GLES decoder
             //
-            size_t last = m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+            size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
             if (last > 0) {
                 progress = true;
                 readBuf.consume(last);
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
index 2ca5755..ad5cde3 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
@@ -32,7 +32,6 @@
 
 private:
     IOStream *m_stream;
-    GLDecoder   m_glDec;
     renderControl_decoder_context_t m_rcDec;
 };
 
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
index 82d2980..cabeb56 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h
@@ -18,12 +18,14 @@
 
 #include "RenderContext.h"
 #include "WindowSurface.h"
+#include "GLDecoder.h"
 
 struct RenderThreadInfo
 {
     RenderContextPtr currContext;
     WindowSurfacePtr currDrawSurf;
     WindowSurfacePtr currReadSurf;
+    GLDecoder        m_glDec;
 };
 
 RenderThreadInfo *getRenderThreadInfo();
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
index a956e2a..21b92e2 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
@@ -123,12 +123,11 @@
 }
 
 //
-// setColorBuffer - this function is called when a new color buffer needs to
-//    be attached to the surface. The function should make sure that the
+// flushColorBuffer - The function makes 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)
+void WindowSurface::flushColorBuffer()
 {
     if (m_attachedColorBuffer.Ptr() != NULL) {
 
@@ -143,9 +142,18 @@
             }
         }
         else {
+            //TODO: EGLImage
         }
     }
+}
 
+//
+// setColorBuffer - this function is called when a new color buffer needs to
+//    be attached to the surface. The function doesn't make sure that the
+//    previous attached color buffer is updated, this is done by flushColorBuffer
+//
+void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer)
+{
     m_attachedColorBuffer = p_colorBuffer;
 }
 
@@ -226,5 +234,4 @@
     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
index 3a01a35..2a496df 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h
@@ -37,6 +37,7 @@
     EGLSurface getEGLSurface() const { return m_eglSurface; }
 
     void setColorBuffer(ColorBufferPtr p_colorBuffer);
+    void flushColorBuffer();
     void bind(RenderContextPtr p_ctx, SurfaceBindType p_bindType);
 
 private:
diff --git a/tools/emulator/opengl/host/renderer/main.cpp b/tools/emulator/opengl/host/renderer/main.cpp
index ccc5d6a..73efe59 100644
--- a/tools/emulator/opengl/host/renderer/main.cpp
+++ b/tools/emulator/opengl/host/renderer/main.cpp
@@ -19,6 +19,11 @@
 #include <stdlib.h>
 #include "FrameBuffer.h"
 
+#include <sys/types.h>
+#include <unistd.h>
+#include <codec_defs.h>
+
+
 static void printUsage(const char *progName)
 {
     fprintf(stderr, "Usage: %s -windowid <windowid> [options]\n", progName);
@@ -33,7 +38,7 @@
 
 int main(int argc, char *argv[])
 {
-    int portNum = 4141;
+    int portNum = CODEC_SERVER_PORT;
     int winX = 0;
     int winY = 0;
     int winWidth = 320;
@@ -84,6 +89,9 @@
         printUsage(argv[0]);
     }
 
+    printf("renderer pid %d , press any key to continue...\n", getpid());
+    getchar();
+
     //
     // initialize Framebuffer
     //
@@ -95,7 +103,7 @@
     }
 
     //
-    // Create and run a render server listening to the givven port number
+    // Create and run a render server listening to the given port number
     //
     RenderServer *server = RenderServer::create(portNum);
     if (!server) {
diff --git a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
index d408e4b..8cc097c 100644
--- a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
+++ b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
@@ -348,6 +348,7 @@
         e->print(fp, true, "_enc", /* classname + "::" */"", "void *self");
         fprintf(fp, "{\n");
 
+//      fprintf(fp, "\n\tDBG(\">>>> %s\\n\");\n", e->name().c_str());
         fprintf(fp, "\n\t%s *ctx = (%s *)self;\n\n",
                 classname.c_str(),
                 classname.c_str());
@@ -454,6 +455,7 @@
                 }
             }
         }
+//XXX       fprintf(fp, "\n\tDBG(\"<<<< %s\\n\");\n", e->name().c_str());
         // todo - return value for pointers
         if (e->retval().isPointer()) {
             fprintf(stderr, "WARNING: %s : return value of pointer is unsupported\n",