[PATCH] evas/wayland_egl: Fix segfault when doing alpha setting in elementary.
cpmichael1 at comcast.net
cpmichael1 at comcast.net
Mon Jul 16 13:18:57 PDT 2012
Alex,
Thanks for the patch :) After a preliminary glance, it seems ok however I will not be able to commit this until I have had time to test it. I am currently engaged with a few other projects at work so it may be some time before I can get to this :( but I will save it in my TODO list and get to it as soon as I can.
Thanks again :)
devilhorns
----- Original Message -----
From: "zhiwen wu" <zhiwen.wu at linux.intel.com>
To: enlightenment-devel at lists.sourceforge.net
Cc: "Alex Wu" <zhiwen.wu at linux.intel.com>, devilhorns at comcast.net, wayland-devel at lists.freedesktop.org
Sent: Monday, July 16, 2012 9:51:44 AM
Subject: [PATCH] evas/wayland_egl: Fix segfault when doing alpha setting in elementary.
From: Alex Wu <zhiwen.wu at linux.intel.com>
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
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list