cogl-xlib-renderer: Move private data to cogl_object_set_user_data

Previously the Xlib renderer data was meant to be the first member of
whatever the winsys data is. This doesn't work well for the EGL winsys
because it only needs the Xlib data if the X11 platform is used. The
Xlib renderer data is now instead created on demand and connected to
the object using cogl_object_set_user_data. There is a new function to
get access to it.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2011-12-12 13:27:33 +00:00
parent f21beeb1bc
commit a8f84af776
7 changed files with 91 additions and 39 deletions

View File

@ -31,8 +31,6 @@
typedef struct _CoglGLXRenderer
{
CoglXlibRenderer _parent;
int glx_major;
int glx_minor;

View File

@ -74,4 +74,7 @@ int
_cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state);
CoglXlibRenderer *
_cogl_xlib_renderer_get_data (CoglRenderer *renderer);
#endif /* __COGL_RENDERER_XLIB_PRIVATE_H */

View File

@ -46,6 +46,39 @@
static char *_cogl_x11_display_name = NULL;
static GList *_cogl_xlib_renderers = NULL;
static void
destroy_xlib_renderer_data (void *user_data)
{
g_slice_free (CoglXlibRenderer, user_data);
}
CoglXlibRenderer *
_cogl_xlib_renderer_get_data (CoglRenderer *renderer)
{
static CoglUserDataKey key;
CoglXlibRenderer *data;
/* Constructs a CoglXlibRenderer struct on demand and attaches it to
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
need the EGL winsys data but only one of them wants the Xlib
data. */
data = cogl_object_get_user_data (COGL_OBJECT (renderer), &key);
if (data == NULL)
{
data = g_slice_new0 (CoglXlibRenderer);
cogl_object_set_user_data (COGL_OBJECT (renderer),
&key,
data,
destroy_xlib_renderer_data);
}
return data;
}
static void
register_xlib_renderer (CoglRenderer *renderer)
{
@ -72,7 +105,8 @@ get_renderer_for_xdisplay (Display *xdpy)
for (l = _cogl_xlib_renderers; l; l = l->next)
{
CoglRenderer *renderer = l->data;
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
if (xlib_renderer->xdpy == xdpy)
return renderer;
@ -90,7 +124,7 @@ error_handler (Display *xdpy,
renderer = get_renderer_for_xdisplay (xdpy);
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
g_assert (xlib_renderer->trap_state);
xlib_renderer->trap_state->trapped_error_code = error->error_code;
@ -104,7 +138,7 @@ _cogl_xlib_renderer_trap_errors (CoglRenderer *renderer,
{
CoglXlibRenderer *xlib_renderer;
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
state->trapped_error_code = 0;
state->old_error_handler = XSetErrorHandler (error_handler);
@ -119,7 +153,7 @@ _cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer,
{
CoglXlibRenderer *xlib_renderer;
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
g_assert (state == xlib_renderer->trap_state);
XSetErrorHandler (state->old_error_handler);
@ -133,7 +167,7 @@ static Display *
assert_xlib_display (CoglRenderer *renderer, GError **error)
{
Display *xdpy = cogl_xlib_renderer_get_foreign_display (renderer);
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
/* A foreign display may have already been set... */
if (xdpy)
@ -159,8 +193,10 @@ assert_xlib_display (CoglRenderer *renderer, GError **error)
gboolean
_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error)
{
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglX11Renderer *x11_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
CoglX11Renderer *x11_renderer =
(CoglX11Renderer *) xlib_renderer;
int damage_error;
if (!assert_xlib_display (renderer, error))
@ -185,7 +221,8 @@ _cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error)
void
_cogl_xlib_renderer_disconnect (CoglRenderer *renderer)
{
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
if (!renderer->foreign_xdpy && xlib_renderer->xdpy)
XCloseDisplay (xlib_renderer->xdpy);
@ -200,7 +237,7 @@ cogl_xlib_renderer_get_display (CoglRenderer *renderer)
_COGL_RETURN_VAL_IF_FAIL (cogl_is_renderer (renderer), NULL);
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
return xlib_renderer->xdpy;
}

View File

@ -102,6 +102,7 @@ _cogl_xlib_get_damage_base (void)
CoglX11Renderer *x11_renderer;
_COGL_GET_CONTEXT (ctxt, -1);
x11_renderer = ctxt->display->renderer->winsys;
x11_renderer =
(CoglX11Renderer *) _cogl_xlib_renderer_get_data (ctxt->display->renderer);
return x11_renderer->damage_base;
}

View File

@ -66,10 +66,6 @@ typedef enum _CoglEGLWinsysFeature
typedef struct _CoglRendererEGL
{
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
CoglXlibRenderer _parent;
#endif
CoglEGLWinsysFeature private_features;
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT

View File

@ -304,7 +304,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
case COGL_WINSYS_ID_EGL_X11:
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
if (!_cogl_xlib_renderer_connect (renderer, error))
goto error;
@ -454,7 +454,8 @@ update_winsys_features (CoglContext *context, GError **error)
static XVisualInfo *
get_visual_info (CoglDisplay *display, EGLConfig egl_config)
{
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (display->renderer);
CoglRendererEGL *egl_renderer = display->renderer->winsys;
XVisualInfo visinfo_template;
int template_mask = 0;
@ -571,7 +572,8 @@ try_create_context (CoglDisplay *display,
CoglDisplayEGL *egl_display = display->winsys;
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
CoglXlibDisplay *xlib_display = display->winsys;
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
#endif
CoglRendererEGL *egl_renderer = renderer->winsys;
EGLDisplay edpy;
@ -881,7 +883,8 @@ cleanup_context (CoglDisplay *display)
CoglRendererEGL *egl_renderer = renderer->winsys;
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
CoglXlibDisplay *xlib_display = display->winsys;
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
#endif
if (egl_renderer->platform_vtable &&
@ -1165,7 +1168,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
CoglRenderer *renderer = display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
CoglOnscreenXlib *xlib_onscreen;
Window xwin;
#endif
@ -1426,7 +1430,8 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
CoglXlibTrapState old_state;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
#endif
@ -1589,7 +1594,8 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
CoglRenderer *renderer = context->display->renderer;
CoglXlibRenderer *xlib_renderer = renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
if (renderer->winsys_vtable->id != COGL_WINSYS_ID_EGL_X11)

View File

@ -314,7 +314,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
renderer->winsys = g_slice_new0 (CoglGLXRenderer);
glx_renderer = renderer->winsys;
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
if (!_cogl_xlib_renderer_connect (renderer, error))
goto error;
@ -378,7 +378,8 @@ static gboolean
update_winsys_features (CoglContext *context, GError **error)
{
CoglGLXDisplay *glx_display = context->display->winsys;
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
const char *glx_extensions;
int default_screen;
@ -514,7 +515,8 @@ find_fbconfig (CoglDisplay *display,
GLXFBConfig *config_ret,
GError **error)
{
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (display->renderer);
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
GLXFBConfig *configs = NULL;
int n_configs;
@ -582,7 +584,8 @@ create_context (CoglDisplay *display, GError **error)
{
CoglGLXDisplay *glx_display = display->winsys;
CoglXlibDisplay *xlib_display = display->winsys;
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (display->renderer);
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
gboolean support_transparent_windows =
display->onscreen_template->config.swap_chain->has_alpha;
@ -712,7 +715,8 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
{
CoglGLXDisplay *glx_display = display->winsys;
CoglXlibDisplay *xlib_display = display->winsys;
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (display->renderer);
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
_COGL_RETURN_IF_FAIL (glx_display != NULL);
@ -796,7 +800,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
CoglContext *context = framebuffer->context;
CoglDisplay *display = context->display;
CoglGLXDisplay *glx_display = display->winsys;
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (display->renderer);
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
Window xwin;
CoglOnscreenXlib *xlib_onscreen;
@ -982,7 +987,8 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *context = framebuffer->context;
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglXlibTrapState old_state;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
@ -1024,7 +1030,8 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
CoglContextGLX *glx_context = context->winsys;
CoglXlibDisplay *xlib_display = context->display->winsys;
CoglGLXDisplay *glx_display = context->display->winsys;
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
@ -1184,7 +1191,8 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *context = framebuffer->context;
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
@ -1338,7 +1346,8 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *context = framebuffer->context;
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
@ -1478,7 +1487,8 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
gboolean visibility)
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
if (visibility)
@ -1500,7 +1510,7 @@ _cogl_winsys_xlib_get_visual_info (void)
_COGL_RETURN_VAL_IF_FAIL (ctx->display->winsys, FALSE);
glx_display = ctx->display->winsys;
xlib_renderer = ctx->display->renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer);
glx_renderer = ctx->display->renderer->winsys;
if (!glx_display->found_fbconfig)
@ -1526,7 +1536,7 @@ get_fbconfig_for_depth (CoglContext *context,
int spare_cache_slot = 0;
gboolean found = FALSE;
xlib_renderer = context->display->renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer);
glx_renderer = context->display->renderer->winsys;
glx_display = context->display->winsys;
@ -1721,7 +1731,7 @@ try_create_glx_pixmap (CoglContext *context,
Visual* visual = tex_pixmap->visual;
renderer = context->display->renderer;
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
glx_renderer = renderer->winsys;
dpy = xlib_renderer->xdpy;
@ -1844,7 +1854,7 @@ free_glx_pixmap (CoglContext *context,
CoglGLXRenderer *glx_renderer;
renderer = context->display->renderer;
xlib_renderer = renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
glx_renderer = renderer->winsys;
if (glx_tex_pixmap->pixmap_bound)
@ -2008,7 +2018,8 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
if (glx_tex_pixmap->bind_tex_image_queued)
{
GLuint gl_handle, gl_target;
CoglXlibRenderer *xlib_renderer = ctx->display->renderer->winsys;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (ctx->display->renderer);
cogl_texture_get_gl_texture (glx_tex_pixmap->glx_tex,
&gl_handle, &gl_target);