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

Robert Bragg robert at sixbynine.org
Mon May 13 19:42:00 PDT 2013


From: Robert Bragg <robert at linux.intel.com>

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.
---
 cogl/cogl-poll-private.h  | 14 ++++++++++-
 cogl/cogl-poll.c          | 59 +++++++++++++++++++++++++++++++++++++++++++----
 cogl/cogl-xlib-renderer.c |  2 +-
 3 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/cogl/cogl-poll-private.h b/cogl/cogl-poll-private.h
index 93ef752..fe830d9 100644
--- a/cogl/cogl-poll-private.h
+++ b/cogl/cogl-poll-private.h
@@ -32,7 +32,7 @@
 void
 _cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd);
 
-typedef CoglBool (*CoglPollCheckCallback) (void *user_data);
+typedef CoglBool (*CoglPollCheckCallback) (void *user_data, int64_t *timeout);
 typedef void (*CoglPollDispatchCallback) (void *user_data);
 
 void
@@ -43,6 +43,18 @@ _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
                             CoglPollDispatchCallback dispatch,
                             void *user_data);
 
+typedef struct _CoglPollSource CoglPollSource;
+
+CoglPollSource *
+_cogl_poll_renderer_add_source (CoglRenderer *renderer,
+                                CoglPollCheckCallback check,
+                                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..31b3330 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;
   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,13 @@ 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->check && source->check (source->user_data, timeout))
         {
           *timeout = 0;
           return renderer->poll_fds_age;
         }
     }
 
-  *timeout = -1;
   return renderer->poll_fds_age;
 }
 
@@ -91,8 +90,21 @@ cogl_poll_renderer_dispatch (CoglRenderer *renderer,
   for (l = renderer->poll_sources; l; l = l->next)
     {
       CoglPollSource *source = l->data;
+      if (source->fd == -1)
+        {
+          source->dispatch (source->user_data);
+          continue;
+        }
+    }
+
+  for (l = renderer->poll_sources; l; l = l->next)
+    {
+      CoglPollSource *source = l->data;
       int i;
 
+      if (source->fd == -1)
+        continue;
+
       for (i = 0; i < n_poll_fds; i++)
         {
           const CoglPollFD *pollfd = &poll_fds[i];
@@ -175,6 +187,43 @@ _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
   renderer->poll_fds_age++;
 }
 
+CoglPollSource *
+_cogl_poll_renderer_add_source (CoglRenderer *renderer,
+                                CoglPollCheckCallback check,
+                                CoglPollDispatchCallback dispatch,
+                                void *user_data)
+{
+  CoglPollSource *source;
+
+  source = g_slice_new0 (CoglPollSource);
+  source->fd = -1;
+  source->check = check;
+  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 92f044d..3c26a92 100644
--- a/cogl/cogl-xlib-renderer.c
+++ b/cogl/cogl-xlib-renderer.c
@@ -469,7 +469,7 @@ randr_filter (XEvent *event,
 }
 
 static CoglBool
-check_xlib_events (void *user_data)
+check_xlib_events (void *user_data, int64_t *timeout)
 {
   CoglRenderer *renderer = user_data;
   CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
-- 
1.8.2.1



More information about the Cogl mailing list