//
/* local variables */
-static Outbuf *_evas_gl_wl_window = NULL;
-static EGLContext context = EGL_NO_CONTEXT;
+static Eina_TLS _outbuf_key = 0;
+static Eina_TLS _context_key = 0;
+static Eina_TLS _display_key = 0;
+
+typedef EGLContext GLContext;
static int win_count = 0;
static void _convert_glcoords(int *result, Outbuf *ob, int x, int y, int w, int h);
+static Eina_Bool initted = EINA_FALSE;
+
+Eina_Bool
+eng_init(void)
+{
+ if (initted)
+ return EINA_TRUE;
+
+#define LINK2GENERIC(sym) \
+ glsym_##sym = dlsym(RTLD_DEFAULT, #sym); \
+ if (!glsym_##sym) ERR("Could not find function '%s'", #sym);
+
+ LINK2GENERIC(evas_gl_common_context_restore_set);
+
+ // FIXME: These resources are never released
+ if (!eina_tls_new(&_outbuf_key))
+ goto error;
+ if (!eina_tls_new(&_context_key))
+ goto error;
+ if (!eina_tls_new(&_display_key))
+ goto error;
+
+ eina_tls_set(_outbuf_key, NULL);
+ eina_tls_set(_context_key, NULL);
+ eina_tls_set(_display_key, NULL);
+
+ initted = EINA_TRUE;
+ return EINA_TRUE;
+
+error:
+ ERR("Could not create TLS key!");
+ return EINA_FALSE;
+}
+
+static inline Outbuf *
+_tls_outbuf_get(void)
+{
+ if (!initted) eng_init();
+ return eina_tls_get(_outbuf_key);
+}
+
+static inline Eina_Bool
+_tls_outbuf_set(Outbuf *wl_win)
+{
+ if (!initted) eng_init();
+ return eina_tls_set(_outbuf_key, wl_win);
+}
+
+static inline GLContext
+_tls_context_get(void)
+{
+ if (!initted) eng_init();
+ return eina_tls_get(_context_key);
+}
+
+static inline Eina_Bool
+_tls_context_set(GLContext ctx)
+{
+ if (!initted) eng_init();
+ return eina_tls_set(_context_key, ctx);
+}
+
+static inline void*
+_tls_display_get(void)
+{
+ if (!initted) eng_init();
+ return eina_tls_get(_display_key);
+}
+
+static inline Eina_Bool
+_tls_display_set(void* disp)
+{
+ if (!initted) eng_init();
+ return eina_tls_set(_display_key, disp);
+}
+
Outbuf *
eng_window_new(Evas_Engine_Info_GL_Tbm *einfo, int w, int h, Render_Output_Swap_Mode swap_mode)
{
Outbuf *gw;
+ GLContext context;
int context_attrs[3];
int config_attrs[40];
int major_version, minor_version;
*/
setenv("EGL_PLATFORM", "tbm", 1);
- gw->tbm_disp = tbm_dummy_display_create();
- gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)gw->tbm_disp);
+ void* tbm_disp = _tls_display_get();
+ if (tbm_disp == NULL)
+ {
+ tbm_disp = tbm_dummy_display_create();
+ _tls_display_set(tbm_disp);
+ }
+ gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)tbm_disp);
// gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)tbm_bufmgr_init(-1));
if (!gw->egl_disp)
{
return NULL;
}
+ context = _tls_context_get();
gw->egl_context[0] =
eglCreateContext(gw->egl_disp, gw->egl_config, context, context_attrs);
if (gw->egl_context[0] == EGL_NO_CONTEXT)
return NULL;
}
- if (context == EGL_NO_CONTEXT) context = gw->egl_context[0];
+ if (context == EGL_NO_CONTEXT)
+ _tls_context_set(gw->egl_context[0]);
SET_RESTORE_CONTEXT();
if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0],
void
eng_window_free(Outbuf *gw)
{
+ Outbuf *wl_win;
+ GLContext context;
int ref = 0;
+ if (!gw) return;
win_count--;
eng_window_use(gw);
- if (gw == _evas_gl_wl_window) _evas_gl_wl_window = NULL;
+ context = _tls_context_get();
+ wl_win = _tls_outbuf_get();
+ if (gw == wl_win) _tls_outbuf_set(NULL);
if (gw->gl_context)
{
ref = gw->gl_context->references - 1;
{
if (context) eglDestroyContext(gw->egl_disp, context);
eglTerminate(gw->egl_disp);
- tbm_dummy_display_destroy(gw->tbm_disp);
eglReleaseThread();
- context = EGL_NO_CONTEXT;
+
+ void* tbm_disp = _tls_display_get();
+ if (tbm_disp)
+ {
+ tbm_dummy_display_destroy(tbm_disp);
+ _tls_display_set(NULL);
+ }
+ _tls_context_set(EGL_NO_CONTEXT);
}
free(gw);
eng_window_use(Outbuf *gw)
{
Eina_Bool force = EINA_FALSE;
+ Outbuf *wl_win;
+
+ wl_win = _tls_outbuf_get();
glsym_evas_gl_preload_render_lock(eng_preload_make_current, gw);
- if (_evas_gl_wl_window)
+ if (wl_win)
{
- if ((eglGetCurrentContext() != _evas_gl_wl_window->egl_context[0])
- || (eglGetCurrentDisplay() != _evas_gl_wl_window->egl_disp))
+ if ((eglGetCurrentContext() != wl_win->egl_context[0])
+ || (eglGetCurrentDisplay() != wl_win->egl_disp))
force = EINA_TRUE;
}
- if ((_evas_gl_wl_window != gw) || (force))
+ if ((wl_win != gw) || (force))
{
- if (_evas_gl_wl_window)
+ if (wl_win)
{
- glsym_evas_gl_common_context_use(_evas_gl_wl_window->gl_context);
- glsym_evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
+ glsym_evas_gl_common_context_use(wl_win->gl_context);
+ glsym_evas_gl_common_context_flush(wl_win->gl_context);
}
- _evas_gl_wl_window = gw;
+ _tls_outbuf_set(gw);
if (gw)
{
if (!getenv("EVAS_GL_WIN_RESURF")) return;
if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", gw);
- if (_evas_gl_wl_window)
- glsym_evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
+ Outbuf *wl_win;
+
+ wl_win = _tls_outbuf_get();
+ if (wl_win)
+ glsym_evas_gl_common_context_flush(wl_win->gl_context);
- if (_evas_gl_wl_window == gw)
+ if (wl_win == gw)
{
SET_RESTORE_CONTEXT();
eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE,
eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
gw->egl_surface[0] = EGL_NO_SURFACE;
- _evas_gl_wl_window = NULL;
+ _tls_outbuf_set(NULL);
}
gw->surf = EINA_FALSE;
Evas_Engine_GL_Context *
eng_outbuf_gl_context_get(Outbuf *ob)
{
+ if (!ob) return NULL;
+
return ob->gl_context;
}