Add a vtable of indirection to the winsys code

So that we can dynamically select what winsys backend to use at runtime
we need to have some indirection to how code accesses the winsys instead
of simply calling _cogl_winsys* functions that would collide if we
wanted to compile more than one backend into Cogl.
This commit is contained in:
Robert Bragg 2011-02-25 11:29:08 +00:00
parent d52e3f0cc2
commit dc7383b714
12 changed files with 484 additions and 242 deletions

View File

@ -68,6 +68,12 @@ cogl_onscreen_clutter_backend_set_size (int width, int height)
XVisualInfo * XVisualInfo *
cogl_clutter_winsys_xlib_get_visual_info (void) 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 #endif

View File

@ -268,6 +268,9 @@ struct _CoglContext
CoglContext * CoglContext *
_cogl_context_get_default (); _cogl_context_get_default ();
const CoglWinsysVtable *
_cogl_context_get_winsys (CoglContext *context);
/* Obtains the context and returns retval if NULL */ /* Obtains the context and returns retval if NULL */
#define _COGL_GET_CONTEXT(ctxvar, retval) \ #define _COGL_GET_CONTEXT(ctxvar, retval) \
CoglContext *ctxvar = _cogl_context_get_default (); \ CoglContext *ctxvar = _cogl_context_get_default (); \

View File

@ -33,6 +33,8 @@
#include "cogl-profile.h" #include "cogl-profile.h"
#include "cogl-util.h" #include "cogl-util.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "cogl-display-private.h"
#include "cogl-renderer-private.h"
#include "cogl-journal-private.h" #include "cogl-journal-private.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-pipeline-private.h" #include "cogl-pipeline-private.h"
@ -83,6 +85,12 @@ _cogl_init_feature_overrides (CoglContext *ctx)
COGL_FEATURE_TEXTURE_NPOT_REPEAT); 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 /* For reference: There was some deliberation over whether to have a
* constructor that could throw an exception but looking at standard * constructor that could throw an exception but looking at standard
* practices with several high level OO languages including python, C++, * practices with several high level OO languages including python, C++,
@ -99,6 +107,7 @@ cogl_context_new (CoglDisplay *display,
CoglContext *context; CoglContext *context;
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 }; GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
unsigned long enable_flags = 0; unsigned long enable_flags = 0;
const CoglWinsysVtable *winsys;
int i; int i;
#ifdef CLUTTER_ENABLE_PROFILE #ifdef CLUTTER_ENABLE_PROFILE
@ -155,7 +164,8 @@ cogl_context_new (CoglDisplay *display,
#ifdef COGL_HAS_FULL_WINSYS #ifdef COGL_HAS_FULL_WINSYS
context->stub_winsys = FALSE; 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); cogl_object_unref (display);
g_free (context); g_free (context);
@ -365,7 +375,9 @@ cogl_context_new (CoglDisplay *display,
static void static void
_cogl_context_free (CoglContext *context) _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 (); _cogl_destroy_texture_units ();
@ -480,7 +492,8 @@ cogl_set_default_context (CoglContext *context)
EGLDisplay EGLDisplay
cogl_context_egl_get_egl_display (CoglContext *context) 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 #endif

View File

@ -32,6 +32,7 @@
#include "cogl-object.h" #include "cogl-object.h"
#include "cogl-display-private.h" #include "cogl-display-private.h"
#include "cogl-renderer-private.h"
#include "cogl-winsys-private.h" #include "cogl-winsys-private.h"
static void _cogl_display_free (CoglDisplay *display); static void _cogl_display_free (CoglDisplay *display);
@ -93,15 +94,26 @@ cogl_display_new (CoglRenderer *renderer,
return _cogl_display_object_new (display); return _cogl_display_object_new (display);
} }
static const CoglWinsysVtable *
_cogl_display_get_winsys (CoglDisplay *display)
{
return display->renderer->winsys_vtable;
}
gboolean gboolean
cogl_display_setup (CoglDisplay *display, cogl_display_setup (CoglDisplay *display,
GError **error) GError **error)
{ {
#ifdef COGL_HAS_FULL_WINSYS
const CoglWinsysVtable *winsys;
#endif
if (display->setup) if (display->setup)
return TRUE; return TRUE;
#ifdef COGL_HAS_FULL_WINSYS #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; return FALSE;
#endif #endif

View File

@ -29,6 +29,8 @@
#include "cogl-debug.h" #include "cogl-debug.h"
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "cogl-display-private.h"
#include "cogl-renderer-private.h"
#include "cogl-handle.h" #include "cogl-handle.h"
#include "cogl-object-private.h" #include "cogl-object-private.h"
#include "cogl-util.h" #include "cogl-util.h"
@ -231,6 +233,12 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
cogl_object_unref (ctx); 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 /* This version of cogl_clear can be used internally as an alternative
* to avoid flushing the journal or the framebuffer state. This is * to avoid flushing the journal or the framebuffer state. This is
* needed when doing operations that may be called whiling flushing * needed when doing operations that may be called whiling flushing
@ -1012,6 +1020,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
GError **error) GError **error)
{ {
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
if (framebuffer->allocated) if (framebuffer->allocated)
return TRUE; return TRUE;
@ -1021,7 +1030,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN,
TRUE); TRUE);
if (!_cogl_winsys_onscreen_init (onscreen, error)) if (!winsys->onscreen_init (onscreen, error))
return FALSE; return FALSE;
framebuffer->allocated = TRUE; framebuffer->allocated = TRUE;
@ -1032,10 +1041,14 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
static void static void
_cogl_onscreen_free (CoglOnscreen *onscreen) _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 */ /* Chain up to parent */
_cogl_framebuffer_free (COGL_FRAMEBUFFER (onscreen)); _cogl_framebuffer_free (framebuffer);
g_free (onscreen); g_free (onscreen);
} }
@ -1350,7 +1363,9 @@ bind_gl_framebuffer (CoglContext *ctx,
else else
{ {
#ifdef COGL_HAS_FULL_WINSYS #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 #endif
GE (glBindFramebuffer (target, 0)); GE (glBindFramebuffer (target, 0));
} }
@ -1582,7 +1597,11 @@ cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer)
/* FIXME: we shouldn't need to flush *all* journals here! */ /* FIXME: we shouldn't need to flush *all* journals here! */
cogl_flush (); cogl_flush ();
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) 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 void
@ -1593,10 +1612,14 @@ cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
/* FIXME: we shouldn't need to flush *all* journals here! */ /* FIXME: we shouldn't need to flush *all* journals here! */
cogl_flush (); cogl_flush ();
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
_cogl_winsys_onscreen_swap_region (COGL_ONSCREEN (framebuffer), {
const CoglWinsysVtable *winsys =
_cogl_framebuffer_get_winsys (framebuffer);
winsys->onscreen_swap_region (COGL_ONSCREEN (framebuffer),
rectangles, rectangles,
n_rectangles); n_rectangles);
} }
}
#ifdef COGL_HAS_X11_SUPPORT #ifdef COGL_HAS_X11_SUPPORT
void void
@ -1609,15 +1632,20 @@ cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen,
guint32 guint32
cogl_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) 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 guint32
cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen) cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen)
{ {
guint32 id; CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
XVisualInfo *visinfo = _cogl_winsys_xlib_get_visual_info (); const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
id = (guint32)visinfo->visualid; XVisualInfo *visinfo = winsys->xlib_get_visual_info ();
guint32 id = (guint32)visinfo->visualid;
XFree (visinfo); XFree (visinfo);
return id; return id;
} }
@ -1629,11 +1657,12 @@ cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
void *user_data) void *user_data)
{ {
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
/* Should this just be cogl_onscreen API instead? */ /* Should this just be cogl_onscreen API instead? */
g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0); g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0);
return _cogl_winsys_onscreen_add_swap_buffers_callback (onscreen, return winsys->onscreen_add_swap_buffers_callback (onscreen,
callback, callback,
user_data); user_data);
} }
@ -1643,15 +1672,21 @@ cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
unsigned int id) unsigned int id)
{ {
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); 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 void
cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
gboolean throttled) gboolean throttled)
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
onscreen->swap_throttled = throttled; onscreen->swap_throttled = throttled;
if (COGL_FRAMEBUFFER (onscreen)->allocated) if (framebuffer->allocated)
_cogl_winsys_onscreen_update_swap_throttled (onscreen); {
const CoglWinsysVtable *winsys =
_cogl_framebuffer_get_winsys (framebuffer);
winsys->onscreen_update_swap_throttled (onscreen);
}
} }

View File

@ -25,6 +25,7 @@
#define __COGL_RENDERER_PRIVATE_H #define __COGL_RENDERER_PRIVATE_H
#include "cogl-object-private.h" #include "cogl-object-private.h"
#include "cogl-winsys-private.h"
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -34,6 +35,7 @@ struct _CoglRenderer
{ {
CoglObject _parent; CoglObject _parent;
gboolean connected; gboolean connected;
const CoglWinsysVtable *winsys_vtable;
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
Display *foreign_xdpy; Display *foreign_xdpy;
#endif #endif

View File

@ -37,6 +37,29 @@
#include "cogl-display-private.h" #include "cogl-display-private.h"
#include "cogl-winsys-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); static void _cogl_renderer_free (CoglRenderer *renderer);
COGL_OBJECT_DEFINE (Renderer, 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"); 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 static void
native_filter_closure_free (CoglNativeFilterClosure *closure) native_filter_closure_free (CoglNativeFilterClosure *closure)
{ {
@ -63,7 +92,8 @@ static void
_cogl_renderer_free (CoglRenderer *renderer) _cogl_renderer_free (CoglRenderer *renderer)
{ {
#ifdef COGL_HAS_FULL_WINSYS #ifdef COGL_HAS_FULL_WINSYS
_cogl_winsys_renderer_disconnect (renderer); const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer);
winsys->renderer_disconnect (renderer);
#endif #endif
g_slist_foreach (renderer->event_filters, g_slist_foreach (renderer->event_filters,
@ -114,8 +144,9 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer,
{ {
#ifdef COGL_HAS_FULL_WINSYS #ifdef COGL_HAS_FULL_WINSYS
CoglDisplay *display; 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; return FALSE;
display = cogl_display_new (renderer, onscreen_template); display = cogl_display_new (renderer, onscreen_template);
@ -135,16 +166,51 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer,
gboolean gboolean
cogl_renderer_connect (CoglRenderer *renderer, GError **error) cogl_renderer_connect (CoglRenderer *renderer, GError **error)
{ {
#ifdef COGL_HAS_FULL_WINSYS
int i;
#endif
GString *error_message;
if (renderer->connected) if (renderer->connected)
return TRUE; return TRUE;
#ifdef COGL_HAS_FULL_WINSYS #ifdef COGL_HAS_FULL_WINSYS
if (!_cogl_winsys_renderer_connect (renderer, error)) error_message = g_string_new ("");
return FALSE; for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++)
#endif {
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; renderer->connected = TRUE;
return TRUE; return TRUE;
#endif
} }
CoglFilterReturn CoglFilterReturn

View File

@ -93,8 +93,17 @@ cogl_get_proc_address (const char* name)
{ {
void *address; void *address;
static GModule *module = NULL; 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); address = _cogl_winsys_get_proc_address (name);
#endif
if (address) if (address)
return address; return address;

View File

@ -42,6 +42,8 @@
#include "cogl-texture-2d-private.h" #include "cogl-texture-2d-private.h"
#include "cogl-texture-rectangle-private.h" #include "cogl-texture-rectangle-private.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "cogl-display-private.h"
#include "cogl-renderer-private.h"
#include "cogl-handle.h" #include "cogl-handle.h"
#include "cogl-winsys-private.h" #include "cogl-winsys-private.h"
#include "cogl-pipeline-opengl-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); && 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 static void
process_damage_event (CoglTexturePixmapX11 *tex_pixmap, process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
XDamageNotifyEvent *damage_event) XDamageNotifyEvent *damage_event)
{ {
Display *display; Display *display;
enum { DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; enum { DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode;
const CoglWinsysVtable *winsys;
_COGL_GET_CONTEXT (ctxt, NO_RETVAL); _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 /* 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 point in getting the region and we can just mark that the texture
needs updating */ 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 static CoglFilterReturn
@ -254,6 +268,7 @@ cogl_texture_pixmap_x11_new (guint32 pixmap,
CoglTexture *tex = COGL_TEXTURE (tex_pixmap); CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
XWindowAttributes window_attributes; XWindowAttributes window_attributes;
int damage_base; int damage_base;
const CoglWinsysVtable *winsys;
_COGL_GET_CONTEXT (ctxt, COGL_INVALID_HANDLE); _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.y1 = 0;
tex_pixmap->damage_rect.y2 = tex_pixmap->height; 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); return _cogl_texture_pixmap_x11_handle_new (tex_pixmap);
} }
@ -390,6 +407,7 @@ cogl_texture_pixmap_x11_update_area (CoglHandle handle,
int height) int height)
{ {
CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle); CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle);
const CoglWinsysVtable *winsys;
if (!cogl_is_texture_pixmap_x11 (handle)) if (!cogl_is_texture_pixmap_x11 (handle))
return; 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 texture because we can't determine which will be needed until we
actually render something */ 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, cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
x, y, width, height); x, y, width, height);
@ -617,7 +636,10 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
{ {
if (tex_pixmap->winsys) 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); _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
return; return;
@ -649,7 +671,11 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if (tex_pixmap->use_winsys_texture) 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 else
tex = tex_pixmap->tex; tex = tex_pixmap->tex;
@ -912,7 +938,11 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
cogl_handle_unref (tex_pixmap->tex); cogl_handle_unref (tex_pixmap->tex);
if (tex_pixmap->winsys) 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 */ /* Chain up */
_cogl_texture_free (COGL_TEXTURE (tex_pixmap)); _cogl_texture_free (COGL_TEXTURE (tex_pixmap));

View File

@ -168,7 +168,7 @@ static const CoglFeatureData winsys_feature_data[] =
#include "cogl-winsys-egl-feature-functions.h" #include "cogl-winsys-egl-feature-functions.h"
}; };
CoglFuncPtr static CoglFuncPtr
_cogl_winsys_get_proc_address (const char *name) _cogl_winsys_get_proc_address (const char *name)
{ {
return (CoglFuncPtr) eglGetProcAddress (name); return (CoglFuncPtr) eglGetProcAddress (name);
@ -237,7 +237,21 @@ event_filter_cb (void *event, void *data)
} }
#endif /* COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT */ #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, _cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error) GError **error)
{ {
@ -285,21 +299,7 @@ error:
return FALSE; return FALSE;
} }
void 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);
}
void
update_winsys_features (CoglContext *context) update_winsys_features (CoglContext *context)
{ {
CoglDisplayEGL *egl_display = context->display->winsys; CoglDisplayEGL *egl_display = context->display->winsys;
@ -675,7 +675,20 @@ create_context (CoglDisplay *display, GError **error)
return status; 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, _cogl_winsys_display_setup (CoglDisplay *display,
GError **error) GError **error)
{ {
@ -698,20 +711,7 @@ error:
return FALSE; return FALSE;
} }
void static gboolean
_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
_cogl_winsys_context_init (CoglContext *context, GError **error) _cogl_winsys_context_init (CoglContext *context, GError **error)
{ {
context->winsys = g_new0 (CoglContextEGL, 1); context->winsys = g_new0 (CoglContextEGL, 1);
@ -726,7 +726,7 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
return TRUE; return TRUE;
} }
void static void
_cogl_winsys_context_deinit (CoglContext *context) _cogl_winsys_context_deinit (CoglContext *context)
{ {
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
@ -737,7 +737,7 @@ _cogl_winsys_context_deinit (CoglContext *context)
g_free (context->winsys); g_free (context->winsys);
} }
gboolean static gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
GError **error) GError **error)
{ {
@ -896,7 +896,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
return TRUE; return TRUE;
} }
void static void
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@ -941,7 +941,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
#endif #endif
} }
void static void
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
{ {
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
@ -982,7 +982,7 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
eglSwapInterval (egl_renderer->edpy, 0); eglSwapInterval (egl_renderer->edpy, 0);
} }
void static void
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
int *rectangles, int *rectangles,
int n_rectangles) int n_rectangles)
@ -998,14 +998,14 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
g_warning ("Error reported by eglSwapBuffersRegion"); g_warning ("Error reported by eglSwapBuffersRegion");
} }
guint32 static guint32
_cogl_winsys_get_vsync_counter (void) _cogl_winsys_get_vsync_counter (void)
{ {
/* Unsupported feature */ /* Unsupported feature */
return 0; return 0;
} }
void static void
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
{ {
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; 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); eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface);
} }
guint32 static guint32
_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
{ {
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
return xlib_onscreen->xwin; return xlib_onscreen->xwin;
} }
unsigned int static unsigned int
_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
CoglSwapBuffersNotify callback, CoglSwapBuffersNotify callback,
void *user_data) void *user_data)
@ -1031,14 +1031,14 @@ _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
return 0; return 0;
} }
void static void
_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
unsigned int id) unsigned int id)
{ {
/* Unsupported feature */ /* Unsupported feature */
} }
void static void
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
{ {
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; 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 #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
/* XXX: This is a particularly hacky _cogl_winsys interface... */ /* XXX: This is a particularly hacky _cogl_winsys interface... */
XVisualInfo * static XVisualInfo *
_cogl_winsys_xlib_get_visual_info (void) _cogl_winsys_xlib_get_visual_info (void)
{ {
CoglDisplayEGL *egl_display; CoglDisplayEGL *egl_display;
@ -1072,7 +1072,7 @@ _cogl_winsys_xlib_get_visual_info (void)
} }
#endif #endif
EGLDisplay static EGLDisplay
_cogl_winsys_context_egl_get_egl_display (CoglContext *context) _cogl_winsys_context_egl_get_egl_display (CoglContext *context)
{ {
CoglRendererEGL *egl_renderer = context->display->renderer->winsys; CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
@ -1080,37 +1080,47 @@ _cogl_winsys_context_egl_get_egl_display (CoglContext *context)
return egl_renderer->edpy; return egl_renderer->edpy;
} }
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT static CoglWinsysVtable _cogl_winsys_vtable =
gboolean
_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
{ {
/* Unsupported feature */ .get_proc_address = _cogl_winsys_get_proc_address,
tex_pixmap->winsys = NULL; .renderer_connect = _cogl_winsys_renderer_connect,
return FALSE; .renderer_disconnect = _cogl_winsys_renderer_disconnect,
} .display_setup = _cogl_winsys_display_setup,
.display_destroy = _cogl_winsys_display_destroy,
void .context_init = _cogl_winsys_context_init,
_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) .context_deinit = _cogl_winsys_context_deinit,
{ .context_egl_get_egl_display =
/* Unsupported feature */ _cogl_winsys_context_egl_get_egl_display,
} #ifdef COGL_HAS_XLIB_SUPPORT
.xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info,
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 */
}
#endif #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;
}

View File

@ -277,7 +277,15 @@ glx_event_filter_cb (void *native_event, void *data)
return COGL_FILTER_CONTINUE; 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, _cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error) GError **error)
{ {
@ -325,15 +333,7 @@ error:
return FALSE; return FALSE;
} }
void static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
{
_cogl_renderer_xlib_disconnect (renderer);
g_slice_free (CoglRendererGLX, renderer->winsys);
}
void
update_winsys_features (CoglContext *context) update_winsys_features (CoglContext *context)
{ {
CoglDisplayGLX *glx_display = context->display->winsys; CoglDisplayGLX *glx_display = context->display->winsys;
@ -625,32 +625,7 @@ create_context (CoglDisplay *display, GError **error)
return TRUE; return TRUE;
} }
gboolean static void
_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
_cogl_winsys_display_destroy (CoglDisplay *display) _cogl_winsys_display_destroy (CoglDisplay *display)
{ {
CoglDisplayGLX *glx_display = display->winsys; CoglDisplayGLX *glx_display = display->winsys;
@ -682,7 +657,32 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
display->winsys = NULL; 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) _cogl_winsys_context_init (CoglContext *context, GError **error)
{ {
context->winsys = g_new0 (CoglContextGLX, 1); context->winsys = g_new0 (CoglContextGLX, 1);
@ -695,7 +695,7 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
return TRUE; return TRUE;
} }
void static void
_cogl_winsys_context_deinit (CoglContext *context) _cogl_winsys_context_deinit (CoglContext *context)
{ {
cogl_renderer_remove_native_filter (context->display->renderer, cogl_renderer_remove_native_filter (context->display->renderer,
@ -704,7 +704,7 @@ _cogl_winsys_context_deinit (CoglContext *context)
g_free (context->winsys); g_free (context->winsys);
} }
gboolean static gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
GError **error) GError **error)
{ {
@ -859,7 +859,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
return TRUE; return TRUE;
} }
void static void
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@ -890,7 +890,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
_cogl_xlib_untrap_errors (&old_state); _cogl_xlib_untrap_errors (&old_state);
} }
void static void
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
{ {
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
@ -1002,7 +1002,7 @@ drm_wait_vblank (int fd, drm_wait_vblank_t *vbl)
} }
#endif /* HAVE_DRM */ #endif /* HAVE_DRM */
void static void
_cogl_winsys_wait_for_vblank (void) _cogl_winsys_wait_for_vblank (void)
{ {
CoglRendererGLX *glx_renderer; CoglRendererGLX *glx_renderer;
@ -1034,7 +1034,22 @@ _cogl_winsys_wait_for_vblank (void)
#endif /* HAVE_DRM */ #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, _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
int *rectangles, int *rectangles,
int n_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; glx_onscreen->last_swap_vsync_counter = end_frame_vsync_counter;
} }
guint32 static void
_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
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (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 (); glx_onscreen->last_swap_vsync_counter = _cogl_winsys_get_vsync_counter ();
} }
guint32 static guint32
_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
{ {
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
return xlib_onscreen->xwin; return xlib_onscreen->xwin;
} }
unsigned int static unsigned int
_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
CoglSwapBuffersNotify callback, CoglSwapBuffersNotify callback,
void *user_data) void *user_data)
@ -1285,7 +1285,7 @@ _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
return entry->id; return entry->id;
} }
void static void
_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
unsigned int id) 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) _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
{ {
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; 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... */ /* XXX: This is a particularly hacky _cogl_winsys interface... */
XVisualInfo * static XVisualInfo *
_cogl_winsys_xlib_get_visual_info (void) _cogl_winsys_xlib_get_visual_info (void)
{ {
CoglDisplayGLX *glx_display; CoglDisplayGLX *glx_display;
@ -1616,7 +1616,7 @@ try_create_glx_pixmap (CoglContext *context,
return TRUE; return TRUE;
} }
gboolean static gboolean
_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
{ {
CoglTexturePixmapGLX *glx_tex_pixmap; CoglTexturePixmapGLX *glx_tex_pixmap;
@ -1697,7 +1697,7 @@ free_glx_pixmap (CoglContext *context,
glx_tex_pixmap->pixmap_bound = FALSE; glx_tex_pixmap->pixmap_bound = FALSE;
} }
void static void
_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
{ {
CoglTexturePixmapGLX *glx_tex_pixmap; CoglTexturePixmapGLX *glx_tex_pixmap;
@ -1720,7 +1720,7 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
g_free (glx_tex_pixmap); g_free (glx_tex_pixmap);
} }
gboolean static gboolean
_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
gboolean needs_mipmap) gboolean needs_mipmap)
{ {
@ -1861,7 +1861,7 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
return TRUE; return TRUE;
} }
void static void
_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
{ {
CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; 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; glx_tex_pixmap->bind_tex_image_queued = TRUE;
} }
CoglHandle static CoglHandle
_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) _cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
{ {
CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
return glx_tex_pixmap->glx_tex; 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;
}

View File

@ -31,6 +31,7 @@
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include "cogl-texture-pixmap-x11-private.h"
#endif #endif
GQuark GQuark
@ -51,95 +52,94 @@ typedef enum
COGL_WINSYS_RECTANGLE_STATE_ENABLE COGL_WINSYS_RECTANGLE_STATE_ENABLE
} CoglWinsysRectangleState; } CoglWinsysRectangleState;
typedef struct _CoglWinsysVtable
{
CoglFuncPtr CoglFuncPtr
_cogl_winsys_get_proc_address (const char *name); (*get_proc_address) (const char *name);
gboolean gboolean
_cogl_winsys_renderer_connect (CoglRenderer *renderer, (*renderer_connect) (CoglRenderer *renderer, GError **error);
GError **error);
void void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer); (*renderer_disconnect) (CoglRenderer *renderer);
gboolean gboolean
_cogl_winsys_display_setup (CoglDisplay *display, (*display_setup) (CoglDisplay *display, GError **error);
GError **error);
void void
_cogl_winsys_display_destroy (CoglDisplay *display); (*display_destroy) (CoglDisplay *display);
gboolean gboolean
_cogl_winsys_context_init (CoglContext *context, GError **error); (*context_init) (CoglContext *context, GError **error);
void void
_cogl_winsys_context_deinit (CoglContext *context); (*context_deinit) (CoglContext *context);
#ifdef COGL_HAS_EGL_SUPPORT #ifdef COGL_HAS_EGL_SUPPORT
EGLDisplay EGLDisplay
_cogl_winsys_context_egl_get_egl_display (CoglContext *context); (*context_egl_get_egl_display) (CoglContext *context);
#endif #endif
gboolean gboolean
_cogl_winsys_has_feature (CoglWinsysFeature feature); (*has_feature) (CoglWinsysFeature feature);
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
XVisualInfo * XVisualInfo *
_cogl_winsys_xlib_get_visual_info (void); (*xlib_get_visual_info) (void);
#endif #endif
gboolean gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, (*onscreen_init) (CoglOnscreen *onscreen, GError **error);
GError **error);
void void
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen); (*onscreen_deinit) (CoglOnscreen *onscreen);
void void
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen); (*onscreen_bind) (CoglOnscreen *onscreen);
void void
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen); (*onscreen_swap_buffers) (CoglOnscreen *onscreen);
void void
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, (*onscreen_swap_region) (CoglOnscreen *onscreen,
int *rectangles, int *rectangles,
int n_rectangles); int n_rectangles);
void void
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen); (*onscreen_update_swap_throttled) (CoglOnscreen *onscreen);
guint32 guint32
_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen); (*onscreen_x11_get_window_xid) (CoglOnscreen *onscreen);
guint32
_cogl_winsys_get_vsync_counter (void);
unsigned int unsigned int
_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, (*onscreen_add_swap_buffers_callback) (CoglOnscreen *onscreen,
CoglSwapBuffersNotify callback, CoglSwapBuffersNotify callback,
void *user_data); void *user_data);
void void
_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, (*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen,
unsigned int id); unsigned int id);
guint32
(*get_vsync_counter) (void);
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
gboolean gboolean
_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap); (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap);
void void
_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap); (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap);
gboolean gboolean
_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap,
gboolean needs_mipmap); gboolean needs_mipmap);
void void
_cogl_winsys_texture_pixmap_x11_damage_notify ( (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap);
CoglTexturePixmapX11 *tex_pixmap);
CoglHandle CoglHandle
_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap); (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap);
#endif #endif
} CoglWinsysVtable;
#endif /* __COGL_WINSYS_PRIVATE_H */ #endif /* __COGL_WINSYS_PRIVATE_H */