emulator opengl: implement glGetString

Added rcGetGLString token to renderControl to query
a GL string constant from the current context from the host.
Implement glGetString functinality in EGL so that the string
value can be cached in the context structure and also
implementation can be shared between GLESv1 and GLESv2.

Also, fixed clientAPI context initialization check in
eglMakeCurrent. The check was for the previously bounded
context instead for the newly bounded context.

Change-Id: I41c0b4ad462c9ad5bd5c66719b41509bb1b7a947
This commit is contained in:
Guy Zadikario
2011-06-04 22:56:54 +03:00
committed by David 'Digit' Turner
parent 5b675210ed
commit 1ef706f96f
6 changed files with 138 additions and 7 deletions

View File

@@ -17,6 +17,9 @@
#include "FrameBuffer.h" #include "FrameBuffer.h"
#include "FBConfig.h" #include "FBConfig.h"
#include "EGLDispatch.h" #include "EGLDispatch.h"
#include "GLDispatch.h"
#include "GL2Dispatch.h"
#include "ThreadInfo.h"
static const GLint rendererVersion = 1; static const GLint rendererVersion = 1;
@@ -58,6 +61,38 @@ static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize)
return len; 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) static EGLint rcGetNumConfigs(uint32_t* numAttribs)
{ {
if (numAttribs) { if (numAttribs) {
@@ -279,6 +314,7 @@ void initRenderControlContext(renderControl_decoder_context_t *dec)
dec->set_rcGetRendererVersion(rcGetRendererVersion); dec->set_rcGetRendererVersion(rcGetRendererVersion);
dec->set_rcGetEGLVersion(rcGetEGLVersion); dec->set_rcGetEGLVersion(rcGetEGLVersion);
dec->set_rcQueryEGLString(rcQueryEGLString); dec->set_rcQueryEGLString(rcQueryEGLString);
dec->set_rcGetGLString(rcGetGLString);
dec->set_rcGetNumConfigs(rcGetNumConfigs); dec->set_rcGetNumConfigs(rcGetNumConfigs);
dec->set_rcGetConfigs(rcGetConfigs); dec->set_rcGetConfigs(rcGetConfigs);
dec->set_rcChooseConfig(rcChooseConfig); dec->set_rcChooseConfig(rcChooseConfig);

View File

@@ -68,10 +68,19 @@ void finish()
glFinish(); glFinish();
} }
const GLubyte *my_glGetString (void *self, GLenum name)
{
if (s_egl) {
return (const GLubyte*)s_egl->getGLString(name);
}
return NULL;
}
void init() void init()
{ {
GET_CONTEXT; GET_CONTEXT;
ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES); ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES);
ctx->set_glGetString(my_glGetString);
} }
extern "C" { extern "C" {

View File

@@ -5,6 +5,7 @@ struct EGLThreadInfo; // defined in ThreadInfo.h
typedef struct { typedef struct {
EGLThreadInfo* (*getThreadInfo)(); EGLThreadInfo* (*getThreadInfo)();
const char* (*getGLString)(int glEnum);
} EGLClient_eglInterface; } EGLClient_eglInterface;
typedef struct { typedef struct {

View File

@@ -142,14 +142,26 @@ struct EGLContext_t {
EGLSurface draw; EGLSurface draw;
EGLint version; EGLint version;
uint32_t rcContext; uint32_t rcContext;
const char* versionString;
const char* vendorString;
const char* rendererString;
const char* extensionString;
GLClientState * getClientState(){ return clientState; } GLClientState * getClientState(){ return clientState; }
private: private:
GLClientState * clientState; GLClientState * clientState;
}; };
EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) : dpy(dpy), config(config), EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) :
read(EGL_NO_SURFACE), draw(EGL_NO_SURFACE), rcContext(0) dpy(dpy),
config(config),
read(EGL_NO_SURFACE),
draw(EGL_NO_SURFACE),
rcContext(0),
versionString(NULL),
vendorString(NULL),
rendererString(NULL),
extensionString(NULL)
{ {
flags = 0; flags = 0;
version = 1; version = 1;
@@ -158,8 +170,13 @@ EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) : dpy(dpy), config(
EGLContext_t::~EGLContext_t() EGLContext_t::~EGLContext_t()
{ {
if (clientState) delete clientState; delete clientState;
delete [] versionString;
delete [] vendorString;
delete [] rendererString;
delete [] extensionString;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
//egl_surface_t //egl_surface_t
@@ -426,13 +443,76 @@ EGLBoolean egl_pbuffer_surface_t::connect()
return EGL_TRUE; 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. // The one and only supported display object.
static eglDisplay s_display; static eglDisplay s_display;
static EGLClient_eglInterface s_eglIface = { static EGLClient_eglInterface s_eglIface = {
getThreadInfo: getEGLThreadInfo getThreadInfo: getEGLThreadInfo,
getGLString: getGLString
}; };
#define DBG_FUNC DBG("%s\n", __FUNCTION__) #define DBG_FUNC DBG("%s\n", __FUNCTION__)
@@ -931,6 +1011,9 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
if (tInfo->currentContext) if (tInfo->currentContext)
tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT; 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 //Check maybe we need to init the encoder, if it's first eglMakeCurrent
if (tInfo->currentContext) { if (tInfo->currentContext) {
if (!hostCon->glEncoder()->isInitialized()) { 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 //connect the color buffer
if (drawSurf) if (drawSurf)
drawSurf->connect(); drawSurf->connect();

View File

@@ -12,6 +12,10 @@ rcQueryEGLString
dir buffer out dir buffer out
len buffer bufferSize len buffer bufferSize
rcGetGLString
dir buffer out
len buffer bufferSize
rcGetNumConfigs rcGetNumConfigs
dir numAttribs out dir numAttribs out
len numAttribs sizeof(uint32_t) len numAttribs sizeof(uint32_t)

View File

@@ -1,6 +1,7 @@
GL_ENRTY(GLint, rcGetRendererVersion) GL_ENRTY(GLint, rcGetRendererVersion)
GL_ENTRY(EGLint, rcGetEGLVersion, EGLint *major, EGLint *minor) GL_ENTRY(EGLint, rcGetEGLVersion, EGLint *major, EGLint *minor)
GL_ENTRY(EGLint, rcQueryEGLString, EGLenum name, void *buffer, EGLint bufferSize) 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, rcGetNumConfigs, uint32_t *numAttribs)
GL_ENTRY(EGLint, rcGetConfigs, uint32_t bufSize, GLuint *buffer) 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) GL_ENTRY(EGLint, rcChooseConfig, EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size)