diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h index 25d2235bc..1a624b5a3 100644 --- a/cogl/cogl-onscreen-private.h +++ b/cogl/cogl-onscreen-private.h @@ -32,6 +32,19 @@ #include #endif +typedef struct _CoglSwapBuffersNotifyEntry CoglSwapBuffersNotifyEntry; + +COGL_TAILQ_HEAD (CoglSwapBuffersNotifyList, CoglSwapBuffersNotifyEntry); + +struct _CoglSwapBuffersNotifyEntry +{ + COGL_TAILQ_ENTRY (CoglSwapBuffersNotifyEntry) list_node; + + CoglSwapBuffersNotify callback; + void *user_data; + unsigned int id; +}; + struct _CoglOnscreen { CoglFramebuffer _parent; @@ -48,6 +61,8 @@ struct _CoglOnscreen gboolean swap_throttled; + CoglSwapBuffersNotifyList swap_callbacks; + void *winsys; }; @@ -58,4 +73,7 @@ void _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, int width, int height); +void +_cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen); + #endif /* __COGL_ONSCREEN_PRIVATE_H */ diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c index 11b14927d..7c81ec008 100644 --- a/cogl/cogl-onscreen.c +++ b/cogl/cogl-onscreen.c @@ -44,6 +44,8 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen, { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + COGL_TAILQ_INIT (&onscreen->swap_callbacks); + framebuffer->config = onscreen_template->config; cogl_object_ref (framebuffer->config.swap_chain); } @@ -256,18 +258,16 @@ cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer, void *user_data) { CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); + CoglSwapBuffersNotifyEntry *entry = g_slice_new0 (CoglSwapBuffersNotifyEntry); + static int next_swap_buffers_callback_id = 0; - /* Should this just be cogl_onscreen API instead? */ - _COGL_RETURN_VAL_IF_FAIL (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0); + entry->callback = callback; + entry->user_data = user_data; + entry->id = next_swap_buffers_callback_id++; - /* This should only be called when - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT is advertised */ - _COGL_RETURN_VAL_IF_FAIL (winsys->onscreen_add_swap_buffers_callback != NULL, 0); + COGL_TAILQ_INSERT_TAIL (&onscreen->swap_callbacks, entry, list_node); - return winsys->onscreen_add_swap_buffers_callback (onscreen, - callback, - user_data); + return entry->id; } void @@ -275,13 +275,17 @@ cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer, unsigned int id) { CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); + CoglSwapBuffersNotifyEntry *entry; - /* This should only be called when - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT is advertised */ - _COGL_RETURN_IF_FAIL (winsys->onscreen_remove_swap_buffers_callback != NULL); - - winsys->onscreen_remove_swap_buffers_callback (onscreen, id); + COGL_TAILQ_FOREACH (entry, &onscreen->swap_callbacks, list_node) + { + if (entry->id == id) + { + COGL_TAILQ_REMOVE (&onscreen->swap_callbacks, entry, list_node); + g_slice_free (CoglSwapBuffersNotifyEntry, entry); + break; + } + } } void @@ -329,6 +333,18 @@ cogl_onscreen_hide (CoglOnscreen *onscreen) } } +void +_cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen) +{ + CoglSwapBuffersNotifyEntry *entry, *tmp; + + COGL_TAILQ_FOREACH_SAFE (entry, + &onscreen->swap_callbacks, + list_node, + tmp) + entry->callback (COGL_FRAMEBUFFER (onscreen), entry->user_data); +} + void _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, int width, int height) diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c index 59165de56..e4a01f819 100644 --- a/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/winsys/cogl-winsys-glx.c @@ -83,13 +83,6 @@ typedef struct _CoglOnscreenGLX GList *swap_callbacks; } CoglOnscreenGLX; -typedef struct _CoglSwapBuffersNotifyEntry -{ - CoglSwapBuffersNotify callback; - void *user_data; - unsigned int id; -} CoglSwapBuffersNotifyEntry; - typedef struct _CoglTexturePixmapGLX { GLXPixmap glx_pixmap; @@ -170,19 +163,11 @@ static void notify_swap_buffers (CoglContext *context, GLXDrawable drawable) { CoglOnscreen *onscreen = find_onscreen_for_xid (context, (guint32)drawable); - CoglOnscreenGLX *glx_onscreen; - GList *l; if (!onscreen) return; - glx_onscreen = onscreen->winsys; - - for (l = glx_onscreen->swap_callbacks; l; l = l->next) - { - CoglSwapBuffersNotifyEntry *entry = l->data; - entry->callback (COGL_FRAMEBUFFER (onscreen), entry->user_data); - } + _cogl_onscreen_notify_swap_buffers (onscreen); } static CoglFilterReturn @@ -1360,45 +1345,6 @@ _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) return xlib_onscreen->xwin; } -static unsigned int -_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data) -{ - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - CoglSwapBuffersNotifyEntry *entry = g_slice_new0 (CoglSwapBuffersNotifyEntry); - static int next_swap_buffers_callback_id = 0; - - entry->callback = callback; - entry->user_data = user_data; - entry->id = next_swap_buffers_callback_id++; - - glx_onscreen->swap_callbacks = - g_list_prepend (glx_onscreen->swap_callbacks, entry); - - return entry->id; -} - -static void -_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, - unsigned int id) -{ - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - GList *l; - - for (l = glx_onscreen->swap_callbacks; l; l = l->next) - { - CoglSwapBuffersNotifyEntry *entry = l->data; - if (entry->id == id) - { - g_slice_free (CoglSwapBuffersNotifyEntry, entry); - glx_onscreen->swap_callbacks = - g_list_delete_link (glx_onscreen->swap_callbacks, l); - return; - } - } -} - static void _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) { @@ -2053,10 +1999,6 @@ static CoglWinsysVtable _cogl_winsys_vtable = _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, .onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility, .poll_get_info = _cogl_winsys_poll_get_info, diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h index 73fcc7b3f..8b864ec6b 100644 --- a/cogl/winsys/cogl-winsys-private.h +++ b/cogl/winsys/cogl-winsys-private.h @@ -129,15 +129,6 @@ typedef struct _CoglWinsysVtable (*onscreen_win32_get_window) (CoglOnscreen *onscreen); #endif - unsigned int - (*onscreen_add_swap_buffers_callback) (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data); - - void - (*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen, - unsigned int id); - void (*poll_get_info) (CoglContext *context, CoglPollFD **poll_fds,