forked from enlightenment/efl
Evas (wayland_egl): Fix crashes when flipping window alpha state.
From: Alex Wu <zhiwen.wu@linux.intel.com> When calling elm_win_alpha_set(), the global EGLContext object keep unchanged, but the new EGLSurface object subjects to the new EGLConfig with changed alpha_size. This makes eng_window_new() failed and hence free the Render_Engine object (e->engine.data.output) and nullize it. Next time other objects reference the output, segfault occurs. In this patch, I give every Evas_GL_Wl_Window object a EGLContext object and all these EGLContext objects share the same shader program objects. A new global EGLContext object "share_context" added, which is responsible for keeping the shared objects alive. e.g. shader program objects.At the first time succeeded to create a EGLContext, assign it to the "share_context", and should not destory it in eng_window_free. The "share_context" will be taken as the 3rd argument when calling eglCreateContext(), and then updated to the new created EGLContext to keep the shared gl objects available. Thanks for devilhorns' review and suggestion. SVN revision: 74328
This commit is contained in:
parent
722fef0199
commit
0f50ef36b9
|
@ -600,6 +600,7 @@ eng_setup(Evas *e, void *in)
|
|||
{
|
||||
Render_Engine *re;
|
||||
Evas_Engine_Info_Wayland_Egl *info;
|
||||
Evas_GL_Wl_Window *new_win = NULL;
|
||||
|
||||
info = (Evas_Engine_Info_Wayland_Egl *)in;
|
||||
if (!e->engine.data.output)
|
||||
|
@ -679,6 +680,18 @@ eng_setup(Evas *e, void *in)
|
|||
return 0;
|
||||
}
|
||||
|
||||
new_win = eng_window_new(re->info->info.display,
|
||||
re->info->info.surface,
|
||||
re->info->info.screen,
|
||||
re->info->info.depth,
|
||||
e->output.w, e->output.h,
|
||||
re->info->indirect,
|
||||
re->info->info.destination_alpha,
|
||||
re->info->info.rotation);
|
||||
|
||||
if (new_win)
|
||||
{
|
||||
// free old win
|
||||
if (re->win)
|
||||
{
|
||||
re->win->gl_context->references++;
|
||||
|
@ -686,21 +699,17 @@ eng_setup(Evas *e, void *in)
|
|||
inc = 1;
|
||||
gl_wins--;
|
||||
}
|
||||
|
||||
re->win = new_win;
|
||||
re->w = e->output.w;
|
||||
re->h = e->output.h;
|
||||
re->win = eng_window_new(re->info->info.display,
|
||||
re->info->info.surface,
|
||||
re->info->info.screen,
|
||||
re->info->info.depth,
|
||||
re->w, re->h,
|
||||
re->info->indirect,
|
||||
re->info->info.destination_alpha,
|
||||
re->info->info.rotation);
|
||||
|
||||
eng_window_use(re->win);
|
||||
if (re->win) gl_wins++;
|
||||
if ((re->win) && (inc))
|
||||
re->win->gl_context->references--;
|
||||
}
|
||||
}
|
||||
else if ((re->win->w != e->output.w) ||
|
||||
(re->win->h != e->output.h))
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
static Evas_GL_Wl_Window *_evas_gl_wl_window = NULL;
|
||||
|
||||
static EGLContext context = EGL_NO_CONTEXT;
|
||||
static EGLContext share_context = EGL_NO_CONTEXT;
|
||||
|
||||
// fixme: something is up/wrong here - dont know what tho...
|
||||
//#define NEWGL 1
|
||||
|
@ -150,10 +150,8 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
context = eglCreateContext(gw->egl_disp, gw->egl_config, NULL,
|
||||
context_attrs);
|
||||
gw->egl_context[0] = context;
|
||||
gw->egl_context[0] = eglCreateContext(gw->egl_disp, gw->egl_config, share_context, context_attrs);
|
||||
|
||||
if (gw->egl_context[0] == EGL_NO_CONTEXT)
|
||||
{
|
||||
ERR("eglCreateContext() fail. code=%#x", eglGetError());
|
||||
|
@ -161,6 +159,9 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (share_context == EGL_NO_CONTEXT)
|
||||
share_context = gw->egl_context[0];
|
||||
|
||||
if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0],
|
||||
gw->egl_context[0]) == EGL_FALSE)
|
||||
{
|
||||
|
@ -213,10 +214,12 @@ eng_window_free(Evas_GL_Wl_Window *gw)
|
|||
if (gw->egl_surface[0] != EGL_NO_SURFACE)
|
||||
eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
|
||||
eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
if (gw->egl_context[0] != EGL_NO_CONTEXT && gw->egl_context[0] != share_context)
|
||||
eglDestroyContext(gw->egl_disp, gw->egl_context[0]);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
if (context) eglDestroyContext(gw->egl_disp, context);
|
||||
context = EGL_NO_CONTEXT;
|
||||
/* NB: This is causing an unknown hang when we run elm apps as
|
||||
* wayland clients inside the weston compositor */
|
||||
/* eglTerminate(gw->egl_disp); */
|
||||
|
|
Loading…
Reference in New Issue