[cogl] Update some of the examples to use the dirty callback



commit 108e3c548b7866190845f163c84a05212718bd70
Author: Neil Roberts <neil linux intel com>
Date:   Tue May 14 13:41:29 2013 +0100

    Update some of the examples to use the dirty callback
    
    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.
    
    Reviewed-by: Robert Bragg <robert linux intel com>

 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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]