From: <zhi...@li...> - 2012-07-16 08:51:33
|
From: Alex Wu <zhi...@li...> The current wayland_egl engine uses a global singleton EGLContext object to render context. All Evas_GL_Wl_Window objects, which wraps EGLSurface, share this object, so we have no chance to differentiate the frame buffer configuration for each EGLSurface. 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. In eng_setup, should create the new window before free the old one, that will keep the "share_context" avaliable for next calling of eng_window_new(). 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. --- .../src/modules/engines/wayland_egl/evas_engine.c | 41 ++++++++++++-------- .../src/modules/engines/wayland_egl/evas_wl_main.c | 23 ++++++----- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/trunk/evas/src/modules/engines/wayland_egl/evas_engine.c b/trunk/evas/src/modules/engines/wayland_egl/evas_engine.c index 7dc158b..758481b 100644 --- a/trunk/evas/src/modules/engines/wayland_egl/evas_engine.c +++ b/trunk/evas/src/modules/engines/wayland_egl/evas_engine.c @@ -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,28 +680,36 @@ eng_setup(Evas *e, void *in) return 0; } - if (re->win) - { - re->win->gl_context->references++; - eng_window_free(re->win); - inc = 1; - gl_wins--; - } - re->w = e->output.w; - re->h = e->output.h; - re->win = eng_window_new(re->info->info.display, + new_win = eng_window_new(re->info->info.display, re->info->info.surface, re->info->info.screen, re->info->info.depth, - re->w, re->h, + e->output.w, e->output.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--; - } + + if (new_win) + { + // free old win + if (re->win) + { + re->win->gl_context->references++; + eng_window_free(re->win); + inc = 1; + gl_wins--; + } + + re->win = new_win; + re->w = e->output.w; + re->h = e->output.h; + + 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)) { diff --git a/trunk/evas/src/modules/engines/wayland_egl/evas_wl_main.c b/trunk/evas/src/modules/engines/wayland_egl/evas_wl_main.c index 58ab1c3..0c5eef1 100644 --- a/trunk/evas/src/modules/engines/wayland_egl/evas_wl_main.c +++ b/trunk/evas/src/modules/engines/wayland_egl/evas_wl_main.c @@ -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 @@ -146,18 +146,17 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen, { ERR("eglCreateWindowSurface() fail for %p. code=%#x", gw->win, eglGetError()); - eng_window_free(gw); + eng_window_free(gw); 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); + share_context = gw->egl_context[0]; + if (gw->egl_context[0] == EGL_NO_CONTEXT) { ERR("eglCreateContext() fail. code=%#x", eglGetError()); - eng_window_free(gw); + eng_window_free(gw); return NULL; } @@ -213,10 +212,16 @@ 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) + { + if (gw->egl_context[0] == share_context) + share_context = EGL_NO_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); */ -- 1.7.9.5 |