Merge "Emulator Opengl unit test - use sperate implementation libraries"

This commit is contained in:
David Turner
2011-05-03 06:04:55 -07:00
committed by Android Code Review
7 changed files with 256 additions and 31 deletions

View File

@@ -1,13 +1,87 @@
LOCAL_PATH := $(call my-dir) 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) include $(CLEAR_VARS)
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
egl.cpp \ egl.cpp \
egl_dispatch.cpp \ egl_dispatch.cpp \
gles.cpp \
gles_dispatch.cpp \
ServerConnection.cpp \ ServerConnection.cpp \
ThreadInfo.cpp ThreadInfo.cpp
@@ -15,27 +89,37 @@ LOCAL_SRC_FILES := \
# is generated # is generated
LOCAL_ADDITIONAL_DEPENDENCIES := \ LOCAL_ADDITIONAL_DEPENDENCIES := \
$(TARGET_OUT_SHARED_LIBRARIES)/libut_rendercontrol_enc$(TARGET_SHLIB_SUFFIX) \ $(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 \ LOCAL_C_INCLUDES := $(emulatorOpengl)/shared/OpenglCodecCommon \
$(emulatorOpengl)/host/include/libOpenglRender \ $(emulatorOpengl)/host/include/libOpenglRender \
$(call intermediates-dir-for, SHARED_LIBRARIES, libut_rendercontrol_enc) \ $(call intermediates-dir-for, SHARED_LIBRARIES, libut_rendercontrol_enc) \
$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_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/GLESv1_enc \
$(emulatorOpengl)/system/GLESv2_enc \
$(emulatorOpengl)/tests/ut_rendercontrol_enc $(emulatorOpengl)/tests/ut_rendercontrol_enc
LOCAL_CFLAGS := -DLOG_TAG=\"eglWrapper\" LOCAL_CFLAGS := $(logTag)
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
LOCAL_MODULE := libGLES_emul LOCAL_MODULE := libEGL_emul
LOCAL_MODULE_TAGS := debug LOCAL_MODULE_TAGS := debug
LOCAL_PRELINK_MODULE := false LOCAL_PRELINK_MODULE := false
#LOCAL_LDLIBS := -lpthread -ldl #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 LOCAL_STATIC_LIBRARIES := libOpenglCodecCommon
include $(BUILD_SHARED_LIBRARY) 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; 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() ServerConnection *ServerConnection::s_getServerConnection()
{ {
EGLThreadInfo *ti = getEGLThreadInfo(); EGLThreadInfo *ti = getEGLThreadInfo();
@@ -85,6 +94,9 @@ int ServerConnection::create(size_t bufsize,
m_glEnc = new GLEncoder(m_stream); m_glEnc = new GLEncoder(m_stream);
m_glEnc->setContextAccessor(s_getGlContext); 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); m_ut_enc = new ut_rendercontrol_encoder_context_t(m_stream);
return 0; return 0;
} }

View File

@@ -17,6 +17,7 @@
#define _SERVER_CONNECTION_H #define _SERVER_CONNECTION_H
#include "GLEncoder.h" #include "GLEncoder.h"
#include "GL2Encoder.h"
#include "TcpStream.h" #include "TcpStream.h"
#include "codec_defs.h" #include "codec_defs.h"
#include "ut_rendercontrol_enc.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); int create(size_t buf_size = 4 * 1024 * 1024, const char *defaultServer = RGL_DEFAULT_SERVER);
static gl_client_context_t *s_getGlContext(); static gl_client_context_t *s_getGlContext();
static ServerConnection *s_getServerConnection(); static ServerConnection *s_getServerConnection();
static gl2_client_context_t *s_getGl2Context();
GLEncoder *glEncoder() { return m_glEnc; } GLEncoder *glEncoder() { return m_glEnc; }
ut_rendercontrol_encoder_context_t * utEnc() { return m_ut_enc; } ut_rendercontrol_encoder_context_t * utEnc() { return m_ut_enc; }
@@ -43,6 +45,7 @@ private:
static void s_initKeys(); static void s_initKeys();
TcpStream *m_stream; TcpStream *m_stream;
GLEncoder *m_glEnc; GLEncoder *m_glEnc;
GL2Encoder *m_gl2Enc;
ut_rendercontrol_encoder_context_t *m_ut_enc; ut_rendercontrol_encoder_context_t *m_ut_enc;
}; };

View File

@@ -32,18 +32,71 @@
#include "ServerConnection.h" #include "ServerConnection.h"
#include "ThreadInfo.h" #include "ThreadInfo.h"
#include <pthread.h> #include <pthread.h>
#include "gl_wrapper_context.h"
#include "gl2_wrapper_context.h"
#define GLES_EMUL_TARGETS_FILE "/system/etc/gles_emul.cfg" #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; static struct egl_dispatch *s_dispatch = NULL;
pthread_once_t dispatchTablesInitialized = PTHREAD_ONCE_INIT; pthread_once_t dispatchTablesInitialized = PTHREAD_ONCE_INIT;
static bool s_needEncode = false; static bool s_needEncode = false;
extern void init_gles(void *gles_android); static gl_wrapper_context_t *g_gl_dispatch = NULL;
extern __eglMustCastToProperFunctionPointerType gles_getProcAddress(const char *procname); 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() const char *getProcName()
{ {
@@ -156,26 +209,31 @@ void initDispatchTables()
s_needEncode = isNeedEncode(); s_needEncode = isNeedEncode();
void *gles_encoder = NULL; void *gles_encoder = NULL;
if (s_needEncode) { if (s_needEncode) {
// initialize a connection to the server, and the GLESv1/v2 encoders;
ServerConnection * connection = ServerConnection::s_getServerConnection(); ServerConnection * connection = ServerConnection::s_getServerConnection();
if (connection == NULL) { if (connection == NULL) {
LOGE("couldn't create server connection\n"); LOGE("couldn't create server connection\n");
s_needEncode = false; 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 dispatch tabels for GLESv1 & GLESv2
init_gles(gles_encoder); if (s_needEncode) {
} else { // 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()); 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 // we do not support eglGetProcAddress for GLESv1 & GLESv2. The loader
__eglMustCastToProperFunctionPointerType f = gles_getProcAddress(procname); // should be able to find this function through dynamic loading.
if (f != NULL) { return NULL;
return f;
}
// should probably fail - search in back-end anyway.
return getDispatch()->eglGetProcAddress(procname);
} }
//////////////// Path through functions ////////// //////////////// 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;
}