[cogl] poll: Add general way to hook into mainloop without fd



commit 81c1ce0ffce4e75e08622e20848405987e00b3cc
Author: Robert Bragg <robert linux intel com>
Date:   Tue May 14 02:51:55 2013 +0100

    poll: Add general way to hook into mainloop without fd
    
    This adds a _cogl_poll_renderer_add_source() function that we can use
    within cogl to hook into the mainloop without necessarily having a file
    descriptor to poll. Since the intention is to use this to support
    polling for fence completions this also updates the
    CoglPollCheckCallback type to take a timeout pointer so sources can
    optionally update the timeout that will be passed to poll.
    
    Reviewed-by: Neil Roberts <neil linux intel com>

 cogl/cogl-poll-private.h              |   18 +++++++-
 cogl/cogl-poll.c                      |   71 +++++++++++++++++++++++++++-----
 cogl/cogl-xlib-renderer.c             |   10 ++--
 cogl/winsys/cogl-winsys-egl-kms.c     |    7 ++-
 cogl/winsys/cogl-winsys-egl-wayland.c |    7 ++-
 cogl/winsys/cogl-winsys-wgl.c         |   10 ++--
 6 files changed, 95 insertions(+), 28 deletions(-)
---
diff --git a/cogl/cogl-poll-private.h b/cogl/cogl-poll-private.h
index 93ef752..3dfaa2b 100644
--- a/cogl/cogl-poll-private.h
+++ b/cogl/cogl-poll-private.h
@@ -32,17 +32,29 @@
 void
 _cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd);
 
-typedef CoglBool (*CoglPollCheckCallback) (void *user_data);
-typedef void (*CoglPollDispatchCallback) (void *user_data);
+typedef int64_t (*CoglPollPrepareCallback) (void *user_data);
+typedef void (*CoglPollDispatchCallback) (void *user_data, int revents);
 
 void
 _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
                             int fd,
                             CoglPollFDEvent events,
-                            CoglPollCheckCallback check,
+                            CoglPollPrepareCallback prepare,
                             CoglPollDispatchCallback dispatch,
                             void *user_data);
 
+typedef struct _CoglPollSource CoglPollSource;
+
+CoglPollSource *
+_cogl_poll_renderer_add_source (CoglRenderer *renderer,
+                                CoglPollPrepareCallback prepare,
+                                CoglPollDispatchCallback dispatch,
+                                void *user_data);
+
+void
+_cogl_poll_renderer_remove_source (CoglRenderer *renderer,
+                                   CoglPollSource *source);
+
 typedef void (*CoglIdleCallback) (void *user_data);
 
 CoglClosure *
diff --git a/cogl/cogl-poll.c b/cogl/cogl-poll.c
index 1528f2c..e29d997 100644
--- a/cogl/cogl-poll.c
+++ b/cogl/cogl-poll.c
@@ -31,15 +31,14 @@
 #include "cogl-poll-private.h"
 #include "cogl-winsys-private.h"
 #include "cogl-renderer-private.h"
-#include "cogl-context-private.h"
 
-typedef struct _CoglPollSource
+struct _CoglPollSource
 {
   int fd;
-  CoglPollCheckCallback check;
+  CoglPollPrepareCallback prepare;
   CoglPollDispatchCallback dispatch;
   void *user_data;
-} CoglPollSource;
+};
 
 int
 cogl_poll_renderer_get_info (CoglRenderer *renderer,
@@ -56,6 +55,7 @@ cogl_poll_renderer_get_info (CoglRenderer *renderer,
 
   *poll_fds = (void *)renderer->poll_fds->data;
   *n_poll_fds = renderer->poll_fds->len;
+  *timeout = -1;
 
   if (!COGL_LIST_EMPTY (&renderer->idle_closures))
     {
@@ -66,14 +66,20 @@ cogl_poll_renderer_get_info (CoglRenderer *renderer,
   for (l = renderer->poll_sources; l; l = l->next)
     {
       CoglPollSource *source = l->data;
-      if (source->check && source->check (source->user_data))
+      if (source->prepare)
         {
-          *timeout = 0;
-          return renderer->poll_fds_age;
+          int64_t source_timeout = source->prepare (source->user_data);
+          if (source_timeout == 0)
+            {
+              *timeout = 0;
+              return renderer->poll_fds_age;
+            }
+          else if (source_timeout > 0 &&
+                   (*timeout == -1 || *timeout > source_timeout))
+            *timeout = source_timeout;
         }
     }
 
-  *timeout = -1;
   return renderer->poll_fds_age;
 }
 
@@ -93,13 +99,19 @@ cogl_poll_renderer_dispatch (CoglRenderer *renderer,
       CoglPollSource *source = l->data;
       int i;
 
+      if (source->fd == -1)
+        {
+          source->dispatch (source->user_data, 0);
+          continue;
+        }
+
       for (i = 0; i < n_poll_fds; i++)
         {
           const CoglPollFD *pollfd = &poll_fds[i];
 
           if (pollfd->fd == source->fd)
             {
-              source->dispatch (source->user_data);
+              source->dispatch (source->user_data, pollfd->revents);
               break;
             }
         }
@@ -151,7 +163,7 @@ void
 _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
                             int fd,
                             CoglPollFDEvent events,
-                            CoglPollCheckCallback check,
+                            CoglPollPrepareCallback prepare,
                             CoglPollDispatchCallback dispatch,
                             void *user_data)
 {
@@ -165,7 +177,7 @@ _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
 
   source = g_slice_new0 (CoglPollSource);
   source->fd = fd;
-  source->check = check;
+  source->prepare = prepare;
   source->dispatch = dispatch;
   source->user_data = user_data;
 
@@ -175,6 +187,43 @@ _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
   renderer->poll_fds_age++;
 }
 
+CoglPollSource *
+_cogl_poll_renderer_add_source (CoglRenderer *renderer,
+                                CoglPollPrepareCallback prepare,
+                                CoglPollDispatchCallback dispatch,
+                                void *user_data)
+{
+  CoglPollSource *source;
+
+  source = g_slice_new0 (CoglPollSource);
+  source->fd = -1;
+  source->prepare = prepare;
+  source->dispatch = dispatch;
+  source->user_data = user_data;
+
+  renderer->poll_sources = g_list_prepend (renderer->poll_sources, source);
+
+  return source;
+}
+
+void
+_cogl_poll_renderer_remove_source (CoglRenderer *renderer,
+                                   CoglPollSource *source)
+{
+  GList *l;
+
+  for (l = renderer->poll_sources; l; l = l->next)
+    {
+      if (l->data == source)
+        {
+          renderer->poll_sources =
+            g_list_delete_link (renderer->poll_sources, l);
+          g_slice_free (CoglPollSource, source);
+          break;
+        }
+    }
+}
+
 CoglClosure *
 _cogl_poll_renderer_add_idle (CoglRenderer *renderer,
                               CoglIdleCallback idle_cb,
diff --git a/cogl/cogl-xlib-renderer.c b/cogl/cogl-xlib-renderer.c
index 3aa70f2..4d332fa 100644
--- a/cogl/cogl-xlib-renderer.c
+++ b/cogl/cogl-xlib-renderer.c
@@ -468,17 +468,17 @@ randr_filter (XEvent *event,
   return COGL_FILTER_CONTINUE;
 }
 
-static CoglBool
-check_xlib_events (void *user_data)
+static int64_t
+prepare_xlib_events_timeout (void *user_data)
 {
   CoglRenderer *renderer = user_data;
   CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
 
-  return XPending (xlib_renderer->xdpy) ? TRUE : FALSE;
+  return XPending (xlib_renderer->xdpy) ? 0 : -1;
 }
 
 static void
-dispatch_xlib_events (void *user_data)
+dispatch_xlib_events (void *user_data, int revents)
 {
   CoglRenderer *renderer = user_data;
   CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
@@ -529,7 +529,7 @@ _cogl_xlib_renderer_connect (CoglRenderer *renderer, CoglError **error)
       _cogl_poll_renderer_add_fd (renderer,
                                   ConnectionNumber (xlib_renderer->xdpy),
                                   COGL_POLL_FD_EVENT_IN,
-                                  check_xlib_events,
+                                  prepare_xlib_events_timeout,
                                   dispatch_xlib_events,
                                   renderer);
     }
diff --git a/cogl/winsys/cogl-winsys-egl-kms.c b/cogl/winsys/cogl-winsys-egl-kms.c
index f7c65db..2cc74a5 100644
--- a/cogl/winsys/cogl-winsys-egl-kms.c
+++ b/cogl/winsys/cogl-winsys-egl-kms.c
@@ -242,12 +242,15 @@ handle_drm_event (CoglRendererKMS *kms_renderer)
 }
 
 static void
-dispatch_kms_events (void *user_data)
+dispatch_kms_events (void *user_data, int revents)
 {
   CoglRenderer *renderer = user_data;
   CoglRendererEGL *egl_renderer = renderer->winsys;
   CoglRendererKMS *kms_renderer = egl_renderer->platform;
 
+  if (!revents)
+    return;
+
   handle_drm_event (kms_renderer);
 }
 
@@ -299,7 +302,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
   _cogl_poll_renderer_add_fd (renderer,
                               kms_renderer->fd,
                               COGL_POLL_FD_EVENT_IN,
-                              NULL, /* no check callback */
+                              NULL, /* no prepare callback */
                               dispatch_kms_events,
                               renderer);
 
diff --git a/cogl/winsys/cogl-winsys-egl-wayland.c b/cogl/winsys/cogl-winsys-egl-wayland.c
index fe8b938..21bd5df 100644
--- a/cogl/winsys/cogl-winsys-egl-wayland.c
+++ b/cogl/winsys/cogl-winsys-egl-wayland.c
@@ -110,12 +110,15 @@ static const struct wl_registry_listener registry_listener = {
 };
 
 static void
-dispatch_wayland_display_events (void *user_data)
+dispatch_wayland_display_events (void *user_data, int revents)
 {
   CoglRenderer *renderer = user_data;
   CoglRendererEGL *egl_renderer = renderer->winsys;
   CoglRendererWayland *wayland_renderer = egl_renderer->platform;
 
+  if (!revents)
+    return;
+
   wl_display_dispatch (wayland_renderer->wayland_display);
 }
 
@@ -191,7 +194,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
   _cogl_poll_renderer_add_fd (renderer,
                               wayland_renderer->fd,
                               COGL_POLL_FD_EVENT_IN,
-                              NULL, /* no check callback */
+                              NULL, /* no prepare callback */
                               dispatch_wayland_display_events,
                               renderer);
 
diff --git a/cogl/winsys/cogl-winsys-wgl.c b/cogl/winsys/cogl-winsys-wgl.c
index ecaf346..6e9a7d8 100644
--- a/cogl/winsys/cogl-winsys-wgl.c
+++ b/cogl/winsys/cogl-winsys-wgl.c
@@ -239,16 +239,16 @@ win32_event_filter_cb (MSG *msg, void *data)
   return COGL_FILTER_CONTINUE;
 }
 
-static CoglBool
-check_messages (void *user_data)
+static int64_t
+prepare_messages (void *user_data)
 {
   MSG msg;
 
-  return PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE) ? TRUE : FALSE;
+  return PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE) ? 0 : -1;
 }
 
 static void
-dispatch_messages (void *user_data)
+dispatch_messages (void *user_data, int revents)
 {
   MSG msg;
 
@@ -274,7 +274,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
       _cogl_poll_renderer_add_fd (renderer,
                                   WIN32_MSG_HANDLE,
                                   COGL_POLL_FD_EVENT_IN,
-                                  check_messages,
+                                  prepare_messages,
                                   dispatch_messages,
                                   renderer);
     }


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