onscreen: Make the resize callback work the same as the frame callback
When adding the frame callback API in 70040166 we decided on a common idiom for adding callbacks which would return an opaque pointer representing the closure for the callback. This pointer can then be used to later remove the callback. The closure can also contain an optional callback to invoke when the user data parameter is destroyed. The resize callback didn't work this way and instead had an integer handle to identify the closure. This patch changes it to work the same way as the frame callback. Reviewed-by: Robert Bragg <robert@linux.intel.com> (cherry picked from commit 33164c4b04d253ebe0ff41b12c1e90232c519274)
This commit is contained in:
parent
b01e0e6a48
commit
816a5bc437
5 changed files with 81 additions and 69 deletions
|
@ -46,17 +46,16 @@ struct _CoglFrameClosure
|
||||||
CoglUserDataDestroyCallback destroy;
|
CoglUserDataDestroyCallback destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _CoglResizeNotifyEntry CoglResizeNotifyEntry;
|
COGL_TAILQ_HEAD (CoglOnscreenResizeCallbackList, CoglOnscreenResizeClosure);
|
||||||
|
|
||||||
COGL_TAILQ_HEAD (CoglResizeNotifyList, CoglResizeNotifyEntry);
|
struct _CoglOnscreenResizeClosure
|
||||||
|
|
||||||
struct _CoglResizeNotifyEntry
|
|
||||||
{
|
{
|
||||||
COGL_TAILQ_ENTRY (CoglResizeNotifyEntry) list_node;
|
COGL_TAILQ_ENTRY (CoglOnscreenResizeClosure) list_node;
|
||||||
|
|
||||||
CoglOnscreenResizeCallback callback;
|
CoglOnscreenResizeCallback callback;
|
||||||
|
|
||||||
void *user_data;
|
void *user_data;
|
||||||
unsigned int id;
|
CoglUserDataDestroyCallback destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _CoglOnscreenEvent CoglOnscreenEvent;
|
typedef struct _CoglOnscreenEvent CoglOnscreenEvent;
|
||||||
|
@ -95,7 +94,7 @@ struct _CoglOnscreen
|
||||||
CoglFrameCallbackList frame_closures;
|
CoglFrameCallbackList frame_closures;
|
||||||
|
|
||||||
CoglBool resizable;
|
CoglBool resizable;
|
||||||
CoglResizeNotifyList resize_callbacks;
|
CoglOnscreenResizeCallbackList resize_closures;
|
||||||
|
|
||||||
int64_t frame_counter;
|
int64_t frame_counter;
|
||||||
int64_t swap_frame_counter; /* frame counter at last all to
|
int64_t swap_frame_counter; /* frame counter at last all to
|
||||||
|
|
|
@ -47,7 +47,7 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
|
||||||
COGL_TAILQ_INIT (&onscreen->frame_closures);
|
COGL_TAILQ_INIT (&onscreen->frame_closures);
|
||||||
COGL_TAILQ_INIT (&onscreen->resize_callbacks);
|
COGL_TAILQ_INIT (&onscreen->resize_closures);
|
||||||
|
|
||||||
framebuffer->config = onscreen_template->config;
|
framebuffer->config = onscreen_template->config;
|
||||||
cogl_object_ref (framebuffer->config.swap_chain);
|
cogl_object_ref (framebuffer->config.swap_chain);
|
||||||
|
@ -115,24 +115,20 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
|
||||||
{
|
{
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
|
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
|
||||||
CoglResizeNotifyEntry *resize_entry;
|
|
||||||
CoglFrameClosure *frame_closure;
|
|
||||||
CoglFrameInfo *frame_info;
|
CoglFrameInfo *frame_info;
|
||||||
|
|
||||||
while ((resize_entry = COGL_TAILQ_FIRST (&onscreen->resize_callbacks)))
|
while (!COGL_TAILQ_EMPTY (&onscreen->resize_closures))
|
||||||
{
|
{
|
||||||
COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, resize_entry, list_node);
|
CoglOnscreenResizeClosure *resize_closure =
|
||||||
g_slice_free (CoglResizeNotifyEntry, resize_entry);
|
COGL_TAILQ_FIRST (&onscreen->resize_closures);
|
||||||
|
cogl_onscreen_remove_resize_callback (onscreen, resize_closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((frame_closure = COGL_TAILQ_FIRST (&onscreen->frame_closures)))
|
while (!COGL_TAILQ_EMPTY (&onscreen->frame_closures))
|
||||||
{
|
{
|
||||||
COGL_TAILQ_REMOVE (&onscreen->frame_closures, frame_closure, list_node);
|
CoglFrameClosure *frame_closure =
|
||||||
|
COGL_TAILQ_FIRST (&onscreen->frame_closures);
|
||||||
if (frame_closure->destroy)
|
cogl_onscreen_remove_frame_callback (onscreen, frame_closure);
|
||||||
frame_closure->destroy (frame_closure->user_data);
|
|
||||||
|
|
||||||
g_slice_free (CoglFrameClosure, frame_closure);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((frame_info = g_queue_pop_tail (&onscreen->pending_frame_infos)))
|
while ((frame_info = g_queue_pop_tail (&onscreen->pending_frame_infos)))
|
||||||
|
@ -566,17 +562,17 @@ _cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info)
|
||||||
void
|
void
|
||||||
_cogl_onscreen_notify_resize (CoglOnscreen *onscreen)
|
_cogl_onscreen_notify_resize (CoglOnscreen *onscreen)
|
||||||
{
|
{
|
||||||
CoglResizeNotifyEntry *entry, *tmp;
|
CoglOnscreenResizeClosure *closure, *tmp;
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
|
||||||
COGL_TAILQ_FOREACH_SAFE (entry,
|
COGL_TAILQ_FOREACH_SAFE (closure,
|
||||||
&onscreen->resize_callbacks,
|
&onscreen->resize_closures,
|
||||||
list_node,
|
list_node,
|
||||||
tmp)
|
tmp)
|
||||||
entry->callback (onscreen,
|
closure->callback (onscreen,
|
||||||
framebuffer->width,
|
framebuffer->width,
|
||||||
framebuffer->height,
|
framebuffer->height,
|
||||||
entry->user_data);
|
closure->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -620,38 +616,33 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen)
|
||||||
return onscreen->resizable;
|
return onscreen->resizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
CoglOnscreenResizeClosure *
|
||||||
cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
|
cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen,
|
||||||
CoglOnscreenResizeCallback callback,
|
CoglOnscreenResizeCallback callback,
|
||||||
void *user_data)
|
void *user_data,
|
||||||
|
CoglUserDataDestroyCallback destroy)
|
||||||
{
|
{
|
||||||
CoglResizeNotifyEntry *entry = g_slice_new (CoglResizeNotifyEntry);
|
CoglOnscreenResizeClosure *closure = g_slice_new (CoglOnscreenResizeClosure);
|
||||||
static int next_resize_callback_id = 0;
|
|
||||||
|
|
||||||
entry->callback = callback;
|
closure->callback = callback;
|
||||||
entry->user_data = user_data;
|
closure->user_data = user_data;
|
||||||
entry->id = next_resize_callback_id++;
|
closure->destroy = destroy;
|
||||||
|
|
||||||
COGL_TAILQ_INSERT_TAIL (&onscreen->resize_callbacks, entry, list_node);
|
COGL_TAILQ_INSERT_TAIL (&onscreen->resize_closures, closure, list_node);
|
||||||
|
|
||||||
return entry->id;
|
return closure;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
|
cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen,
|
||||||
unsigned int id)
|
CoglOnscreenResizeClosure *closure)
|
||||||
{
|
{
|
||||||
CoglResizeNotifyEntry *entry;
|
if (closure->destroy)
|
||||||
|
closure->destroy (closure->user_data);
|
||||||
|
|
||||||
COGL_TAILQ_FOREACH (entry, &onscreen->resize_callbacks, list_node)
|
COGL_TAILQ_REMOVE (&onscreen->resize_closures, closure, list_node);
|
||||||
{
|
|
||||||
if (entry->id == id)
|
g_slice_free (CoglOnscreenResizeClosure, closure);
|
||||||
{
|
|
||||||
COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, entry, list_node);
|
|
||||||
g_slice_free (CoglResizeNotifyEntry, entry);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
|
|
|
@ -614,7 +614,7 @@ cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
|
||||||
* will be automatically updated to match the new size of the
|
* will be automatically updated to match the new size of the
|
||||||
* framebuffer with an origin of (0,0). If your application needs more
|
* framebuffer with an origin of (0,0). If your application needs more
|
||||||
* specialized control of the viewport it will need to register a
|
* specialized control of the viewport it will need to register a
|
||||||
* resize handler using cogl_onscreen_add_resize_handler() so that it
|
* resize handler using cogl_onscreen_add_resize_callback() so that it
|
||||||
* can track when the viewport has been changed automatically.</note>
|
* can track when the viewport has been changed automatically.</note>
|
||||||
*
|
*
|
||||||
* Since: 2.0
|
* Since: 2.0
|
||||||
|
@ -655,10 +655,10 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen);
|
||||||
* @width: The new width of @onscreen
|
* @width: The new width of @onscreen
|
||||||
* @height: The new height of @onscreen
|
* @height: The new height of @onscreen
|
||||||
* @user_data: The private passed to
|
* @user_data: The private passed to
|
||||||
* cogl_onscreen_add_resize_handler()
|
* cogl_onscreen_add_resize_callback()
|
||||||
*
|
*
|
||||||
* Is a callback type used with the
|
* Is a callback type used with the
|
||||||
* cogl_onscreen_add_resize_handler() allowing applications to be
|
* cogl_onscreen_add_resize_callback() allowing applications to be
|
||||||
* notified whenever an @onscreen framebuffer is resized.
|
* notified whenever an @onscreen framebuffer is resized.
|
||||||
*
|
*
|
||||||
* <note>Cogl automatically updates the viewport of an @onscreen
|
* <note>Cogl automatically updates the viewport of an @onscreen
|
||||||
|
@ -679,18 +679,34 @@ typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_onscreen_add_resize_handler:
|
* CoglOnscreenResizeClosure:
|
||||||
|
*
|
||||||
|
* An opaque type that tracks a #CoglOnscreenResizeCallback and
|
||||||
|
* associated user data. A #CoglOnscreenResizeClosure pointer will be
|
||||||
|
* returned from cogl_onscreen_add_resize_callback() and it allows you
|
||||||
|
* to remove a callback later using
|
||||||
|
* cogl_onscreen_remove_resize_callback().
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
typedef struct _CoglOnscreenResizeClosure CoglOnscreenResizeClosure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_onscreen_add_resize_callback:
|
||||||
* @onscreen: A #CoglOnscreen framebuffer
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
* @callback: A #CoglOnscreenResizeCallback to call when the @onscreen
|
* @callback: A #CoglOnscreenResizeCallback to call when the @onscreen
|
||||||
* changes size.
|
* changes size.
|
||||||
* @user_data: Private data to be passed to @callback.
|
* @user_data: Private data to be passed to @callback.
|
||||||
|
* @destroy: An optional callback to destroy @user_data when the
|
||||||
|
* @callback is removed or @onscreen is freed.
|
||||||
*
|
*
|
||||||
* Registers a @callback with @onscreen that will be called whenever
|
* Registers a @callback with @onscreen that will be called whenever
|
||||||
* the @onscreen framebuffer changes size.
|
* the @onscreen framebuffer changes size.
|
||||||
*
|
*
|
||||||
* The @callback can be removed using
|
* The @callback can be removed using
|
||||||
* cogl_onscreen_remove_resize_handler() passing the same @callback
|
* cogl_onscreen_remove_resize_callback() passing the returned closure
|
||||||
* and @user_data pair.
|
* pointer.
|
||||||
*
|
*
|
||||||
* <note>Since Cogl automatically updates the viewport of an @onscreen
|
* <note>Since Cogl automatically updates the viewport of an @onscreen
|
||||||
* framebuffer that is resized, a resize callback can also be used to
|
* framebuffer that is resized, a resize callback can also be used to
|
||||||
|
@ -704,29 +720,29 @@ typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen,
|
||||||
* while an application might have arbitrary locks held for
|
* while an application might have arbitrary locks held for
|
||||||
* example.</note>
|
* example.</note>
|
||||||
*
|
*
|
||||||
* Return value: a unique identifier that can be used to remove to remove
|
* Return value: a #CoglOnscreenResizeClosure pointer that can be used to
|
||||||
* the callback later.
|
* remove the callback and associated @user_data later.
|
||||||
*
|
|
||||||
* Since: 2.0
|
* Since: 2.0
|
||||||
*/
|
*/
|
||||||
unsigned int
|
CoglOnscreenResizeClosure *
|
||||||
cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
|
cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen,
|
||||||
CoglOnscreenResizeCallback callback,
|
CoglOnscreenResizeCallback callback,
|
||||||
void *user_data);
|
void *user_data,
|
||||||
|
CoglUserDataDestroyCallback destroy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_onscreen_remove_resize_handler:
|
* cogl_onscreen_remove_resize_callback:
|
||||||
* @onscreen: A #CoglOnscreen framebuffer
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
* @id: An identifier returned from cogl_onscreen_add_resize_handler()
|
* @closure: An identifier returned from cogl_onscreen_add_resize_callback()
|
||||||
*
|
*
|
||||||
* Removes a resize @callback and @user_data pair that were previously
|
* Removes a resize @callback and @user_data pair that were previously
|
||||||
* associated with @onscreen via cogl_onscreen_add_resize_handler().
|
* associated with @onscreen via cogl_onscreen_add_resize_callback().
|
||||||
*
|
*
|
||||||
* Since: 2.0
|
* Since: 2.0
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
|
cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen,
|
||||||
unsigned int id);
|
CoglOnscreenResizeClosure *closure);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_is_onscreen:
|
* cogl_is_onscreen:
|
||||||
|
|
|
@ -609,6 +609,12 @@ CoglFrameClosure
|
||||||
cogl_onscreen_add_frame_callback
|
cogl_onscreen_add_frame_callback
|
||||||
cogl_onscreen_remove_frame_callback
|
cogl_onscreen_remove_frame_callback
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
CoglOnscreenResizeCallback
|
||||||
|
CoglOnscreenResizeClosure
|
||||||
|
cogl_onscreen_add_resize_callback
|
||||||
|
cogl_onscreen_remove_resize_callback
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
cogl_onscreen_swap_buffers
|
cogl_onscreen_swap_buffers
|
||||||
cogl_onscreen_swap_region
|
cogl_onscreen_swap_region
|
||||||
|
|
|
@ -160,7 +160,7 @@ main (int argc, char **argv)
|
||||||
fb = COGL_FRAMEBUFFER (onscreen);
|
fb = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
|
||||||
cogl_onscreen_set_resizable (onscreen, TRUE);
|
cogl_onscreen_set_resizable (onscreen, TRUE);
|
||||||
cogl_onscreen_add_resize_handler (onscreen, resize_handler, onscreen);
|
cogl_onscreen_add_resize_callback (onscreen, resize_handler, onscreen, NULL);
|
||||||
|
|
||||||
triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
|
triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
|
||||||
3, triangle_vertices);
|
3, triangle_vertices);
|
||||||
|
|
Loading…
Reference in a new issue