Merge "Fix EGL shim extension injection for GL ES 3 drivers."
This commit is contained in:
commit
5a606c3ab9
@ -292,6 +292,44 @@ const GLubyte * egl_get_string_for_current_context(GLenum name) {
|
||||
return (const GLubyte *)c->gl_extensions.string();
|
||||
}
|
||||
|
||||
const GLubyte * egl_get_string_for_current_context(GLenum name, GLuint index) {
|
||||
// NOTE: returning NULL here will fall-back to the default
|
||||
// implementation.
|
||||
|
||||
EGLContext context = egl_tls_t::getContext();
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
return NULL;
|
||||
|
||||
egl_context_t const * const c = get_context(context);
|
||||
if (c == NULL) // this should never happen, by construction
|
||||
return NULL;
|
||||
|
||||
if (name != GL_EXTENSIONS)
|
||||
return NULL;
|
||||
|
||||
// if index is out of bounds, assume it will be in the default
|
||||
// implementation too, so we don't have to generate a GL error here
|
||||
if (index >= c->tokenized_gl_extensions.size())
|
||||
return NULL;
|
||||
|
||||
return (const GLubyte *)c->tokenized_gl_extensions.itemAt(index).string();
|
||||
}
|
||||
|
||||
GLint egl_get_num_extensions_for_current_context() {
|
||||
// NOTE: returning -1 here will fall-back to the default
|
||||
// implementation.
|
||||
|
||||
EGLContext context = egl_tls_t::getContext();
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
return -1;
|
||||
|
||||
egl_context_t const * const c = get_context(context);
|
||||
if (c == NULL) // this should never happen, by construction
|
||||
return -1;
|
||||
|
||||
return (GLint)c->tokenized_gl_extensions.size();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// this mutex protects:
|
||||
|
@ -113,6 +113,18 @@ void egl_context_t::onMakeCurrent(EGLSurface draw, EGLSurface read) {
|
||||
temp.append(gl_extensions);
|
||||
gl_extensions.setTo(temp);
|
||||
}
|
||||
|
||||
// tokenize the supported extensions for the glGetStringi() wrapper
|
||||
exts = gl_extensions.string();
|
||||
while (1) {
|
||||
const char *end = strchr(exts, ' ');
|
||||
if (end == NULL) {
|
||||
tokenized_gl_extensions.push(String8(exts));
|
||||
break;
|
||||
}
|
||||
tokenized_gl_extensions.push(String8(exts, end - exts));
|
||||
exts = end + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
#include <system/window.h>
|
||||
|
||||
@ -159,6 +160,7 @@ public:
|
||||
egl_connection_t const* cnx;
|
||||
int version;
|
||||
String8 gl_extensions;
|
||||
Vector<String8> tokenized_gl_extensions;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -205,13 +205,22 @@ extern "C" {
|
||||
#undef CALL_GL_API_RETURN
|
||||
|
||||
/*
|
||||
* glGetString() is special because we expose some extensions in the wrapper
|
||||
* glGetString() and glGetStringi() are special because we expose some
|
||||
* extensions in the wrapper. Also, wrapping glGetXXX() is required because
|
||||
* the value returned for GL_NUM_EXTENSIONS may have been altered by the
|
||||
* injection of the additional extensions.
|
||||
*/
|
||||
|
||||
extern "C" const GLubyte * __glGetString(GLenum name);
|
||||
extern "C" {
|
||||
const GLubyte * __glGetString(GLenum name);
|
||||
const GLubyte * __glGetStringi(GLenum name, GLuint index);
|
||||
void __glGetBooleanv(GLenum pname, GLboolean * data);
|
||||
void __glGetFloatv(GLenum pname, GLfloat * data);
|
||||
void __glGetIntegerv(GLenum pname, GLint * data);
|
||||
void __glGetInteger64v(GLenum pname, GLint64 * data);
|
||||
}
|
||||
|
||||
const GLubyte * glGetString(GLenum name)
|
||||
{
|
||||
const GLubyte * glGetString(GLenum name) {
|
||||
const GLubyte * ret = egl_get_string_for_current_context(name);
|
||||
if (ret == NULL) {
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
|
||||
@ -219,3 +228,64 @@ const GLubyte * glGetString(GLenum name)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const GLubyte * glGetStringi(GLenum name, GLuint index) {
|
||||
const GLubyte * ret = egl_get_string_for_current_context(name, index);
|
||||
if (ret == NULL) {
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
|
||||
if(_c) ret = _c->glGetStringi(name, index);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void glGetBooleanv(GLenum pname, GLboolean * data) {
|
||||
if (pname == GL_NUM_EXTENSIONS) {
|
||||
int num_exts = egl_get_num_extensions_for_current_context();
|
||||
if (num_exts >= 0) {
|
||||
*data = num_exts > 0 ? GL_TRUE : GL_FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
|
||||
if (_c) _c->glGetBooleanv(pname, data);
|
||||
}
|
||||
|
||||
void glGetFloatv(GLenum pname, GLfloat * data) {
|
||||
if (pname == GL_NUM_EXTENSIONS) {
|
||||
int num_exts = egl_get_num_extensions_for_current_context();
|
||||
if (num_exts >= 0) {
|
||||
*data = (GLfloat)num_exts;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
|
||||
if (_c) _c->glGetFloatv(pname, data);
|
||||
}
|
||||
|
||||
void glGetIntegerv(GLenum pname, GLint * data) {
|
||||
if (pname == GL_NUM_EXTENSIONS) {
|
||||
int num_exts = egl_get_num_extensions_for_current_context();
|
||||
if (num_exts >= 0) {
|
||||
*data = (GLint)num_exts;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
|
||||
if (_c) _c->glGetIntegerv(pname, data);
|
||||
}
|
||||
|
||||
void glGetInteger64v(GLenum pname, GLint64 * data) {
|
||||
if (pname == GL_NUM_EXTENSIONS) {
|
||||
int num_exts = egl_get_num_extensions_for_current_context();
|
||||
if (num_exts >= 0) {
|
||||
*data = (GLint64)num_exts;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
|
||||
if (_c) _c->glGetInteger64v(pname, data);
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxCount, GLsizei *
|
||||
GLint API_ENTRY(glGetAttribLocation)(GLuint program, const GLchar * name) {
|
||||
CALL_GL_API_RETURN(glGetAttribLocation, program, name);
|
||||
}
|
||||
void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean * data) {
|
||||
void API_ENTRY(__glGetBooleanv)(GLenum pname, GLboolean * data) {
|
||||
CALL_GL_API(glGetBooleanv, pname, data);
|
||||
}
|
||||
void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint * params) {
|
||||
@ -181,13 +181,13 @@ void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint * para
|
||||
GLenum API_ENTRY(glGetError)(void) {
|
||||
CALL_GL_API_RETURN(glGetError);
|
||||
}
|
||||
void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat * data) {
|
||||
void API_ENTRY(__glGetFloatv)(GLenum pname, GLfloat * data) {
|
||||
CALL_GL_API(glGetFloatv, pname, data);
|
||||
}
|
||||
void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint * params) {
|
||||
CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetIntegerv)(GLenum pname, GLint * data) {
|
||||
void API_ENTRY(__glGetIntegerv)(GLenum pname, GLint * data) {
|
||||
CALL_GL_API(glGetIntegerv, pname, data);
|
||||
}
|
||||
void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint * params) {
|
||||
@ -604,7 +604,7 @@ void API_ENTRY(glClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *
|
||||
void API_ENTRY(glClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
|
||||
CALL_GL_API(glClearBufferfi, buffer, drawbuffer, depth, stencil);
|
||||
}
|
||||
const GLubyte * API_ENTRY(glGetStringi)(GLenum name, GLuint index) {
|
||||
const GLubyte * API_ENTRY(__glGetStringi)(GLenum name, GLuint index) {
|
||||
CALL_GL_API_RETURN(glGetStringi, name, index);
|
||||
}
|
||||
void API_ENTRY(glCopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
|
||||
@ -649,7 +649,7 @@ GLenum API_ENTRY(glClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeo
|
||||
void API_ENTRY(glWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout) {
|
||||
CALL_GL_API(glWaitSync, sync, flags, timeout);
|
||||
}
|
||||
void API_ENTRY(glGetInteger64v)(GLenum pname, GLint64 * data) {
|
||||
void API_ENTRY(__glGetInteger64v)(GLenum pname, GLint64 * data) {
|
||||
CALL_GL_API(glGetInteger64v, pname, data);
|
||||
}
|
||||
void API_ENTRY(glGetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values) {
|
||||
|
@ -30,6 +30,9 @@ namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name);
|
||||
EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name,
|
||||
GLuint index);
|
||||
EGLAPI GLint egl_get_num_extensions_for_current_context();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
@ -86,11 +86,25 @@ def fmtTypeNameList(params):
|
||||
return ', '.join(['"%s", %s' % (p[0], p[1]) for p in params])
|
||||
|
||||
|
||||
def overrideSymbolName(sym):
|
||||
# The wrapper intercepts glGetString and (sometimes) calls the generated
|
||||
# __glGetString thunk which dispatches to the driver's glGetString
|
||||
if sym == 'glGetString':
|
||||
return '__glGetString'
|
||||
def overrideSymbolName(sym, apiname):
|
||||
# The wrapper intercepts various glGet and glGetString functions and
|
||||
# (sometimes) calls the generated thunk which dispatches to the
|
||||
# driver's implementation
|
||||
wrapped_get_syms = {
|
||||
'gles1' : [
|
||||
'glGetString'
|
||||
],
|
||||
'gles2' : [
|
||||
'glGetString',
|
||||
'glGetStringi',
|
||||
'glGetBooleanv',
|
||||
'glGetFloatv',
|
||||
'glGetIntegerv',
|
||||
'glGetInteger64v',
|
||||
],
|
||||
}
|
||||
if sym in wrapped_get_syms.get(apiname):
|
||||
return '__' + sym
|
||||
else:
|
||||
return sym
|
||||
|
||||
@ -115,8 +129,8 @@ class TrampolineGen(reg.OutputGenerator):
|
||||
print('%s API_ENTRY(%s)(%s) {\n'
|
||||
' %s(%s%s%s);\n'
|
||||
'}'
|
||||
% (rtype, overrideSymbolName(fname), fmtParams(params),
|
||||
call, fname,
|
||||
% (rtype, overrideSymbolName(fname, self.genOpts.apiname),
|
||||
fmtParams(params), call, fname,
|
||||
', ' if len(params) > 0 else '',
|
||||
fmtArgs(params)),
|
||||
file=self.outFile)
|
||||
|
Loading…
Reference in New Issue
Block a user