cogl/xlib-renderer: Save Xlib renderer data in custom winsys pointer
XLib renderer saves its data as the object cogl user data, however this data is free'd as part of the object destruction that happens before free'ing the renderer in _cogl_renderer_free(), from where we're calling the renderer disconnect vfunc. Thus in _cogl_xlib_renderer_disconnect() we happen to get an invalid pointer to CoglXlibRenderer and we try access to it in order to close the X11 display. This causes all the cogl tests to crash when G_SLICE=always-malloc is set and when using MALLOC_CHECK_. Fix this using the renderer winsys custom data instead of using cogl object data for storing the CoglXlibRenderer, and handling the destruction of it manually. As bonus this also makes access to the renderer data faster. https://gitlab.gnome.org/GNOME/mutter/merge_requests/581
This commit is contained in:
parent
f99cd18254
commit
61c173b777
@ -54,41 +54,27 @@ static char *_cogl_x11_display_name = NULL;
|
|||||||
static GList *_cogl_xlib_renderers = NULL;
|
static GList *_cogl_xlib_renderers = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_xlib_renderer_data (void *user_data)
|
_xlib_renderer_data_free (CoglXlibRenderer *data)
|
||||||
{
|
{
|
||||||
CoglXlibRenderer *data = user_data;
|
|
||||||
|
|
||||||
if (data->xvisinfo)
|
if (data->xvisinfo)
|
||||||
XFree (data->xvisinfo);
|
XFree (data->xvisinfo);
|
||||||
|
|
||||||
g_slice_free (CoglXlibRenderer, user_data);
|
g_slice_free (CoglXlibRenderer, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglXlibRenderer *
|
CoglXlibRenderer *
|
||||||
_cogl_xlib_renderer_get_data (CoglRenderer *renderer)
|
_cogl_xlib_renderer_get_data (CoglRenderer *renderer)
|
||||||
{
|
{
|
||||||
static CoglUserDataKey key;
|
|
||||||
CoglXlibRenderer *data;
|
|
||||||
|
|
||||||
/* Constructs a CoglXlibRenderer struct on demand and attaches it to
|
/* Constructs a CoglXlibRenderer struct on demand and attaches it to
|
||||||
the object using user data. It's done this way instead of using a
|
the object using user data. It's done this way instead of using a
|
||||||
subclassing hierarchy in the winsys data because all EGL winsys's
|
subclassing hierarchy in the winsys data because all EGL winsys's
|
||||||
need the EGL winsys data but only one of them wants the Xlib
|
need the EGL winsys data but only one of them wants the Xlib
|
||||||
data. */
|
data. */
|
||||||
|
|
||||||
data = cogl_object_get_user_data (COGL_OBJECT (renderer), &key);
|
if (!renderer->custom_winsys_user_data)
|
||||||
|
renderer->custom_winsys_user_data = g_slice_new0 (CoglXlibRenderer);
|
||||||
|
|
||||||
if (data == NULL)
|
return renderer->custom_winsys_user_data;
|
||||||
{
|
|
||||||
data = g_slice_new0 (CoglXlibRenderer);
|
|
||||||
|
|
||||||
cogl_object_set_user_data (COGL_OBJECT (renderer),
|
|
||||||
&key,
|
|
||||||
data,
|
|
||||||
destroy_xlib_renderer_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -570,6 +556,8 @@ _cogl_xlib_renderer_disconnect (CoglRenderer *renderer)
|
|||||||
if (!renderer->foreign_xdpy && xlib_renderer->xdpy)
|
if (!renderer->foreign_xdpy && xlib_renderer->xdpy)
|
||||||
XCloseDisplay (xlib_renderer->xdpy);
|
XCloseDisplay (xlib_renderer->xdpy);
|
||||||
|
|
||||||
|
g_clear_pointer (&renderer->custom_winsys_user_data, _xlib_renderer_data_free);
|
||||||
|
|
||||||
unregister_xlib_renderer (renderer);
|
unregister_xlib_renderer (renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user