diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk b/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk index 15e2e98f0..7901220e0 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk +++ b/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk @@ -1,13 +1,87 @@ LOCAL_PATH := $(call my-dir) -##### libGLES_emul.so ########### +emulatorOpengl := $(LOCAL_PATH)/../.. +logTag := -DLOG_TAG=\"eglWrapper\" +EMUGEN = $(BUILD_OUT_EXECUTABLES)/emugen + +#### libGLESv1_CM_emul.so +include $(CLEAR_VARS) + + + +LOCAL_MODULE := libGLESv1_CM_emul +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_SRC_FILES := glesv1_emul_ifc.cpp + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_TAGS := debug +LOCAL_SHARED_LIBRARIES := libdl + +LOCAL_C_INCLUDES += \ + $(emulatorOpengl)/system/GLESv1_enc \ + $(emulatorOpengl)/shared/OpenglCodecCommon + +glesv1_emul_intermediates := $(local-intermediates-dir) + +GEN_GLESv1_emul := \ + $(glesv1_emul_intermediates)/gl_wrapper_entry.cpp \ + $(glesv1_emul_intermediates)/gl_wrapper_context.cpp +$(GEN_GLESv1_emul) : PRIVATE_PATH := $(LOCAL_PATH) +$(GEN_GLESv1_emul) : PRIVATE_CUSTOM_TOOL := \ + $(EMUGEN) -W $(glesv1_emul_intermediates) -i $(emulatorOpengl)/system/GLESv1_enc gl +$(GEN_GLESv1_emul) : $(EMUGEN) \ + $(emulatorOpengl)/system/GLESv1_enc/gl.in \ + $(emulatorOpengl)/system/GLESv1_enc/gl.attrib \ + $(emulatorOpengl)/system/GLESv1_enc/gl.types + $(transform-generated-source) + +LOCAL_GENERATED_SOURCES += $(GEN_GLESv1_emul) + +include $(BUILD_SHARED_LIBRARY) + +#### libGLESv2_CM_emul.so +include $(CLEAR_VARS) + +LOCAL_MODULE := libGLESv2_emul +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_SRC_FILES := glesv2_emul_ifc.cpp + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_TAGS := debug +LOCAL_SHARED_LIBRARIES := libdl + +LOCAL_C_INCLUDES += \ + $(emulatorOpengl)/system/GLESv2_enc \ + $(emulatorOpengl)/shared/OpenglCodecCommon + +glesv2_emul_intermediates := $(local-intermediates-dir) + +GEN_GLESv2_emul := \ + $(glesv2_emul_intermediates)/gl2_wrapper_entry.cpp \ + $(glesv2_emul_intermediates)/gl2_wrapper_context.cpp + +$(GEN_GLESv2_emul) : PRIVATE_PATH := $(LOCAL_PATH) +$(GEN_GLESv2_emul) : PRIVATE_CUSTOM_TOOL := \ + $(EMUGEN) -W $(glesv2_emul_intermediates) -i $(emulatorOpengl)/system/GLESv2_enc gl2 +$(GEN_GLESv2_emul) : $(EMUGEN) \ + $(emulatorOpengl)/system/GLESv2_enc/gl2.in \ + $(emulatorOpengl)/system/GLESv2_enc/gl2.attrib \ + $(emulatorOpengl)/system/GLESv2_enc/gl2.types + $(transform-generated-source) + +LOCAL_GENERATED_SOURCES += $(GEN_GLESv2_emul) + +include $(BUILD_SHARED_LIBRARY) + + +##### libEGL_emul.so ########### include $(CLEAR_VARS) LOCAL_SRC_FILES := \ egl.cpp \ egl_dispatch.cpp \ - gles.cpp \ - gles_dispatch.cpp \ ServerConnection.cpp \ ThreadInfo.cpp @@ -15,27 +89,37 @@ LOCAL_SRC_FILES := \ # is generated LOCAL_ADDITIONAL_DEPENDENCIES := \ $(TARGET_OUT_SHARED_LIBRARIES)/libut_rendercontrol_enc$(TARGET_SHLIB_SUFFIX) \ - $(TARGET_OUT_SHARED_LIBRARIES)/libGLESv1_enc$(TARGET_SHLIB_SUFFIX) + $(TARGET_OUT_SHARED_LIBRARIES)/libGLESv1_enc$(TARGET_SHLIB_SUFFIX) \ + $(TARGET_OUT_SHARED_LIBRARIES)/libGLESv2_enc$(TARGET_SHLIB_SUFFIX) \ + $(TARGET_OUT_SHARED_LIBRARIES)/egl/libGLESv1_CM_emul$(TARGET_SHLIB_SUFFIX) \ + $(TARGET_OUT_SHARED_LIBRARIES)/egl/libGLESv2_emul$(TARGET_SHLIB_SUFFIX) -emulatorOpengl := $(LOCAL_PATH)/../.. LOCAL_C_INCLUDES := $(emulatorOpengl)/shared/OpenglCodecCommon \ $(emulatorOpengl)/host/include/libOpenglRender \ $(call intermediates-dir-for, SHARED_LIBRARIES, libut_rendercontrol_enc) \ $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc) \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv2_enc) \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_CM_emul) \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv2_emul) \ $(emulatorOpengl)/system/GLESv1_enc \ + $(emulatorOpengl)/system/GLESv2_enc \ $(emulatorOpengl)/tests/ut_rendercontrol_enc -LOCAL_CFLAGS := -DLOG_TAG=\"eglWrapper\" +LOCAL_CFLAGS := $(logTag) LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl -LOCAL_MODULE := libGLES_emul +LOCAL_MODULE := libEGL_emul LOCAL_MODULE_TAGS := debug LOCAL_PRELINK_MODULE := false #LOCAL_LDLIBS := -lpthread -ldl -LOCAL_SHARED_LIBRARIES := libdl libcutils libGLESv1_enc libut_rendercontrol_enc +LOCAL_SHARED_LIBRARIES := libdl \ + libcutils \ + libGLESv1_enc \ + libGLESv2_enc \ + libut_rendercontrol_enc LOCAL_STATIC_LIBRARIES := libOpenglCodecCommon include $(BUILD_SHARED_LIBRARY) diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ApiInitializer.h b/tools/emulator/opengl/tests/gles_android_wrapper/ApiInitializer.h new file mode 100644 index 000000000..7dc500621 --- /dev/null +++ b/tools/emulator/opengl/tests/gles_android_wrapper/ApiInitializer.h @@ -0,0 +1,26 @@ +#ifndef _API_INITIALIZER_H_ +#define _API_INITIALIZER_H_ +#include +#include + +class ApiInitializer { +public: + ApiInitializer(void *dso) : + m_dso(dso) { + } + static void *s_getProc(const char *name, void *userData) { + ApiInitializer *self = (ApiInitializer *)userData; + return self->getProc(name); + } +private: + void *m_dso; + void *getProc(const char *name) { + void *symbol = NULL; + if (m_dso) { + symbol = dlsym(m_dso, name); + } + return symbol; + } +}; + +#endif diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp index 2a82bfa66..ea36c72ba 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp +++ b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp @@ -28,6 +28,15 @@ gl_client_context_t *ServerConnection::s_getGlContext() return NULL; } +gl2_client_context_t *ServerConnection::s_getGl2Context() +{ + EGLThreadInfo *ti = getEGLThreadInfo(); + if (ti->serverConn) { + return ti->serverConn->m_gl2Enc; + } + return NULL; +} + ServerConnection *ServerConnection::s_getServerConnection() { EGLThreadInfo *ti = getEGLThreadInfo(); @@ -85,6 +94,9 @@ int ServerConnection::create(size_t bufsize, m_glEnc = new GLEncoder(m_stream); m_glEnc->setContextAccessor(s_getGlContext); + m_gl2Enc = new GL2Encoder(m_stream); + m_gl2Enc->setContextAccessor(s_getGl2Context); + m_ut_enc = new ut_rendercontrol_encoder_context_t(m_stream); return 0; } diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h index 6eae859d6..ed5b31433 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h +++ b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h @@ -17,6 +17,7 @@ #define _SERVER_CONNECTION_H #include "GLEncoder.h" +#include "GL2Encoder.h" #include "TcpStream.h" #include "codec_defs.h" #include "ut_rendercontrol_enc.h" @@ -31,6 +32,7 @@ public: int create(size_t buf_size = 4 * 1024 * 1024, const char *defaultServer = RGL_DEFAULT_SERVER); static gl_client_context_t *s_getGlContext(); static ServerConnection *s_getServerConnection(); + static gl2_client_context_t *s_getGl2Context(); GLEncoder *glEncoder() { return m_glEnc; } ut_rendercontrol_encoder_context_t * utEnc() { return m_ut_enc; } @@ -43,6 +45,7 @@ private: static void s_initKeys(); TcpStream *m_stream; GLEncoder *m_glEnc; + GL2Encoder *m_gl2Enc; ut_rendercontrol_encoder_context_t *m_ut_enc; }; diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp index ea78bbba8..cc6b4f532 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp +++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp @@ -32,18 +32,71 @@ #include "ServerConnection.h" #include "ThreadInfo.h" #include - +#include "gl_wrapper_context.h" +#include "gl2_wrapper_context.h" #define GLES_EMUL_TARGETS_FILE "/system/etc/gles_emul.cfg" +// implementation libraries; +#define GLESv1_enc_LIB "/system/lib/libGLESv1_enc.so" +#define GLESv2_enc_LIB "/system/lib/libGLESv2_enc.so" +#define GLES_android_LIB "/system/lib/egl/libGLES_android.so" +// driver libraries; +#define GLESv1_DRIVER "/system/lib/egl/libGLESv1_CM_emul.so" +#define GLESv2_DRIVER "/system/lib/egl/libGLESv2_emul.so" + static struct egl_dispatch *s_dispatch = NULL; pthread_once_t dispatchTablesInitialized = PTHREAD_ONCE_INIT; static bool s_needEncode = false; -extern void init_gles(void *gles_android); -extern __eglMustCastToProperFunctionPointerType gles_getProcAddress(const char *procname); +static gl_wrapper_context_t *g_gl_dispatch = NULL; +static gl2_wrapper_context_t *g_gl2_dispatch = NULL; +template +int initApi(const char *driverLibName, const char *implLibName, T **dispatchTable, T *(*accessor)()) +{ + void *driverLib = dlopen(driverLibName, RTLD_NOW | RTLD_LOCAL); + if (driverLib == NULL) { + LOGE("failed to load %s : %s\n", driverLibName, dlerror()); + return -1; + } + + typedef T *(*createFcn_t)(void *, T *(*accessor)()); + createFcn_t createFcn; + createFcn = (createFcn_t) dlsym(driverLib, "createFromLib"); + if (createFcn == NULL) { + LOGE("failed to load createFromLib constructor function\n"); + return -1; + } + + void *implLib = dlopen(implLibName, RTLD_NOW | RTLD_LOCAL); + if (implLib == NULL) { + LOGE("couldn't open %s", implLibName); + return -2; + } + *dispatchTable = createFcn(implLib, accessor); + if (*dispatchTable == NULL) { + return -3; + } + + // XXX - we do close the impl library since it doesn't have data, as far as we concern. + dlclose(implLib); + + // XXX - we do not dlclose the driver library, so its not initialized when + // later loaded by android - is this required? + return 0; +} + +static gl_wrapper_context_t *getGLContext() +{ + return g_gl_dispatch; +} + +static gl2_wrapper_context_t *getGL2Context() +{ + return g_gl2_dispatch; +} const char *getProcName() { @@ -156,26 +209,31 @@ void initDispatchTables() s_needEncode = isNeedEncode(); void *gles_encoder = NULL; if (s_needEncode) { + // initialize a connection to the server, and the GLESv1/v2 encoders; ServerConnection * connection = ServerConnection::s_getServerConnection(); if (connection == NULL) { LOGE("couldn't create server connection\n"); s_needEncode = false; - } else { - LOGD("Created server connection for %s\n", getProcName()); - gles_encoder = dlopen("/system/lib/libGLESv1_enc.so", RTLD_NOW); - if (gles_encoder == NULL) { - LOGE("couldn't open libGLESv1_enc.so... aborting connection"); - delete connection; - s_needEncode = false; - } } } - if (s_needEncode && gles_encoder) { - init_gles(gles_encoder); - } else { + // init dispatch tabels for GLESv1 & GLESv2 + if (s_needEncode) { + // XXX - we do not check the retrun value because there isn't much we can do here on failure. + + if (initApi(GLESv1_DRIVER, GLESv1_enc_LIB, &g_gl_dispatch, getGLContext) < 0) { + // fallback to android on faluire + s_needEncode = false; + } else { + initApi(GLESv2_DRIVER, GLESv2_enc_LIB, &g_gl2_dispatch, getGL2Context); + } + } + + if (!s_needEncode) { LOGD("Initializing native opengl for %s\n", getProcName()); - init_gles(gles_android); + initApi(GLESv1_DRIVER, GLES_android_LIB, &g_gl_dispatch, getGLContext); + // try to initialize gl2 from GLES, though its probably going to fail + initApi(GLESv2_DRIVER, GLES_android_LIB, &g_gl2_dispatch, getGL2Context); } } @@ -195,14 +253,9 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) } } - // search in GLES function table - __eglMustCastToProperFunctionPointerType f = gles_getProcAddress(procname); - if (f != NULL) { - return f; - } - - // should probably fail - search in back-end anyway. - return getDispatch()->eglGetProcAddress(procname); + // we do not support eglGetProcAddress for GLESv1 & GLESv2. The loader + // should be able to find this function through dynamic loading. + return NULL; } //////////////// Path through functions ////////// diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp new file mode 100644 index 000000000..41e7b7a7c --- /dev/null +++ b/tools/emulator/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp @@ -0,0 +1,23 @@ +#include +#include "ApiInitializer.h" +#include +#include "gl_wrapper_context.h" + +extern "C" { + gl_wrapper_context_t *createFromLib(void *solib, gl_wrapper_context_t *(*accessor)()); +} + +gl_wrapper_context_t * createFromLib(void *solib, gl_wrapper_context_t *(accessor)()) +{ + gl_wrapper_context_t *ctx = new gl_wrapper_context_t; + if (ctx == NULL) { + return NULL; + } + ApiInitializer *initializer = new ApiInitializer(solib); + ctx->initDispatchByName(ApiInitializer::s_getProc, initializer); + gl_wrapper_context_t::setContextAccessor(accessor); + delete initializer; + return ctx; +} + + diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp new file mode 100644 index 000000000..cf0dfed96 --- /dev/null +++ b/tools/emulator/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp @@ -0,0 +1,24 @@ +#include +#include "ApiInitializer.h" +#include +#include "gl2_wrapper_context.h" + +extern "C" { + gl2_wrapper_context_t *createFromLib(void *solib, gl2_wrapper_context_t *(*accessor)()); +} + +gl2_wrapper_context_t * createFromLib(void *solib, gl2_wrapper_context_t *(*accessor)()) +{ + gl2_wrapper_context_t *ctx = new gl2_wrapper_context_t; + if (ctx == NULL) { + return NULL; + } + ApiInitializer *initializer = new ApiInitializer(solib); + ctx->initDispatchByName(ApiInitializer::s_getProc, initializer); + gl2_wrapper_context_t::setContextAccessor(accessor); + delete initializer; + return ctx; +} + + +