gl: Fix usage of GLX/EGL/GL extensions

This is reverts:
e4c641ed1e
  build fix
19eb7b727fbf35620a13fb65b50d3056a484360e:
  glx: Fix black windows in E on nvidia

For all extension functions, we need to match with the extension itself
since GetProcAddress() can return a non-NULL value even when the function
does not exist. Drivers can do a runtime mapping depending on the
context. So, we only trust the return value of GetProcAddress() when
we know for sure that the extension exists.

Thus, if a symbol exists we will always prefer it rather than relying
on GetProcAddress().

Also, glGetString(GL_EXTENSIONS) is now deprecated so we're lucky
it still works most of the time. glGetStringi() should be used
instead. This patch changes some of the use cases, but not all.

Fixes T3030 (again)
Fixes T4288

@fix
This commit is contained in:
Jean-Philippe Andre 2016-08-04 11:49:33 +09:00
parent cb24d5f489
commit d5da8d31ce
5 changed files with 278 additions and 186 deletions

View File

@ -11,7 +11,6 @@
#define GLPIPES 1
#define FREE(a) do { if (a) { free(a); } a = NULL; } while(0)
static int sym_done = 0;
static int tbm_sym_done = 0;
int _evas_engine_GL_common_log_dom = -1;
Cutout_Rects *_evas_gl_common_cutout_rects = NULL;
@ -34,6 +33,8 @@ GLboolean (*glsym_glUnmapBuffer) (GLenum a) = NULL;
void (*glsym_glStartTiling) (GLuint a, GLuint b, GLuint c, GLuint d, GLuint e) = NULL;
void (*glsym_glEndTiling) (GLuint a) = NULL;
const char *(*glsym_glGetStringi) (GLenum name, GLuint index) = NULL;
#ifdef GL_GLES
# ifndef GL_LINE_SMOOTH
@ -79,106 +80,184 @@ sym_missing(void)
ERR("GL symbols missing!");
}
static int
_has_ext(const char *ext, const char **pexts, int *pnum)
{
if (!ext) return EINA_FALSE;
if (glsym_glGetStringi)
{
GLint num = *pnum, k;
if (!num)
{
glGetIntegerv(GL_NUM_EXTENSIONS, &num);
*pnum = num;
}
for (k = 0; k < num; k++)
{
const char *support = glsym_glGetStringi(GL_EXTENSIONS, k);
if (support && !strcmp(support, ext))
return EINA_TRUE;
}
return EINA_FALSE;
}
else
{
const char *exts = *pexts;
if (!exts)
{
exts = (const char *) glGetString(GL_EXTENSIONS);
if (!exts) return EINA_FALSE;
*pexts = exts;
}
return strstr(exts, ext) != NULL;
}
}
/* FIXME: return error if a required symbol was not found */
EAPI void
evas_gl_symbols(void *(*GetProcAddress)(const char *name))
{
if (sym_done) return;
sym_done = 1;
int failed = 0, num = 0;
const char *exts = NULL;
#define FINDSYM(dst, sym, typ) \
if (GetProcAddress) { \
if (!dst) dst = (typ)GetProcAddress(sym); \
} else { \
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
}
#define FINDSYM2(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
#define FALLBAK(dst, typ) if (!dst) dst = (typ)sym_missing
static int done = 0;
if (done) return;
#define SWAP(a, b, tmp) \
tmp = *a; \
*a = *b; \
*b = tmp;
/* For all extension functions, we need to match with the extension itself
* since GetProcAddress() can return a non-NULL value even when the function
* does not exist. Drivers can do a runtime mapping depending on the
* context. So, we only trust the return value of GetProcAddress() when
* we know for sure that the extension exists.
*
* Thus, if a symbol exists we will always prefer it rather than relying
* on GetProcAddress().
*
* -- jpeg, 2016/08/04
*/
glsym_glGetStringi = dlsym(RTLD_DEFAULT, "glGetStringi");
#define FINDSYM(dst, sym, ext, typ) do { \
if (!dst) { \
if (_has_ext(ext, &exts, &num) && GetProcAddress) \
dst = (typ) GetProcAddress(sym); \
if (!dst) \
dst = (typ) dlsym(RTLD_DEFAULT, sym); \
}} while (0)
#define FALLBAK(dst, typ) do { \
if (!dst) { \
ERR("Symbol '%s' could not be found!", (#dst) + 6); \
dst = (typ) sym_missing; \
failed = EINA_TRUE; \
}} while (0)
#ifdef GL_GLES
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
FINDSYM2(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", NULL, glsym_func_void);
FALLBAK(glsym_glGenFramebuffers, glsym_func_void);
FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer", NULL, glsym_func_void);
FALLBAK(glsym_glBindFramebuffer, glsym_func_void);
#else
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersEXT", glsym_func_void);
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersARB", glsym_func_void);
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
// nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
FINDSYM2(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
/*
Note about FBO APIs (from ARB_framebuffer_object):
Framebuffer objects created with the commands defined by the
GL_EXT_framebuffer_object extension are defined to be shared, while
FBOs created with commands defined by the OpenGL core or
GL_ARB_framebuffer_object extension are defined *not* to be shared.
[...]
Since the above pairs are aliases, the functions of a pair are
equivalent. Note that the functions BindFramebuffer and
BindFramebufferEXT are not aliases and neither are the functions
BindRenderbuffer and BindRenderbufferEXT. Because object creation
occurs when the framebuffer object is bound for the first time, a
framebuffer object can be shared across contexts only if it was first
bound with BindFramebufferEXT. Framebuffers first bound with
BindFramebuffer may not be shared across contexts. Framebuffer
objects created with BindFramebufferEXT may subsequently be bound
using BindFramebuffer. Framebuffer objects created with
BindFramebuffer may be bound with BindFramebufferEXT provided they are
bound to the same context they were created on.
Undefined behavior results when using FBOs created by EXT commands
through non-EXT interfaces, or vice-versa.
Thus, I believe core should come first, then ARB and use EXT as fallback.
-- jpeg, 2016/08/04
Old note:
nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it:
glGenFramebuffers, glBindFramebuffer, glFramebufferTexture2D, glDeleteFramebuffers
*/
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", NULL, glsym_func_void);
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersARB", "GL_ARB_framebuffer_object", glsym_func_void);
FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersEXT", "GL_EXT_framebuffer_object", glsym_func_void);
FALLBAK(glsym_glGenFramebuffers, glsym_func_void);
FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer", NULL, glsym_func_void);
FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferARB", "GL_ARB_framebuffer_object", glsym_func_void);
FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferEXT", "GL_EXT_framebuffer_object", glsym_func_void);
FALLBAK(glsym_glBindFramebuffer, glsym_func_void);
#endif
#ifdef GL_GLES
FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
FINDSYM2(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
FALLBAK(glsym_glBindFramebuffer, glsym_func_void);
#else
FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferEXT", glsym_func_void);
FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferARB", glsym_func_void);
FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
// nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
FINDSYM2(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
FALLBAK(glsym_glBindFramebuffer, glsym_func_void);
#endif
FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DEXT", glsym_func_void);
FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DARB", glsym_func_void);
FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void);
// nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
FINDSYM2(glsym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void);
FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2D", NULL, glsym_func_void);
FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DARB", "GL_ARB_framebuffer_object", glsym_func_void);
FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DEXT", "GL_EXT_framebuffer_object", glsym_func_void);
FALLBAK(glsym_glFramebufferTexture2D, glsym_func_void);
FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersEXT", glsym_func_void);
FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersARB", glsym_func_void);
FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void);
// nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
FINDSYM2(glsym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void);
FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffers", NULL, glsym_func_void);
FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersARB", "GL_ARB_framebuffer_object", glsym_func_void);
FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersEXT", "GL_EXT_framebuffer_object", glsym_func_void);
FALLBAK(glsym_glDeleteFramebuffers, glsym_func_void);
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void);
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryKHR", glsym_func_void);
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryEXT", glsym_func_void);
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryARB", glsym_func_void);
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void);
// Not sure there's an EXT variant
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinary", NULL, glsym_func_void);
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryOES", "GL_OES_get_program_binary", glsym_func_void);
FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryEXT", "GL_EXT_get_program_binary", glsym_func_void);
FINDSYM(glsym_glProgramBinary, "glProgramBinaryOES", glsym_func_void);
FINDSYM(glsym_glProgramBinary, "glProgramBinaryKHR", glsym_func_void);
FINDSYM(glsym_glProgramBinary, "glProgramBinaryEXT", glsym_func_void);
FINDSYM(glsym_glProgramBinary, "glProgramBinaryARB", glsym_func_void);
FINDSYM(glsym_glProgramBinary, "glProgramBinary", glsym_func_void);
// Not sure there's an EXT variant
FINDSYM(glsym_glProgramBinary, "glProgramBinary", NULL, glsym_func_void);
FINDSYM(glsym_glProgramBinary, "glProgramBinaryOES", "GL_OES_get_program_binary", glsym_func_void);
FINDSYM(glsym_glProgramBinary, "glProgramBinaryEXT", "GL_EXT_get_program_binary", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", NULL, glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", "GL_EXT_separate_shader_objects", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", "GL_ARB_geometry_shader4", glsym_func_void);
FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompilerEXT", glsym_func_void);
FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompilerARB", glsym_func_void);
FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompiler", glsym_func_void);
FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompiler", NULL, glsym_func_void);
#ifndef GL_GLES
FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompiler", "GL_ARB_ES2_compatibility", glsym_func_void);
#endif
FINDSYM(glsym_glStartTiling, "glStartTilingQCOM", glsym_func_void);
FINDSYM(glsym_glStartTiling, "glStartTiling", glsym_func_void);
FINDSYM(glsym_glStartTiling, "glActivateTileQCOM", glsym_func_void);
FINDSYM(glsym_glEndTiling, "glEndTilingQCOM", glsym_func_void);
FINDSYM(glsym_glEndTiling, "glEndTiling", glsym_func_void);
// Not sure there's a core variant, glActivateTileQCOM is strange as well
FINDSYM(glsym_glStartTiling, "glStartTilingQCOM", "GL_QCOM_tiled_rendering", glsym_func_void);
FINDSYM(glsym_glStartTiling, "glStartTiling", NULL, glsym_func_void);
FINDSYM(glsym_glStartTiling, "glActivateTileQCOM", NULL, glsym_func_void);
FINDSYM(glsym_glEndTiling, "glEndTilingQCOM", "GL_QCOM_tiled_rendering", glsym_func_void);
FINDSYM(glsym_glEndTiling, "glEndTiling", NULL, glsym_func_void);
if (!getenv("EVAS_GL_MAPBUFFER_DISABLE"))
{
FINDSYM(glsym_glMapBuffer, "glMapBufferOES", glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBufferEXT", glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBufferARB", glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBufferKHR", glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBuffer", glsym_func_void_ptr);
// Not sure there's an EXT variant. (probably no KHR variant)
FINDSYM(glsym_glMapBuffer, "glMapBuffer", NULL, glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBufferOES", "GL_OES_mapbuffer", glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBufferARB", "GL_ARB_vertex_buffer_object", glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBufferARB", "GLX_ARB_vertex_buffer_object", glsym_func_void_ptr);
FINDSYM(glsym_glMapBuffer, "glMapBufferEXT", NULL, glsym_func_void_ptr);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferOES", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferEXT", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferARB", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferKHR", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBuffer", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBuffer", NULL, glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferOES", "GL_OES_mapbuffer", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferARB", "GL_ARB_vertex_buffer_object", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferARB", "GLX_ARB_vertex_buffer_object", glsym_func_boolean);
FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferEXT", NULL, glsym_func_boolean);
}
#ifdef GL_GLES
@ -188,36 +267,41 @@ evas_gl_symbols(void *(*GetProcAddress)(const char *name))
// wrong as this is not x11 (output) layer specific like the native surface
// stuff. this is generic zero-copy textures for gl
FINDSYM(secsym_eglCreateImage, "eglCreateImageOES", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImageKHR", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImageEXT", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImageARB", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImage", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImage", NULL, secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImageOES", "GL_OES_EGL_image_base", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImageOES", "GL_OES_EGL_image", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImageKHR", "GL_EGL_KHR_image_base", secsym_func_void_ptr);
FINDSYM(secsym_eglCreateImage, "eglCreateImageKHR", "GL_EGL_KHR_image", secsym_func_void_ptr);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageOES", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageKHR", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageEXT", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageARB", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImage", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImage", NULL, secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageOES", "GL_OES_EGL_image_base", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageOES", "GL_OES_EGL_image", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageKHR", "GL_EGL_KHR_image_base", secsym_func_uint);
FINDSYM(secsym_eglDestroyImage, "eglDestroyImageKHR", "GL_EGL_KHR_image", secsym_func_uint);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriOES", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriKHR", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", NULL, glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", "GL_EXT_geometry_shader4", glsym_func_void);
FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", "GL_ARB_geometry_shader4", glsym_func_void);
FINDSYM(secsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
FINDSYM(secsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", "GL_OES_EGL_image_external", glsym_func_void);
FINDSYM(secsym_eglMapImageSEC, "eglMapImageSEC", secsym_func_void_ptr);
// Old SEC extensions
FINDSYM(secsym_eglMapImageSEC, "eglMapImageSEC", NULL, secsym_func_void_ptr);
FINDSYM(secsym_eglUnmapImageSEC, "eglUnmapImageSEC", NULL, secsym_func_uint);
FINDSYM(secsym_eglGetImageAttribSEC, "eglGetImageAttribSEC", NULL, secsym_func_uint);
FINDSYM(secsym_eglUnmapImageSEC, "eglUnmapImageSEC", secsym_func_uint);
FINDSYM(secsym_eglGetImageAttribSEC, "eglGetImageAttribSEC", secsym_func_uint);
#endif
#undef FINDSYM
#undef FINDSYM2
#undef FALLBAK
if (failed)
{
ERR("Some core GL symbols could not be found, the GL engine will not "
"work properly.");
}
done = 1;
}
static void
@ -484,8 +568,9 @@ _evas_gl_common_version_check(int *gles_ver)
*gles_ver = 3;
else if ((major > 3) || ((major == 3) && (minor >= 3))) /* >= 3.3 */
{
const char *exts = (const char *) glGetString(GL_EXTENSIONS);
if (exts && strstr(exts, "GL_ARB_ES3_compatibility"))
const char *exts = NULL;
int num = 0;
if (_has_ext("GL_ARB_ES3_compatibility", &exts, &num))
*gles_ver = 3;
else
*gles_ver = 2;
@ -669,6 +754,10 @@ evas_gl_common_context_new(void)
return _evas_gl_common_context;
}
#endif
if (!glsym_glGetStringi)
glsym_glGetStringi = dlsym(RTLD_DEFAULT, "glGetStringi");
if (!_evas_gl_common_version_check(&gles_version))
return NULL;
gc = calloc(1, sizeof(Evas_Engine_GL_Context));
@ -1756,6 +1845,11 @@ evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
PUSH_6_COLORS(pn, r, g, b, a);
}
#define SWAP(a, b, tmp) \
tmp = *a; \
*a = *b; \
*b = tmp;
// 1-2 4-1
// | | => | |
// 4-3 3-2

View File

@ -189,6 +189,9 @@
#ifndef GL_WRITE_ONLY
#define GL_WRITE_ONLY 0x88B9
#endif
#ifndef GL_NUM_EXTENSIONS
#define GL_NUM_EXTENSIONS 0x821D
#endif
#ifndef EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC
#define EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC 1
#endif

View File

@ -1256,6 +1256,12 @@ static const EVGL_Interface evgl_funcs =
//----------------------------------------------------------//
static inline int
_has_ext(const char *exts, const char *ext)
{
if (!exts || !ext) return EINA_FALSE;
return strstr(exts, ext) != NULL;
}
static void
gl_symbols(void)
@ -1299,125 +1305,123 @@ gl_symbols(void)
LINK2GENERIC(evas_gl_common_current_context_get);
LINK2GENERIC(evas_gl_common_shaders_flush);
#define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym);
#ifdef GL_GLES
#define FINDSYM(dst, sym, typ) \
if (glsym_eglGetProcAddress) { \
if (!dst) dst = (typ)glsym_eglGetProcAddress(sym); \
} else { \
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
}
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
FINDSYM(glsym_eglQueryWaylandBufferWL, "eglQueryWaylandBufferWL",
glsym_func_uint)
#else
#define FINDSYM(dst, sym, typ) \
if (glsym_glXGetProcAddress) { \
if (!dst) dst = (typ)glsym_glXGetProcAddress(sym); \
} else { \
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
}
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
#endif
#undef FINDSYM
done = 1;
}
void
eng_gl_symbols(Eina_Bool noext_glXCreatePixmap)
eng_gl_symbols(Outbuf *ob)
{
static int done = 0;
const char *exts;
if (done) return;
/* GetProcAddress() may not return NULL, even if the extension is not
* supported. Nvidia drivers since version 360 never return NULL, thus
* we need to always match the function name with their full extension
* name. Other drivers tend to return NULL for glX/egl prefixed names, but
* this could change in the future.
*
* -- jpeg, 2016/08/04
*/
#ifdef GL_GLES
(void) noext_glXCreatePixmap;
#define FINDSYM(dst, sym, typ) \
if (glsym_eglGetProcAddress) { \
if (!dst) dst = (typ)glsym_eglGetProcAddress(sym); \
} else { \
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
}
#define FINDSYM(dst, sym, ext, typ) do { \
if (!dst) { \
if (_has_ext(exts, ext) && glsym_eglGetProcAddress) \
dst = (typ) glsym_eglGetProcAddress(sym); \
if (!dst) \
dst = (typ) dlsym(RTLD_DEFAULT, sym); \
}} while (0)
// Find GL extensions
glsym_evas_gl_symbols((void*)glsym_eglGetProcAddress);
FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
// Find EGL extensions
exts = eglQueryString(ob->egl_disp, EGL_EXTENSIONS);
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_void);
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_void);
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageARB", glsym_func_void);
FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", glsym_func_void);
FINDSYM(glsym_eglCreateImage, "eglCreateImage", NULL, glsym_func_void_ptr);
FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", "EGL_KHR_image_base", glsym_func_void_ptr);
FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", "EGL_KHR_image", glsym_func_void_ptr);
FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", NULL, glsym_func_void);
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", "EGL_KHR_image_base", glsym_func_void);
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", "EGL_KHR_image", glsym_func_void);
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT", glsym_func_uint);
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL", glsym_func_uint);
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", glsym_func_uint);
FINDSYM(glsym_eglSetDamageRegionKHR, "eglSetDamageRegionKHR", glsym_func_uint);
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", NULL, glsym_func_uint);
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT", "EGL_EXT_swap_buffers_with_damage", glsym_func_uint);
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageKHR", "EGL_KHR_swap_buffers_with_damage", glsym_func_uint);
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL", "EGL_INTEL_swap_buffers_with_damage", glsym_func_uint);
FINDSYM(glsym_eglSetDamageRegionKHR, "eglSetDamageRegionKHR", "EGL_KHR_partial_update", glsym_func_uint);
FINDSYM(glsym_eglQueryWaylandBufferWL, "eglQueryWaylandBufferWL", "EGL_WL_bind_wayland_display", glsym_func_uint);
// This is a GL extension
exts = (const char *) glGetString(GL_EXTENSIONS);
FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", "GL_OES_EGL_image", glsym_func_void);
FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", "GL_OES_EGL_image_external", glsym_func_void);
#else
#define FINDSYM(dst, sym, typ) \
if (glsym_glXGetProcAddress) { \
if (!dst) dst = (typ)glsym_glXGetProcAddress(sym); \
} else { \
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
}
#define FINDSYM(dst, sym, ext, typ) do { \
if (!dst) { \
if (_has_ext(exts, ext) && glsym_glXGetProcAddress) \
dst = (typ) glsym_glXGetProcAddress(sym); \
if (!dst) \
dst = (typ) dlsym(RTLD_DEFAULT, sym); \
}} while (0)
// Find GL extensions
glsym_evas_gl_symbols((void*)glsym_glXGetProcAddress);
if (noext_glXCreatePixmap)
{
/* Note for nvidia >= 360:
* glXBindTexImage{EXT,ARB} should be preferred over glXBindTexImage
* glXCreatePixmap should be preferred over glXCreatePixmap{EXT,ARB}
*/
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
}
// Find GLX extensions
exts = glXQueryExtensionsString((Display *) ob->disp, ob->screen);
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", glsym_func_void);
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", glsym_func_void);
FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", glsym_func_void);
FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", NULL, glsym_func_void);
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", "GLX_EXT_texture_from_pixmap", glsym_func_void);
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", "GLX_ARB_render_texture", glsym_func_void);
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", glsym_func_void);
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", glsym_func_void);
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", glsym_func_void);
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", NULL, glsym_func_void);
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", "GLX_EXT_texture_from_pixmap", glsym_func_void);
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", "GLX_ARB_render_texture", glsym_func_void);
FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", glsym_func_int);
FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", "GLX_SGI_video_sync", glsym_func_int);
FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", "GLX_SGI_video_sync", glsym_func_int);
FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", glsym_func_int);
// GLX 1.3
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", NULL, glsym_func_xid);
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", NULL, glsym_func_void);
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", NULL, glsym_func_int);
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapEXT", glsym_func_xid);
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapARB", glsym_func_xid);
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
// swap interval: MESA and SGI take (interval)
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", "GLX_MESA_swap_control", glsym_func_int);
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", "GLX_SGI_swap_control", glsym_func_int);
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapEXT", glsym_func_void);
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapARB", glsym_func_void);
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
// swap interval: EXT takes (dpy, drawable, interval)
FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", "GLX_EXT_swap_control", glsym_func_void);
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", glsym_func_int);
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_int);
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_int);
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int);
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int);
FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void);
FINDSYM(glsym_glXReleaseBuffersMESA, "glXReleaseBuffersMESA", glsym_func_void);
FINDSYM(glsym_glXReleaseBuffersMESA, "glXReleaseBuffersMESA", "GLX_MESA_release_buffers", glsym_func_void);
#endif
#undef FINDSYM
done = 1;
}

View File

@ -76,7 +76,6 @@ struct _Outbuf
unsigned char msaa;
#ifndef GL_GLES
Eina_Bool loose_binding : 1;
Eina_Bool noext_glXCreatePixmap : 1;
#endif
} detected;
@ -200,7 +199,7 @@ Evas_Engine_GL_Context *eng_outbuf_gl_context_get(Outbuf *ob);
void *eng_outbuf_egl_display_get(Outbuf *ob);
Eina_Bool eng_preload_make_current(void *data, void *doit);
void eng_gl_symbols(Eina_Bool noext_glXCreatePixmap);
void eng_gl_symbols(Outbuf *ob);
static inline int
_re_wincheck(Outbuf *ob)

View File

@ -542,9 +542,6 @@ try_gles2:
// ALSO as of some nvidia driver version loose binding is
// probably not needed
if (v1 < 195) gw->detected.loose_binding = 1;
#ifndef GL_GLES
if (v1 >= 360) gw->detected.noext_glXCreatePixmap = 1;
#endif
}
}
else
@ -560,12 +557,7 @@ try_gles2:
gw->detected.msaa = val;
#endif
#ifndef GL_GLES
eng_gl_symbols(gw->detected.noext_glXCreatePixmap);
#else
eng_gl_symbols(EINA_FALSE); // EINA_FALSE is ignored anyway for gl_gles
#endif
eng_gl_symbols(gw);
gw->gl_context = glsym_evas_gl_common_context_new();
if (!gw->gl_context)
{