mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 03:20:46 -05:00
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> (cherry picked from commit 81c1ce0ffce4e75e08622e20848405987e00b3cc)
This commit is contained in:
parent
c08fe74cd0
commit
7b14b5e3da
@ -32,17 +32,29 @@
|
|||||||
void
|
void
|
||||||
_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd);
|
_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd);
|
||||||
|
|
||||||
typedef CoglBool (*CoglPollCheckCallback) (void *user_data);
|
typedef int64_t (*CoglPollPrepareCallback) (void *user_data);
|
||||||
typedef void (*CoglPollDispatchCallback) (void *user_data);
|
typedef void (*CoglPollDispatchCallback) (void *user_data, int revents);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
_cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
||||||
int fd,
|
int fd,
|
||||||
CoglPollFDEvent events,
|
CoglPollFDEvent events,
|
||||||
CoglPollCheckCallback check,
|
CoglPollPrepareCallback prepare,
|
||||||
CoglPollDispatchCallback dispatch,
|
CoglPollDispatchCallback dispatch,
|
||||||
void *user_data);
|
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);
|
typedef void (*CoglIdleCallback) (void *user_data);
|
||||||
|
|
||||||
CoglClosure *
|
CoglClosure *
|
||||||
|
@ -31,15 +31,14 @@
|
|||||||
#include "cogl-poll-private.h"
|
#include "cogl-poll-private.h"
|
||||||
#include "cogl-winsys-private.h"
|
#include "cogl-winsys-private.h"
|
||||||
#include "cogl-renderer-private.h"
|
#include "cogl-renderer-private.h"
|
||||||
#include "cogl-context-private.h"
|
|
||||||
|
|
||||||
typedef struct _CoglPollSource
|
struct _CoglPollSource
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
CoglPollCheckCallback check;
|
CoglPollPrepareCallback prepare;
|
||||||
CoglPollDispatchCallback dispatch;
|
CoglPollDispatchCallback dispatch;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
} CoglPollSource;
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
cogl_poll_renderer_get_info (CoglRenderer *renderer,
|
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;
|
*poll_fds = (void *)renderer->poll_fds->data;
|
||||||
*n_poll_fds = renderer->poll_fds->len;
|
*n_poll_fds = renderer->poll_fds->len;
|
||||||
|
*timeout = -1;
|
||||||
|
|
||||||
if (!COGL_LIST_EMPTY (&renderer->idle_closures))
|
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)
|
for (l = renderer->poll_sources; l; l = l->next)
|
||||||
{
|
{
|
||||||
CoglPollSource *source = l->data;
|
CoglPollSource *source = l->data;
|
||||||
if (source->check && source->check (source->user_data))
|
if (source->prepare)
|
||||||
{
|
{
|
||||||
*timeout = 0;
|
int64_t source_timeout = source->prepare (source->user_data);
|
||||||
return renderer->poll_fds_age;
|
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;
|
return renderer->poll_fds_age;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,13 +99,19 @@ cogl_poll_renderer_dispatch (CoglRenderer *renderer,
|
|||||||
CoglPollSource *source = l->data;
|
CoglPollSource *source = l->data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (source->fd == -1)
|
||||||
|
{
|
||||||
|
source->dispatch (source->user_data, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < n_poll_fds; i++)
|
for (i = 0; i < n_poll_fds; i++)
|
||||||
{
|
{
|
||||||
const CoglPollFD *pollfd = &poll_fds[i];
|
const CoglPollFD *pollfd = &poll_fds[i];
|
||||||
|
|
||||||
if (pollfd->fd == source->fd)
|
if (pollfd->fd == source->fd)
|
||||||
{
|
{
|
||||||
source->dispatch (source->user_data);
|
source->dispatch (source->user_data, pollfd->revents);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,7 +163,7 @@ void
|
|||||||
_cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
_cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
||||||
int fd,
|
int fd,
|
||||||
CoglPollFDEvent events,
|
CoglPollFDEvent events,
|
||||||
CoglPollCheckCallback check,
|
CoglPollPrepareCallback prepare,
|
||||||
CoglPollDispatchCallback dispatch,
|
CoglPollDispatchCallback dispatch,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
@ -165,7 +177,7 @@ _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
|||||||
|
|
||||||
source = g_slice_new0 (CoglPollSource);
|
source = g_slice_new0 (CoglPollSource);
|
||||||
source->fd = fd;
|
source->fd = fd;
|
||||||
source->check = check;
|
source->prepare = prepare;
|
||||||
source->dispatch = dispatch;
|
source->dispatch = dispatch;
|
||||||
source->user_data = user_data;
|
source->user_data = user_data;
|
||||||
|
|
||||||
@ -175,6 +187,43 @@ _cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
|||||||
renderer->poll_fds_age++;
|
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 *
|
CoglClosure *
|
||||||
_cogl_poll_renderer_add_idle (CoglRenderer *renderer,
|
_cogl_poll_renderer_add_idle (CoglRenderer *renderer,
|
||||||
CoglIdleCallback idle_cb,
|
CoglIdleCallback idle_cb,
|
||||||
|
@ -468,17 +468,17 @@ randr_filter (XEvent *event,
|
|||||||
return COGL_FILTER_CONTINUE;
|
return COGL_FILTER_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglBool
|
static int64_t
|
||||||
check_xlib_events (void *user_data)
|
prepare_xlib_events_timeout (void *user_data)
|
||||||
{
|
{
|
||||||
CoglRenderer *renderer = user_data;
|
CoglRenderer *renderer = user_data;
|
||||||
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
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
|
static void
|
||||||
dispatch_xlib_events (void *user_data)
|
dispatch_xlib_events (void *user_data, int revents)
|
||||||
{
|
{
|
||||||
CoglRenderer *renderer = user_data;
|
CoglRenderer *renderer = user_data;
|
||||||
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
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,
|
_cogl_poll_renderer_add_fd (renderer,
|
||||||
ConnectionNumber (xlib_renderer->xdpy),
|
ConnectionNumber (xlib_renderer->xdpy),
|
||||||
COGL_POLL_FD_EVENT_IN,
|
COGL_POLL_FD_EVENT_IN,
|
||||||
check_xlib_events,
|
prepare_xlib_events_timeout,
|
||||||
dispatch_xlib_events,
|
dispatch_xlib_events,
|
||||||
renderer);
|
renderer);
|
||||||
}
|
}
|
||||||
|
@ -242,12 +242,15 @@ handle_drm_event (CoglRendererKMS *kms_renderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dispatch_kms_events (void *user_data)
|
dispatch_kms_events (void *user_data, int revents)
|
||||||
{
|
{
|
||||||
CoglRenderer *renderer = user_data;
|
CoglRenderer *renderer = user_data;
|
||||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||||
|
|
||||||
|
if (!revents)
|
||||||
|
return;
|
||||||
|
|
||||||
handle_drm_event (kms_renderer);
|
handle_drm_event (kms_renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +302,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||||||
_cogl_poll_renderer_add_fd (renderer,
|
_cogl_poll_renderer_add_fd (renderer,
|
||||||
kms_renderer->fd,
|
kms_renderer->fd,
|
||||||
COGL_POLL_FD_EVENT_IN,
|
COGL_POLL_FD_EVENT_IN,
|
||||||
NULL, /* no check callback */
|
NULL, /* no prepare callback */
|
||||||
dispatch_kms_events,
|
dispatch_kms_events,
|
||||||
renderer);
|
renderer);
|
||||||
|
|
||||||
|
@ -110,12 +110,15 @@ static const struct wl_registry_listener registry_listener = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dispatch_wayland_display_events (void *user_data)
|
dispatch_wayland_display_events (void *user_data, int revents)
|
||||||
{
|
{
|
||||||
CoglRenderer *renderer = user_data;
|
CoglRenderer *renderer = user_data;
|
||||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglRendererWayland *wayland_renderer = egl_renderer->platform;
|
CoglRendererWayland *wayland_renderer = egl_renderer->platform;
|
||||||
|
|
||||||
|
if (!revents)
|
||||||
|
return;
|
||||||
|
|
||||||
wl_display_dispatch (wayland_renderer->wayland_display);
|
wl_display_dispatch (wayland_renderer->wayland_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +194,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||||||
_cogl_poll_renderer_add_fd (renderer,
|
_cogl_poll_renderer_add_fd (renderer,
|
||||||
wayland_renderer->fd,
|
wayland_renderer->fd,
|
||||||
COGL_POLL_FD_EVENT_IN,
|
COGL_POLL_FD_EVENT_IN,
|
||||||
NULL, /* no check callback */
|
NULL, /* no prepare callback */
|
||||||
dispatch_wayland_display_events,
|
dispatch_wayland_display_events,
|
||||||
renderer);
|
renderer);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user