summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-07-20 13:16:50 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-07-20 13:31:15 +0900
commit0c78783045e1b6b26133350865a910f97031ad02 (patch)
treef334e4c61ad561e5d155045413ed220c3628a95e
parentef9bd4183196b60e28b54d15eebdcc7428242d9f (diff)
downloadefl-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.c32
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);