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
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 (); \
#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"
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++,
CoglContext *context;
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
unsigned long enable_flags = 0;
+ const CoglWinsysVtable *winsys;
int i;
#ifdef CLUTTER_ENABLE_PROFILE
#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);
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 ();
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
#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);
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
#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"
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
GError **error)
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+ const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
if (framebuffer->allocated)
return TRUE;
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;
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);
}
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));
}
/* 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
/* 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
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;
}
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
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);
+ }
}
#define __COGL_RENDERER_PRIVATE_H
#include "cogl-object-private.h"
+#include "cogl-winsys-private.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h>
{
CoglObject _parent;
gboolean connected;
+ const CoglWinsysVtable *winsys_vtable;
#ifdef COGL_HAS_XLIB_SUPPORT
Display *foreign_xdpy;
#endif
#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);
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)
{
_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,
{
#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);
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
{
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;
#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"
&& 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);
/* 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
CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
XWindowAttributes window_attributes;
int damage_base;
+ const CoglWinsysVtable *winsys;
_COGL_GET_CONTEXT (ctxt, COGL_INVALID_HANDLE);
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);
}
int height)
{
CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle);
+ const CoglWinsysVtable *winsys;
if (!cogl_is_texture_pixmap_x11 (handle))
return;
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);
{
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;
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;
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));
#include "cogl-winsys-egl-feature-functions.h"
};
-CoglFuncPtr
+static CoglFuncPtr
_cogl_winsys_get_proc_address (const char *name)
{
return (CoglFuncPtr) eglGetProcAddress (name);
}
#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)
{
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;
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)
{
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);
return TRUE;
}
-void
+static void
_cogl_winsys_context_deinit (CoglContext *context)
{
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
g_free (context->winsys);
}
-gboolean
+static gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
GError **error)
{
return TRUE;
}
-void
+static void
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
#endif
}
-void
+static void
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
eglSwapInterval (egl_renderer->edpy, 0);
}
-void
+static void
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
int *rectangles,
int n_rectangles)
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;
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)
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;
#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;
}
#endif
-EGLDisplay
+static EGLDisplay
_cogl_winsys_context_egl_get_egl_display (CoglContext *context)
{
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
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 */
-}
+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
+ };
-CoglHandle
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+/* 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)
{
- /* Unsupported feature */
+ return &_cogl_winsys_vtable;
}
-#endif
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)
{
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;
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;
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);
return TRUE;
}
-void
+static void
_cogl_winsys_context_deinit (CoglContext *context)
{
cogl_renderer_remove_native_filter (context->display->renderer,
g_free (context->winsys);
}
-gboolean
+static gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
GError **error)
{
return TRUE;
}
-void
+static void
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
_cogl_xlib_untrap_errors (&old_state);
}
-void
+static void
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
}
#endif /* HAVE_DRM */
-void
+static void
_cogl_winsys_wait_for_vblank (void)
{
CoglRendererGLX *glx_renderer;
#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)
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);
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)
return entry->id;
}
-void
+static void
_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
unsigned int id)
{
}
}
-void
+static void
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
}
/* XXX: This is a particularly hacky _cogl_winsys interface... */
-XVisualInfo *
+static XVisualInfo *
_cogl_winsys_xlib_get_visual_info (void)
{
CoglDisplayGLX *glx_display;
return TRUE;
}
-gboolean
+static gboolean
_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
{
CoglTexturePixmapGLX *glx_tex_pixmap;
glx_tex_pixmap->pixmap_bound = FALSE;
}
-void
+static void
_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
{
CoglTexturePixmapGLX *glx_tex_pixmap;
g_free (glx_tex_pixmap);
}
-gboolean
+static gboolean
_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
gboolean needs_mipmap)
{
return TRUE;
}
-void
+static void
_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
{
CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
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;
+}
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xutil.h>
+#include "cogl-texture-pixmap-x11-private.h"
#endif
GQuark
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 */