diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-07-20 13:16:50 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-07-20 13:31:15 +0900 |
commit | 0c78783045e1b6b26133350865a910f97031ad02 (patch) | |
tree | f334e4c61ad561e5d155045413ed220c3628a95e | |
parent | ef9bd4183196b60e28b54d15eebdcc7428242d9f (diff) | |
download | efl-0c78783045e1b6b26133350865a910f97031ad02.tar.gz |
evas gl: Check EGL version before using dlsym
A recent commit broke texture_from_pixmap for NVIDIA EGL
(again), because eglCreateImage is a symbol in libEGL.so
but isn't in fact implemented by the driver.
That's because eglCreateImage() is exposed by libglvnd but
the underlying EGL implementation is NVIDIA and its version
is only 1.4, not 1.5 (where the API was introduced as core).
Instead of reverting the patch, it's better to cover our
bases properly and use dlsym() only if the version is right.
Note that GetProcAddress() may return garbage function
pointers for ALL functions as dynamic virtual functions may
be created on the fly by libglvnd. So it is absolutely
necessary to check the extension string as well.
See 0255f14dc2189c71776408b00307b8488bfa4dc5
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_context.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index c3534a5149..4ba070a574 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -324,15 +324,29 @@ evas_gl_symbols(void *(*GetProcAddress)(const char *name), const char *extsn) // wrong as this is not x11 (output) layer specific like the native surface // stuff. this is generic zero-copy textures for gl - FINDSYMN(eglsym_eglCreateImage, "eglCreateImage", NULL, secsym_func_void_ptr); - FINDSYMN(secsym_eglDestroyImage, "eglDestroyImage", NULL, secsym_func_uint); - if (!eglsym_eglCreateImage || !secsym_eglDestroyImage) - { - eglsym_eglCreateImage = NULL; - secsym_eglDestroyImage = NULL; - FINDSYMN(eglsym_eglCreateImageKHR, "eglCreateImageKHR", "EGL_KHR_image_base", secsym_func_void_ptr); - FINDSYMN(secsym_eglDestroyImage, "eglDestroyImageKHR", "EGL_KHR_image_base", secsym_func_uint); - } + { + const char *egl_version = eglQueryString(eglGetCurrentDisplay(), EGL_VERSION); + int vmin = 1, vmaj = 0; + + if (!egl_version || (sscanf(egl_version, "%d.%d", &vmaj, &vmin) != 2)) + vmaj = 0; + + // Verify that EGL is >= 1.5 before looking up core function + if ((vmaj > 1) || (vmaj == 1 && vmin >= 5)) + { + eglsym_eglCreateImage = dlsym(RTLD_DEFAULT, "eglCreateImage"); + secsym_eglDestroyImage = dlsym(RTLD_DEFAULT, "eglDestroyImage"); + } + + // For EGL <= 1.4 only the KHR extension exists: "EGL_KHR_image_base" + if (!eglsym_eglCreateImage || !secsym_eglDestroyImage) + { + eglsym_eglCreateImage = NULL; + secsym_eglDestroyImage = NULL; + FINDSYMN(eglsym_eglCreateImageKHR, "eglCreateImageKHR", "EGL_KHR_image_base", secsym_func_void_ptr); + FINDSYMN(secsym_eglDestroyImage, "eglDestroyImageKHR", "EGL_KHR_image_base", secsym_func_uint); + } + } FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", NULL, glsym_func_void); FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", "GL_EXT_geometry_shader4", glsym_func_void); |