emulator opengl: pool of fixups to the system components.

Those fixes make the system load without failure.
Also the flinger and bootanimation are running.

Change-Id: Ieb7039e76c444df778a421a07bccc48514199245
This commit is contained in:
Stas Gurtovoy
2011-05-31 15:06:07 +03:00
committed by Guy Zadickario
parent 2220d27302
commit 6a79e88f01
21 changed files with 397 additions and 116 deletions

View File

@@ -26,12 +26,12 @@ LOCAL_C_INCLUDES += \
$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc) $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc)
LOCAL_MODULE_TAGS := debug LOCAL_MODULE_TAGS := debug
LOCAL_MODULE := libGL_emulation LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
LOCAL_MODULE := libGLESv1_CM_emulation
LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_STATIC_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \
libOpenglSystemCommon \
libOpenglCodecCommon \ libOpenglCodecCommon \
libqemu libqemu
@@ -39,6 +39,7 @@ LOCAL_SHARED_LIBRARIES := \
libcutils \ libcutils \
libutils \ libutils \
libdl \ libdl \
libOpenglSystemCommon \
libGLESv1_enc \ libGLESv1_enc \
lib_renderControl_enc lib_renderControl_enc

View File

@@ -3,6 +3,10 @@
#include "GLEncoder.h" #include "GLEncoder.h"
#include "GLES/gl.h" #include "GLES/gl.h"
#include "GLES/glext.h" #include "GLES/glext.h"
#include "ErrorLog.h"
#include <private/ui/android_natives_priv.h>
#include "gralloc_cb.h"
//XXX: fix this macro to get the context from fast tls path //XXX: fix this macro to get the context from fast tls path
#define GET_CONTEXT gl_client_context_t * ctx = HostConnection::get()->glEncoder(); #define GET_CONTEXT gl_client_context_t * ctx = HostConnection::get()->glEncoder();
@@ -15,6 +19,39 @@
static EGLClient_eglInterface * s_egl = NULL; static EGLClient_eglInterface * s_egl = NULL;
static EGLClient_glesInterface * s_gl = NULL; static EGLClient_glesInterface * s_gl = NULL;
#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
HostConnection *hostCon = HostConnection::get(); \
if (!hostCon) { \
LOGE("egl: Failed to get host connection\n"); \
return ret; \
} \
renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
if (!rcEnc) { \
LOGE("egl: Failed to get renderControl encoder context\n"); \
return ret; \
}
//GL extensions
void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image)
{
DBG("glEGLImageTargetTexture2DOES");
//TODO: check error - we don't have a way to set gl error
android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
return;
}
if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
return;
}
DEFINE_AND_VALIDATE_HOST_CONNECTION();
rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle);
return;
}
void * getProcAddress(const char * procname) void * getProcAddress(const char * procname)
{ {
// search in GL function table // search in GL function table
@@ -31,6 +68,13 @@ void finish()
glFinish(); glFinish();
} }
void init()
{
GET_CONTEXT;
ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES);
}
extern "C" {
EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface) EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface)
{ {
s_egl = eglIface; s_egl = eglIface;
@@ -39,8 +83,11 @@ EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface)
s_gl = new EGLClient_glesInterface(); s_gl = new EGLClient_glesInterface();
s_gl->getProcAddress = getProcAddress; s_gl->getProcAddress = getProcAddress;
s_gl->finish = finish; s_gl->finish = finish;
s_gl->init = init;
} }
return s_gl; return s_gl;
} }
} //extern

View File

@@ -19,19 +19,16 @@ LOCAL_PRELINK_MODULE := false
LOCAL_CFLAGS += -DLOG_TAG=\"egl_GLESv1_enc\" LOCAL_CFLAGS += -DLOG_TAG=\"egl_GLESv1_enc\"
LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES += \
$(emulatorOpengl)/shared/OpenglCodecCommon \ $(emulatorOpengl)/shared/OpenglCodecCommon \
$(emulatorOpengl)/system/OpenglSystemCommon \
$(emulatorOpengl)/host/include/libOpenglRender \ $(emulatorOpengl)/host/include/libOpenglRender \
$(emulatorOpengl)/system/renderControl_enc \ $(emulatorOpengl)/system/renderControl_enc \
$(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_enc) \ $(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_enc) \
$(glesv1_intermediates) $(glesv1_intermediates)
LOCAL_STATIC_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \
libOpenglSystemCommon \
libOpenglCodecCommon \ libOpenglCodecCommon \
libqemu libqemu
LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \
lib_renderControl_enc \
libcutils libcutils
EMUGEN := $(HOST_OUT_EXECUTABLES)/emugen EMUGEN := $(HOST_OUT_EXECUTABLES)/emugen

View File

@@ -16,10 +16,6 @@
#include "GLEncoder.h" #include "GLEncoder.h"
#include "glUtils.h" #include "glUtils.h"
#include "FixedBuffer.h" #include "FixedBuffer.h"
#include "HostConnection.h"
#include <private/ui/android_natives_priv.h>
#include "gralloc_cb.h"
#include <cutils/log.h> #include <cutils/log.h>
#include <assert.h> #include <assert.h>
@@ -154,7 +150,7 @@ void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value)
{ {
GLEncoder *ctx = (GLEncoder *)self; GLEncoder *ctx = (GLEncoder *)self;
ctx->m_glPixelStorei_enc(ctx, param, value); ctx->m_glPixelStorei_enc(ctx, param, value);
assert(ctx->m_state != NULL); LOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei");
ctx->m_state->setPixelStore(param, value); ctx->m_state->setPixelStore(param, value);
} }
@@ -455,6 +451,7 @@ void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum
GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream) GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
{ {
m_initialized = false;
m_state = NULL; m_state = NULL;
m_compressedTextureFormats = NULL; m_compressedTextureFormats = NULL;
// overrides; // overrides;
@@ -483,7 +480,6 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
set_glGetString(s_glGetString); set_glGetString(s_glGetString);
set_glFinish(s_glFinish); set_glFinish(s_glFinish);
set_glEGLImageTargetTexture2DOES(s_glEGLImageTargetTexture2DOES);
} }
@@ -504,21 +500,3 @@ void GLEncoder::s_glFinish(void *self)
ctx->glFinishRoundTrip(self); ctx->glFinishRoundTrip(self);
} }
void GLEncoder::s_glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image)
{
//TODO: check error - we don't have a way to set gl error
android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
return;
}
if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
return;
}
DEFINE_AND_VALIDATE_HOST_CONNECTION();
rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle);
return;
}

View File

@@ -30,8 +30,13 @@ public:
} }
void flush() { m_stream->flush(); } void flush() { m_stream->flush(); }
size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack); size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack);
void setInitialized(){ m_initialized = true; };
bool isInitialized(){ return m_initialized; };
private: private:
bool m_initialized;
GLClientState *m_state; GLClientState *m_state;
FixedBuffer m_fixedBuffer; FixedBuffer m_fixedBuffer;
GLint *m_compressedTextureFormats; GLint *m_compressedTextureFormats;

View File

@@ -23,7 +23,19 @@ LOCAL_C_INCLUDES += \
$(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_enc) \ $(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_enc) \
$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc) $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc)
LOCAL_STATIC_LIBRARIES := \
libOpenglCodecCommon \
libqemu
LOCAL_SHARED_LIBRARIES := \
lib_renderControl_enc \
libGLESv1_enc \
libcutils \
libutils
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS := debug LOCAL_MODULE_TAGS := debug
LOCAL_MODULE := libOpenglSystemCommon LOCAL_MODULE := libOpenglSystemCommon
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
include $(BUILD_STATIC_LIBRARY) include $(BUILD_SHARED_LIBRARY)

View File

@@ -9,6 +9,7 @@ typedef struct {
typedef struct { typedef struct {
void* (*getProcAddress)(const char *funcName); void* (*getProcAddress)(const char *funcName);
void (*init)();
void (*finish)(); void (*finish)();
} EGLClient_glesInterface; } EGLClient_glesInterface;

View File

@@ -20,7 +20,7 @@
#include <cutils/log.h> #include <cutils/log.h>
#define STREAM_BUFFER_SIZE 4*1024*1024 #define STREAM_BUFFER_SIZE 4*1024*1024
#define STREAM_PORT_NUM 4141 #define STREAM_PORT_NUM 22468
/* Set to 1 to use a QEMU pipe, or 0 for a TCP connection */ /* Set to 1 to use a QEMU pipe, or 0 for a TCP connection */
#define USE_QEMU_PIPE 1 #define USE_QEMU_PIPE 1
@@ -56,6 +56,22 @@ HostConnection *HostConnection::get()
return NULL; return NULL;
} }
#if 0
TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE);
if (stream) {
if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) {
LOGE("Failed to connect to host (TcpStream)!!!\n");
delete stream;
stream = NULL;
}
else {
con->m_stream = stream;
LOGE("Established TCP connection with HOST\n");
}
}
if (!stream)
#endif
if (useQemuPipe) { if (useQemuPipe) {
QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE); QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE);
if (!stream) { if (!stream) {
@@ -64,7 +80,7 @@ HostConnection *HostConnection::get()
return NULL; return NULL;
} }
if (stream->connect() < 0) { if (stream->connect() < 0) {
LOGE("Failed to connect to host !!!\n"); LOGE("Failed to connect to host (QemuPipeStream)!!!\n");
delete con; delete con;
return NULL; return NULL;
} }
@@ -80,13 +96,13 @@ HostConnection *HostConnection::get()
} }
if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) { if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) {
LOGE("Failed to connect to host !!!\n"); LOGE("Failed to connect to host (TcpStream)!!!\n");
delete con; delete con;
return NULL; return NULL;
} }
con->m_stream = stream; con->m_stream = stream;
} }
LOGD("Host Connection established \n"); LOGD("HostConnection::get() New Host Connection established %p, tid %d\n", con, gettid());
tinfo->hostConn = con; tinfo->hostConn = con;
} }
@@ -97,6 +113,7 @@ GLEncoder *HostConnection::glEncoder()
{ {
if (!m_glEnc) { if (!m_glEnc) {
m_glEnc = new GLEncoder(m_stream); m_glEnc = new GLEncoder(m_stream);
DBG("HostConnection::glEncoder new encoder %p, tid %d", m_glEnc, gettid());
m_glEnc->setContextAccessor(s_getGLContext); m_glEnc->setContextAccessor(s_getGLContext);
} }
return m_glEnc; return m_glEnc;

View File

@@ -84,6 +84,7 @@ int QemuPipeStream::commitBuffer(size_t size)
int QemuPipeStream::writeFully(const void *buf, size_t len) int QemuPipeStream::writeFully(const void *buf, size_t len)
{ {
//DBG(">> QemuPipeStream::writeFully %d\n", len);
if (!valid()) return -1; if (!valid()) return -1;
size_t res = len; size_t res = len;
@@ -107,11 +108,13 @@ int QemuPipeStream::writeFully(const void *buf, size_t len)
ERR("QemuPipeStream::writeFully failed: %s\n", strerror(errno)); ERR("QemuPipeStream::writeFully failed: %s\n", strerror(errno));
break; break;
} }
//DBG("<< QemuPipeStream::writeFully %d\n", len );
return retval; return retval;
} }
const unsigned char *QemuPipeStream::readFully(void *buf, size_t len) const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
{ {
//DBG(">> QemuPipeStream::readFully %d\n", len);
if (!valid()) return NULL; if (!valid()) return NULL;
if (!buf) { if (!buf) {
ERR("QemuPipeStream::readFully failed, buf=NULL"); ERR("QemuPipeStream::readFully failed, buf=NULL");
@@ -135,11 +138,13 @@ const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
res -= stat; res -= stat;
} }
} }
//DBG("<< QemuPipeStream::readFully %d\n", len);
return (const unsigned char *)buf; return (const unsigned char *)buf;
} }
const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len) const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len)
{ {
//DBG(">> QemuPipeStream::read %d\n", *inout_len);
if (!valid()) return NULL; if (!valid()) return NULL;
if (!buf) { if (!buf) {
ERR("QemuPipeStream::read failed, buf=NULL"); ERR("QemuPipeStream::read failed, buf=NULL");
@@ -153,6 +158,7 @@ const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len)
return (const unsigned char *)buf; return (const unsigned char *)buf;
} }
//DBG("<< QemuPipeStream::read %d\n", *inout_len);
return NULL; return NULL;
} }

View File

@@ -6,7 +6,7 @@
#include <cutils/native_handle.h> #include <cutils/native_handle.h>
#define BUFFER_HANDLE_MAGIC ((int)0xabfabfab) #define BUFFER_HANDLE_MAGIC ((int)0xabfabfab)
#define CB_HANDLE_NUM_INTS(nfds) ((sizeof(cb_handle_t) - (nfds)*sizeof(int)) / sizeof(int)) #define CB_HANDLE_NUM_INTS(nfds) (int)((sizeof(cb_handle_t) - (nfds)*sizeof(int)) / sizeof(int))
// //
// Our buffer handle structure // Our buffer handle structure
@@ -32,7 +32,7 @@ struct cb_handle_t : public native_handle {
hostHandle(0) hostHandle(0)
{ {
version = sizeof(native_handle); version = sizeof(native_handle);
numFds = 1; numFds = 0;
numInts = CB_HANDLE_NUM_INTS(numFds); numInts = CB_HANDLE_NUM_INTS(numFds);
} }
@@ -40,11 +40,21 @@ struct cb_handle_t : public native_handle {
magic = 0; magic = 0;
} }
void setFd(int p_fd) {
if (p_fd >= 0) {
numFds = 1;
}
else {
numFds = 0;
}
fd = p_fd;
numInts = CB_HANDLE_NUM_INTS(numFds);
}
bool validate() const { bool validate() const {
return (version == sizeof(native_handle) && return (version == sizeof(native_handle) &&
magic == BUFFER_HANDLE_MAGIC && magic == BUFFER_HANDLE_MAGIC &&
numInts == CB_HANDLE_NUM_INTS(1) && numInts == CB_HANDLE_NUM_INTS(numFds));
numFds == 1);
} }
bool canBePosted() { bool canBePosted() {

View File

@@ -29,12 +29,12 @@ LOCAL_C_INCLUDES += \
$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc) $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc)
LOCAL_MODULE_TAGS := debug LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
LOCAL_MODULE := libEGL_emulation LOCAL_MODULE := libEGL_emulation
LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PRELINK_MODULE := false
LOCAL_STATIC_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \
libOpenglSystemCommon \
libOpenglCodecCommon \ libOpenglCodecCommon \
libqemu libqemu
@@ -43,9 +43,29 @@ LOCAL_SHARED_LIBRARIES := \
libutils \ libutils \
libdl \ libdl \
libGLESv1_enc \ libGLESv1_enc \
libOpenglSystemCommon \
lib_renderControl_enc lib_renderControl_enc
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
#### egl.cfg ####
# Ensure that this file is only copied to emulator-specific builds.
# Other builds are device-specific and will provide their own
# version of this file to point to the appropriate HW EGL libraries.
#
ifneq (,$(filter full full_x86 sdk sdk_x86,$(TARGET_PRODUCT)))
include $(CLEAR_VARS)
LOCAL_MODULE := egl.cfg
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_CLASS := ETC
include $(BUILD_PREBUILT)
endif # TARGET_PRODUCT in 'full sdk full_x86 sdk_x86'
endif # of ifneq (,$(BUILD_EMULATOR_OPENGL_DRIVER)) endif # of ifneq (,$(BUILD_EMULATOR_OPENGL_DRIVER))

View File

@@ -0,0 +1 @@
0 0 emulation

View File

@@ -19,19 +19,63 @@
#include "egl_ftable.h" #include "egl_ftable.h"
#include <cutils/log.h> #include <cutils/log.h>
#include "gralloc_cb.h" #include "gralloc_cb.h"
#include "GLClientState.h"
#include <private/ui/android_natives_priv.h> #include <private/ui/android_natives_priv.h>
template<typename T> template<typename T>
static T setError(GLint error, T returnValue) { static T setErrorFunc(GLint error, T returnValue) {
getEGLThreadInfo()->eglError = error; getEGLThreadInfo()->eglError = error;
return returnValue; return returnValue;
} }
const char * eglStrError(EGLint err)
{
switch (err){
case EGL_SUCCESS: return "EGL_SUCCESS";
case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
default: return "UNKNOWN";
}
}
#define LOG_EGL_ERRORS 1
#ifdef LOG_EGL_ERRORS
#define setErrorReturn(error, retVal) \
{ \
LOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error)); \
return setErrorFunc(error, retVal); \
}
#define RETURN_ERROR(ret,err) \
LOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err)); \
getEGLThreadInfo()->eglError = err; \
return ret;
#else //!LOG_EGL_ERRORS
#define setErrorReturn(error, retVal) return setErrorFunc(error, retVal);
#define RETURN_ERROR(ret,err) \ #define RETURN_ERROR(ret,err) \
getEGLThreadInfo()->eglError = err; \ getEGLThreadInfo()->eglError = err; \
return ret; return ret;
#endif //LOG_EGL_ERRORS
#define VALIDATE_CONFIG(cfg,ret) \ #define VALIDATE_CONFIG(cfg,ret) \
if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \ if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \
RETURN_ERROR(ret,EGL_BAD_CONFIG); \ RETURN_ERROR(ret,EGL_BAD_CONFIG); \
@@ -39,15 +83,13 @@ static T setError(GLint error, T returnValue) {
#define VALIDATE_DISPLAY(dpy,ret) \ #define VALIDATE_DISPLAY(dpy,ret) \
if ((dpy) != (EGLDisplay)&s_display) { \ if ((dpy) != (EGLDisplay)&s_display) { \
getEGLThreadInfo()->eglError = EGL_BAD_DISPLAY; \ RETURN_ERROR(ret, EGL_BAD_DISPLAY); \
return ret; \
} }
#define VALIDATE_DISPLAY_INIT(dpy,ret) \ #define VALIDATE_DISPLAY_INIT(dpy,ret) \
VALIDATE_DISPLAY(dpy, ret) \ VALIDATE_DISPLAY(dpy, ret) \
if (!s_display.initialized()) { \ if (!s_display.initialized()) { \
getEGLThreadInfo()->eglError = EGL_NOT_INITIALIZED; \ RETURN_ERROR(ret, EGL_NOT_INITIALIZED); \
return ret; \
} }
#define DEFINE_HOST_CONNECTION \ #define DEFINE_HOST_CONNECTION \
@@ -75,9 +117,9 @@ static T setError(GLint error, T returnValue) {
if (surface != EGL_NO_SURFACE) { \ if (surface != EGL_NO_SURFACE) { \
egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \ egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \
if (!s->isValid()) \ if (!s->isValid()) \
return setError(EGL_BAD_SURFACE, EGL_FALSE); \ setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); \
if (s->dpy != (EGLDisplay)&s_display) \ if (s->dpy != (EGLDisplay)&s_display) \
return setError(EGL_BAD_DISPLAY, EGL_FALSE); \ setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); \
} }
@@ -91,13 +133,8 @@ struct EGLContext_t {
NEVER_CURRENT = 0x00020000 NEVER_CURRENT = 0x00020000
}; };
EGLContext_t(EGLDisplay dpy, EGLConfig config) : dpy(dpy), config(config), EGLContext_t(EGLDisplay dpy, EGLConfig config);
read(EGL_NO_SURFACE), draw(EGL_NO_SURFACE), ~EGLContext_t();
rcContext(0) {
flags = 0;
version = 1;
};
~EGLContext_t(){};
uint32_t flags; uint32_t flags;
EGLDisplay dpy; EGLDisplay dpy;
EGLConfig config; EGLConfig config;
@@ -105,8 +142,24 @@ struct EGLContext_t {
EGLSurface draw; EGLSurface draw;
EGLint version; EGLint version;
uint32_t rcContext; uint32_t rcContext;
GLClientState * getClientState(){ return clientState; }
private:
GLClientState * clientState;
}; };
EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) : dpy(dpy), config(config),
read(EGL_NO_SURFACE), draw(EGL_NO_SURFACE), rcContext(0)
{
flags = 0;
version = 1;
clientState = new GLClientState();
};
EGLContext_t::~EGLContext_t()
{
if (clientState) delete clientState;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
//egl_surface_t //egl_surface_t
@@ -127,6 +180,7 @@ struct egl_surface_t {
virtual EGLBoolean connect() { return EGL_TRUE; } virtual EGLBoolean connect() { return EGL_TRUE; }
virtual void disconnect() {} virtual void disconnect() {}
virtual EGLBoolean swapBuffers() { return EGL_TRUE; } virtual EGLBoolean swapBuffers() { return EGL_TRUE; }
virtual EGLint getSwapBehavior() const;
void setRcSurface(uint32_t handle){ rcSurface = handle; } void setRcSurface(uint32_t handle){ rcSurface = handle; }
uint32_t getRcSurface(){ return rcSurface; } uint32_t getRcSurface(){ return rcSurface; }
@@ -169,6 +223,10 @@ egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceTyp
texTarget = EGL_NO_TEXTURE; texTarget = EGL_NO_TEXTURE;
} }
EGLint egl_surface_t::getSwapBehavior() const {
return EGL_BUFFER_PRESERVED;
}
egl_surface_t::~egl_surface_t() egl_surface_t::~egl_surface_t()
{ {
} }
@@ -221,7 +279,7 @@ egl_window_surface_t::~egl_window_surface_t() {
EGLBoolean egl_window_surface_t::rcCreate() EGLBoolean egl_window_surface_t::rcCreate()
{ {
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
uint32_t rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, getWidth(), getHeight()); rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, getWidth(), getHeight());
if (!rcSurface) { if (!rcSurface) {
LOGE("rcCreateWindowSurface returned 0"); LOGE("rcCreateWindowSurface returned 0");
return EGL_FALSE; return EGL_FALSE;
@@ -248,7 +306,7 @@ EGLBoolean egl_window_surface_t::connect()
{ {
// dequeue a buffer // dequeue a buffer
if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) {
return setError(EGL_BAD_ALLOC, EGL_FALSE); setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
} }
buffer->common.incRef(&buffer->common); buffer->common.incRef(&buffer->common);
@@ -270,17 +328,19 @@ void egl_window_surface_t::disconnect()
EGLBoolean egl_window_surface_t::swapBuffers() EGLBoolean egl_window_surface_t::swapBuffers()
{ {
if (!buffer) { if (!buffer) {
return setError(EGL_BAD_ACCESS, EGL_FALSE); setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
//post the back buffer //post the back buffer
nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->queueBuffer(nativeWindow, buffer);
// dequeue a new buffer // dequeue a new buffer
if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) { if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) {
return setError(EGL_BAD_ALLOC, EGL_FALSE); setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
} }
rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle); rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle);
@@ -374,6 +434,8 @@ static eglDisplay s_display;
static EGLClient_eglInterface s_eglIface = { static EGLClient_eglInterface s_eglIface = {
getThreadInfo: getEGLThreadInfo getThreadInfo: getEGLThreadInfo
}; };
#define DBG_FUNC DBG("%s\n", __FUNCTION__)
EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
{ {
// //
@@ -492,7 +554,7 @@ EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
*num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size, (uint32_t*)configs, config_size); *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)configs, config_size*sizeof(EGLint));
return EGL_TRUE; return EGL_TRUE;
} }
@@ -517,27 +579,27 @@ EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWin
VALIDATE_DISPLAY_INIT(dpy, NULL); VALIDATE_DISPLAY_INIT(dpy, NULL);
VALIDATE_CONFIG(config, EGL_FALSE); VALIDATE_CONFIG(config, EGL_FALSE);
if (win == 0) { if (win == 0) {
return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
} }
EGLint surfaceType; EGLint surfaceType;
if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE;
if (!(surfaceType & EGL_WINDOW_BIT)) { if (!(surfaceType & EGL_WINDOW_BIT)) {
return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
} }
if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
} }
egl_surface_t* surface; egl_surface_t* surface;
surface = new egl_window_surface_t(&s_display, config, surfaceType, static_cast<ANativeWindow*>(win)); surface = new egl_window_surface_t(&s_display, config, surfaceType, static_cast<ANativeWindow*>(win));
if (!surface) if (!surface)
return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
if (!surface->rcCreate()) { if (!surface->rcCreate()) {
delete surface; delete surface;
return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
} }
return surface; return surface;
@@ -552,7 +614,7 @@ EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLin
if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE;
if (!(surfaceType & EGL_PBUFFER_BIT)) { if (!(surfaceType & EGL_PBUFFER_BIT)) {
return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
} }
int32_t w = 0; int32_t w = 0;
@@ -580,20 +642,20 @@ EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLin
} }
if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) || if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) ||
((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) { ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) {
return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
} }
// TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage
GLenum pixelFormat; GLenum pixelFormat;
if (s_display.getConfigPixelFormat(config, &pixelFormat) == EGL_FALSE) if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE)
return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
egl_surface_t* surface = new egl_pbuffer_surface_t(dpy, config, surfaceType, w, h, pixelFormat); egl_surface_t* surface = new egl_pbuffer_surface_t(dpy, config, surfaceType, w, h, pixelFormat);
if (!surface) if (!surface)
return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
if (!surface->rcCreate()) { if (!surface->rcCreate()) {
delete surface; delete surface;
return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
} }
//setup attributes //setup attributes
@@ -650,9 +712,13 @@ EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribu
case EGL_TEXTURE_TARGET: case EGL_TEXTURE_TARGET:
*value = surface->getTextureTarget(); *value = surface->getTextureTarget();
break; break;
case EGL_SWAP_BEHAVIOR:
*value = surface->getSwapBehavior();
break;
//TODO: complete other attributes //TODO: complete other attributes
default: default:
ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE); LOGE("eglQuerySurface %x EGL_BAD_ATTRIBUTE", attribute);
ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE);
break; break;
} }
@@ -662,7 +728,7 @@ EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribu
EGLBoolean eglBindAPI(EGLenum api) EGLBoolean eglBindAPI(EGLenum api)
{ {
if (api != EGL_OPENGL_ES_API) if (api != EGL_OPENGL_ES_API)
return setError(EGL_BAD_PARAMETER, EGL_FALSE); setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
return EGL_TRUE; return EGL_TRUE;
} }
@@ -704,21 +770,21 @@ EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer)
VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
if (eglSurface == EGL_NO_SURFACE) { if (eglSurface == EGL_NO_SURFACE) {
return setError(EGL_BAD_SURFACE, EGL_FALSE); setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
} }
if (buffer != EGL_BACK_BUFFER) { if (buffer != EGL_BACK_BUFFER) {
return setError(EGL_BAD_PARAMETER, EGL_FALSE); setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
} }
egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
if (surface->getTextureFormat() == EGL_NO_TEXTURE) { if (surface->getTextureFormat() == EGL_NO_TEXTURE) {
return setError(EGL_BAD_MATCH, EGL_FALSE); setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
} }
if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) { if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) {
return setError(EGL_BAD_SURFACE, EGL_FALSE); setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
} }
//It's now safe to cast to pbuffer surface //It's now safe to cast to pbuffer surface
@@ -752,7 +818,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c
VALIDATE_CONFIG(config, EGL_NO_CONTEXT); VALIDATE_CONFIG(config, EGL_NO_CONTEXT);
EGLint version = 1; //default EGLint version = 1; //default
while (attrib_list[0]) { while (attrib_list && attrib_list[0]) {
if (attrib_list[0] == EGL_CONTEXT_CLIENT_VERSION) version = attrib_list[1]; if (attrib_list[0] == EGL_CONTEXT_CLIENT_VERSION) version = attrib_list[1];
attrib_list+=2; attrib_list+=2;
} }
@@ -762,19 +828,19 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c
EGLContext_t * shareCtx = static_cast<EGLContext_t*>(share_context); EGLContext_t * shareCtx = static_cast<EGLContext_t*>(share_context);
rcShareCtx = shareCtx->rcContext; rcShareCtx = shareCtx->rcContext;
if (shareCtx->dpy != dpy) if (shareCtx->dpy != dpy)
return setError(EGL_BAD_MATCH, EGL_NO_CONTEXT); setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT);
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT);
uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version); uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version);
if (!rcContext) { if (!rcContext) {
LOGE("rcCreateContext returned 0"); LOGE("rcCreateContext returned 0");
return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
} }
EGLContext_t * context = new EGLContext_t(dpy, config); EGLContext_t * context = new EGLContext_t(dpy, config);
if (!context) if (!context)
return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
context->version = version; context->version = version;
context->rcContext = rcContext; context->rcContext = rcContext;
@@ -812,9 +878,9 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
VALIDATE_SURFACE_RETURN(read, EGL_FALSE); VALIDATE_SURFACE_RETURN(read, EGL_FALSE);
if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT)) if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
return setError(EGL_BAD_MATCH, EGL_FALSE); setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT)) if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))
return setError(EGL_BAD_MATCH, EGL_FALSE); setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
EGLContext_t * context = static_cast<EGLContext_t*>(ctx); EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
uint32_t ctxHandle = (context) ? context->rcContext : 0; uint32_t ctxHandle = (context) ? context->rcContext : 0;
@@ -836,13 +902,13 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) { if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) {
//context is current to another thread //context is current to another thread
return setError(EGL_BAD_ACCESS, EGL_FALSE); setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) { if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) {
LOGE("rcMakeCurrent returned EGL_FALSE"); LOGE("rcMakeCurrent returned EGL_FALSE");
return setError(EGL_BAD_CONTEXT, EGL_FALSE); setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
} }
// //
@@ -858,15 +924,29 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
context->draw = draw; context->draw = draw;
context->read = read; context->read = read;
context->flags |= EGLContext_t::IS_CURRENT; context->flags |= EGLContext_t::IS_CURRENT;
//set the client state
hostCon->glEncoder()->setClientState(context->getClientState());
} }
if (tInfo->currentContext) if (tInfo->currentContext)
tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT; tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT;
//Check maybe we need to init the encoder, if it's first eglMakeCurrent
if (tInfo->currentContext) {
if (!hostCon->glEncoder()->isInitialized()) {
if (tInfo->currentContext->version == 2) {
s_display.gles2_iface()->init();
}
else {
s_display.gles_iface()->init();
}
hostCon->glEncoder()->setInitialized();
}
}
//Now make current //Now make current
tInfo->currentContext = context; tInfo->currentContext = context;
//connect the color buffer //connect the color buffer
if (drawSurf) if (drawSurf)
drawSurf->connect(); drawSurf->connect();
@@ -891,7 +971,7 @@ EGLSurface eglGetCurrentSurface(EGLint readdraw)
case EGL_DRAW: case EGL_DRAW:
return context->draw; return context->draw;
default: default:
return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
} }
} }
@@ -929,7 +1009,9 @@ EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGL
*value = EGL_BACK_BUFFER; //single buffer not supported *value = EGL_BACK_BUFFER; //single buffer not supported
break; break;
default: default:
return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE); LOGE("eglQueryContext %x EGL_BAD_ATTRIBUTE", attribute);
setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
break;
} }
return ret; return ret;
@@ -961,15 +1043,15 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
{ {
VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
if (eglSurface == EGL_NO_SURFACE) if (eglSurface == EGL_NO_SURFACE)
return setError(EGL_BAD_SURFACE, EGL_FALSE); setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface); egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface);
if (!d->isValid()) if (!d->isValid())
return setError(EGL_BAD_SURFACE, EGL_FALSE); setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
if (d->dpy != dpy) if (d->dpy != dpy)
return setError(EGL_BAD_DISPLAY, EGL_FALSE); setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);
// post the surface // post the surface
d->swapBuffers(); d->swapBuffers();
@@ -1001,19 +1083,19 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EG
VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR); VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR);
if (ctx != EGL_NO_CONTEXT) { if (ctx != EGL_NO_CONTEXT) {
return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
} }
if (target != EGL_NATIVE_BUFFER_ANDROID) { if (target != EGL_NATIVE_BUFFER_ANDROID) {
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
} }
android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer; android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
if (native_buffer->common.version != sizeof(android_native_buffer_t)) if (native_buffer->common.version != sizeof(android_native_buffer_t))
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
switch (native_buffer->format) { switch (native_buffer->format) {
case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBA_8888:
@@ -1025,7 +1107,7 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EG
case HAL_PIXEL_FORMAT_RGBA_4444: case HAL_PIXEL_FORMAT_RGBA_4444:
break; break;
default: default:
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
} }
native_buffer->common.incRef(&native_buffer->common); native_buffer->common.incRef(&native_buffer->common);
@@ -1039,10 +1121,10 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
android_native_buffer_t* native_buffer = (android_native_buffer_t*)img; android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
return setError(EGL_BAD_PARAMETER, EGL_FALSE); setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
if (native_buffer->common.version != sizeof(android_native_buffer_t)) if (native_buffer->common.version != sizeof(android_native_buffer_t))
return setError(EGL_BAD_PARAMETER, EGL_FALSE); setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
native_buffer->common.decRef(&native_buffer->common); native_buffer->common.decRef(&native_buffer->common);

View File

@@ -83,6 +83,7 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
&s_gles_lib); &s_gles_lib);
if (!m_gles_iface) { if (!m_gles_iface) {
pthread_mutex_unlock(&m_lock); pthread_mutex_unlock(&m_lock);
LOGE("Failed to load gles1 iface");
return false; return false;
} }
@@ -100,6 +101,7 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
HostConnection *hcon = HostConnection::get(); HostConnection *hcon = HostConnection::get();
if (!hcon) { if (!hcon) {
pthread_mutex_unlock(&m_lock); pthread_mutex_unlock(&m_lock);
LOGE("Failed to establish connection with the host\n");
return false; return false;
} }
@@ -109,6 +111,7 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
renderControl_encoder_context_t *rcEnc = hcon->rcEncoder(); renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
if (!rcEnc) { if (!rcEnc) {
pthread_mutex_unlock(&m_lock); pthread_mutex_unlock(&m_lock);
LOGE("Failed to get renderControl encoder instance");
return false; return false;
} }
@@ -147,7 +150,7 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1); uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1);
EGLint tmp_buf[nInts]; EGLint tmp_buf[nInts];
m_configs = new EGLint[nInts-1]; m_configs = new EGLint[nInts-m_numConfigAttribs];
if (!m_configs) { if (!m_configs) {
pthread_mutex_unlock(&m_lock); pthread_mutex_unlock(&m_lock);
return false; return false;
@@ -162,21 +165,34 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
//Fill the attributes vector. //Fill the attributes vector.
//The first m_numConfigAttribs values of tmp_buf are the actual attributes enums. //The first m_numConfigAttribs values of tmp_buf are the actual attributes enums.
for (int i=0; i<m_numConfigAttribs; i++) for (int i=0; i<m_numConfigAttribs; i++) {
{
m_attribs.add(tmp_buf[i], i); m_attribs.add(tmp_buf[i], i);
} }
//Copy the actual configs data to m_configs //Copy the actual configs data to m_configs
memcpy(m_configs, tmp_buf + m_numConfigAttribs, m_numConfigs*sizeof(EGLint)); memcpy(m_configs, tmp_buf + m_numConfigAttribs, m_numConfigs*m_numConfigAttribs*sizeof(EGLint));
m_initialized = true; m_initialized = true;
} }
pthread_mutex_unlock(&m_lock); pthread_mutex_unlock(&m_lock);
processConfigs();
return true; return true;
} }
void eglDisplay::processConfigs()
{
for (int i=0; i<m_numConfigs; i++) {
EGLConfig config = (EGLConfig)i;
//Setup the EGL_NATIVE_VISUAL_ID attribute
PixelFormat format;
if (getConfigNativePixelFormat(config, &format)) {
setConfigAttrib(config, EGL_NATIVE_VISUAL_ID, format);
}
}
}
void eglDisplay::terminate() void eglDisplay::terminate()
{ {
pthread_mutex_lock(&m_lock); pthread_mutex_lock(&m_lock);
@@ -207,12 +223,14 @@ EGLClient_glesInterface *eglDisplay::loadGLESClientAPI(const char *libName,
{ {
void *lib = dlopen(libName, RTLD_NOW); void *lib = dlopen(libName, RTLD_NOW);
if (!lib) { if (!lib) {
LOGE("Failed to dlopen %s", libName);
return NULL; return NULL;
} }
init_emul_gles_t init_gles_func = (init_emul_gles_t)dlsym(lib,"init_emul_gles"); init_emul_gles_t init_gles_func = (init_emul_gles_t)dlsym(lib,"init_emul_gles");
if (!init_gles_func) { if (!init_gles_func) {
dlclose((void*)libName); LOGE("Failed to find init_emul_gles");
dlclose((void*)lib);
return NULL; return NULL;
} }
@@ -390,7 +408,41 @@ EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint *
return ret; return ret;
} }
EGLBoolean eglDisplay::getConfigPixelFormat(EGLConfig config, GLenum * format) void eglDisplay::dumpConfig(EGLConfig config)
{
EGLint value = 0;
DBG("^^^^^^^^^^ dumpConfig %d ^^^^^^^^^^^^^^^^^^", (int)config);
for (int i=0; i<m_numConfigAttribs; i++) {
getAttribValue(config, i, &value);
DBG("{%d}[%d] %d\n", (int)config, i, value);
}
}
/* To set the value of attribute <a> of config <c> use the following formula:
* *(m_configs + (int)c*m_numConfigAttribs + a) = value;
*/
EGLBoolean eglDisplay::setAttribValue(EGLConfig config, EGLint attribIdx, EGLint value)
{
if (attribIdx == ATTRIBUTE_NONE)
{
LOGE("[%s] Bad attribute idx\n", __FUNCTION__);
return EGL_FALSE;
}
*(m_configs + (int)config*m_numConfigAttribs + attribIdx) = value;
return EGL_TRUE;
}
EGLBoolean eglDisplay::setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value)
{
//Though it seems that valueFor() is thread-safe, we don't take chanses
pthread_mutex_lock(&m_lock);
EGLBoolean ret = setAttribValue(config, m_attribs.valueFor(attrib), value);
pthread_mutex_unlock(&m_lock);
return ret;
}
EGLBoolean eglDisplay::getConfigNativePixelFormat(EGLConfig config, PixelFormat * format)
{ {
EGLint redSize, blueSize, greenSize, alphaSize; EGLint redSize, blueSize, greenSize, alphaSize;
@@ -404,11 +456,35 @@ EGLBoolean eglDisplay::getConfigPixelFormat(EGLConfig config, GLenum * format)
} }
//calculate the GL internal format //calculate the GL internal format
if ((redSize==8)&&(blueSize==8)&&(greenSize==8)&&(alphaSize==8)) *format = GL_RGBA; if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = PIXEL_FORMAT_RGBA_8888; //XXX: BGR?
else if ((redSize==8)&&(blueSize==8)&&(greenSize==8)&&(alphaSize==0)) *format = GL_RGB; else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGBX_8888; //XXX or PIXEL_FORMAT_RGB_888
else if ((redSize==5)&&(blueSize==6)&&(greenSize==5)&&(alphaSize==0)) *format = GL_RGB565_OES; else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGB_565;
else if ((redSize==5)&&(blueSize==5)&&(greenSize==5)&&(alphaSize==1)) *format = GL_RGB5_A1_OES; else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = PIXEL_FORMAT_RGBA_5551;
else if ((redSize==4)&&(blueSize==4)&&(greenSize==4)&&(alphaSize==4)) *format = GL_RGBA4_OES; else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = PIXEL_FORMAT_RGBA_4444;
else {
return EGL_FALSE;
}
return EGL_TRUE;
}
EGLBoolean eglDisplay::getConfigGLPixelFormat(EGLConfig config, GLenum * format)
{
EGLint redSize, blueSize, greenSize, alphaSize;
if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) &&
getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) &&
getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) &&
getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) )
{
LOGE("Couldn't find value for one of the pixel format attributes");
return EGL_FALSE;
}
//calculate the GL internal format
if ((redSize==8)&&(blueSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = GL_RGBA;
else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = GL_RGB;
else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = GL_RGB565_OES;
else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = GL_RGB5_A1_OES;
else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = GL_RGBA4_OES;
else return EGL_FALSE; else return EGL_FALSE;
return EGL_TRUE; return EGL_TRUE;

View File

@@ -23,6 +23,8 @@
#include "EGLClientIface.h" #include "EGLClientIface.h"
#include <utils/KeyedVector.h> #include <utils/KeyedVector.h>
#include <ui/PixelFormat.h>
#define ATTRIBUTE_NONE -1 #define ATTRIBUTE_NONE -1
//FIXME: are we in this namespace? //FIXME: are we in this namespace?
using namespace android; using namespace android;
@@ -46,13 +48,18 @@ public:
int getNumConfigs(){ return m_numConfigs; } int getNumConfigs(){ return m_numConfigs; }
EGLBoolean getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value); EGLBoolean getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value);
EGLBoolean getConfigPixelFormat(EGLConfig config, GLenum * format); EGLBoolean setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value);
EGLBoolean getConfigGLPixelFormat(EGLConfig config, GLenum * format);
EGLBoolean getConfigNativePixelFormat(EGLConfig config, PixelFormat * format);
void dumpConfig(EGLConfig config);
private: private:
EGLClient_glesInterface *loadGLESClientAPI(const char *libName, EGLClient_glesInterface *loadGLESClientAPI(const char *libName,
EGLClient_eglInterface *eglIface, EGLClient_eglInterface *eglIface,
void **libHandle); void **libHandle);
EGLBoolean getAttribValue(EGLConfig config, EGLint attribIdxi, EGLint * value); EGLBoolean getAttribValue(EGLConfig config, EGLint attribIdxi, EGLint * value);
EGLBoolean setAttribValue(EGLConfig config, EGLint attribIdxi, EGLint value);
void processConfigs();
private: private:
pthread_mutex_t m_lock; pthread_mutex_t m_lock;

View File

@@ -31,12 +31,12 @@ LOCAL_MODULE_PATH = $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_MODULE := gralloc.goldfish LOCAL_MODULE := gralloc.goldfish
LOCAL_STATIC_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \
libOpenglSystemCommon \
libOpenglCodecCommon \ libOpenglCodecCommon \
libqemu libqemu
LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \
libcutils \ libcutils \
libOpenglSystemCommon \
libGLESv1_enc \ libGLESv1_enc \
lib_renderControl_enc lib_renderControl_enc

View File

@@ -29,6 +29,7 @@
#include <cutils/log.h> #include <cutils/log.h>
#define DBG_FUNC DBG("%s\n", __FUNCTION__)
// //
// our private gralloc module structure // our private gralloc module structure
// //
@@ -163,7 +164,7 @@ static int gralloc_alloc(alloc_device_t* dev,
*pStride = bpr / bpp; *pStride = bpr / bpp;
} }
LOGD("gralloc_alloc ashmem_size=%d\n", ashmem_size); LOGD("gralloc_alloc ashmem_size=%d, tid %d\n", ashmem_size, gettid());
// //
// Allocate space in ashmem if needed // Allocate space in ashmem if needed
@@ -193,6 +194,8 @@ static int gralloc_alloc(alloc_device_t* dev,
delete cb; delete cb;
return err; return err;
} }
cb->setFd(fd);
} }
// //
@@ -299,6 +302,12 @@ static int gralloc_device_close(struct hw_device_t *dev)
return 0; return 0;
} }
static int fb_compositionComplete(struct framebuffer_device_t* dev)
{
LOGI("fb_compositionComplete");
return 0;
}
// //
// Framebuffer device functions // Framebuffer device functions
// //
@@ -650,6 +659,7 @@ static int gralloc_device_open(const hw_module_t* module,
if (NULL == dev) { if (NULL == dev) {
return -ENOMEM; return -ENOMEM;
} }
memset(dev, 0, sizeof(fb_device_t));
// Initialize our device structure // Initialize our device structure
// //
@@ -659,7 +669,8 @@ static int gralloc_device_open(const hw_module_t* module,
dev->device.common.close = fb_close; dev->device.common.close = fb_close;
dev->device.setSwapInterval = fb_setSwapInterval; dev->device.setSwapInterval = fb_setSwapInterval;
dev->device.post = fb_post; dev->device.post = fb_post;
dev->device.setUpdateRect = 0; //XXX: fb_setUpdateRect; dev->device.setUpdateRect = fb_setUpdateRect;
dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy
const_cast<uint32_t&>(dev->device.flags) = 0; const_cast<uint32_t&>(dev->device.flags) = 0;
const_cast<uint32_t&>(dev->device.width) = width; const_cast<uint32_t&>(dev->device.width) = width;

View File

@@ -20,6 +20,8 @@ LOCAL_STATIC_LIBRARIES := \
libOpenglCodecCommon libOpenglCodecCommon
LOCAL_SHARED_LIBRARIES := libcutils LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_CFLAGS += -DDEBUG_PRINTOUT -O0 -g
RC_GEN := \ RC_GEN := \
$(rc_intermediates)/renderControl_enc.cpp \ $(rc_intermediates)/renderControl_enc.cpp \
$(rc_intermediates)/renderControl_enc.h $(rc_intermediates)/renderControl_enc.h

View File

@@ -81,6 +81,9 @@ uint32_t rcCreateColorBuffer(uint32_t width, uint32_t height, GLenum internalFor
void rcDestroyColorBuffer(uint32_t colorbuffer); void rcDestroyColorBuffer(uint32_t colorbuffer);
destroyes a colorBuffer object. destroyes a colorBuffer object.
void rcFlushWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer);
This flushes the current window color buffer
void rcSetWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer); void rcSetWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer);
This set the target color buffer for a windowSurface, when set the This set the target color buffer for a windowSurface, when set the
previous target colorBuffer gets updated before switching to the new previous target colorBuffer gets updated before switching to the new

View File

@@ -12,6 +12,7 @@ GL_ENTRY(void, rcDestroyWindowSurface, uint32_t windowSurface)
GL_ENTRY(uint32_t, rcCreateColorBuffer, uint32_t width, uint32_t height, GLenum internalFormat) GL_ENTRY(uint32_t, rcCreateColorBuffer, uint32_t width, uint32_t height, GLenum internalFormat)
GL_ENTRY(void, rcDestroyColorBuffer, uint32_t colorbuffer) GL_ENTRY(void, rcDestroyColorBuffer, uint32_t colorbuffer)
GL_ENTRY(void, rcSetWindowColorBuffer, uint32_t windowSurface, uint32_t colorBuffer) GL_ENTRY(void, rcSetWindowColorBuffer, uint32_t windowSurface, uint32_t colorBuffer)
GL_ENTRY(void, rcFlushWindowColorBuffer, uint32_t windowSurface)
GL_ENTRY(EGLint, rcMakeCurrent, uint32_t context, uint32_t drawSurf, uint32_t readSurf) GL_ENTRY(EGLint, rcMakeCurrent, uint32_t context, uint32_t drawSurf, uint32_t readSurf)
GL_ENTRY(void, rcFBPost, uint32_t colorBuffer) GL_ENTRY(void, rcFBPost, uint32_t colorBuffer)
GL_ENTRY(void, rcFBSetSwapInterval, EGLint interval) GL_ENTRY(void, rcFBSetSwapInterval, EGLint interval)

View File

@@ -127,8 +127,10 @@ LOCAL_SHARED_LIBRARIES := libdl \
libcutils \ libcutils \
libGLESv1_enc \ libGLESv1_enc \
libGLESv2_enc \ libGLESv2_enc \
libut_rendercontrol_enc libut_rendercontrol_enc \
LOCAL_STATIC_LIBRARIES := libOpenglCodecCommon libOpenglSystemCommon libqemu libOpenglSystemCommon
LOCAL_STATIC_LIBRARIES := libOpenglCodecCommon libqemu
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
@@ -139,6 +141,7 @@ include $(BUILD_SHARED_LIBRARY)
# version of this file to point to the appropriate HW EGL libraries. # version of this file to point to the appropriate HW EGL libraries.
# #
ifneq (,$(filter full full_x86 sdk sdk_x86,$(TARGET_PRODUCT))) ifneq (,$(filter full full_x86 sdk sdk_x86,$(TARGET_PRODUCT)))
ifeq (,$(BUILD_EMULATOR_OPENGL_DRIVER))
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := egl.cfg LOCAL_MODULE := egl.cfg
@@ -149,6 +152,7 @@ LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_CLASS := ETC
include $(BUILD_PREBUILT) include $(BUILD_PREBUILT)
endif # building 'real' driver BUILD_EMULATOR_OPENGL_DRIVER
endif # TARGET_PRODUCT in 'full sdk full_x86 sdk_x86' endif # TARGET_PRODUCT in 'full sdk full_x86 sdk_x86'
#### gles_emul.cfg #### #### gles_emul.cfg ####