opengl emulator : GLESv2 handling in the test egl implementation

Handle GLESv2 rendering in the emulator:
* load and initialize GLESv2 encoder library
* hide request for GLESv2 surfaces and contexts from the emulator
native implementation
* communicate the context/surface version configuration to the rendering
server

Change-Id: I9226275fc4a24983767735bdf19ddafbe9d07f34
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h
index ed5b314..0a39afe 100644
--- a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h
@@ -34,6 +34,7 @@
     static ServerConnection *s_getServerConnection();
     static gl2_client_context_t *s_getGl2Context();
     GLEncoder *glEncoder() { return m_glEnc; }
+    GL2Encoder *gl2Encoder() { return m_gl2Enc; }
     ut_rendercontrol_encoder_context_t * utEnc() { return m_ut_enc; }
 
 private:
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp
index a392650..f05ec30 100644
--- a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp
@@ -85,7 +85,9 @@
 
     // XXX - we do not dlclose the driver library, so its not initialized when
     // later loaded by android - is this required?
+    LOGD("loading %s into %s complete\n", implLibName, driverLibName);
     return 0;
+
 }
 
 static gl_wrapper_context_t *getGLContext()
@@ -143,7 +145,6 @@
             procname = strdup(p);
         }
     }
-    LOGD("getProcessName: %s\n", procname == NULL ? "NULL": procname);
 
     return procname;
 }
@@ -290,14 +291,69 @@
     return getDispatch()->eglGetConfigs(dpy, configs, config_size, num_config);
 }
 
+static EGLint * filter_es2_bit(const EGLint *attrib_list, bool *isES2)
+{
+    if (attrib_list == NULL) {
+        if (isES2 != NULL) *isES2 = false;
+        return NULL;
+    }
+
+    EGLint *attribs = NULL;
+    int nAttribs = 0;
+    while(attrib_list[nAttribs] != EGL_NONE) nAttribs++;
+    nAttribs++;
+
+    attribs = new EGLint[nAttribs];
+    memcpy(attribs, attrib_list, nAttribs * sizeof(EGLint));
+    if (isES2 != NULL) *isES2 = false;
+
+    // scan the attribute list for ES2 request and replace with ES1.
+    for (int i = 0; i < nAttribs; i++) {
+        if (attribs[i] == EGL_RENDERABLE_TYPE) {
+            if (attribs[i + 1] & EGL_OPENGL_ES2_BIT) {
+                attribs[i + 1] &= ~EGL_OPENGL_ES2_BIT;
+                attribs[i + 1] |= EGL_OPENGL_ES_BIT;
+                LOGD("removing ES2 bit 0x%x\n", attribs[i + 1]);
+                if (isES2 != NULL) *isES2 = true;
+            }
+        }
+    }
+    return attribs;
+}
+
 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
 {
-    return getDispatch()->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+    EGLBoolean res;
+    if (s_needEncode) {
+        EGLint *attribs = filter_es2_bit(attrib_list, NULL);
+        res =  getDispatch()->eglChooseConfig(dpy,
+                                              attribs,
+                                              configs,
+                                              config_size,
+                                              num_config);
+        LOGD("eglChooseConfig: %d configs found\n", *num_config);
+        if (*num_config == 0 && attribs != NULL) {
+            LOGD("requested attributes:\n");
+            for (int i = 0; attribs[i] != EGL_NONE; i++) {
+                LOGD("%d: 0x%x\n", i, attribs[i]);
+            }
+        }
+
+        delete attribs;
+    } else {
+        res = getDispatch()->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+    }
+    return res;
 }
 
 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
 {
-    return getDispatch()->eglGetConfigAttrib(dpy, config, attribute, value);
+    if (s_needEncode && attribute == EGL_RENDERABLE_TYPE) {
+        *value = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
+        return EGL_TRUE;
+    } else {
+        return getDispatch()->eglGetConfigAttrib(dpy, config, attribute, value);
+    }
 }
 
 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
@@ -400,11 +456,37 @@
 
 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
 {
+
     EGLContext share = share_context;
     if (share) share = ((EGLWrapperContext *)share_context)->aglContext;
 
-    EGLContext ctx =  getDispatch()->eglCreateContext(dpy, config, share, attrib_list);
-    EGLWrapperContext *wctx = new EGLWrapperContext(ctx,1);
+    // check if are ES2, and convert it to ES1.
+    int nAttribs = 0;
+    if (attrib_list != NULL) {
+        while(attrib_list[nAttribs] != EGL_NONE) {
+            nAttribs++;
+        }
+        nAttribs++;
+    }
+
+    EGLint *attrib = NULL;
+    if (nAttribs > 0) {
+        attrib = new EGLint[nAttribs];
+        memcpy(attrib, attrib_list, nAttribs * sizeof(EGLint));
+    }
+
+    int  version  = 1;
+    for (int i = 0; i < nAttribs; i++) {
+        if (attrib[i] == EGL_CONTEXT_CLIENT_VERSION &&
+            attrib[i + 1] == 2) {
+            version = 2;
+            attrib[i + 1] = 1; // replace to version 1
+        }
+    }
+
+    EGLContext ctx =  getDispatch()->eglCreateContext(dpy, config, share, attrib);
+    delete attrib;
+    EGLWrapperContext *wctx = new EGLWrapperContext(ctx, version);
     if (ctx != EGL_NO_CONTEXT) {
         ServerConnection *server;
         if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
@@ -451,6 +533,7 @@
                                                 (uint32_t) (read == EGL_NO_SURFACE ? 0 : read),
                                                 (uint32_t) (ctx == EGL_NO_CONTEXT ? 0 : ctx));
             ti->serverConn->glEncoder()->setClientState( wctx ? wctx->clientState : NULL );
+            ti->serverConn->gl2Encoder()->setClientState( wctx ? wctx->clientState : NULL );
         }
 
         // set current context in our thread info
@@ -480,7 +563,12 @@
 {
     EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
     if (wctx) {
-        return getDispatch()->eglQueryContext(dpy, wctx->aglContext, attribute, value);
+        if (attribute == EGL_CONTEXT_CLIENT_VERSION) {
+            *value = wctx->version;
+            return EGL_TRUE;
+        } else {
+            return getDispatch()->eglQueryContext(dpy, wctx->aglContext, attribute, value);
+        }
     }
     else {
         return EGL_BAD_CONTEXT;
@@ -503,6 +591,7 @@
     if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
         server->utEnc()->swapBuffers(server->utEnc(), getpid(), (uint32_t)surface);
         server->glEncoder()->flush();
+        server->gl2Encoder()->flush();
         return 1;
     }
     return getDispatch()->eglSwapBuffers(dpy, surface);
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/gles_emul.cfg b/tools/emulator/opengl/tests/gles_android_wrapper/gles_emul.cfg
index fcb0aeb..fba3466 100644
--- a/tools/emulator/opengl/tests/gles_android_wrapper/gles_emul.cfg
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/gles_emul.cfg
@@ -3,3 +3,4 @@
 org.zeroxlab.benchmark
 com.cooliris.media
 com.polarbit.waveblazerlite
+test-opengl-gl2_basic