diff --git a/cogl/cogl-clutter.c b/cogl/cogl-clutter.c index facdeb31f..49821ac66 100644 --- a/cogl/cogl-clutter.c +++ b/cogl/cogl-clutter.c @@ -68,6 +68,12 @@ cogl_onscreen_clutter_backend_set_size (int width, int height) XVisualInfo * cogl_clutter_winsys_xlib_get_visual_info (void) { - return _cogl_winsys_xlib_get_visual_info (); + const CoglWinsysVtable *winsys; + + _COGL_GET_CONTEXT (ctx, NULL); + + winsys = _cogl_context_get_winsys (ctx); + + return winsys->xlib_get_visual_info (); } #endif diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h index 9093b44b0..2f1642cab 100644 --- a/cogl/cogl-context-private.h +++ b/cogl/cogl-context-private.h @@ -268,6 +268,9 @@ struct _CoglContext CoglContext * _cogl_context_get_default (); +const CoglWinsysVtable * +_cogl_context_get_winsys (CoglContext *context); + /* Obtains the context and returns retval if NULL */ #define _COGL_GET_CONTEXT(ctxvar, retval) \ CoglContext *ctxvar = _cogl_context_get_default (); \ diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index e1b18f6e5..d8dc5c6a4 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -33,6 +33,8 @@ #include "cogl-profile.h" #include "cogl-util.h" #include "cogl-context-private.h" +#include "cogl-display-private.h" +#include "cogl-renderer-private.h" #include "cogl-journal-private.h" #include "cogl-texture-private.h" #include "cogl-pipeline-private.h" @@ -83,6 +85,12 @@ _cogl_init_feature_overrides (CoglContext *ctx) COGL_FEATURE_TEXTURE_NPOT_REPEAT); } +const CoglWinsysVtable * +_cogl_context_get_winsys (CoglContext *context) +{ + return context->display->renderer->winsys_vtable; +} + /* For reference: There was some deliberation over whether to have a * constructor that could throw an exception but looking at standard * practices with several high level OO languages including python, C++, @@ -99,6 +107,7 @@ cogl_context_new (CoglDisplay *display, CoglContext *context; GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 }; unsigned long enable_flags = 0; + const CoglWinsysVtable *winsys; int i; #ifdef CLUTTER_ENABLE_PROFILE @@ -155,7 +164,8 @@ cogl_context_new (CoglDisplay *display, #ifdef COGL_HAS_FULL_WINSYS context->stub_winsys = FALSE; - if (!_cogl_winsys_context_init (context, error)) + winsys = _cogl_context_get_winsys (context); + if (!winsys->context_init (context, error)) { cogl_object_unref (display); g_free (context); @@ -365,7 +375,9 @@ cogl_context_new (CoglDisplay *display, static void _cogl_context_free (CoglContext *context) { - _cogl_winsys_context_deinit (context); + const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); + + winsys->context_deinit (context); _cogl_destroy_texture_units (); @@ -480,7 +492,8 @@ cogl_set_default_context (CoglContext *context) EGLDisplay cogl_context_egl_get_egl_display (CoglContext *context) { - return _cogl_winsys_context_egl_get_egl_display (context); + const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); + return winsys->context_egl_get_egl_display (context); } #endif diff --git a/cogl/cogl-display.c b/cogl/cogl-display.c index a09de181b..bb792b75a 100644 --- a/cogl/cogl-display.c +++ b/cogl/cogl-display.c @@ -32,6 +32,7 @@ #include "cogl-object.h" #include "cogl-display-private.h" +#include "cogl-renderer-private.h" #include "cogl-winsys-private.h" static void _cogl_display_free (CoglDisplay *display); @@ -93,15 +94,26 @@ cogl_display_new (CoglRenderer *renderer, return _cogl_display_object_new (display); } +static const CoglWinsysVtable * +_cogl_display_get_winsys (CoglDisplay *display) +{ + return display->renderer->winsys_vtable; +} + gboolean cogl_display_setup (CoglDisplay *display, GError **error) { +#ifdef COGL_HAS_FULL_WINSYS + const CoglWinsysVtable *winsys; +#endif + if (display->setup) return TRUE; #ifdef COGL_HAS_FULL_WINSYS - if (!_cogl_winsys_display_setup (display, error)) + winsys = _cogl_display_get_winsys (display); + if (!winsys->display_setup (display, error)) return FALSE; #endif diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index 8f0769dff..9712fe747 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -29,6 +29,8 @@ #include "cogl-debug.h" #include "cogl-internal.h" #include "cogl-context-private.h" +#include "cogl-display-private.h" +#include "cogl-renderer-private.h" #include "cogl-handle.h" #include "cogl-object-private.h" #include "cogl-util.h" @@ -231,6 +233,12 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer) cogl_object_unref (ctx); } +static const CoglWinsysVtable * +_cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer) +{ + return framebuffer->context->display->renderer->winsys_vtable; +} + /* This version of cogl_clear can be used internally as an alternative * to avoid flushing the journal or the framebuffer state. This is * needed when doing operations that may be called whiling flushing @@ -1012,6 +1020,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, GError **error) { CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); if (framebuffer->allocated) return TRUE; @@ -1021,7 +1030,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, TRUE); - if (!_cogl_winsys_onscreen_init (onscreen, error)) + if (!winsys->onscreen_init (onscreen, error)) return FALSE; framebuffer->allocated = TRUE; @@ -1032,10 +1041,14 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, static void _cogl_onscreen_free (CoglOnscreen *onscreen) { - _cogl_winsys_onscreen_deinit (onscreen); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); + + winsys->onscreen_deinit (onscreen); + g_return_if_fail (onscreen->winsys == NULL); /* Chain up to parent */ - _cogl_framebuffer_free (COGL_FRAMEBUFFER (onscreen)); + _cogl_framebuffer_free (framebuffer); g_free (onscreen); } @@ -1350,7 +1363,9 @@ bind_gl_framebuffer (CoglContext *ctx, else { #ifdef COGL_HAS_FULL_WINSYS - _cogl_winsys_onscreen_bind (COGL_ONSCREEN (framebuffer)); + const CoglWinsysVtable *winsys = + _cogl_framebuffer_get_winsys (framebuffer); + winsys->onscreen_bind (COGL_ONSCREEN (framebuffer)); #endif GE (glBindFramebuffer (target, 0)); } @@ -1582,7 +1597,11 @@ cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer) /* FIXME: we shouldn't need to flush *all* journals here! */ cogl_flush (); if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - _cogl_winsys_onscreen_swap_buffers (COGL_ONSCREEN (framebuffer)); + { + const CoglWinsysVtable *winsys = + _cogl_framebuffer_get_winsys (framebuffer); + winsys->onscreen_swap_buffers (COGL_ONSCREEN (framebuffer)); + } } void @@ -1593,9 +1612,13 @@ cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer, /* FIXME: we shouldn't need to flush *all* journals here! */ cogl_flush (); if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - _cogl_winsys_onscreen_swap_region (COGL_ONSCREEN (framebuffer), - rectangles, - n_rectangles); + { + const CoglWinsysVtable *winsys = + _cogl_framebuffer_get_winsys (framebuffer); + winsys->onscreen_swap_region (COGL_ONSCREEN (framebuffer), + rectangles, + n_rectangles); + } } #ifdef COGL_HAS_X11_SUPPORT @@ -1609,15 +1632,20 @@ cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen, guint32 cogl_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) { - return _cogl_winsys_onscreen_x11_get_window_xid (onscreen); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); + + return winsys->onscreen_x11_get_window_xid (onscreen); } guint32 cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen) { - guint32 id; - XVisualInfo *visinfo = _cogl_winsys_xlib_get_visual_info (); - id = (guint32)visinfo->visualid; + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); + XVisualInfo *visinfo = winsys->xlib_get_visual_info (); + guint32 id = (guint32)visinfo->visualid; + XFree (visinfo); return id; } @@ -1629,13 +1657,14 @@ cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer, void *user_data) { CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); /* Should this just be cogl_onscreen API instead? */ g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0); - return _cogl_winsys_onscreen_add_swap_buffers_callback (onscreen, - callback, - user_data); + return winsys->onscreen_add_swap_buffers_callback (onscreen, + callback, + user_data); } void @@ -1643,15 +1672,21 @@ cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer, unsigned int id) { CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - _cogl_winsys_onscreen_remove_swap_buffers_callback (onscreen, id); + winsys->onscreen_remove_swap_buffers_callback (onscreen, id); } void cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, gboolean throttled) { + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); onscreen->swap_throttled = throttled; - if (COGL_FRAMEBUFFER (onscreen)->allocated) - _cogl_winsys_onscreen_update_swap_throttled (onscreen); + if (framebuffer->allocated) + { + const CoglWinsysVtable *winsys = + _cogl_framebuffer_get_winsys (framebuffer); + winsys->onscreen_update_swap_throttled (onscreen); + } } diff --git a/cogl/cogl-renderer-private.h b/cogl/cogl-renderer-private.h index 660082553..8b9ebe7a7 100644 --- a/cogl/cogl-renderer-private.h +++ b/cogl/cogl-renderer-private.h @@ -25,6 +25,7 @@ #define __COGL_RENDERER_PRIVATE_H #include "cogl-object-private.h" +#include "cogl-winsys-private.h" #ifdef COGL_HAS_XLIB_SUPPORT #include @@ -34,6 +35,7 @@ struct _CoglRenderer { CoglObject _parent; gboolean connected; + const CoglWinsysVtable *winsys_vtable; #ifdef COGL_HAS_XLIB_SUPPORT Display *foreign_xdpy; #endif diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c index 548c2f0ff..613b1634d 100644 --- a/cogl/cogl-renderer.c +++ b/cogl/cogl-renderer.c @@ -37,6 +37,29 @@ #include "cogl-display-private.h" #include "cogl-winsys-private.h" +#ifdef COGL_HAS_FULL_WINSYS + +#ifdef COGL_HAS_GLX_SUPPORT +extern const CoglWinsysVtable *_cogl_winsys_glx_get_vtable (void); +#endif +#ifdef COGL_HAS_EGL_SUPPORT +extern const CoglWinsysVtable *_cogl_winsys_egl_get_vtable (void); +#endif + +typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void); + +static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] = +{ +#ifdef COGL_HAS_GLX_SUPPORT + _cogl_winsys_glx_get_vtable, +#endif +#ifdef COGL_HAS_EGL_SUPPORT + _cogl_winsys_egl_get_vtable +#endif +}; + +#endif /* COGL_HAS_FULL_WINSYS */ + static void _cogl_renderer_free (CoglRenderer *renderer); COGL_OBJECT_DEFINE (Renderer, renderer); @@ -53,6 +76,12 @@ cogl_renderer_error_quark (void) return g_quark_from_static_string ("cogl-renderer-error-quark"); } +static const CoglWinsysVtable * +_cogl_renderer_get_winsys (CoglRenderer *renderer) +{ + return renderer->winsys_vtable; +} + static void native_filter_closure_free (CoglNativeFilterClosure *closure) { @@ -63,7 +92,8 @@ static void _cogl_renderer_free (CoglRenderer *renderer) { #ifdef COGL_HAS_FULL_WINSYS - _cogl_winsys_renderer_disconnect (renderer); + const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); + winsys->renderer_disconnect (renderer); #endif g_slist_foreach (renderer->event_filters, @@ -114,8 +144,9 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer, { #ifdef COGL_HAS_FULL_WINSYS CoglDisplay *display; + const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - if (!_cogl_winsys_renderer_connect (renderer, error)) + if (!winsys->renderer_connect (renderer, error)) return FALSE; display = cogl_display_new (renderer, onscreen_template); @@ -135,16 +166,51 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer, gboolean cogl_renderer_connect (CoglRenderer *renderer, GError **error) { +#ifdef COGL_HAS_FULL_WINSYS + int i; +#endif + GString *error_message; + if (renderer->connected) return TRUE; #ifdef COGL_HAS_FULL_WINSYS - if (!_cogl_winsys_renderer_connect (renderer, error)) - return FALSE; -#endif + error_message = g_string_new (""); + for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++) + { + const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i](); + GError *tmp_error = NULL; + if (!winsys->renderer_connect (renderer, &tmp_error)) + { + g_string_append_c (error_message, '\n'); + g_string_append (error_message, tmp_error->message); + g_error_free (tmp_error); + } + else + { + renderer->winsys_vtable = winsys; + renderer->connected = TRUE; + g_string_free (error_message, TRUE); + return TRUE; + } + } + if (!renderer->connected) + { + renderer->winsys_vtable = NULL; + g_set_error (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_INIT, + "Failed to connected to any renderer: %s", + error_message->str); + g_string_free (error_message, TRUE); + return FALSE; + } + + return TRUE; +#else renderer->connected = TRUE; return TRUE; +#endif } CoglFilterReturn diff --git a/cogl/cogl.c b/cogl/cogl.c index 4dbe4aebe..69ed65243 100644 --- a/cogl/cogl.c +++ b/cogl/cogl.c @@ -93,8 +93,17 @@ cogl_get_proc_address (const char* name) { void *address; static GModule *module = NULL; +#ifdef COGL_HAS_FULL_WINSYS + const CoglWinsysVtable *winsys; + _COGL_GET_CONTEXT (ctx, NULL); + + winsys = _cogl_context_get_winsys (ctx); + + address = winsys->get_proc_address (name); +#else address = _cogl_winsys_get_proc_address (name); +#endif if (address) return address; diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c index c59d76018..01657d1ec 100644 --- a/cogl/winsys/cogl-texture-pixmap-x11.c +++ b/cogl/winsys/cogl-texture-pixmap-x11.c @@ -42,6 +42,8 @@ #include "cogl-texture-2d-private.h" #include "cogl-texture-rectangle-private.h" #include "cogl-context-private.h" +#include "cogl-display-private.h" +#include "cogl-renderer-private.h" #include "cogl-handle.h" #include "cogl-winsys-private.h" #include "cogl-pipeline-opengl-private.h" @@ -101,12 +103,23 @@ cogl_damage_rectangle_is_whole (const CoglDamageRectangle *damage_rect, && damage_rect->x2 == width && damage_rect->y2 == height); } +static const CoglWinsysVtable * +_cogl_texture_pixmap_x11_get_winsys (CoglTexturePixmapX11 *tex_pixmap) +{ + /* FIXME: A CoglContext should be reachable from a CoglTexture + * pointer */ + _COGL_GET_CONTEXT (ctx, NULL); + + return ctx->display->renderer->winsys_vtable; +} + static void process_damage_event (CoglTexturePixmapX11 *tex_pixmap, XDamageNotifyEvent *damage_event) { Display *display; enum { DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; + const CoglWinsysVtable *winsys; _COGL_GET_CONTEXT (ctxt, NO_RETVAL); @@ -195,7 +208,8 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap, /* If we're using the texture from pixmap extension then there's no point in getting the region and we can just mark that the texture needs updating */ - _cogl_winsys_texture_pixmap_x11_damage_notify (tex_pixmap); + winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); + winsys->texture_pixmap_x11_damage_notify (tex_pixmap); } static CoglFilterReturn @@ -254,6 +268,7 @@ cogl_texture_pixmap_x11_new (guint32 pixmap, CoglTexture *tex = COGL_TEXTURE (tex_pixmap); XWindowAttributes window_attributes; int damage_base; + const CoglWinsysVtable *winsys; _COGL_GET_CONTEXT (ctxt, COGL_INVALID_HANDLE); @@ -307,7 +322,9 @@ cogl_texture_pixmap_x11_new (guint32 pixmap, tex_pixmap->damage_rect.y1 = 0; tex_pixmap->damage_rect.y2 = tex_pixmap->height; - _cogl_winsys_texture_pixmap_x11_create (tex_pixmap); + winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); + if (winsys->texture_pixmap_x11_create) + winsys->texture_pixmap_x11_create (tex_pixmap); return _cogl_texture_pixmap_x11_handle_new (tex_pixmap); } @@ -390,6 +407,7 @@ cogl_texture_pixmap_x11_update_area (CoglHandle handle, int height) { CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle); + const CoglWinsysVtable *winsys; if (!cogl_is_texture_pixmap_x11 (handle)) return; @@ -398,7 +416,8 @@ cogl_texture_pixmap_x11_update_area (CoglHandle handle, texture because we can't determine which will be needed until we actually render something */ - _cogl_winsys_texture_pixmap_x11_damage_notify (tex_pixmap); + winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); + winsys->texture_pixmap_x11_damage_notify (tex_pixmap); cogl_damage_rectangle_union (&tex_pixmap->damage_rect, x, y, width, height); @@ -617,7 +636,10 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, { if (tex_pixmap->winsys) { - if (_cogl_winsys_texture_pixmap_x11_update (tex_pixmap, needs_mipmap)) + const CoglWinsysVtable *winsys = + _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); + + if (winsys->texture_pixmap_x11_update (tex_pixmap, needs_mipmap)) { _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE); return; @@ -649,7 +671,11 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) for (i = 0; i < 2; i++) { if (tex_pixmap->use_winsys_texture) - tex = _cogl_winsys_texture_pixmap_x11_get_texture (tex_pixmap); + { + const CoglWinsysVtable *winsys = + _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); + tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap); + } else tex = tex_pixmap->tex; @@ -912,7 +938,11 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) cogl_handle_unref (tex_pixmap->tex); if (tex_pixmap->winsys) - _cogl_winsys_texture_pixmap_x11_free (tex_pixmap); + { + const CoglWinsysVtable *winsys = + _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); + winsys->texture_pixmap_x11_free (tex_pixmap); + } /* Chain up */ _cogl_texture_free (COGL_TEXTURE (tex_pixmap)); diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index 44583af1e..46f5842b3 100644 --- a/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/winsys/cogl-winsys-egl.c @@ -168,7 +168,7 @@ static const CoglFeatureData winsys_feature_data[] = #include "cogl-winsys-egl-feature-functions.h" }; -CoglFuncPtr +static CoglFuncPtr _cogl_winsys_get_proc_address (const char *name) { return (CoglFuncPtr) eglGetProcAddress (name); @@ -237,7 +237,21 @@ event_filter_cb (void *event, void *data) } #endif /* COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT */ -gboolean +static void +_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) +{ + CoglRendererEGL *egl_renderer = renderer->winsys; + +#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT + _cogl_renderer_xlib_disconnect (renderer); +#endif + + eglTerminate (egl_renderer->edpy); + + g_slice_free (CoglRendererEGL, egl_renderer); +} + +static gboolean _cogl_winsys_renderer_connect (CoglRenderer *renderer, GError **error) { @@ -285,21 +299,7 @@ error: return FALSE; } -void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - _cogl_renderer_xlib_disconnect (renderer); -#endif - - eglTerminate (egl_renderer->edpy); - - g_slice_free (CoglRendererEGL, egl_renderer); -} - -void +static void update_winsys_features (CoglContext *context) { CoglDisplayEGL *egl_display = context->display->winsys; @@ -675,7 +675,20 @@ create_context (CoglDisplay *display, GError **error) return status; } -gboolean +static void +_cogl_winsys_display_destroy (CoglDisplay *display) +{ + CoglDisplayEGL *egl_display = display->winsys; + + g_return_if_fail (egl_display != NULL); + + cleanup_context (display); + + g_slice_free (CoglDisplayEGL, display->winsys); + display->winsys = NULL; +} + +static gboolean _cogl_winsys_display_setup (CoglDisplay *display, GError **error) { @@ -698,20 +711,7 @@ error: return FALSE; } -void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - - g_return_if_fail (egl_display != NULL); - - cleanup_context (display); - - g_slice_free (CoglDisplayEGL, display->winsys); - display->winsys = NULL; -} - -gboolean +static gboolean _cogl_winsys_context_init (CoglContext *context, GError **error) { context->winsys = g_new0 (CoglContextEGL, 1); @@ -726,7 +726,7 @@ _cogl_winsys_context_init (CoglContext *context, GError **error) return TRUE; } -void +static void _cogl_winsys_context_deinit (CoglContext *context) { #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT @@ -737,7 +737,7 @@ _cogl_winsys_context_deinit (CoglContext *context) g_free (context->winsys); } -gboolean +static gboolean _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, GError **error) { @@ -896,7 +896,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, return TRUE; } -void +static void _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); @@ -941,7 +941,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) #endif } -void +static void _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; @@ -982,7 +982,7 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) eglSwapInterval (egl_renderer->edpy, 0); } -void +static void _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, int *rectangles, int n_rectangles) @@ -998,14 +998,14 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, g_warning ("Error reported by eglSwapBuffersRegion"); } -guint32 +static guint32 _cogl_winsys_get_vsync_counter (void) { /* Unsupported feature */ return 0; } -void +static void _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; @@ -1015,14 +1015,14 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface); } -guint32 +static guint32 _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) { CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; return xlib_onscreen->xwin; } -unsigned int +static unsigned int _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, CoglSwapBuffersNotify callback, void *user_data) @@ -1031,14 +1031,14 @@ _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, return 0; } -void +static void _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, unsigned int id) { /* Unsupported feature */ } -void +static void _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; @@ -1054,7 +1054,7 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT /* XXX: This is a particularly hacky _cogl_winsys interface... */ -XVisualInfo * +static XVisualInfo * _cogl_winsys_xlib_get_visual_info (void) { CoglDisplayEGL *egl_display; @@ -1072,7 +1072,7 @@ _cogl_winsys_xlib_get_visual_info (void) } #endif -EGLDisplay +static EGLDisplay _cogl_winsys_context_egl_get_egl_display (CoglContext *context) { CoglRendererEGL *egl_renderer = context->display->renderer->winsys; @@ -1080,37 +1080,47 @@ _cogl_winsys_context_egl_get_egl_display (CoglContext *context) return egl_renderer->edpy; } -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT -gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - /* Unsupported feature */ - tex_pixmap->winsys = NULL; - return FALSE; -} - -void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - /* Unsupported feature */ -} - -gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap) -{ - /* Unsupported feature */ -} - -void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - /* Unsupported feature */ -} - -CoglHandle -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - /* Unsupported feature */ -} +static CoglWinsysVtable _cogl_winsys_vtable = + { + .get_proc_address = _cogl_winsys_get_proc_address, + .renderer_connect = _cogl_winsys_renderer_connect, + .renderer_disconnect = _cogl_winsys_renderer_disconnect, + .display_setup = _cogl_winsys_display_setup, + .display_destroy = _cogl_winsys_display_destroy, + .context_init = _cogl_winsys_context_init, + .context_deinit = _cogl_winsys_context_deinit, + .context_egl_get_egl_display = + _cogl_winsys_context_egl_get_egl_display, +#ifdef COGL_HAS_XLIB_SUPPORT + .xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info, #endif + .onscreen_init = _cogl_winsys_onscreen_init, + .onscreen_deinit = _cogl_winsys_onscreen_deinit, + .onscreen_bind = _cogl_winsys_onscreen_bind, + .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers, + .onscreen_swap_region = _cogl_winsys_onscreen_swap_region, + .onscreen_update_swap_throttled = + _cogl_winsys_onscreen_update_swap_throttled, + .onscreen_x11_get_window_xid = + _cogl_winsys_onscreen_x11_get_window_xid, + .onscreen_add_swap_buffers_callback = + _cogl_winsys_onscreen_add_swap_buffers_callback, + .onscreen_remove_swap_buffers_callback = + _cogl_winsys_onscreen_remove_swap_buffers_callback, + .get_vsync_counter = _cogl_winsys_get_vsync_counter + }; + +/* XXX: we use a function because no doubt someone will complain + * about using c99 member initializers because they aren't portable + * to windows. We want to avoid having to rigidly follow the real + * order of members since some members are #ifdefd and we'd have + * to mirror the #ifdefing to add padding etc. For any winsys that + * can assume the platform has a sane compiler then we can just use + * c99 initializers for insane platforms they can initialize + * the members by name in a function. + */ +const CoglWinsysVtable * +_cogl_winsys_egl_get_vtable (void) +{ + return &_cogl_winsys_vtable; +} diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c index 7668a5f3b..26ad6e6e7 100644 --- a/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/winsys/cogl-winsys-glx.c @@ -277,7 +277,15 @@ glx_event_filter_cb (void *native_event, void *data) return COGL_FILTER_CONTINUE; } -gboolean +static void +_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) +{ + _cogl_renderer_xlib_disconnect (renderer); + + g_slice_free (CoglRendererGLX, renderer->winsys); +} + +static gboolean _cogl_winsys_renderer_connect (CoglRenderer *renderer, GError **error) { @@ -325,15 +333,7 @@ error: return FALSE; } -void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - _cogl_renderer_xlib_disconnect (renderer); - - g_slice_free (CoglRendererGLX, renderer->winsys); -} - -void +static void update_winsys_features (CoglContext *context) { CoglDisplayGLX *glx_display = context->display->winsys; @@ -625,32 +625,7 @@ create_context (CoglDisplay *display, GError **error) return TRUE; } -gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayGLX *glx_display; - int i; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - glx_display = g_slice_new0 (CoglDisplayGLX); - display->winsys = glx_display; - - if (!create_context (display, error)) - goto error; - - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - glx_display->glx_cached_configs[i].depth = -1; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -void +static void _cogl_winsys_display_destroy (CoglDisplay *display) { CoglDisplayGLX *glx_display = display->winsys; @@ -682,7 +657,32 @@ _cogl_winsys_display_destroy (CoglDisplay *display) display->winsys = NULL; } -gboolean +static gboolean +_cogl_winsys_display_setup (CoglDisplay *display, + GError **error) +{ + CoglDisplayGLX *glx_display; + int i; + + g_return_val_if_fail (display->winsys == NULL, FALSE); + + glx_display = g_slice_new0 (CoglDisplayGLX); + display->winsys = glx_display; + + if (!create_context (display, error)) + goto error; + + for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) + glx_display->glx_cached_configs[i].depth = -1; + + return TRUE; + +error: + _cogl_winsys_display_destroy (display); + return FALSE; +} + +static gboolean _cogl_winsys_context_init (CoglContext *context, GError **error) { context->winsys = g_new0 (CoglContextGLX, 1); @@ -695,7 +695,7 @@ _cogl_winsys_context_init (CoglContext *context, GError **error) return TRUE; } -void +static void _cogl_winsys_context_deinit (CoglContext *context) { cogl_renderer_remove_native_filter (context->display->renderer, @@ -704,7 +704,7 @@ _cogl_winsys_context_deinit (CoglContext *context) g_free (context->winsys); } -gboolean +static gboolean _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, GError **error) { @@ -859,7 +859,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, return TRUE; } -void +static void _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); @@ -890,7 +890,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) _cogl_xlib_untrap_errors (&old_state); } -void +static void _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; @@ -1002,7 +1002,7 @@ drm_wait_vblank (int fd, drm_wait_vblank_t *vbl) } #endif /* HAVE_DRM */ -void +static void _cogl_winsys_wait_for_vblank (void) { CoglRendererGLX *glx_renderer; @@ -1034,7 +1034,22 @@ _cogl_winsys_wait_for_vblank (void) #endif /* HAVE_DRM */ } -void +static guint32 +_cogl_winsys_get_vsync_counter (void) +{ + guint32 video_sync_count; + CoglRendererGLX *glx_renderer; + + _COGL_GET_CONTEXT (ctx, 0); + + glx_renderer = ctx->display->renderer->winsys; + + glx_renderer->pf_glXGetVideoSync (&video_sync_count); + + return video_sync_count; +} + +static void _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, int *rectangles, int n_rectangles) @@ -1167,22 +1182,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, glx_onscreen->last_swap_vsync_counter = end_frame_vsync_counter; } -guint32 -_cogl_winsys_get_vsync_counter (void) -{ - guint32 video_sync_count; - CoglRendererGLX *glx_renderer; - - _COGL_GET_CONTEXT (ctx, 0); - - glx_renderer = ctx->display->renderer->winsys; - - glx_renderer->pf_glXGetVideoSync (&video_sync_count); - - return video_sync_count; -} - -void +static void _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); @@ -1259,14 +1259,14 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) glx_onscreen->last_swap_vsync_counter = _cogl_winsys_get_vsync_counter (); } -guint32 +static guint32 _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) { CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; return xlib_onscreen->xwin; } -unsigned int +static unsigned int _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, CoglSwapBuffersNotify callback, void *user_data) @@ -1285,7 +1285,7 @@ _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, return entry->id; } -void +static void _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, unsigned int id) { @@ -1305,7 +1305,7 @@ _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, } } -void +static void _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; @@ -1323,7 +1323,7 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) } /* XXX: This is a particularly hacky _cogl_winsys interface... */ -XVisualInfo * +static XVisualInfo * _cogl_winsys_xlib_get_visual_info (void) { CoglDisplayGLX *glx_display; @@ -1616,7 +1616,7 @@ try_create_glx_pixmap (CoglContext *context, return TRUE; } -gboolean +static gboolean _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) { CoglTexturePixmapGLX *glx_tex_pixmap; @@ -1697,7 +1697,7 @@ free_glx_pixmap (CoglContext *context, glx_tex_pixmap->pixmap_bound = FALSE; } -void +static void _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) { CoglTexturePixmapGLX *glx_tex_pixmap; @@ -1720,7 +1720,7 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) g_free (glx_tex_pixmap); } -gboolean +static gboolean _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, gboolean needs_mipmap) { @@ -1861,7 +1861,7 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, return TRUE; } -void +static void _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) { CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; @@ -1869,10 +1869,66 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) glx_tex_pixmap->bind_tex_image_queued = TRUE; } -CoglHandle +static CoglHandle _cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) { CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; return glx_tex_pixmap->glx_tex; } + + +static CoglWinsysVtable _cogl_winsys_vtable = + { + .get_proc_address = _cogl_winsys_get_proc_address, + .renderer_connect = _cogl_winsys_renderer_connect, + .renderer_disconnect = _cogl_winsys_renderer_disconnect, + .display_setup = _cogl_winsys_display_setup, + .display_destroy = _cogl_winsys_display_destroy, + .context_init = _cogl_winsys_context_init, + .context_deinit = _cogl_winsys_context_deinit, + .xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info, + .onscreen_init = _cogl_winsys_onscreen_init, + .onscreen_deinit = _cogl_winsys_onscreen_deinit, + .onscreen_bind = _cogl_winsys_onscreen_bind, + .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers, + .onscreen_swap_region = _cogl_winsys_onscreen_swap_region, + .onscreen_update_swap_throttled = + _cogl_winsys_onscreen_update_swap_throttled, + .onscreen_x11_get_window_xid = + _cogl_winsys_onscreen_x11_get_window_xid, + .onscreen_add_swap_buffers_callback = + _cogl_winsys_onscreen_add_swap_buffers_callback, + .onscreen_remove_swap_buffers_callback = + _cogl_winsys_onscreen_remove_swap_buffers_callback, + .get_vsync_counter = _cogl_winsys_get_vsync_counter, + + /* X11 tfp support... */ + /* XXX: instead of having a rather monolithic winsys vtable we could + * perhaps look for a way to separate these... */ + .texture_pixmap_x11_create = + _cogl_winsys_texture_pixmap_x11_create, + .texture_pixmap_x11_free = + _cogl_winsys_texture_pixmap_x11_free, + .texture_pixmap_x11_update = + _cogl_winsys_texture_pixmap_x11_update, + .texture_pixmap_x11_damage_notify = + _cogl_winsys_texture_pixmap_x11_damage_notify, + .texture_pixmap_x11_get_texture = + _cogl_winsys_texture_pixmap_x11_get_texture, + }; + +/* XXX: we use a function because no doubt someone will complain + * about using c99 member initializers because they aren't portable + * to windows. We want to avoid having to rigidly follow the real + * order of members since some members are #ifdefd and we'd have + * to mirror the #ifdefing to add padding etc. For any winsys that + * can assume the platform has a sane compiler then we can just use + * c99 initializers for insane platforms they can initialize + * the members by name in a function. + */ +const CoglWinsysVtable * +_cogl_winsys_glx_get_vtable (void) +{ + return &_cogl_winsys_vtable; +} diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h index 150f2dcc6..a61084869 100644 --- a/cogl/winsys/cogl-winsys-private.h +++ b/cogl/winsys/cogl-winsys-private.h @@ -31,6 +31,7 @@ #ifdef COGL_HAS_XLIB_SUPPORT #include +#include "cogl-texture-pixmap-x11-private.h" #endif GQuark @@ -51,95 +52,94 @@ typedef enum COGL_WINSYS_RECTANGLE_STATE_ENABLE } CoglWinsysRectangleState; -CoglFuncPtr -_cogl_winsys_get_proc_address (const char *name); +typedef struct _CoglWinsysVtable +{ + CoglFuncPtr + (*get_proc_address) (const char *name); -gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error); + gboolean + (*renderer_connect) (CoglRenderer *renderer, GError **error); -void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer); + void + (*renderer_disconnect) (CoglRenderer *renderer); -gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error); + gboolean + (*display_setup) (CoglDisplay *display, GError **error); -void -_cogl_winsys_display_destroy (CoglDisplay *display); + void + (*display_destroy) (CoglDisplay *display); -gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error); + gboolean + (*context_init) (CoglContext *context, GError **error); -void -_cogl_winsys_context_deinit (CoglContext *context); + void + (*context_deinit) (CoglContext *context); #ifdef COGL_HAS_EGL_SUPPORT -EGLDisplay -_cogl_winsys_context_egl_get_egl_display (CoglContext *context); + EGLDisplay + (*context_egl_get_egl_display) (CoglContext *context); #endif -gboolean -_cogl_winsys_has_feature (CoglWinsysFeature feature); + gboolean + (*has_feature) (CoglWinsysFeature feature); #ifdef COGL_HAS_XLIB_SUPPORT -XVisualInfo * -_cogl_winsys_xlib_get_visual_info (void); + XVisualInfo * + (*xlib_get_visual_info) (void); #endif -gboolean -_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, - GError **error); + gboolean + (*onscreen_init) (CoglOnscreen *onscreen, GError **error); -void -_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen); + void + (*onscreen_deinit) (CoglOnscreen *onscreen); -void -_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen); + void + (*onscreen_bind) (CoglOnscreen *onscreen); -void -_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen); + void + (*onscreen_swap_buffers) (CoglOnscreen *onscreen); -void -_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, - int *rectangles, - int n_rectangles); + void + (*onscreen_swap_region) (CoglOnscreen *onscreen, + int *rectangles, + int n_rectangles); -void -_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen); + void + (*onscreen_update_swap_throttled) (CoglOnscreen *onscreen); -guint32 -_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen); + guint32 + (*onscreen_x11_get_window_xid) (CoglOnscreen *onscreen); -guint32 -_cogl_winsys_get_vsync_counter (void); + unsigned int + (*onscreen_add_swap_buffers_callback) (CoglOnscreen *onscreen, + CoglSwapBuffersNotify callback, + void *user_data); -unsigned int -_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data); + void + (*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen, + unsigned int id); -void -_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, - unsigned int id); + guint32 + (*get_vsync_counter) (void); #ifdef COGL_HAS_XLIB_SUPPORT -gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap); + gboolean + (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap); + void + (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap); -void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap); + gboolean + (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, + gboolean needs_mipmap); -gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap); + void + (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap); -void -_cogl_winsys_texture_pixmap_x11_damage_notify ( - CoglTexturePixmapX11 *tex_pixmap); - -CoglHandle -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap); + CoglHandle + (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap); #endif +} CoglWinsysVtable; + #endif /* __COGL_WINSYS_PRIVATE_H */