emulator opengl: add GLESv2 support to driver + renderer

Added GLESv2 library to system.
Made fixes to the host libOpenGLRender to
compile and support GLESv2 (defined WITH_GLES2).
Other fixes required to make GLESv2 to work.

Change-Id: I9eb198e6092e7fa3550342c50929dd1714282cb3
This commit is contained in:
Stas Gurtovoy
2011-06-16 14:51:21 +03:00
committed by Guy Zadickario
parent 39386d450f
commit 62d074d9f8
25 changed files with 233 additions and 29 deletions

View File

@@ -18,6 +18,12 @@ EMUGL_PATH := $(call my-dir)
#
EMUGL_COMMON_INCLUDES := $(EMUGL_PATH)/host/include/libOpenglRender
# common cflags used by several modules
# This is always set to a module's LOCAL_CFLAGS
# See the definition of emugl-begin-module in common.mk
#
EMUGL_COMMON_CFLAGS := -DWITH_GLES2
# Include common definitions used by all the modules included later
# in this build file. This contains the definition of all useful
# emugl-xxxx functions.
@@ -55,6 +61,7 @@ include $(EMUGL_PATH)/tests/ut_rendercontrol_enc/Android.mk
# System shared libraries
include $(EMUGL_PATH)/system/GLESv1/Android.mk
include $(EMUGL_PATH)/system/GLESv2/Android.mk
include $(EMUGL_PATH)/system/egl/Android.mk
include $(EMUGL_PATH)/tests/gles_android_wrapper/Android.mk

View File

@@ -38,6 +38,7 @@ emugl-begin-module = \
$(eval LOCAL_MODULE_CLASS := $(patsubst HOST_%,%,$(patsubst %EXECUTABLE,%EXECUTABLES,$(patsubst %LIBRARY,%LIBRARIES,$2)))) \
$(eval LOCAL_IS_HOST_MODULE := $(if $3,true,))\
$(eval LOCAL_C_INCLUDES := $(EMUGL_COMMON_INCLUDES)) \
$(eval LOCAL_CFLAGS := $(EMUGL_COMMON_CFLAGS)) \
$(eval LOCAL_PRELINK_MODULE := false)\
$(eval _EMUGL_INCLUDE_TYPE := $(BUILD_$2)) \
$(call _emugl-init-module,$1,$2,$3)

View File

@@ -108,7 +108,7 @@ void GL2Decoder::s_glDrawElementsOffset(void *self, GLenum mode, GLsizei count,
ctx->glDrawElements(mode, count, type, (void *)offset);
}
void GL2Decoder::s_glShaderString(void *self, GLuint shader, GLstr string, GLsizei len)
void GL2Decoder::s_glShaderString(void *self, GLuint shader, const GLchar* string, GLsizei len)
{
GL2Decoder *ctx = (GL2Decoder *)self;
ctx->glShaderSource(shader, 1, &string, NULL);

View File

@@ -30,6 +30,6 @@ private:
static void s_glDrawElementsOffset(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset);
static void s_glDrawElementsData(void *self, GLenum mode, GLsizei count, GLenum type, void * data, GLuint datalen);
static void s_glShaderString(void *self, GLuint shader, GLstr string, GLsizei len);
static void s_glShaderString(void *self, GLuint shader, const GLchar* string, GLsizei len);
};
#endif

View File

@@ -5,7 +5,7 @@ ifneq ($(HOST_OS),darwin)
### libOpenglRender #################################################
$(call emugl-begin-host-shared-library,libOpenglRender)
$(call emugl-import,libGLESv1_dec lib_renderControl_dec libOpenglCodecCommon libOpenglOsUtils)
$(call emugl-import,libGLESv1_dec libGLESv2_dec lib_renderControl_dec libOpenglCodecCommon libOpenglOsUtils)
LOCAL_SRC_FILES := \
render_api.cpp \

View File

@@ -77,8 +77,8 @@ static const char *getGLES2ExtensionString(EGLDisplay p_dpy,
}
s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL);
s_egl.eglDestroySurface(p_dpy, surface);
s_egl.eglDestroyContext(p_dpy, ctx);
s_egl.eglDestroySurface(p_dpy, surface);
return extString;
}
@@ -564,8 +564,14 @@ bool FrameBuffer::bindContext(HandleType p_context,
tinfo->currContext = ctx;
tinfo->currDrawSurf = draw;
tinfo->currReadSurf = read;
tinfo->m_glDec.setContextData(&ctx->decoderContextData());
if (ctx) {
if (ctx->isGL2()) tinfo->m_gl2Dec.setContextData(&ctx->decoderContextData());
else tinfo->m_glDec.setContextData(&ctx->decoderContextData());
}
else {
tinfo->m_glDec.setContextData(NULL);
tinfo->m_gl2Dec.setContextData(NULL);
}
return true;
}

View File

@@ -41,7 +41,8 @@ bool init_gl2_dispatch()
//
// init the GLES dispatch table
//
return s_gl2.initDispatchByName( gl2_dispatch_get_proc_func, NULL );
s_gl2.initDispatchByName( gl2_dispatch_get_proc_func, NULL );
return true;
}
//

View File

@@ -23,7 +23,7 @@
bool init_gl2_dispatch();
void *gl2_dispatch_get_proc_func(const char *name, void *userData);
extern gl2_decoder_context_t s_gl;
extern gl2_decoder_context_t s_gl2;
#endif
#endif

View File

@@ -19,6 +19,7 @@
#include "ReadBuffer.h"
#include "TimeUtils.h"
#include "GLDispatch.h"
#include "GL2Dispatch.h"
#define STREAM_BUFFER_SIZE 4*1024*1024
@@ -47,6 +48,7 @@ int RenderThread::Main()
// initialize decoders
//
tInfo->m_glDec.initGL( gl_dispatch_get_proc_func, NULL );
tInfo->m_gl2Dec.initGL( gl2_dispatch_get_proc_func, NULL );
initRenderControlContext( &m_rcDec );
ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE);
@@ -79,7 +81,7 @@ int RenderThread::Main()
progress = false;
//
// try to process some of the command buffer using the GLES decoder
// try to process some of the command buffer using the GLESv1 decoder
//
size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
if (last > 0) {
@@ -87,6 +89,15 @@ int RenderThread::Main()
readBuf.consume(last);
}
//
// try to process some of the command buffer using the GLESv2 decoder
//
last = tInfo->m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream);
if (last > 0) {
progress = true;
readBuf.consume(last);
}
//
// try to process some of the command buffer using the
// renderControl decoder

View File

@@ -19,6 +19,7 @@
#include "RenderContext.h"
#include "WindowSurface.h"
#include "GLDecoder.h"
#include "GL2Decoder.h"
struct RenderThreadInfo
{
@@ -26,6 +27,7 @@ struct RenderThreadInfo
WindowSurfacePtr currDrawSurf;
WindowSurfacePtr currReadSurf;
GLDecoder m_glDec;
GL2Decoder m_gl2Dec;
};
RenderThreadInfo *getRenderThreadInfo();

View File

@@ -23,6 +23,7 @@ LOCAL_C_INCLUDES := $(emulatorOpengl)/host/include \
LOCAL_SHARED_LIBRARIES := libOpenglRender \
libGLESv1_dec \
libGLESv2_dec \
lib_renderControl_dec
include $(BUILD_HOST_EXECUTABLE)

View File

@@ -637,7 +637,7 @@ int ApiGen::genDecoderImpl(const std::string &filename)
}
} else if (pass == PASS_DebugPrint) {
fprintf(fp, "#ifdef DEBUG_PRINTOUT\n");
fprintf(fp, "\t\t\tfprintf(stderr,\"%s(%s)\\n\"", e->name().c_str(), printString.c_str());
fprintf(fp, "\t\t\tfprintf(stderr,\"%s: %s(%s)\\n\"", m_basename.c_str(), e->name().c_str(), printString.c_str());
if (e->vars().size() > 0 && !e->vars()[0].isVoid()) fprintf(fp, ",");
}

View File

@@ -0,0 +1,13 @@
LOCAL_PATH := $(call my-dir)
### GLESv2 implementation ###########################################
$(call emugl-begin-shared-library,libGLESv2_emulation)
$(call emugl-import,libOpenglSystemCommon libGLESv2_enc lib_renderControl_enc)
LOCAL_CFLAGS += -DLOG_TAG=\"GLESv2_emulation\" -DGL_GLEXT_PROTOTYPES
LOCAL_SRC_FILES := gl2.cpp
LOCAL_STATIC_LIBRARIES += libqemu
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
$(call emugl-end-module)

View File

@@ -0,0 +1,103 @@
#include "EGLClientIface.h"
#include "HostConnection.h"
#include "GL2Encoder.h"
#include "GLES/gl.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
#define GET_CONTEXT gl2_client_context_t * ctx = HostConnection::get()->gl2Encoder();
#include "gl2_entry.cpp"
//The functions table
#include "gl2_ftable.h"
static EGLClient_eglInterface * s_egl = 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)
{
// search in GL function table
for (int i=0; i<gl2_num_funcs; i++) {
if (!strcmp(gl2_funcs_by_name[i].name, procname)) {
return gl2_funcs_by_name[i].proc;
}
}
return NULL;
}
void finish()
{
glFinish();
}
const GLubyte *my_glGetString (void *self, GLenum name)
{
if (s_egl) {
return (const GLubyte*)s_egl->getGLString(name);
}
return NULL;
}
void init()
{
GET_CONTEXT;
ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES);
ctx->set_glGetString(my_glGetString);
}
extern "C" {
EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface)
{
s_egl = eglIface;
if (!s_gl) {
s_gl = new EGLClient_glesInterface();
s_gl->getProcAddress = getProcAddress;
s_gl->finish = finish;
s_gl->init = init;
}
return s_gl;
}
} //extern

View File

@@ -325,9 +325,8 @@ GLint * GL2Encoder::getCompressedTextureFormats()
return m_compressedTextureFormats;
}
void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLstr *string, const GLint *length)
void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **string, const GLint *length)
{
int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
char *str = new char[len + 1];
glUtilsPackStrings(str, (char**)string, (GLint*)length, count);

View File

@@ -33,7 +33,13 @@ public:
void flush() {
gl2_encoder_context_t::m_stream->flush();
}
void setInitialized(){ m_initialized = true; };
bool isInitialized(){ return m_initialized; };
private:
bool m_initialized;
GLClientState *m_state;
GLint *m_compressedTextureFormats;
@@ -91,7 +97,7 @@ private:
glGetVertexAttribPointerv_client_proc_t m_glGetVertexAttribPointerv;
static void s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer);
static void s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLstr *string, const GLint *length);
static void s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
static void s_glFinish(void *self);
};

View File

@@ -152,6 +152,7 @@ glGetShaderiv
glGetShaderInfoLog
dir length out
len length (sizeof(GLsizei))
var_flag length nullAllowed
dir infolog out
len infolog bufsize
@@ -521,9 +522,11 @@ glVertexAttribPointerData
len data datalen
custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen)
flag custom_decoder
flag not_api
glVertexAttribPointerOffset
flag custom_decoder
flag not_api
#client-state, handled by the encoder
#GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer)
@@ -533,20 +536,24 @@ glGetVertexAttribPointerv
glDrawElementsData
len data datalen
flag custom_decoder
flag not_api
glDrawElementsOffset
flag custom_decoder
flag not_api
#GL_ENTRY(void, glGetCompressedTextureFormats, int count, GLint *formats)
glGetCompressedTextureFormats
dir formats out
len formats (count * sizeof(GLint))
flag custom_decoder
flag not_api
#GL_ENTRY(void, glShaderString, GLuint shader, GLchar *string, GLsizei len)
glShaderString
len string len
flag custom_decoder
flag not_api
glFinishRoundTrip
flag custom_decoder

View File

@@ -96,7 +96,7 @@ GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsi
GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLstr* string, const GLint* length)
GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
GL_ENTRY(void, glStencilMask, GLuint mask)
@@ -210,5 +210,5 @@ GL_ENTRY(void, glVertexAttribPointerOffset, GLuint indx, GLint size, GLenum type
GL_ENTRY(void, glDrawElementsOffset, GLenum mode, GLsizei count, GLenum type, GLuint offset)
GL_ENTRY(void, glDrawElementsData, GLenum mode, GLsizei count, GLenum type, void *data, GLuint datalen)
GL_ENTRY(void, glGetCompressedTextureFormats, int count, GLint *formats)
GL_ENTRY(void, glShaderString, GLuint shader, GLstr string, GLsizei len)
GL_ENTRY(void, glShaderString, GLuint shader, const GLchar* string, GLsizei len)
GL_ENTRY(int, glFinishRoundTrip, void)

View File

@@ -29,6 +29,7 @@ GLubyte* 32 0x%08x true
GLuint* 32 0x%08x true
GLvoid* 32 0x%08x true
GLchar* 32 0x%08x true
GLchar** 32 0x%08x true
GLvoid** 32 0x%08x true
void* 32 0x%08x true
GLstr 32 %s true

View File

@@ -1,7 +1,7 @@
LOCAL_PATH := $(call my-dir)
$(call emugl-begin-shared-library,libOpenglSystemCommon)
$(call emugl-import,libGLESv1_enc lib_renderControl_enc)
$(call emugl-import,libGLESv1_enc libGLESv2_enc lib_renderControl_enc)
LOCAL_SRC_FILES := \
HostConnection.cpp \

View File

@@ -18,6 +18,8 @@
#include "QemuPipeStream.h"
#include "ThreadInfo.h"
#include <cutils/log.h>
#include "GLEncoder.h"
#include "GL2Encoder.h"
#define STREAM_BUFFER_SIZE 4*1024*1024
#define STREAM_PORT_NUM 22468
@@ -28,6 +30,7 @@
HostConnection::HostConnection() :
m_stream(NULL),
m_glEnc(NULL),
m_gl2Enc(NULL),
m_rcEnc(NULL)
{
}
@@ -36,6 +39,7 @@ HostConnection::~HostConnection()
{
delete m_stream;
delete m_glEnc;
delete m_gl2Enc;
delete m_rcEnc;
}
@@ -119,6 +123,16 @@ GLEncoder *HostConnection::glEncoder()
return m_glEnc;
}
GL2Encoder *HostConnection::gl2Encoder()
{
if (!m_gl2Enc) {
m_gl2Enc = new GL2Encoder(m_stream);
DBG("HostConnection::gl2Encoder new encoder %p, tid %d", m_gl2Enc, gettid());
m_gl2Enc->setContextAccessor(s_getGL2Context);
}
return m_gl2Enc;
}
renderControl_encoder_context_t *HostConnection::rcEncoder()
{
if (!m_rcEnc) {
@@ -135,3 +149,12 @@ gl_client_context_t *HostConnection::s_getGLContext()
}
return NULL;
}
gl2_client_context_t *HostConnection::s_getGL2Context()
{
EGLThreadInfo *ti = getEGLThreadInfo();
if (ti->hostConn) {
return ti->hostConn->m_gl2Enc;
}
return NULL;
}

View File

@@ -17,9 +17,13 @@
#define __COMMON_HOST_CONNECTION_H
#include "IOStream.h"
#include "GLEncoder.h"
#include "renderControl_enc.h"
class GLEncoder;
class gl_client_context_t;
class GL2Encoder;
class gl2_client_context_t;
class HostConnection
{
public:
@@ -27,6 +31,7 @@ public:
~HostConnection();
GLEncoder *glEncoder();
GL2Encoder *gl2Encoder();
renderControl_encoder_context_t *rcEncoder();
void flush() {
@@ -38,10 +43,12 @@ public:
private:
HostConnection();
static gl_client_context_t *s_getGLContext();
static gl2_client_context_t *s_getGL2Context();
private:
IOStream *m_stream;
GLEncoder *m_glEnc;
GL2Encoder *m_gl2Enc;
renderControl_encoder_context_t *m_rcEnc;
};

View File

@@ -117,7 +117,7 @@ const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
//DBG(">> QemuPipeStream::readFully %d\n", len);
if (!valid()) return NULL;
if (!buf) {
ERR("QemuPipeStream::readFully failed, buf=NULL");
ERR("QemuPipeStream::readFully failed, buf=NULL, len %d", len);
return NULL; // do not allow NULL buf in that implementation
}
size_t res = len;

View File

@@ -18,15 +18,17 @@ LOCAL_SRC_FILES := \
LOCAL_PRELINK_MODULE := false
LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES -DWITH_GLES2
LOCAL_C_INCLUDES += \
$(emulatorOpengl)/host/include/libOpenglRender \
$(emulatorOpengl)/shared/OpenglCodecCommon \
$(emulatorOpengl)/system/OpenglSystemCommon \
$(emulatorOpengl)/system/GLESv1_enc \
$(emulatorOpengl)/system/GLESv2_enc \
$(emulatorOpengl)/system/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) \
$(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv2_enc)
LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
@@ -43,6 +45,7 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libdl \
libGLESv1_enc \
libGLESv2_enc \
libOpenglSystemCommon \
lib_renderControl_enc

View File

@@ -21,6 +21,11 @@
#include "gralloc_cb.h"
#include "GLClientState.h"
#include "GLEncoder.h"
#ifdef WITH_GLES2
#include "GL2Encoder.h"
#endif
#include <private/ui/android_natives_priv.h>
template<typename T>
@@ -1012,8 +1017,13 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
context->read = read;
context->flags |= EGLContext_t::IS_CURRENT;
//set the client state
if (context->version == 2) {
hostCon->gl2Encoder()->setClientState(context->getClientState());
}
else {
hostCon->glEncoder()->setClientState(context->getClientState());
}
}
if (tInfo->currentContext)
tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT;
@@ -1023,16 +1033,19 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
//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) {
if (!hostCon->gl2Encoder()->isInitialized()) {
s_display.gles2_iface()->init();
hostCon->gl2Encoder()->setInitialized();
}
}
else {
if (!hostCon->glEncoder()->isInitialized()) {
s_display.gles_iface()->init();
}
hostCon->glEncoder()->setInitialized();
}
}
}
//connect the color buffer
if (drawSurf)