[Cogl] [PATCH 2/2] Update some of the examples to use the expose callback
Neil Roberts
neil at linux.intel.com
Tue May 14 06:34:47 PDT 2013
This updates Cogland and the three hello examples to use the expose
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 | 49 ++++++++++++++++++------
examples/cogl-sdl-hello.c | 20 +++++++---
examples/cogl-sdl2-hello.c | 20 +++++++---
examples/cogland.c | 93 ++++++++--------------------------------------
4 files changed, 83 insertions(+), 99 deletions(-)
diff --git a/examples/cogl-hello.c b/examples/cogl-hello.c
index 3ba1e31..36f43b1 100644
--- a/examples/cogl-hello.c
+++ b/examples/cogl-hello.c
@@ -8,18 +8,24 @@ typedef struct _Data
CoglFramebuffer *fb;
CoglPrimitive *triangle;
CoglPipeline *pipeline;
+
+ CoglBool redraw_queued;
+ CoglBool draw_ready;
} Data;
-static CoglBool
-paint_cb (void *user_data)
+static void
+maybe_redraw (Data *data)
{
- Data *data = user_data;
-
- cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
- cogl_framebuffer_draw_primitive (data->fb, data->pipeline, data->triangle);
- cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
+ if (data->redraw_queued && data->draw_ready) {
+ data->redraw_queued = FALSE;
+ data->draw_ready = FALSE;
- return FALSE; /* remove the callback */
+ cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
+ cogl_framebuffer_draw_primitive (data->fb,
+ data->pipeline,
+ data->triangle);
+ cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
+ }
}
static void
@@ -28,8 +34,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
+expose_cb (CoglOnscreen *onscreen,
+ const CoglOnscreenExposeInfo *info,
+ void *user_data)
+{
+ Data *data = user_data;
+
+ data->redraw_queued = TRUE;
+ maybe_redraw (data);
}
int
@@ -46,6 +67,9 @@ main (int argc, char **argv)
GSource *cogl_source;
GMainLoop *loop;
+ data.redraw_queued = 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 +95,10 @@ main (int argc, char **argv)
frame_event_cb,
&data,
NULL); /* destroy notify */
- g_idle_add (paint_cb, &data);
+ cogl_onscreen_add_expose_callback (COGL_ONSCREEN (data.fb),
+ expose_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..f2ebaa7 100644
--- a/examples/cogl-sdl-hello.c
+++ b/examples/cogl-sdl-hello.c
@@ -33,14 +33,20 @@ redraw (Data *data)
}
static void
+expose_cb (CoglOnscreen *onscreen,
+ const CoglOnscreenExposeInfo *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_expose_callback (onscreen,
+ expose_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..c2f0ea0 100644
--- a/examples/cogl-sdl2-hello.c
+++ b/examples/cogl-sdl2-hello.c
@@ -33,6 +33,16 @@ redraw (Data *data)
}
static void
+expose_cb (CoglOnscreen *onscreen,
+ const CoglOnscreenExposeInfo *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_expose_callback (onscreen,
+ expose_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..eb4e10c 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
+expose_cb (CoglOnscreen *onscreen,
+ const CoglOnscreenExposeInfo *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_expose_callback (output->onscreen,
+ expose_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
More information about the Cogl
mailing list