From 0c814b227c284b83e8e32cb2ae4e87ba05e511c0 Mon Sep 17 00:00:00 2001 From: Jacky Romano Date: Sat, 23 Apr 2011 20:19:39 +0300 Subject: [PATCH 1/4] emulator opengl - encode glShaderSource glShaderSource strings are concatenated into a single string before sent over the wire protocol. The wire protocol transfer is done using a special api call 'glShaderString' Change-Id: I90c157df66fe82fee17c460a1e7852d370c77088 --- .../shared/OpenglCodecCommon/glUtils.cpp | 47 ++++++++++++------- .../opengl/shared/OpenglCodecCommon/glUtils.h | 4 +- .../opengl/system/GLESv2_enc/GL2Encoder.cpp | 13 +++++ .../opengl/system/GLESv2_enc/GL2Encoder.h | 1 + .../opengl/system/GLESv2_enc/gl2.attrib | 7 +-- 5 files changed, 50 insertions(+), 22 deletions(-) diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp index 597919386..206b5f52f 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp @@ -363,24 +363,37 @@ int glUtilsPixelBitSize(GLenum format, GLenum type) return pixelsize; } - -int glUtilsSumArrayValues(GLint *array, GLsizei count) +// pack a list of strings into one. +void glUtilsPackStrings(char *ptr, char **strings, GLint *length, GLsizei count) { - int sum = 0; + char *p = ptr; + *p = '\0'; for (int i = 0; i < count; i++) { - sum += *array; - array++; - } - return sum; -} - -void glUtilsPackStrings(void *ptr, char **strings, GLint *length, GLsizei count) -{ - unsigned char *p = (unsigned char *)ptr; - for (int i = 0; i < count; i++) { - memcpy(p, *strings, *length); - p += *length; - strings++; - length++; + int l; + if (length == NULL || length[i] < 0) { + l = strlen(strings[i]); + strcat(p, strings[i]); + } else { + l = length[i]; + strncat(p, strings[i], l); + } + p += l; } } + +// claculate the length of a list of strings +int glUtilsCalcShaderSourceLen( char **strings, GLint *length, GLsizei count) +{ + int len = 0; + for (int i = 0; i < count; i++) { + int l; + if (length == NULL || length[i] < 0) { + l = strlen(strings[i]); + } else { + l = length[i]; + } + len += l; + } + return len; + +} diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h index 3a1ec544b..c66c568f0 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h @@ -52,8 +52,8 @@ extern "C" { int size, GLenum type, unsigned int stride, unsigned int datalen); int glUtilsPixelBitSize(GLenum format, GLenum type); - int glUtilsSumArrayValues(GLint *array, GLsizei count); - void glUtilsPackStrings(void *ptr, char **strings, GLint *length, GLsizei count); + void glUtilsPackStrings(char *ptr, char **strings, GLint *length, GLsizei count); + int glUtilsCalcShaderSourceLen(char **strings, GLint *length, GLsizei count); #ifdef __cplusplus }; #endif diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp index 846e475bd..8c982ce2f 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -25,6 +25,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) m_glGetVertexAttribiv_enc = set_glGetVertexAttribiv(s_glGetVertexAttribiv); m_glGetVertexAttribfv_enc = set_glGetVertexAttribfv(s_glGetVertexAttribfv); m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv); + set_glShaderSource(s_glShaderSource); } GL2Encoder::~GL2Encoder() @@ -322,3 +323,15 @@ GLint * GL2Encoder::getCompressedTextureFormats() } return m_compressedTextureFormats; } + +void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, GLstr *string, GLint *length) +{ + + int len = glUtilsCalcShaderSourceLen(string, length, count); + char *str = new char[len + 1]; + glUtilsPackStrings(str, string, length, count); + + GL2Encoder *ctx = (GL2Encoder *)self; + ctx->glShaderString(ctx, shader, str, len + 1); + delete str; +} diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h index 897a011f5..f628aca90 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h @@ -91,5 +91,6 @@ private: glGetVertexAttribPointerv_client_proc_t m_glGetVertexAttribPointerv; static void s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer); + static void s_glShaderSource(void *self, GLuint shader, GLsizei count, GLstr *string, GLint *length); }; #endif diff --git a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib index bce9b5113..ac32a7bdc 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib +++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib @@ -344,11 +344,12 @@ glMultiDrawArraysEXT glMultiDrawElementsEXT flag unsupported + +# handled by encoder #void glShaderSource(GLuint shader, GLsizei count, GLstr *string, const GLint *length) glShaderSource - len length (count * sizeof(GLint)) - len string (glUtilsSumArrayValues(length, count)) - custom_pack string glUtilsPackStrings(ptr, string, length, count) + flag unsupported + #void glGetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups) From 25af30c4643ce8f6e9ee09cfdd72b5a52fbd465f Mon Sep 17 00:00:00 2001 From: Jacky Romano Date: Sat, 23 Apr 2011 22:28:23 +0300 Subject: [PATCH 2/4] emulator opengl: context version param add version parameter when creating new context Change-Id: I3e36796dd4e582b5deda0da2aaf764ceba92a1d1 --- .../opengl/tests/gles_android_wrapper/ThreadInfo.h | 4 +++- .../emulator/opengl/tests/gles_android_wrapper/egl.cpp | 4 ++-- .../tests/ut_rendercontrol_enc/ut_rendercontrol.in | 2 +- tools/emulator/opengl/tests/ut_renderer/Renderer.cpp | 4 ++-- tools/emulator/opengl/tests/ut_renderer/Renderer.h | 2 +- .../opengl/tests/ut_renderer/RendererContext.cpp | 10 +++++++--- .../opengl/tests/ut_renderer/RendererContext.h | 8 +++++--- .../opengl/tests/ut_renderer/RenderingThread.cpp | 5 +++-- .../opengl/tests/ut_renderer/RenderingThread.h | 2 +- 9 files changed, 25 insertions(+), 16 deletions(-) diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.h b/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.h index f98019536..f748a3973 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.h +++ b/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.h @@ -21,9 +21,10 @@ struct EGLWrapperContext { - EGLWrapperContext(EGLContext p_aglContext) { + EGLWrapperContext(EGLContext p_aglContext, int _version) { aglContext = p_aglContext; clientState = NULL; + version = _version; } ~EGLWrapperContext() { @@ -32,6 +33,7 @@ struct EGLWrapperContext EGLContext aglContext; GLClientState *clientState; + int version; }; struct EGLThreadInfo diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp index cc6b4f532..a392650b0 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp +++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp @@ -404,14 +404,14 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c if (share) share = ((EGLWrapperContext *)share_context)->aglContext; EGLContext ctx = getDispatch()->eglCreateContext(dpy, config, share, attrib_list); - EGLWrapperContext *wctx = new EGLWrapperContext(ctx); + EGLWrapperContext *wctx = new EGLWrapperContext(ctx,1); if (ctx != EGL_NO_CONTEXT) { ServerConnection *server; if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) { wctx->clientState = new GLClientState(); server->utEnc()->createContext(server->utEnc(), getpid(), (uint32_t)wctx, - (uint32_t)(share_context == EGL_NO_CONTEXT ? 0 : share_context)); + (uint32_t)(share_context == EGL_NO_CONTEXT ? 0 : share_context), wctx->version); } } return (EGLContext)wctx; diff --git a/tools/emulator/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.in b/tools/emulator/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.in index 856fed621..0d5942f9f 100644 --- a/tools/emulator/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.in +++ b/tools/emulator/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.in @@ -1,4 +1,4 @@ -GL_ENTRY(int, createContext, uint32_t pid, uint32_t handle, uint32_t shareCtx) +GL_ENTRY(int, createContext, uint32_t pid, uint32_t handle, uint32_t shareCtx, int version) GL_ENTRY(int, createSurface, uint32_t pid, uint32_t handle) GL_ENTRY(int, makeCurrentContext, uint32_t pid, uint32_t drawSurface, uint32_t readSurface, uint32_t ctxHandle) GL_ENTRY(void, swapBuffers, uint32_t pid, uint32_t surface) diff --git a/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp index 3228df6f9..edfdd6419 100644 --- a/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp +++ b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp @@ -88,7 +88,7 @@ int Renderer::destroySurface(RenderingThread *thread, const ClientHandle &handle return 0; } -int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle, ClientHandle shareCtx) +int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle, ClientHandle shareCtx, int version) { android::Mutex::Autolock(this->m_mutex); @@ -104,7 +104,7 @@ int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle, RendererContext *ctx = RendererContext::create(m_dpy, RendererSurface::getEglConfig(m_dpy, RendererSurface::CONFIG_DEPTH), - shared); + shared, version); if (ctx == NULL) { fprintf(stderr, "failed to create context\n"); return -1; diff --git a/tools/emulator/opengl/tests/ut_renderer/Renderer.h b/tools/emulator/opengl/tests/ut_renderer/Renderer.h index 49be147aa..cdf10b6e1 100644 --- a/tools/emulator/opengl/tests/ut_renderer/Renderer.h +++ b/tools/emulator/opengl/tests/ut_renderer/Renderer.h @@ -41,7 +41,7 @@ public: static Renderer *instance(); int createSurface(RenderingThread *thread, const ClientHandle & handle); int destroySurface(RenderingThread *thread, const ClientHandle &handle); - int createContext(RenderingThread *thread, const ClientHandle & ctx, const ClientHandle shareCtx); + int createContext(RenderingThread *thread, const ClientHandle & ctx, const ClientHandle shareCtx, int version); int destroyContext(RenderingThread *thread,const ClientHandle & ctx); int makeCurrent(RenderingThread *thread, const ClientHandle & drawSurface, const ClientHandle & readSurface, const ClientHandle & ctx); diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp b/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp index 271494d27..26f2e3574 100644 --- a/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp +++ b/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp @@ -17,14 +17,18 @@ #include #include -RendererContext * RendererContext::create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx) +RendererContext * RendererContext::create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx, int version) { EGLContext ctx; EGLContext shared = shareCtx == NULL ? EGL_NO_CONTEXT : shareCtx->eglContext(); - ctx = eglCreateContext(dpy, config, shared, NULL); + + EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; + context_attributes[1] = version; + + ctx = eglCreateContext(dpy, config, shared, context_attributes); if (eglGetError() != EGL_SUCCESS) return NULL; - return new RendererContext(dpy, ctx); + return new RendererContext(dpy, ctx, version); } int RendererContext::destroy() diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererContext.h b/tools/emulator/opengl/tests/ut_renderer/RendererContext.h index c0fd6dc8b..6daf91813 100644 --- a/tools/emulator/opengl/tests/ut_renderer/RendererContext.h +++ b/tools/emulator/opengl/tests/ut_renderer/RendererContext.h @@ -38,7 +38,7 @@ typedef std::set PendingCropRectSet; class RendererContext : public RendererObject { public: - static RendererContext *create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx); + static RendererContext *create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx, int version); EGLContext eglContext() { return m_ctx; } int destroy(); GLDecoderContextData & decoderContextData() { return m_contextData; } @@ -99,10 +99,12 @@ private: EGLDisplay m_dpy; EGLContext m_ctx; GLDecoderContextData m_contextData; + int m_version; - RendererContext(EGLDisplay dpy, EGLContext ctx) : + RendererContext(EGLDisplay dpy, EGLContext ctx, int version) : m_dpy(dpy), - m_ctx(ctx) + m_ctx(ctx), + m_version(version) { #ifdef PVR_WAR m_activeTexture = 0; diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp index a7bd939af..cf1d070f1 100644 --- a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp +++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp @@ -210,10 +210,11 @@ void RenderingThread::fixTextureEnable() #endif -int RenderingThread::s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx) +int RenderingThread::s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx, int version) { return Renderer::instance()->createContext(m_tls, Renderer::ClientHandle(pid, handle), - Renderer::ClientHandle(pid, shareCtx)); + Renderer::ClientHandle(pid, shareCtx), + version); } diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h index bbc4dd38a..19b3060b2 100644 --- a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h +++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h @@ -62,7 +62,7 @@ private: static void * s_thread(void *data); static __thread RenderingThread *m_tls; - static int s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx); + static int s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx, int version); static int s_createSurface(uint32_t pid, uint32_t handle); static int s_destroySurface(uint32_t pid, uint32_t handle); static int s_destroyContext(uint32_t pid, uint32_t handle); From 0c01f32aa242efb4e0d54b6ca703f76bdc8a896f Mon Sep 17 00:00:00 2001 From: Jacky Romano Date: Mon, 25 Apr 2011 12:59:37 +0300 Subject: [PATCH 3/4] emulator opengl : unit-test renderer GLESv2 Make the unit test renderer (ut_renderer) encode GLESv2 commands. A rendering thread has both V1 & V2 decoder object, and tryies to decode commands of the two protocols from the stream. Context creating is taking into account the API version and creates context accordingly. Decoder data is shared between the V1 & V2 decoders and applied to both of them on makeCurrent (regardless to the requested context version) Change-Id: If78e84310e5dcd22108c19656051b138b22e3c9f --- tools/emulator/opengl/tests/ut_renderer/Android.mk | 13 +++++++++---- .../emulator/opengl/tests/ut_renderer/Renderer.cpp | 2 ++ .../opengl/tests/ut_renderer/RenderingThread.cpp | 10 ++++++++++ .../opengl/tests/ut_renderer/RenderingThread.h | 4 ++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/tools/emulator/opengl/tests/ut_renderer/Android.mk b/tools/emulator/opengl/tests/ut_renderer/Android.mk index 28317e9b3..e4c43a2ac 100644 --- a/tools/emulator/opengl/tests/ut_renderer/Android.mk +++ b/tools/emulator/opengl/tests/ut_renderer/Android.mk @@ -22,7 +22,8 @@ LOCAL_MODULE_TAGS := debug # is generated LOCAL_ADDITIONAL_DEPENDENCIES := \ $(HOST_OUT_SHARED_LIBRARIES)/libut_rendercontrol_dec$(HOST_SHLIB_SUFFIX) \ - $(HOST_OUT_SHARED_LIBRARIES)/libGLESv1_dec$(HOST_SHLIB_SUFFIX) + $(HOST_OUT_SHARED_LIBRARIES)/libGLESv1_dec$(HOST_SHLIB_SUFFIX) \ + $(HOST_OUT_SHARED_LIBRARIES)/libGLESv2_dec$(HOST_SHLIB_SUFFIX) LOCAL_SRC_FILES := ut_renderer.cpp \ RenderingThread.cpp \ @@ -43,14 +44,18 @@ LOCAL_CFLAGS := -DPVR_WAR #LOCAL_CFLAGS += -g -O0 LOCAL_C_INCLUDES := $(emulatorOpengl)/shared/OpenglCodecCommon \ + $(emulatorOpengl)/shared \ $(emulatorOpengl)/host/include/libOpenglRender \ - $(call intermediates-dir-for, SHARED_LIBRARIES, libut_rendercontrol_dec, HOST) \ - $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_dec, HOST) \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libut_rendercontrol_dec, HOST) \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_dec, HOST) \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv2_dec, HOST) \ $(emulatorOpengl)/host/libs/GLESv1_dec \ + $(emulatorOpengl)/host/libs/GLESv2_dec \ $(emulatorOpengl)/system/GLESv1_enc \ + $(emulatorOpengl)/system/GLESv2_enc \ $(emulatorOpengl)/tests/ut_rendercontrol_enc -LOCAL_SHARED_LIBRARIES := libut_rendercontrol_dec libGLESv1_dec libEGL_host_wrapper +LOCAL_SHARED_LIBRARIES := libut_rendercontrol_dec libGLESv1_dec libGLESv2_dec libEGL_host_wrapper LOCAL_STATIC_LIBRARIES := \ libOpenglCodecCommon \ libcutils diff --git a/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp index edfdd6419..22afadb82 100644 --- a/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp +++ b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp @@ -147,6 +147,7 @@ int Renderer::makeCurrent(RenderingThread *thread, eglContext = c->second->eglContext(); thread->setCurrentContext(c->second); thread->glDecoder().setContextData(&c->second->decoderContextData()); + thread->gl2Decoder().setContextData(&c->second->decoderContextData()); } else { // same context is already set eglContext = c->second->eglContext(); @@ -156,6 +157,7 @@ int Renderer::makeCurrent(RenderingThread *thread, if (currentContext != NULL) currentContext->unref(); thread->setCurrentContext(NULL); thread->glDecoder().setContextData(NULL); + thread->gl2Decoder().setContextData(NULL); } EGLSurface draw = EGL_NO_SURFACE; diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp index cf1d070f1..546c62d56 100644 --- a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp +++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp @@ -312,6 +312,8 @@ void *RenderingThread::thread() m_glDisableClientState = m_glDec.set_glDisableClientState(s_glDisableClientState); #endif + m_gl2Dec.initGL(); + m_utDec.set_swapBuffers(s_swapBuffers); m_utDec.set_createContext(s_createContext); m_utDec.set_destroyContext(s_destroyContext); @@ -359,6 +361,14 @@ void *RenderingThread::thread() } } + if (readBuf.validData() >= 8) { + size_t last = m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream); + if (last > 0) { + readBuf.consume(last); + progress = true; + } + } + if (readBuf.validData() >= 8) { size_t last = m_utDec.decode(readBuf.buf(), readBuf.validData(), m_stream); if (last > 0) { diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h index 19b3060b2..ca8f6f494 100644 --- a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h +++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h @@ -18,6 +18,7 @@ #include "TcpStream.h" #include "GLDecoder.h" +#include "GL2Decoder.h" #include "ut_rendercontrol_dec.h" #include @@ -43,12 +44,15 @@ public: RendererContext *currentContext() { return m_currentContext; } void setCurrentContext(RendererContext *ctx) { m_currentContext = ctx; } GLDecoder & glDecoder() { return m_glDec; } + GL2Decoder & gl2Decoder() { return m_gl2Dec; } + private: void initBackendCaps(); private: GLDecoder m_glDec; ut_rendercontrol_decoder_context_t m_utDec; + GL2Decoder m_gl2Dec; TcpStream *m_stream; pthread_t m_thread; From 44d4d9473e54a5e189bdf9ac18fe090cc112a3f1 Mon Sep 17 00:00:00 2001 From: Jacky Romano Date: Mon, 25 Apr 2011 13:14:58 +0300 Subject: [PATCH 4/4] 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 --- .../gles_android_wrapper/ServerConnection.h | 1 + .../opengl/tests/gles_android_wrapper/egl.cpp | 101 ++++++++++++++++-- .../tests/gles_android_wrapper/gles_emul.cfg | 1 + 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h index ed5b31433..0a39afe3f 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 @@ public: 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 a392650b0..f05ec30ff 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 @@ int initApi(const char *driverLibName, const char *implLibName, T **dispatchTabl // 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 @@ const char *getProcName() procname = strdup(p); } } - LOGD("getProcessName: %s\n", procname == NULL ? "NULL": procname); return procname; } @@ -290,14 +291,69 @@ EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, 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 @@ EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) 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 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC (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 @@ EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGL { 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 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 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 fcb0aebb1..fba3466cf 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 @@ my-tritex org.zeroxlab.benchmark com.cooliris.media com.polarbit.waveblazerlite +test-opengl-gl2_basic