jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=8942c0c29bc0f58c8821136c03b6cbff9b5b13c8
commit 8942c0c29bc0f58c8821136c03b6cbff9b5b13c8 Author: Jean-Philippe Andre <jp.an...@samsung.com> Date: Thu Jul 16 22:25:36 2015 +0900 Evas GL: Fix sync, wlbuffer and image egl ext functions Before this patch, those EGL/EvasGL functions can not work without a current context. But EGL does not require any current context for those to work, or at least, this should be left to the driver to decide. Evas GL was only able to get a pointer to the display if a context was current. The display pointer should be infered from Evas_GL unless we can find a current display. EGL does not require a context to be current in most of these function calls. This should bring evasgl a little bit closer to EGL in terms of behaviour (those are EGL-only extensions, btw). Thanks @spacegrapher for the quick review @fix --- src/lib/evas/canvas/evas_gl.c | 15 +++- src/lib/evas/include/evas_private.h | 2 +- .../evas/engines/gl_common/evas_gl_api_ext.c | 97 ++++++++++++---------- src/modules/evas/engines/gl_common/evas_gl_core.c | 19 ++++- src/modules/evas/engines/gl_common/evas_gl_core.h | 2 +- .../evas/engines/gl_common/evas_gl_core_private.h | 1 + src/modules/evas/engines/gl_generic/evas_engine.c | 5 +- .../evas/engines/software_generic/evas_engine.c | 3 +- 8 files changed, 91 insertions(+), 53 deletions(-) diff --git a/src/lib/evas/canvas/evas_gl.c b/src/lib/evas/canvas/evas_gl.c index 68ac0ec..5b539e4 100644 --- a/src/lib/evas/canvas/evas_gl.c +++ b/src/lib/evas/canvas/evas_gl.c @@ -326,7 +326,7 @@ evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf) surf = NULL; } -// Internal function - called from evas_gl_core.c +// Internal functions - called from evas_gl_core.c static void * evas_gl_native_context_get(void *context) { @@ -335,6 +335,17 @@ evas_gl_native_context_get(void *context) return ctx->data; } +static void * +evas_gl_engine_data_get(void *evgl) +{ + Evas_GL *evasgl = evgl; + + if (!evasgl) return NULL; + if (!evasgl->evas) return NULL; + + return evasgl->evas->engine.data.output; +} + EAPI Evas_GL_Context * evas_gl_context_version_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx, Evas_GL_Context_Version version) @@ -367,7 +378,7 @@ evas_gl_context_version_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx, ctx->version = version; ctx->data = evas_gl->evas->engine.func->gl_context_create (evas_gl->evas->engine.data.output, share_ctx ? share_ctx->data : NULL, - version, &evas_gl_native_context_get); + version, &evas_gl_native_context_get, &evas_gl_engine_data_get); // Set a few variables if (!ctx->data) diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index ecb8b8c..2e54ab0 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1370,7 +1370,7 @@ struct _Evas_Func void *(*gl_surface_create) (void *data, void *config, int w, int h); void *(*gl_pbuffer_surface_create) (void *data, void *config, int w, int h, int const *attrib_list); int (*gl_surface_destroy) (void *data, void *surface); - void *(*gl_context_create) (void *data, void *share_context, int version, void *(*native_context_get)(void *ctx)); + void *(*gl_context_create) (void *data, void *share_context, int version, void *(*native_context_get)(void *ctx), void *(*engine_data_get)(void *evasgl)); int (*gl_context_destroy) (void *data, void *context); int (*gl_make_current) (void *data, void *surface, void *context); const char *(*gl_string_query) (void *data, int name); diff --git a/src/modules/evas/engines/gl_common/evas_gl_api_ext.c b/src/modules/evas/engines/gl_common/evas_gl_api_ext.c index ef5ee4f..0f91566 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_api_ext.c +++ b/src/modules/evas/engines/gl_common/evas_gl_api_ext.c @@ -115,7 +115,7 @@ struct wl_resource; // Evas extensions from EGL extensions #ifdef GL_GLES -#define EGLDISPLAY_GET() _evgl_egl_display_get(__FUNCTION__) +#define EGLDISPLAY_GET(a) _evgl_egl_display_get(__FUNCTION__, a) // this struct defines an EvasGLImage when using EGL typedef struct _EvasGLImage { @@ -124,13 +124,21 @@ typedef struct _EvasGLImage { } EvasGLImage_EGL; static EGLDisplay -_evgl_egl_display_get(const char *function) +_evgl_egl_display_get(const char *function, Evas_GL *evgl) { EGLDisplay dpy = EGL_NO_DISPLAY; EVGL_Resource *rsc; + if (!evgl_engine || !evgl_engine->funcs || !evgl_engine->funcs->display_get) + { + ERR("%s: Invalid Engine... (Can't acccess EGL Display)\n", function); + evas_gl_common_error_set(NULL, EVAS_GL_BAD_DISPLAY); + return EGL_NO_DISPLAY; + } + if (!(rsc=_evgl_tls_resource_get())) { + if (evgl) goto fallback; ERR("%s: Unable to execute GL command. Error retrieving tls", function); evas_gl_common_error_set(NULL, EVAS_GL_NOT_INITIALIZED); return EGL_NO_DISPLAY; @@ -138,22 +146,18 @@ _evgl_egl_display_get(const char *function) if (!rsc->current_eng) { + if (evgl) goto fallback; ERR("%s: no current engine set; ensure you've called evas_gl_make_current()", function); evas_gl_common_error_set(NULL, EVAS_GL_NOT_INITIALIZED); return EGL_NO_DISPLAY; } - if ((evgl_engine) && (evgl_engine->funcs->display_get)) - { - dpy = (EGLDisplay)evgl_engine->funcs->display_get(rsc->current_eng); - return dpy; - } - else - { - ERR("%s: Invalid Engine... (Can't acccess EGL Display)\n", function); - evas_gl_common_error_set(NULL, EVAS_GL_BAD_DISPLAY); - return EGL_NO_DISPLAY; - } + dpy = (EGLDisplay) evgl_engine->funcs->display_get(rsc->current_eng); + return dpy; + +fallback: + dpy = (EGLDisplay) evgl_engine->funcs->display_get(_evgl_engine_data_get(evgl)); + return dpy; } static void * @@ -198,29 +202,38 @@ _evgl_eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, static void * evgl_evasglCreateImage(int target, void* buffer, const int *attrib_list) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(NULL); EGLContext ctx = EGL_NO_CONTEXT; - if (!dpy) return NULL; + if (!dpy) + { + WRN("No display found, use evasglCreateImageForContext instead."); + return NULL; + } /* EGL_NO_CONTEXT will always fail for TEXTURE_2D */ if (target == EVAS_GL_TEXTURE_2D) { ctx = eglGetCurrentContext(); - INF("Creating EGL image based on the current context: %p", ctx); + DBG("Creating EGL image based on the current context: %p", ctx); } return _evgl_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list); } static void * -evgl_evasglCreateImageForContext(Evas_GL *evasgl EINA_UNUSED, Evas_GL_Context *evasctx, +evgl_evasglCreateImageForContext(Evas_GL *evasgl, Evas_GL_Context *evasctx, int target, void* buffer, const int *attrib_list) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evasgl); EGLContext ctx = EGL_NO_CONTEXT; - if (!evasgl || !dpy) return NULL; + if (!dpy || !evasgl) + { + ERR("Evas_GL can not be NULL here."); + evas_gl_common_error_set(NULL, EVAS_GL_BAD_DISPLAY); + return NULL; + } ctx = _evgl_native_context_get(evasctx); return _evgl_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list); @@ -229,13 +242,9 @@ evgl_evasglCreateImageForContext(Evas_GL *evasgl EINA_UNUSED, Evas_GL_Context *e static void evgl_evasglDestroyImage(EvasGLImage image) { - EGLDisplay dpy = EGLDISPLAY_GET(); EvasGLImage_EGL *img = image; - if (dpy) - EXT_FUNC_EGL(eglDestroyImage)(dpy, img->img); - else - EXT_FUNC_EGL(eglDestroyImage)(img->dpy, img->img); + EXT_FUNC_EGL(eglDestroyImage)(img->dpy, img->img); free(img); } @@ -256,81 +265,81 @@ evgl_glEvasGLImageTargetRenderbufferStorage(GLenum target, EvasGLImage image) } static EvasGLSync -evgl_evasglCreateSync(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglCreateSync(Evas_GL *evas_gl, unsigned int type, const int *attrib_list) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return NULL; return EXT_FUNC_EGL(eglCreateSyncKHR)(dpy, type, attrib_list); } static Eina_Bool -evgl_evasglDestroySync(Evas_GL *evas_gl EINA_UNUSED, EvasGLSync sync) +evgl_evasglDestroySync(Evas_GL *evas_gl, EvasGLSync sync) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglDestroySyncKHR)(dpy, sync); } static int -evgl_evasglClientWaitSync(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglClientWaitSync(Evas_GL *evas_gl, EvasGLSync sync, int flags, EvasGLTime timeout) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglClientWaitSyncKHR)(dpy, sync, flags, timeout); } static Eina_Bool -evgl_evasglSignalSync(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglSignalSync(Evas_GL *evas_gl, EvasGLSync sync, unsigned mode) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglSignalSyncKHR)(dpy, sync, mode); } static Eina_Bool -evgl_evasglGetSyncAttrib(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglGetSyncAttrib(Evas_GL *evas_gl, EvasGLSync sync, int attribute, int *value) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglGetSyncAttribKHR)(dpy, sync, attribute, value); } static int -evgl_evasglWaitSync(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglWaitSync(Evas_GL *evas_gl, EvasGLSync sync, int flags) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglWaitSyncKHR)(dpy, sync, flags); } static Eina_Bool -evgl_evasglBindWaylandDisplay(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglBindWaylandDisplay(Evas_GL *evas_gl, void *wl_display) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglBindWaylandDisplayWL)(dpy, wl_display); } static Eina_Bool -evgl_evasglUnbindWaylandDisplay(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglUnbindWaylandDisplay(Evas_GL *evas_gl, void *wl_display) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglUnbindWaylandDisplayWL)(dpy, wl_display); } static Eina_Bool -evgl_evasglQueryWaylandBuffer(Evas_GL *evas_gl EINA_UNUSED, +evgl_evasglQueryWaylandBuffer(Evas_GL *evas_gl, void *buffer, int attribute, int *value) { - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(evas_gl); if (!dpy) return EINA_FALSE; return EXT_FUNC_EGL(eglQueryWaylandBufferWL)(dpy, buffer, attribute, value); } @@ -835,7 +844,7 @@ _evgl_api_gles1_ext_init(void *getproc, const char *glueexts) #ifdef GL_GLES EVGL_Resource *rsc; EGLint context_version; - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(NULL); /* glGetString returns the information for the currently bound context * So, update glexts only if GLES1 context is currently bound. @@ -1119,7 +1128,7 @@ _evgl_api_gles3_ext_init(void *getproc, const char *glueexts) #ifdef GL_GLES EVGL_Resource *rsc; EGLint context_version; - EGLDisplay dpy = EGLDISPLAY_GET(); + EGLDisplay dpy = EGLDISPLAY_GET(NULL); /* glGetString returns the information for the currently bound context * So, update gles3_exts only if GLES3 context is currently bound. diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c index 809c63d..29bcd4e 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -20,6 +20,7 @@ int _evas_gl_log_level = -1; typedef void *(*glsym_func_void_ptr) (); glsym_func_void_ptr glsym_evas_gl_native_context_get = NULL; +glsym_func_void_ptr glsym_evas_gl_engine_data_get = NULL; static void _surface_cap_print(int error); static void _surface_context_list_print(); @@ -1616,7 +1617,19 @@ _evgl_native_context_get(Evas_GL_Context *ctx) evglctx = glsym_evas_gl_native_context_get(ctx); if (!evglctx) return NULL; - return evgl_current_native_context_get(evglctx);; + return evgl_current_native_context_get(evglctx); +} + +void * +_evgl_engine_data_get(Evas_GL *evasgl) +{ + if (!glsym_evas_gl_engine_data_get) + { + ERR("Engine can't get a pointer to the native display"); + return NULL; + } + + return glsym_evas_gl_engine_data_get(evasgl); } //---------------------------------------------------------------// @@ -2071,13 +2084,15 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc) void * evgl_context_create(void *eng_data, EVGL_Context *share_ctx, Evas_GL_Context_Version version, - void *(*native_context_get)(void *)) + void *(*native_context_get)(void *), + void *(*engine_data_get)(void *)) { EVGL_Context *ctx = NULL; EVGL_Resource *rsc = NULL; // A little bit ugly. But it works even when dlsym(DEFAULT) doesn't work. glsym_evas_gl_native_context_get = native_context_get; + glsym_evas_gl_engine_data_get = engine_data_get; // Check the input if (!evgl_engine) diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.h b/src/modules/evas/engines/gl_common/evas_gl_core.h index 991cae6..7c321e2 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core.h @@ -58,7 +58,7 @@ EVGL_Engine *evgl_engine_init(void *eng_data, const EVGL_Interface *efunc); void *evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h); void *evgl_pbuffer_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h, const int *attrib_list); int evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc); -void *evgl_context_create(void *eng_data, EVGL_Context *share_ctx, Evas_GL_Context_Version version, void *(*native_context_get)(void *)); +void *evgl_context_create(void *eng_data, EVGL_Context *share_ctx, Evas_GL_Context_Version version, void *(*native_context_get)(void *), void *(*engine_data_get)(void *)); int evgl_context_destroy(void *eng_data, EVGL_Context *ctx); int evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx); diff --git a/src/modules/evas/engines/gl_common/evas_gl_core_private.h b/src/modules/evas/engines/gl_common/evas_gl_core_private.h index 6498b1a..24aaed6 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h @@ -351,6 +351,7 @@ extern EVGL_Context *_evgl_current_context_get(void); extern int _evgl_not_in_pixel_get(void); extern int _evgl_direct_enabled(void); extern EVGLNative_Context _evgl_native_context_get(Evas_GL_Context *ctx); +extern void *_evgl_engine_data_get(Evas_GL *evasgl); Eina_Bool _evgl_api_gles2_ext_init(void *getproc, const char *glueexts); Eina_Bool _evgl_api_gles1_ext_init(void *getproc, const char *glueexts); Eina_Bool _evgl_api_gles3_ext_init(void *getproc, const char *glueexts); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 473f3f6..caa2da6 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -1425,12 +1425,13 @@ eng_gl_surface_destroy(void *data, void *surface) static void * eng_gl_context_create(void *data, void *share_context, int version, - void *(*native_context_get)(void *)) + void *(*native_context_get)(void *), + void *(*engine_data_get)(void *)) { EVGL_Context *sctx = (EVGL_Context *)share_context; EVGLINIT(data, NULL); - return evgl_context_create(data, sctx, version, native_context_get); + return evgl_context_create(data, sctx, version, native_context_get, engine_data_get); } static int diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index aedd80e..234be12 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -2938,7 +2938,8 @@ eng_gl_surface_destroy(void *data EINA_UNUSED, void *surface) static void * eng_gl_context_create(void *data EINA_UNUSED, void *share_context, int version, - void *(*native_context_get)(void *) EINA_UNUSED) + void *(*native_context_get)(void *) EINA_UNUSED, + void *(*engine_data_get)(void *) EINA_UNUSED) { #ifdef EVAS_GL Render_Engine_GL_Context *ctx; --