diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp index c0f626073..9c973e9f6 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp @@ -17,6 +17,9 @@ #include "FrameBuffer.h" #include "FBConfig.h" #include "EGLDispatch.h" +#include "GLDispatch.h" +#include "GL2Dispatch.h" +#include "ThreadInfo.h" static const GLint rendererVersion = 1; @@ -58,6 +61,38 @@ static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize) return len; } +static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) +{ + RenderThreadInfo *tInfo = getRenderThreadInfo(); + if (!tInfo || !tInfo->currContext.Ptr()) { + return 0; + } + + const char *str = NULL; +#ifdef WITH_GLES2 + if (tInfo->currContext->isGL2()) { + str = (const char *)s_gl2.glGetString(name); + } + else { +#endif + str = (const char *)s_gl.glGetString(name); +#ifdef WITH_GLES2 + } +#endif + + if (!str) { + return 0; + } + + int len = strlen(str) + 1; + if (!buffer || len > bufferSize) { + return -len; + } + + strcpy((char *)buffer, str); + return len; +} + static EGLint rcGetNumConfigs(uint32_t* numAttribs) { if (numAttribs) { @@ -279,6 +314,7 @@ void initRenderControlContext(renderControl_decoder_context_t *dec) dec->set_rcGetRendererVersion(rcGetRendererVersion); dec->set_rcGetEGLVersion(rcGetEGLVersion); dec->set_rcQueryEGLString(rcQueryEGLString); + dec->set_rcGetGLString(rcGetGLString); dec->set_rcGetNumConfigs(rcGetNumConfigs); dec->set_rcGetConfigs(rcGetConfigs); dec->set_rcChooseConfig(rcChooseConfig); diff --git a/tools/emulator/opengl/system/GLESv1/gl.cpp b/tools/emulator/opengl/system/GLESv1/gl.cpp index eb7c0a949..d57624f62 100644 --- a/tools/emulator/opengl/system/GLESv1/gl.cpp +++ b/tools/emulator/opengl/system/GLESv1/gl.cpp @@ -68,10 +68,19 @@ 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" { diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/EGLClientIface.h b/tools/emulator/opengl/system/OpenglSystemCommon/EGLClientIface.h index f959b4439..108934020 100644 --- a/tools/emulator/opengl/system/OpenglSystemCommon/EGLClientIface.h +++ b/tools/emulator/opengl/system/OpenglSystemCommon/EGLClientIface.h @@ -5,6 +5,7 @@ struct EGLThreadInfo; // defined in ThreadInfo.h typedef struct { EGLThreadInfo* (*getThreadInfo)(); + const char* (*getGLString)(int glEnum); } EGLClient_eglInterface; typedef struct { diff --git a/tools/emulator/opengl/system/egl/egl.cpp b/tools/emulator/opengl/system/egl/egl.cpp index c45e7e7a2..d8ef8aa03 100644 --- a/tools/emulator/opengl/system/egl/egl.cpp +++ b/tools/emulator/opengl/system/egl/egl.cpp @@ -142,14 +142,26 @@ struct EGLContext_t { EGLSurface draw; EGLint version; uint32_t rcContext; + const char* versionString; + const char* vendorString; + const char* rendererString; + const char* extensionString; 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) +EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) : + dpy(dpy), + config(config), + read(EGL_NO_SURFACE), + draw(EGL_NO_SURFACE), + rcContext(0), + versionString(NULL), + vendorString(NULL), + rendererString(NULL), + extensionString(NULL) { flags = 0; version = 1; @@ -158,8 +170,13 @@ EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) : dpy(dpy), config( EGLContext_t::~EGLContext_t() { - if (clientState) delete clientState; + delete clientState; + delete [] versionString; + delete [] vendorString; + delete [] rendererString; + delete [] extensionString; } + // ---------------------------------------------------------------------------- //egl_surface_t @@ -426,13 +443,76 @@ EGLBoolean egl_pbuffer_surface_t::connect() return EGL_TRUE; } +static const char *getGLString(int glEnum) +{ + EGLThreadInfo *tInfo = getEGLThreadInfo(); + if (!tInfo || !tInfo->currentContext) { + return NULL; + } + + const char** strPtr = NULL; + +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + + switch(glEnum) { + case GL_VERSION: + strPtr = &tInfo->currentContext->versionString; + break; + case GL_VENDOR: + strPtr = &tInfo->currentContext->vendorString; + break; + case GL_RENDERER: + strPtr = &tInfo->currentContext->rendererString; + break; + case GL_EXTENSIONS: + strPtr = &tInfo->currentContext->extensionString; + break; + } + + if (!strPtr) { + return NULL; + } + + if (*strPtr != NULL) { + // + // string is already cached + // + return *strPtr; + } + + // + // first query of that string - need to query host + // + DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL); + char *hostStr = NULL; + int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0); + if (n < 0) { + hostStr = new char[-n+1]; + n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n); + if (n <= 0) { + delete [] hostStr; + hostStr = NULL; + } + } + + // + // keep the string in the context and return its value + // + *strPtr = hostStr; + return hostStr; +} + // ---------------------------------------------------------------------------- // The one and only supported display object. static eglDisplay s_display; static EGLClient_eglInterface s_eglIface = { - getThreadInfo: getEGLThreadInfo + getThreadInfo: getEGLThreadInfo, + getGLString: getGLString }; #define DBG_FUNC DBG("%s\n", __FUNCTION__) @@ -931,6 +1011,9 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC if (tInfo->currentContext) tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT; + //Now make current + tInfo->currentContext = context; + //Check maybe we need to init the encoder, if it's first eglMakeCurrent if (tInfo->currentContext) { if (!hostCon->glEncoder()->isInitialized()) { @@ -944,9 +1027,6 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC } } - //Now make current - tInfo->currentContext = context; - //connect the color buffer if (drawSurf) drawSurf->connect(); diff --git a/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib b/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib index a77d21fcc..4197d64ef 100644 --- a/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib +++ b/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib @@ -12,6 +12,10 @@ rcQueryEGLString dir buffer out len buffer bufferSize +rcGetGLString + dir buffer out + len buffer bufferSize + rcGetNumConfigs dir numAttribs out len numAttribs sizeof(uint32_t) diff --git a/tools/emulator/opengl/system/renderControl_enc/renderControl.in b/tools/emulator/opengl/system/renderControl_enc/renderControl.in index 505c6ce0d..37a8e9013 100644 --- a/tools/emulator/opengl/system/renderControl_enc/renderControl.in +++ b/tools/emulator/opengl/system/renderControl_enc/renderControl.in @@ -1,6 +1,7 @@ GL_ENRTY(GLint, rcGetRendererVersion) GL_ENTRY(EGLint, rcGetEGLVersion, EGLint *major, EGLint *minor) GL_ENTRY(EGLint, rcQueryEGLString, EGLenum name, void *buffer, EGLint bufferSize) +GL_ENTRY(EGLint, rcGetGLString, EGLenum name, void *buffer, EGLint bufferSize) GL_ENTRY(EGLint, rcGetNumConfigs, uint32_t *numAttribs) GL_ENTRY(EGLint, rcGetConfigs, uint32_t bufSize, GLuint *buffer) GL_ENTRY(EGLint, rcChooseConfig, EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size)