From 4efd82a3b6c9877681786e2f6f26970eeb681ee7 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Thu, 31 Jan 2013 12:06:52 +0000 Subject: [PATCH] Convert the two SDL examples to use the frame callback The two SDL examples now throttle their rendering to the COGL_FRAME_EVENT_SYNC event. Previously the examples would redraw whenever a mouse motion event is received but now they additionally wait for the sync event which means that if another mouse event comes immediately after rendering the last frame it theoretically could avoid blocking waiting for the last frame to complete. In practice however the SDL winsys doesn't support swap events so it will get the sync event immediately anyway, but it's nice to have the code as an example and a test. This patch also changes the mainloop a bit to do the equivalent steps without the outer main loop which I think makes it a bit easier to follow. Reviewed-by: Robert Bragg (cherry picked from commit 97cdd832dded2ebfaa42ee4bc43319cb8648d01b) --- examples/cogl-sdl-hello.c | 52 +++++++++++++++++++++++++------------- examples/cogl-sdl2-hello.c | 52 +++++++++++++++++++++++++------------- 2 files changed, 70 insertions(+), 34 deletions(-) diff --git a/examples/cogl-sdl-hello.c b/examples/cogl-sdl-hello.c index 987cc131d..961137aef 100644 --- a/examples/cogl-sdl-hello.c +++ b/examples/cogl-sdl-hello.c @@ -13,9 +13,10 @@ typedef struct Data CoglFramebuffer *fb; CoglBool quit; CoglBool redraw_queued; + CoglBool ready_to_draw; } Data; -static CoglBool +static void redraw (Data *data) { CoglFramebuffer *fb = data->fb; @@ -29,8 +30,6 @@ redraw (Data *data) cogl_framebuffer_pop_matrix (fb); cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb)); - - return FALSE; } static void @@ -62,6 +61,18 @@ handle_event (Data *data, SDL_Event *event) } } +static void +frame_cb (CoglOnscreen *onscreen, + CoglFrameEvent event, + CoglFrameInfo *info, + void *user_data) +{ + Data *data = user_data; + + if (event == COGL_FRAME_EVENT_SYNC) + data->ready_to_draw = TRUE; +} + int main (int argc, char **argv) { @@ -86,6 +97,11 @@ main (int argc, char **argv) onscreen = cogl_onscreen_new (ctx, 800, 600); data.fb = COGL_FRAMEBUFFER (onscreen); + cogl_onscreen_add_frame_callback (onscreen, + frame_cb, + &data, + NULL /* destroy callback */); + data.center_x = 0.0f; data.center_y = 0.0f; data.quit = FALSE; @@ -97,28 +113,30 @@ main (int argc, char **argv) data.pipeline = cogl_pipeline_new (ctx); data.redraw_queued = TRUE; + data.ready_to_draw = TRUE; + while (!data.quit) { - while (!data.quit) + if (!SDL_PollEvent (&event)) { - if (!SDL_PollEvent (&event)) + if (data.redraw_queued && data.ready_to_draw) { - if (data.redraw_queued) - break; - - cogl_sdl_idle (ctx); - if (!SDL_WaitEvent (&event)) - { - fprintf (stderr, "Error waiting for SDL events"); - return 1; - } + redraw (&data); + data.redraw_queued = FALSE; + data.ready_to_draw = FALSE; + continue; } - handle_event (&data, &event); - cogl_sdl_handle_event (ctx, &event); + cogl_sdl_idle (ctx); + if (!SDL_WaitEvent (&event)) + { + fprintf (stderr, "Error waiting for SDL events"); + return 1; + } } - data.redraw_queued = redraw (&data); + handle_event (&data, &event); + cogl_sdl_handle_event (ctx, &event); } cogl_object_unref (ctx); diff --git a/examples/cogl-sdl2-hello.c b/examples/cogl-sdl2-hello.c index 03704609d..405cb92dd 100644 --- a/examples/cogl-sdl2-hello.c +++ b/examples/cogl-sdl2-hello.c @@ -13,9 +13,10 @@ typedef struct Data CoglFramebuffer *fb; CoglBool quit; CoglBool redraw_queued; + CoglBool ready_to_draw; } Data; -static CoglBool +static void redraw (Data *data) { CoglFramebuffer *fb = data->fb; @@ -29,8 +30,6 @@ redraw (Data *data) cogl_framebuffer_pop_matrix (fb); cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb)); - - return FALSE; } static void @@ -71,6 +70,18 @@ handle_event (Data *data, SDL_Event *event) } } +static void +frame_cb (CoglOnscreen *onscreen, + CoglFrameEvent event, + CoglFrameInfo *info, + void *user_data) +{ + Data *data = user_data; + + if (event == COGL_FRAME_EVENT_SYNC) + data->ready_to_draw = TRUE; +} + int main (int argc, char **argv) { @@ -95,6 +106,11 @@ main (int argc, char **argv) onscreen = cogl_onscreen_new (ctx, 800, 600); data.fb = COGL_FRAMEBUFFER (onscreen); + cogl_onscreen_add_frame_callback (onscreen, + frame_cb, + &data, + NULL /* destroy callback */); + data.center_x = 0.0f; data.center_y = 0.0f; data.quit = FALSE; @@ -110,28 +126,30 @@ main (int argc, char **argv) data.pipeline = cogl_pipeline_new (ctx); data.redraw_queued = TRUE; + data.ready_to_draw = TRUE; + while (!data.quit) { - while (!data.quit) + if (!SDL_PollEvent (&event)) { - if (!SDL_PollEvent (&event)) + if (data.redraw_queued && data.ready_to_draw) { - if (data.redraw_queued) - break; - - cogl_sdl_idle (ctx); - if (!SDL_WaitEvent (&event)) - { - fprintf (stderr, "Error waiting for SDL events"); - return 1; - } + redraw (&data); + data.redraw_queued = FALSE; + data.ready_to_draw = FALSE; + continue; } - handle_event (&data, &event); - cogl_sdl_handle_event (ctx, &event); + cogl_sdl_idle (ctx); + if (!SDL_WaitEvent (&event)) + { + fprintf (stderr, "Error waiting for SDL events"); + return 1; + } } - data.redraw_queued = redraw (&data); + handle_event (&data, &event); + cogl_sdl_handle_event (ctx, &event); } cogl_object_unref (ctx);