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:
committed by
David 'Digit' Turner
parent
5b675210ed
commit
1ef706f96f
@@ -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);
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -5,6 +5,7 @@ struct EGLThreadInfo; // defined in ThreadInfo.h
|
||||
|
||||
typedef struct {
|
||||
EGLThreadInfo* (*getThreadInfo)();
|
||||
const char* (*getGLString)(int glEnum);
|
||||
} EGLClient_eglInterface;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user