Move the add_swap_buffers_callback functions out of the winsys

Instead of having each winsys implement its own list of callbacks the
list is now just attached directly to the CoglOnscreen using code in
cogl-onscreen.c. The winsys's can invoke this list of callbacks by
calling _cogl_onscreen_notify_swap_buffers(). All of the winsys's
would probably have a very similar implementation for this anyway and
I don't think it makes much sense to try and save the cost of a list
pointer in the CoglOnscreen struct.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2011-12-19 19:26:44 +00:00 committed by Robert Bragg
parent 389198a0d5
commit 99c651d2b4
4 changed files with 50 additions and 83 deletions

View File

@ -32,6 +32,19 @@
#include <windows.h>
#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 */

View File

@ -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)

View File

@ -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,

View File

@ -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,