[Cogl] [PATCH 3/3] Update some of the examples to use the dirty callback
Robert Bragg
robert at sixbynine.org
Tue May 28 04:43:27 PDT 2013
This looks good to land to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
- Robert
On Tue, May 14, 2013 at 5:03 PM, Neil Roberts <neil at linux.intel.com> wrote:
> This updates Cogland and the three hello examples to use the dirty
> callback. For Cogland, this removes the manual handling of X events
> and for the other examples it removes the need to redraw continously.
> ---
> examples/cogl-hello.c | 55 ++++++++++++++++++++++++---
> examples/cogl-sdl-hello.c | 20 +++++++---
> examples/cogl-sdl2-hello.c | 20 +++++++---
> examples/cogland.c | 93 ++++++++--------------------------------------
> 4 files changed, 94 insertions(+), 94 deletions(-)
>
> diff --git a/examples/cogl-hello.c b/examples/cogl-hello.c
> index 3ba1e31..49f9336 100644
> --- a/examples/cogl-hello.c
> +++ b/examples/cogl-hello.c
> @@ -8,18 +8,39 @@ typedef struct _Data
> CoglFramebuffer *fb;
> CoglPrimitive *triangle;
> CoglPipeline *pipeline;
> +
> + unsigned int redraw_idle;
> + CoglBool is_dirty;
> + CoglBool draw_ready;
> } Data;
>
> -static CoglBool
> +static gboolean
> paint_cb (void *user_data)
> {
> Data *data = user_data;
>
> + data->redraw_idle = 0;
> + data->is_dirty = FALSE;
> + data->draw_ready = FALSE;
> +
> cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
> - cogl_framebuffer_draw_primitive (data->fb, data->pipeline, data->triangle);
> + cogl_framebuffer_draw_primitive (data->fb,
> + data->pipeline,
> + data->triangle);
> cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
>
> - return FALSE; /* remove the callback */
> + return G_SOURCE_REMOVE;
> +}
> +
> +static void
> +maybe_redraw (Data *data)
> +{
> + if (data->is_dirty && data->draw_ready && data->redraw_idle == 0) {
> + /* We'll draw on idle instead of drawing immediately so that
> + * if Cogl reports multiple dirty rectangles we won't
> + * redundantly draw multiple frames */
> + data->redraw_idle = g_idle_add (paint_cb, data);
> + }
> }
>
> static void
> @@ -28,8 +49,23 @@ frame_event_cb (CoglOnscreen *onscreen,
> CoglFrameInfo *info,
> void *user_data)
> {
> - if (event == COGL_FRAME_EVENT_SYNC)
> - paint_cb (user_data);
> + Data *data = user_data;
> +
> + if (event == COGL_FRAME_EVENT_SYNC) {
> + data->draw_ready = TRUE;
> + maybe_redraw (data);
> + }
> +}
> +
> +static void
> +dirty_cb (CoglOnscreen *onscreen,
> + const CoglOnscreenDirtyInfo *info,
> + void *user_data)
> +{
> + Data *data = user_data;
> +
> + data->is_dirty = TRUE;
> + maybe_redraw (data);
> }
>
> int
> @@ -46,6 +82,10 @@ main (int argc, char **argv)
> GSource *cogl_source;
> GMainLoop *loop;
>
> + data.redraw_idle = 0;
> + data.is_dirty = FALSE;
> + data.draw_ready = TRUE;
> +
> data.ctx = cogl_context_new (NULL, &error);
> if (!data.ctx) {
> fprintf (stderr, "Failed to create context: %s\n", error->message);
> @@ -71,7 +111,10 @@ main (int argc, char **argv)
> frame_event_cb,
> &data,
> NULL); /* destroy notify */
> - g_idle_add (paint_cb, &data);
> + cogl_onscreen_add_dirty_callback (COGL_ONSCREEN (data.fb),
> + dirty_cb,
> + &data,
> + NULL); /* destroy notify */
>
> loop = g_main_loop_new (NULL, TRUE);
> g_main_loop_run (loop);
> diff --git a/examples/cogl-sdl-hello.c b/examples/cogl-sdl-hello.c
> index acb9125..ef0d08d 100644
> --- a/examples/cogl-sdl-hello.c
> +++ b/examples/cogl-sdl-hello.c
> @@ -33,14 +33,20 @@ redraw (Data *data)
> }
>
> static void
> +dirty_cb (CoglOnscreen *onscreen,
> + const CoglOnscreenDirtyInfo *info,
> + void *user_data)
> +{
> + Data *data = user_data;
> +
> + data->redraw_queued = TRUE;
> +}
> +
> +static void
> handle_event (Data *data, SDL_Event *event)
> {
> switch (event->type)
> {
> - case SDL_VIDEOEXPOSE:
> - data->redraw_queued = TRUE;
> - break;
> -
> case SDL_MOUSEMOTION:
> {
> int width =
> @@ -101,6 +107,10 @@ main (int argc, char **argv)
> frame_cb,
> &data,
> NULL /* destroy callback */);
> + cogl_onscreen_add_dirty_callback (onscreen,
> + dirty_cb,
> + &data,
> + NULL /* destroy callback */);
>
> data.center_x = 0.0f;
> data.center_y = 0.0f;
> @@ -112,7 +122,7 @@ main (int argc, char **argv)
> 3, triangle_vertices);
> data.pipeline = cogl_pipeline_new (ctx);
>
> - data.redraw_queued = TRUE;
> + data.redraw_queued = FALSE;
> data.ready_to_draw = TRUE;
>
> while (!data.quit)
> diff --git a/examples/cogl-sdl2-hello.c b/examples/cogl-sdl2-hello.c
> index 12e6ced..fb51c7f 100644
> --- a/examples/cogl-sdl2-hello.c
> +++ b/examples/cogl-sdl2-hello.c
> @@ -33,6 +33,16 @@ redraw (Data *data)
> }
>
> static void
> +dirty_cb (CoglOnscreen *onscreen,
> + const CoglOnscreenDirtyInfo *info,
> + void *user_data)
> +{
> + Data *data = user_data;
> +
> + data->redraw_queued = TRUE;
> +}
> +
> +static void
> handle_event (Data *data, SDL_Event *event)
> {
> switch (event->type)
> @@ -40,10 +50,6 @@ handle_event (Data *data, SDL_Event *event)
> case SDL_WINDOWEVENT:
> switch (event->window.event)
> {
> - case SDL_WINDOWEVENT_EXPOSED:
> - data->redraw_queued = TRUE;
> - break;
> -
> case SDL_WINDOWEVENT_CLOSE:
> data->quit = TRUE;
> break;
> @@ -110,6 +116,10 @@ main (int argc, char **argv)
> frame_cb,
> &data,
> NULL /* destroy callback */);
> + cogl_onscreen_add_dirty_callback (onscreen,
> + dirty_cb,
> + &data,
> + NULL /* destroy callback */);
>
> data.center_x = 0.0f;
> data.center_y = 0.0f;
> @@ -125,7 +135,7 @@ main (int argc, char **argv)
> 3, triangle_vertices);
> data.pipeline = cogl_pipeline_new (ctx);
>
> - data.redraw_queued = TRUE;
> + data.redraw_queued = FALSE;
> data.ready_to_draw = TRUE;
>
> while (!data.quit)
> diff --git a/examples/cogland.c b/examples/cogland.c
> index 928a735..98865f0 100644
> --- a/examples/cogland.c
> +++ b/examples/cogland.c
> @@ -8,10 +8,6 @@
>
> #include <wayland-server.h>
>
> -#ifdef COGL_HAS_XLIB_SUPPORT
> -#include <cogl/cogl-xlib.h>
> -#endif
> -
> typedef struct _CoglandCompositor CoglandCompositor;
>
> typedef struct
> @@ -782,6 +778,16 @@ bind_output (struct wl_client *client,
> }
>
> static void
> +dirty_cb (CoglOnscreen *onscreen,
> + const CoglOnscreenDirtyInfo *info,
> + void *user_data)
> +{
> + CoglandCompositor *compositor = user_data;
> +
> + cogland_queue_redraw (compositor);
> +}
> +
> +static void
> cogland_compositor_create_output (CoglandCompositor *compositor,
> int x,
> int y,
> @@ -813,6 +819,11 @@ cogland_compositor_create_output (CoglandCompositor *compositor,
> if (!cogl_framebuffer_allocate (fb, &error))
> g_error ("Failed to allocate framebuffer: %s\n", error->message);
>
> + cogl_onscreen_add_dirty_callback (output->onscreen,
> + dirty_cb,
> + compositor,
> + NULL /* destroy */);
> +
> cogl_onscreen_show (output->onscreen);
> cogl_framebuffer_set_viewport (fb,
> -x, -y,
> @@ -1051,78 +1062,6 @@ create_cogl_context (CoglandCompositor *compositor,
> return context;
> }
>
> -#ifdef COGL_HAS_XLIB_SUPPORT
> -
> -static CoglFilterReturn
> -x_event_cb (XEvent *event,
> - void *data)
> -{
> - CoglandCompositor *compositor = data;
> -
> - if (event->type == Expose)
> - cogland_queue_redraw (compositor);
> -
> - return COGL_FILTER_CONTINUE;
> -}
> -
> -#endif /* COGL_HAS_XLIB_SUPPORT */
> -
> -static gboolean
> -timeout_cb (void *data)
> -{
> - cogland_queue_redraw (data);
> -
> - return TRUE;
> -}
> -
> -static void
> -init_redraws (CoglandCompositor *compositor)
> -{
> -#ifdef COGL_HAS_XLIB_SUPPORT
> - CoglRenderer *renderer = cogl_context_get_renderer (compositor->cogl_context);
> - CoglWinsysID winsys = cogl_renderer_get_winsys_id (renderer);
> -
> - /* If Cogl is using X then we can listen for Expose events to know
> - * when to repaint the window. Otherwise we don't have any code to
> - * know when the contents of the window is dirty so we'll just
> - * redraw constantly */
> - switch (winsys)
> - {
> - case COGL_WINSYS_ID_GLX:
> - case COGL_WINSYS_ID_EGL_XLIB:
> - {
> - Display *display = cogl_xlib_renderer_get_display (renderer);
> - GList *l;
> -
> - for (l = compositor->outputs; l; l = l->next)
> - {
> - CoglandOutput *output = l->data;
> - XWindowAttributes win_attribs;
> - Window win;
> -
> - win = cogl_x11_onscreen_get_window_xid (output->onscreen);
> - if (XGetWindowAttributes (display, win, &win_attribs))
> - {
> - XSelectInput (display,
> - win,
> - win_attribs.your_event_mask | ExposureMask);
> - cogl_xlib_renderer_add_filter (renderer,
> - x_event_cb,
> - compositor);
> -
> - }
> - }
> - }
> - return;
> -
> - default:
> - break;
> - }
> -#endif /* COGL_HAS_XLIB_SUPPORT */
> -
> - g_timeout_add (16, timeout_cb, compositor);
> -}
> -
> int
> main (int argc, char **argv)
> {
> @@ -1229,8 +1168,6 @@ main (int argc, char **argv)
>
> g_source_attach (cogl_source, NULL);
>
> - init_redraws (&compositor);
> -
> g_main_loop_run (loop);
>
> return 0;
> --
> 1.7.11.3.g3c3efa5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list