forked from enlightenment/efl
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
This commit is contained in:
parent
51b097c014
commit
8942c0c29b
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue