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 <robert@linux.intel.com>

(cherry picked from commit 97cdd832dded2ebfaa42ee4bc43319cb8648d01b)
This commit is contained in:
Neil Roberts 2013-01-31 12:06:52 +00:00
parent 1f84b5c9b4
commit 4efd82a3b6
2 changed files with 70 additions and 34 deletions

View File

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

View File

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