am 0e5c2beb: Merge "First commit of the system egl implementation."
* commit '0e5c2beb132d87f1190ab8d2aa9edde2563007f9': First commit of the system egl implementation.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
#ifndef _SYSTEM_COMMON_EGL_CLIENT_IFACE_H
|
||||
#define _SYSTEM_COMMON_EGL_CLIENT_IFACE_H
|
||||
|
||||
struct EGLThreadInfo; // defined in ThreadInfo.h
|
||||
|
||||
typedef struct {
|
||||
EGLThreadInfo* (*getThreadInfo)();
|
||||
} EGLClient_eglInterface;
|
||||
|
||||
typedef struct {
|
||||
void* (*getProcAddress)(const char *funcName);
|
||||
} EGLClient_glesInterface;
|
||||
|
||||
//
|
||||
// Any GLES/GLES2 client API library should define a function named "init_emul_gles"
|
||||
// with the following prototype,
|
||||
// It will be called by EGL after loading the GLES library for initialization
|
||||
// and exchanging interface function pointers.
|
||||
//
|
||||
typedef EGLClient_glesInterface *(*init_emul_gles_t)(EGLClient_eglInterface *eglIface);
|
||||
|
||||
#endif
|
||||
@@ -22,10 +22,11 @@ struct EGLContext_t;
|
||||
|
||||
struct EGLThreadInfo
|
||||
{
|
||||
EGLThreadInfo() : currentContext(NULL), hostConn(NULL) {}
|
||||
EGLThreadInfo() : currentContext(NULL), hostConn(NULL), eglError(0) {}
|
||||
|
||||
EGLContext_t *currentContext;
|
||||
HostConnection *hostConn;
|
||||
int eglError;
|
||||
};
|
||||
|
||||
|
||||
|
||||
50
tools/emulator/opengl/system/egl/Android.mk
Normal file
50
tools/emulator/opengl/system/egl/Android.mk
Normal file
@@ -0,0 +1,50 @@
|
||||
ifneq (,$(BUILD_EMULATOR_OPENGL_DRIVER))
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
emulatorOpengl := $(LOCAL_PATH)/../..
|
||||
|
||||
### EGL implementation ###########################################
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# add additional depencies to ensure that the generated code that we depend on
|
||||
# is generated
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := \
|
||||
$(TARGET_OUT_SHARED_LIBRARIES)/lib_renderControl_enc$(TARGET_SHLIB_SUFFIX) \
|
||||
$(TARGET_OUT_SHARED_LIBRARIES)/libGLESv1_enc$(TARGET_SHLIB_SUFFIX)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
eglDisplay.cpp \
|
||||
egl.cpp
|
||||
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(emulatorOpengl)/host/include/libOpenglRender \
|
||||
$(emulatorOpengl)/shared/OpenglCodecCommon \
|
||||
$(emulatorOpengl)/system/OpenglSystemCommon \
|
||||
$(emulatorOpengl)/system/GLESv1_enc \
|
||||
$(emulatorOpengl)/system/renderControl_enc \
|
||||
$(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_enc) \
|
||||
$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc)
|
||||
|
||||
LOCAL_MODULE_TAGS := debug
|
||||
LOCAL_MODULE := libEGL_emulation
|
||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libOpenglSystemCommon \
|
||||
libOpenglCodecCommon
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
libutils \
|
||||
libdl \
|
||||
libGLESv1_enc \
|
||||
lib_renderControl_enc
|
||||
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
endif # of ifneq (,$(BUILD_EMULATOR_OPENGL_DRIVER))
|
||||
387
tools/emulator/opengl/system/egl/egl.cpp
Normal file
387
tools/emulator/opengl/system/egl/egl.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "HostConnection.h"
|
||||
#include "ThreadInfo.h"
|
||||
#include "eglDisplay.h"
|
||||
#include "egl_ftable.h"
|
||||
#include <cutils/log.h>
|
||||
|
||||
// The one and only supported display object.
|
||||
static eglDisplay s_display;
|
||||
|
||||
static EGLClient_eglInterface s_eglIface = {
|
||||
getThreadInfo: getEGLThreadInfo
|
||||
};
|
||||
|
||||
#define RETURN_ERROR(ret,err) \
|
||||
getEGLThreadInfo()->eglError = err; \
|
||||
return ret;
|
||||
|
||||
#define VALIDATE_CONFIG(cfg,ret) \
|
||||
if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \
|
||||
RETURN_ERROR(ret,EGL_BAD_CONFIG); \
|
||||
}
|
||||
|
||||
#define VALIDATE_DISPLAY(dpy,ret) \
|
||||
if ((dpy) != (EGLDisplay)&s_display) { \
|
||||
getEGLThreadInfo()->eglError = EGL_BAD_DISPLAY; \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define VALIDATE_DISPLAY_INIT(dpy,ret) \
|
||||
VALIDATE_DISPLAY(dpy, ret) \
|
||||
if (!s_display.initialized()) { \
|
||||
getEGLThreadInfo()->eglError = EGL_NOT_INITIALIZED; \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
|
||||
{
|
||||
//
|
||||
// we support only EGL_DEFAULT_DISPLAY.
|
||||
//
|
||||
if (display_id != EGL_DEFAULT_DISPLAY) {
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
return (EGLDisplay)&s_display;
|
||||
}
|
||||
|
||||
EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
||||
{
|
||||
VALIDATE_DISPLAY(dpy,EGL_FALSE);
|
||||
|
||||
if (!s_display.initialize(&s_eglIface)) {
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
*major = s_display.getVersionMajor();
|
||||
*minor = s_display.getVersionMinor();
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean eglTerminate(EGLDisplay dpy)
|
||||
{
|
||||
VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
|
||||
|
||||
s_display.terminate();
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLint eglGetError()
|
||||
{
|
||||
return getEGLThreadInfo()->eglError;
|
||||
}
|
||||
|
||||
__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
|
||||
{
|
||||
// search in EGL function table
|
||||
for (int i=0; i<egl_num_funcs; i++) {
|
||||
if (!strcmp(egl_funcs_by_name[i].name, procname)) {
|
||||
return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure display is initialized before searching in client APIs
|
||||
//
|
||||
if (!s_display.initialized()) {
|
||||
if (!s_display.initialize(&s_eglIface)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// look in gles
|
||||
void *proc = s_display.gles_iface()->getProcAddress( procname );
|
||||
if (proc != NULL) {
|
||||
return (__eglMustCastToProperFunctionPointerType)proc;
|
||||
}
|
||||
|
||||
// look in gles2
|
||||
if (s_display.gles2_iface() != NULL) {
|
||||
proc = s_display.gles2_iface()->getProcAddress( procname );
|
||||
if (proc != NULL) {
|
||||
return (__eglMustCastToProperFunctionPointerType)proc;
|
||||
}
|
||||
}
|
||||
|
||||
// Fail - function not found.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* eglQueryString(EGLDisplay dpy, EGLint name)
|
||||
{
|
||||
VALIDATE_DISPLAY_INIT(dpy, NULL);
|
||||
|
||||
return s_display.queryString(name);
|
||||
}
|
||||
|
||||
EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
|
||||
{
|
||||
VALIDATE_DISPLAY_INIT(dpy, NULL);
|
||||
|
||||
if(!num_config) {
|
||||
RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
GLint numConfigs = s_display.getNumConfigs();
|
||||
if (!configs) {
|
||||
*num_config = numConfigs;
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
int i=0;
|
||||
for (i=0 ; i<numConfigs && i<config_size ; i++) {
|
||||
*configs++ = (EGLConfig)i;
|
||||
}
|
||||
*num_config = i;
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
|
||||
{
|
||||
VALIDATE_DISPLAY_INIT(dpy, NULL);
|
||||
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
|
||||
{
|
||||
VALIDATE_DISPLAY_INIT(dpy, NULL);
|
||||
VALIDATE_CONFIG(config, EGL_FALSE);
|
||||
|
||||
EGLint attribVal = s_display.getConfigAttrib(config, attribute);
|
||||
|
||||
if (attribVal == ATTRIBUTE_NONE) {
|
||||
RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
*value = attribVal;
|
||||
return EGL_TRUE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglBindAPI(EGLenum api)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLenum eglQueryAPI()
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglWaitClient()
|
||||
{ //TODO
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
EGLBoolean eglReleaseThread()
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLContext eglGetCurrentContext()
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLSurface eglGetCurrentSurface(EGLint readdraw)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLDisplay eglGetCurrentDisplay()
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglWaitGL()
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglWaitNative(EGLint engine)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
376
tools/emulator/opengl/system/egl/eglDisplay.cpp
Normal file
376
tools/emulator/opengl/system/egl/eglDisplay.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "eglDisplay.h"
|
||||
#include "HostConnection.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
static const int systemEGLVersionMajor = 1;
|
||||
static const int systemEGLVersionMinor = 4;
|
||||
static const char *systemEGLVendor = "Google Android emulator";
|
||||
|
||||
// list of extensions supported by this EGL implementation
|
||||
// NOTE that each extension name should be suffixed with space
|
||||
static const char *systemStaticEGLExtensions =
|
||||
"EGL_ANDROID_image_native_buffer ";
|
||||
|
||||
// list of extensions supported by this EGL implementation only if supported
|
||||
// on the host implementation.
|
||||
// NOTE that each extension name should be suffixed with space
|
||||
static const char *systemDynamicEGLExtensions =
|
||||
"EGL_KHR_image_base "
|
||||
"EGL_KHR_gl_texture_2d_image ";
|
||||
|
||||
|
||||
static void *s_gles_lib = NULL;
|
||||
static void *s_gles2_lib = NULL;
|
||||
|
||||
// The following function will be called when we (libEGL)
|
||||
// gets unloaded
|
||||
// At this point we want to unload the gles libraries we
|
||||
// might have loaded during initialization
|
||||
static void __attribute__ ((destructor)) do_on_unload(void)
|
||||
{
|
||||
if (s_gles_lib) {
|
||||
dlclose(s_gles_lib);
|
||||
}
|
||||
|
||||
if (s_gles2_lib) {
|
||||
dlclose(s_gles2_lib);
|
||||
}
|
||||
}
|
||||
|
||||
eglDisplay::eglDisplay() :
|
||||
m_initialized(false),
|
||||
m_major(0),
|
||||
m_minor(0),
|
||||
m_hostRendererVersion(0),
|
||||
m_numConfigs(0),
|
||||
m_numConfigAttribs(0),
|
||||
m_attribs(DefaultKeyedVector<EGLint, EGLint>(ATTRIBUTE_NONE)),
|
||||
m_configs(NULL),
|
||||
m_gles_iface(NULL),
|
||||
m_gles2_iface(NULL),
|
||||
m_versionString(NULL),
|
||||
m_vendorString(NULL),
|
||||
m_extensionString(NULL)
|
||||
{
|
||||
pthread_mutex_init(&m_lock, NULL);
|
||||
}
|
||||
|
||||
bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
|
||||
{
|
||||
pthread_mutex_lock(&m_lock);
|
||||
if (!m_initialized) {
|
||||
|
||||
//
|
||||
// load GLES client API
|
||||
//
|
||||
m_gles_iface = loadGLESClientAPI("/system/lib/egl/libGLESv1_CM_emulation.so",
|
||||
eglIface,
|
||||
&s_gles_lib);
|
||||
if (!m_gles_iface) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WITH_GLES2
|
||||
m_gles2_iface = loadGLESClientAPI("/system/lib/egl/libGLESv2_emulation.so",
|
||||
eglIface,
|
||||
&s_gles2_lib);
|
||||
// Note that if loading gles2 failed, we can still run with no
|
||||
// GLES2 support, having GLES2 is not mandatory.
|
||||
#endif
|
||||
|
||||
//
|
||||
// establish connection with the host
|
||||
//
|
||||
HostConnection *hcon = HostConnection::get();
|
||||
if (!hcon) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// get renderControl encoder instance
|
||||
//
|
||||
renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
|
||||
if (!rcEnc) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Query host reneder and EGL version
|
||||
//
|
||||
m_hostRendererVersion = rcEnc->rcGetRendererVersion(rcEnc);
|
||||
EGLint status = rcEnc->rcGetEGLVersion(rcEnc, &m_major, &m_minor);
|
||||
if (status != EGL_TRUE) {
|
||||
// host EGL initialization failed !!
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Take minimum version beween what we support and what the host support
|
||||
//
|
||||
if (m_major > systemEGLVersionMajor) {
|
||||
m_major = systemEGLVersionMajor;
|
||||
m_minor = systemEGLVersionMinor;
|
||||
}
|
||||
else if (m_major == systemEGLVersionMajor &&
|
||||
m_minor > systemEGLVersionMinor) {
|
||||
m_minor = systemEGLVersionMinor;
|
||||
}
|
||||
|
||||
//
|
||||
// Query the host for the set of configs
|
||||
//
|
||||
m_numConfigs = rcEnc->rcGetNumConfigs(rcEnc, (uint32_t*)&m_numConfigAttribs);
|
||||
if (m_numConfigs <= 0 || m_numConfigAttribs <= 0) {
|
||||
// just sanity check - should never happen
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1);
|
||||
EGLint tmp_buf[nInts];
|
||||
m_configs = new EGLint[nInts-1];
|
||||
if (!m_configs) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
//EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), m_configs);
|
||||
EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), (GLuint*)tmp_buf);
|
||||
if (n != m_numConfigs) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Fill the attributes vector.
|
||||
//The first m_numConfigAttribs values of tmp_buf are the actual attributes enums.
|
||||
for (int i=0; i<m_numConfigAttribs; i++)
|
||||
{
|
||||
m_attribs.add(tmp_buf[i], i);
|
||||
}
|
||||
|
||||
//Copy the actual configs data to m_configs
|
||||
memcpy(m_configs, tmp_buf + m_numConfigAttribs*sizeof(EGLint), m_numConfigs*sizeof(EGLint));
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void eglDisplay::terminate()
|
||||
{
|
||||
pthread_mutex_lock(&m_lock);
|
||||
if (m_initialized) {
|
||||
m_initialized = false;
|
||||
delete [] m_configs;
|
||||
m_configs = NULL;
|
||||
|
||||
if (m_versionString) {
|
||||
free(m_versionString);
|
||||
m_versionString = NULL;
|
||||
}
|
||||
if (m_vendorString) {
|
||||
free(m_vendorString);
|
||||
m_vendorString = NULL;
|
||||
}
|
||||
if (m_extensionString) {
|
||||
free(m_extensionString);
|
||||
m_extensionString = NULL;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
}
|
||||
|
||||
EGLClient_glesInterface *eglDisplay::loadGLESClientAPI(const char *libName,
|
||||
EGLClient_eglInterface *eglIface,
|
||||
void **libHandle)
|
||||
{
|
||||
void *lib = dlopen(libName, RTLD_NOW);
|
||||
if (!lib) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
init_emul_gles_t init_gles_func = (init_emul_gles_t)dlsym(lib,"init_emul_gles");
|
||||
if (!init_gles_func) {
|
||||
dlclose((void*)libName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*libHandle = lib;
|
||||
return (*init_gles_func)(eglIface);
|
||||
}
|
||||
|
||||
static char *queryHostEGLString(EGLint name)
|
||||
{
|
||||
HostConnection *hcon = HostConnection::get();
|
||||
if (hcon) {
|
||||
renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
|
||||
if (rcEnc) {
|
||||
int n = rcEnc->rcQueryEGLString(rcEnc, name, NULL, 0);
|
||||
if (n < 0) {
|
||||
// allocate space for the string with additional
|
||||
// space charachter to be suffixed at the end.
|
||||
char *str = (char *)malloc(-n+2);
|
||||
n = rcEnc->rcQueryEGLString(rcEnc, name, str, -n);
|
||||
if (n > 0) {
|
||||
// add extra space at end of string which will be
|
||||
// needed later when filtering the extension list.
|
||||
strcat(str, " ");
|
||||
return str;
|
||||
}
|
||||
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool findExtInList(const char* token, int tokenlen, const char* list)
|
||||
{
|
||||
const char* p = list;
|
||||
while (*p != '\0') {
|
||||
const char* q = strchr(p, ' ');
|
||||
if (q == NULL) {
|
||||
/* should not happen, list must be space-terminated */
|
||||
break;
|
||||
}
|
||||
if (tokenlen == (q - p) && !memcmp(token, p, tokenlen)) {
|
||||
return true; /* found it */
|
||||
}
|
||||
p = q+1;
|
||||
}
|
||||
return false; /* not found */
|
||||
}
|
||||
|
||||
static char *buildExtensionString()
|
||||
{
|
||||
//Query host extension string
|
||||
char *hostExt = queryHostEGLString(EGL_EXTENSIONS);
|
||||
if (!hostExt || (hostExt[1] == '\0')) {
|
||||
// no extensions on host - only static extension list supported
|
||||
return strdup(systemStaticEGLExtensions);
|
||||
}
|
||||
|
||||
//
|
||||
// Filter host extension list to include only extensions
|
||||
// we can support (in the systemDynamicEGLExtensions list)
|
||||
//
|
||||
char *ext = (char *)hostExt;
|
||||
char *c = ext;
|
||||
char *insert = ext;
|
||||
while(*c != '\0') {
|
||||
if (*c == ' ') {
|
||||
int len = c - ext;
|
||||
if (findExtInList(ext, len, systemDynamicEGLExtensions)) {
|
||||
if (ext != insert) {
|
||||
memcpy(insert, ext, len+1); // including space
|
||||
}
|
||||
insert += (len + 1);
|
||||
}
|
||||
ext = c + 1;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
*insert = '\0';
|
||||
|
||||
int n = strlen(hostExt);
|
||||
if (n > 0) {
|
||||
char *str;
|
||||
asprintf(&str,"%s%s", systemStaticEGLExtensions, hostExt);
|
||||
free((char*)hostExt);
|
||||
return str;
|
||||
}
|
||||
else {
|
||||
free((char*)hostExt);
|
||||
return strdup(systemStaticEGLExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
const char *eglDisplay::queryString(EGLint name)
|
||||
{
|
||||
if (name == EGL_CLIENT_APIS) {
|
||||
return "OpenGL_ES";
|
||||
}
|
||||
else if (name == EGL_VERSION) {
|
||||
pthread_mutex_lock(&m_lock);
|
||||
if (m_versionString) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return m_versionString;
|
||||
}
|
||||
|
||||
// build version string
|
||||
asprintf(&m_versionString, "%d.%d", m_major, m_minor);
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
|
||||
return m_versionString;
|
||||
}
|
||||
else if (name == EGL_VENDOR) {
|
||||
pthread_mutex_lock(&m_lock);
|
||||
if (m_vendorString) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return m_vendorString;
|
||||
}
|
||||
|
||||
// build vendor string
|
||||
const char *hostVendor = queryHostEGLString(EGL_VENDOR);
|
||||
|
||||
if (hostVendor) {
|
||||
asprintf(&m_vendorString, "%s Host: %s",
|
||||
systemEGLVendor, hostVendor);
|
||||
free((char*)hostVendor);
|
||||
}
|
||||
else {
|
||||
m_vendorString = (char *)systemEGLVendor;
|
||||
}
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
|
||||
return m_vendorString;
|
||||
}
|
||||
else if (name == EGL_EXTENSIONS) {
|
||||
pthread_mutex_lock(&m_lock);
|
||||
if (m_extensionString) {
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
return m_extensionString;
|
||||
}
|
||||
|
||||
// build extension string
|
||||
m_extensionString = buildExtensionString();
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
|
||||
return m_extensionString;
|
||||
}
|
||||
else {
|
||||
LOGE("[%s] Unknown name %d\n", __FUNCTION__, name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EGLint eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib)
|
||||
{
|
||||
EGLint attrIdx = m_attribs.valueFor(attrib);
|
||||
|
||||
if (attrIdx == ATTRIBUTE_NONE) return ATTRIBUTE_NONE;
|
||||
else return *(m_configs + (int)config*m_numConfigAttribs + attrIdx);
|
||||
}
|
||||
71
tools/emulator/opengl/system/egl/eglDisplay.h
Normal file
71
tools/emulator/opengl/system/egl/eglDisplay.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef _SYSTEM_EGL_DISPLAY_H
|
||||
#define _SYSTEM_EGL_DISPLAY_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include "EGLClientIface.h"
|
||||
#include <utils/KeyedVector.h>
|
||||
|
||||
#define ATTRIBUTE_NONE -1
|
||||
//FIXME: are we in this namespace?
|
||||
using namespace android;
|
||||
|
||||
class eglDisplay
|
||||
{
|
||||
public:
|
||||
eglDisplay();
|
||||
|
||||
bool initialize(EGLClient_eglInterface *eglIface);
|
||||
void terminate();
|
||||
|
||||
int getVersionMajor() const { return m_major; }
|
||||
int getVersionMinor() const { return m_minor; }
|
||||
bool initialized() const { return m_initialized; }
|
||||
|
||||
const char *queryString(EGLint name);
|
||||
|
||||
const EGLClient_glesInterface *gles_iface() const { return m_gles_iface; }
|
||||
const EGLClient_glesInterface *gles2_iface() const { return m_gles2_iface; }
|
||||
|
||||
int getNumConfigs(){ return m_numConfigs; }
|
||||
EGLint getConfigAttrib(EGLConfig config, EGLint attrib);
|
||||
|
||||
private:
|
||||
EGLClient_glesInterface *loadGLESClientAPI(const char *libName,
|
||||
EGLClient_eglInterface *eglIface,
|
||||
void **libHandle);
|
||||
|
||||
private:
|
||||
pthread_mutex_t m_lock;
|
||||
bool m_initialized;
|
||||
int m_major;
|
||||
int m_minor;
|
||||
int m_hostRendererVersion;
|
||||
int m_numConfigs;
|
||||
int m_numConfigAttribs;
|
||||
DefaultKeyedVector<EGLint, EGLint> m_attribs;
|
||||
EGLint *m_configs;
|
||||
EGLClient_glesInterface *m_gles_iface;
|
||||
EGLClient_glesInterface *m_gles2_iface;
|
||||
char *m_versionString;
|
||||
char *m_vendorString;
|
||||
char *m_extensionString;
|
||||
};
|
||||
|
||||
#endif
|
||||
66
tools/emulator/opengl/system/egl/egl_ftable.h
Normal file
66
tools/emulator/opengl/system/egl/egl_ftable.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
static struct _egl_funcs_by_name {
|
||||
const char *name;
|
||||
void *proc;
|
||||
} egl_funcs_by_name[] = {
|
||||
{"eglGetError", (void *)eglGetError},
|
||||
{"eglGetDisplay", (void *)eglGetDisplay},
|
||||
{"eglInitialize", (void *)eglInitialize},
|
||||
{"eglTerminate", (void *)eglTerminate},
|
||||
{"eglQueryString", (void *)eglQueryString},
|
||||
{"eglGetConfigs", (void *)eglGetConfigs},
|
||||
{"eglChooseConfig", (void *)eglChooseConfig},
|
||||
{"eglGetConfigAttrib", (void *)eglGetConfigAttrib},
|
||||
{"eglCreateWindowSurface", (void *)eglCreateWindowSurface},
|
||||
{"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface},
|
||||
{"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface},
|
||||
{"eglDestroySurface", (void *)eglDestroySurface},
|
||||
{"eglQuerySurface", (void *)eglQuerySurface},
|
||||
{"eglBindAPI", (void *)eglBindAPI},
|
||||
{"eglQueryAPI", (void *)eglQueryAPI},
|
||||
{"eglWaitClient", (void *)eglWaitClient},
|
||||
{"eglReleaseThread", (void *)eglReleaseThread},
|
||||
{"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer},
|
||||
{"eglSurfaceAttrib", (void *)eglSurfaceAttrib},
|
||||
{"eglBindTexImage", (void *)eglBindTexImage},
|
||||
{"eglReleaseTexImage", (void *)eglReleaseTexImage},
|
||||
{"eglSwapInterval", (void *)eglSwapInterval},
|
||||
{"eglCreateContext", (void *)eglCreateContext},
|
||||
{"eglDestroyContext", (void *)eglDestroyContext},
|
||||
{"eglMakeCurrent", (void *)eglMakeCurrent},
|
||||
{"eglGetCurrentContext", (void *)eglGetCurrentContext},
|
||||
{"eglGetCurrentSurface", (void *)eglGetCurrentSurface},
|
||||
{"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay},
|
||||
{"eglQueryContext", (void *)eglQueryContext},
|
||||
{"eglWaitGL", (void *)eglWaitGL},
|
||||
{"eglWaitNative", (void *)eglWaitNative},
|
||||
{"eglSwapBuffers", (void *)eglSwapBuffers},
|
||||
{"eglCopyBuffers", (void *)eglCopyBuffers},
|
||||
{"eglGetProcAddress", (void *)eglGetProcAddress},
|
||||
{"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR},
|
||||
{"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR},
|
||||
{"eglCreateImageKHR", (void *)eglCreateImageKHR},
|
||||
{"eglDestroyImageKHR", (void *)eglDestroyImageKHR},
|
||||
{"eglCreateSyncKHR", (void *)eglCreateSyncKHR},
|
||||
{"eglDestroySyncKHR", (void *)eglDestroySyncKHR},
|
||||
{"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR},
|
||||
{"eglSignalSyncKHR", (void *)eglSignalSyncKHR},
|
||||
{"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR},
|
||||
{"eglSetSwapRectangleANDROID", (void *)eglSetSwapRectangleANDROID}
|
||||
};
|
||||
|
||||
static int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);
|
||||
Reference in New Issue
Block a user