Emulator Opengl unit test - use sperate implementation libraries

Use seperate EGL_emul, GLESv1_CM_emul and GLESv2_emul implementation
libraries.  This replaces GLES_emul that was prviously included
EGL and GLESv1.
This change enables the wrapper to support GLESv2. However,
this current EGL implementation uses the native android emulator
EGL thus will not expose this GLESv2 capability.

Change-Id: Ib0a309d71cce1248efe9a08aa59434101d0ac607
This commit is contained in:
Jacky Romano
2011-04-20 10:15:11 +03:00
committed by David 'Digit' Turner
parent 318ffd3798
commit e359543f4a
7 changed files with 256 additions and 31 deletions

View File

@@ -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)

View File

@@ -0,0 +1,26 @@
#ifndef _API_INITIALIZER_H_
#define _API_INITIALIZER_H_
#include <stdlib.h>
#include <dlfcn.h>
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

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -32,18 +32,71 @@
#include "ServerConnection.h"
#include "ThreadInfo.h"
#include <pthread.h>
#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 <class T>
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);
// 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<gl_wrapper_context_t>(GLESv1_DRIVER, GLESv1_enc_LIB, &g_gl_dispatch, getGLContext) < 0) {
// fallback to android on faluire
s_needEncode = false;
} else {
initApi<gl2_wrapper_context_t>(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<gl_wrapper_context_t>(GLESv1_DRIVER, GLES_android_LIB, &g_gl_dispatch, getGLContext);
// try to initialize gl2 from GLES, though its probably going to fail
initApi<gl2_wrapper_context_t>(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 //////////

View File

@@ -0,0 +1,23 @@
#include <stdlib.h>
#include "ApiInitializer.h"
#include <dlfcn.h>
#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;
}

View File

@@ -0,0 +1,24 @@
#include <stdlib.h>
#include "ApiInitializer.h"
#include <dlfcn.h>
#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;
}