mirror of
https://github.com/brl/mutter.git
synced 2024-12-26 04:42:14 +00:00
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
@ -46,17 +46,16 @@ struct _CoglFrameClosure
|
||||
CoglUserDataDestroyCallback destroy;
|
||||
};
|
||||
|
||||
typedef struct _CoglResizeNotifyEntry CoglResizeNotifyEntry;
|
||||
COGL_TAILQ_HEAD (CoglOnscreenResizeCallbackList, CoglOnscreenResizeClosure);
|
||||
|
||||
COGL_TAILQ_HEAD (CoglResizeNotifyList, CoglResizeNotifyEntry);
|
||||
|
||||
struct _CoglResizeNotifyEntry
|
||||
struct _CoglOnscreenResizeClosure
|
||||
{
|
||||
COGL_TAILQ_ENTRY (CoglResizeNotifyEntry) list_node;
|
||||
COGL_TAILQ_ENTRY (CoglOnscreenResizeClosure) list_node;
|
||||
|
||||
CoglOnscreenResizeCallback callback;
|
||||
|
||||
void *user_data;
|
||||
unsigned int id;
|
||||
CoglUserDataDestroyCallback destroy;
|
||||
};
|
||||
|
||||
typedef struct _CoglOnscreenEvent CoglOnscreenEvent;
|
||||
@ -95,7 +94,7 @@ struct _CoglOnscreen
|
||||
CoglFrameCallbackList frame_closures;
|
||||
|
||||
CoglBool resizable;
|
||||
CoglResizeNotifyList resize_callbacks;
|
||||
CoglOnscreenResizeCallbackList resize_closures;
|
||||
|
||||
int64_t frame_counter;
|
||||
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);
|
||||
|
||||
COGL_TAILQ_INIT (&onscreen->frame_closures);
|
||||
COGL_TAILQ_INIT (&onscreen->resize_callbacks);
|
||||
COGL_TAILQ_INIT (&onscreen->resize_closures);
|
||||
|
||||
framebuffer->config = onscreen_template->config;
|
||||
cogl_object_ref (framebuffer->config.swap_chain);
|
||||
@ -115,24 +115,20 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
|
||||
CoglResizeNotifyEntry *resize_entry;
|
||||
CoglFrameClosure *frame_closure;
|
||||
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);
|
||||
g_slice_free (CoglResizeNotifyEntry, resize_entry);
|
||||
CoglOnscreenResizeClosure *resize_closure =
|
||||
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);
|
||||
|
||||
if (frame_closure->destroy)
|
||||
frame_closure->destroy (frame_closure->user_data);
|
||||
|
||||
g_slice_free (CoglFrameClosure, frame_closure);
|
||||
CoglFrameClosure *frame_closure =
|
||||
COGL_TAILQ_FIRST (&onscreen->frame_closures);
|
||||
cogl_onscreen_remove_frame_callback (onscreen, frame_closure);
|
||||
}
|
||||
|
||||
while ((frame_info = g_queue_pop_tail (&onscreen->pending_frame_infos)))
|
||||
@ -566,17 +562,17 @@ _cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info)
|
||||
void
|
||||
_cogl_onscreen_notify_resize (CoglOnscreen *onscreen)
|
||||
{
|
||||
CoglResizeNotifyEntry *entry, *tmp;
|
||||
CoglOnscreenResizeClosure *closure, *tmp;
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
|
||||
COGL_TAILQ_FOREACH_SAFE (entry,
|
||||
&onscreen->resize_callbacks,
|
||||
COGL_TAILQ_FOREACH_SAFE (closure,
|
||||
&onscreen->resize_closures,
|
||||
list_node,
|
||||
tmp)
|
||||
entry->callback (onscreen,
|
||||
framebuffer->width,
|
||||
framebuffer->height,
|
||||
entry->user_data);
|
||||
closure->callback (onscreen,
|
||||
framebuffer->width,
|
||||
framebuffer->height,
|
||||
closure->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
@ -620,38 +616,33 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen)
|
||||
return onscreen->resizable;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
|
||||
CoglOnscreenResizeCallback callback,
|
||||
void *user_data)
|
||||
CoglOnscreenResizeClosure *
|
||||
cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen,
|
||||
CoglOnscreenResizeCallback callback,
|
||||
void *user_data,
|
||||
CoglUserDataDestroyCallback destroy)
|
||||
{
|
||||
CoglResizeNotifyEntry *entry = g_slice_new (CoglResizeNotifyEntry);
|
||||
static int next_resize_callback_id = 0;
|
||||
CoglOnscreenResizeClosure *closure = g_slice_new (CoglOnscreenResizeClosure);
|
||||
|
||||
entry->callback = callback;
|
||||
entry->user_data = user_data;
|
||||
entry->id = next_resize_callback_id++;
|
||||
closure->callback = callback;
|
||||
closure->user_data = user_data;
|
||||
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
|
||||
cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
|
||||
unsigned int id)
|
||||
cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen,
|
||||
CoglOnscreenResizeClosure *closure)
|
||||
{
|
||||
CoglResizeNotifyEntry *entry;
|
||||
if (closure->destroy)
|
||||
closure->destroy (closure->user_data);
|
||||
|
||||
COGL_TAILQ_FOREACH (entry, &onscreen->resize_callbacks, list_node)
|
||||
{
|
||||
if (entry->id == id)
|
||||
{
|
||||
COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, entry, list_node);
|
||||
g_slice_free (CoglResizeNotifyEntry, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
COGL_TAILQ_REMOVE (&onscreen->resize_closures, closure, list_node);
|
||||
|
||||
g_slice_free (CoglOnscreenResizeClosure, closure);
|
||||
}
|
||||
|
||||
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
|
||||
* framebuffer with an origin of (0,0). If your application needs more
|
||||
* 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>
|
||||
*
|
||||
* Since: 2.0
|
||||
@ -655,10 +655,10 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen);
|
||||
* @width: The new width of @onscreen
|
||||
* @height: The new height of @onscreen
|
||||
* @user_data: The private passed to
|
||||
* cogl_onscreen_add_resize_handler()
|
||||
* cogl_onscreen_add_resize_callback()
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* <note>Cogl automatically updates the viewport of an @onscreen
|
||||
@ -679,18 +679,34 @@ typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen,
|
||||
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
|
||||
* @callback: A #CoglOnscreenResizeCallback to call when the @onscreen
|
||||
* changes size.
|
||||
* @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
|
||||
* the @onscreen framebuffer changes size.
|
||||
*
|
||||
* The @callback can be removed using
|
||||
* cogl_onscreen_remove_resize_handler() passing the same @callback
|
||||
* and @user_data pair.
|
||||
* cogl_onscreen_remove_resize_callback() passing the returned closure
|
||||
* pointer.
|
||||
*
|
||||
* <note>Since Cogl automatically updates the viewport of an @onscreen
|
||||
* 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
|
||||
* example.</note>
|
||||
*
|
||||
* Return value: a unique identifier that can be used to remove to remove
|
||||
* the callback later.
|
||||
*
|
||||
* Return value: a #CoglOnscreenResizeClosure pointer that can be used to
|
||||
* remove the callback and associated @user_data later.
|
||||
* Since: 2.0
|
||||
*/
|
||||
unsigned int
|
||||
cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
|
||||
CoglOnscreenResizeCallback callback,
|
||||
void *user_data);
|
||||
CoglOnscreenResizeClosure *
|
||||
cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen,
|
||||
CoglOnscreenResizeCallback callback,
|
||||
void *user_data,
|
||||
CoglUserDataDestroyCallback destroy);
|
||||
|
||||
/**
|
||||
* cogl_onscreen_remove_resize_handler:
|
||||
* cogl_onscreen_remove_resize_callback:
|
||||
* @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
|
||||
* associated with @onscreen via cogl_onscreen_add_resize_handler().
|
||||
* associated with @onscreen via cogl_onscreen_add_resize_callback().
|
||||
*
|
||||
* Since: 2.0
|
||||
*/
|
||||
void
|
||||
cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
|
||||
unsigned int id);
|
||||
cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen,
|
||||
CoglOnscreenResizeClosure *closure);
|
||||
|
||||
/**
|
||||
* cogl_is_onscreen:
|
||||
|
@ -609,6 +609,12 @@ CoglFrameClosure
|
||||
cogl_onscreen_add_frame_callback
|
||||
cogl_onscreen_remove_frame_callback
|
||||
|
||||
<SUBSECTION>
|
||||
CoglOnscreenResizeCallback
|
||||
CoglOnscreenResizeClosure
|
||||
cogl_onscreen_add_resize_callback
|
||||
cogl_onscreen_remove_resize_callback
|
||||
|
||||
<SUBSECTION>
|
||||
cogl_onscreen_swap_buffers
|
||||
cogl_onscreen_swap_region
|
||||
|
@ -160,7 +160,7 @@ main (int argc, char **argv)
|
||||
fb = COGL_FRAMEBUFFER (onscreen);
|
||||
|
||||
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,
|
||||
3, triangle_vertices);
|
||||
|
Loading…
Reference in New Issue
Block a user