wayland/dma-buf: Add meta_wayland_dma_buf_create_source
Creates a GSource which will call the specified dispatch callback when all dma-buf file descriptors for the buffer have become readable. v2: * Hold a reference to the buffer in the source, to prevent the buffer from getting destroyed before the source. v3: * Do not use check callback, handle everything in dispatch callback. (Dor Askayo) v4: (Georges Basile Stavracas Neto) * Define and use MetaWaylandDmaBufSource & MetaWaylandDmaBufSourceDispatch types. * Fix meta_wayland_dma_buf_source_dispatch & meta_wayland_dma_buf_source_funcs formatting. * Use gpointer instead of void*. * Rename meta_wayland_dma_buf_get_source to meta_wayland_dma_buf_create_source. (Carlos Garnacho) v5: * Explicitly handle NULL return value. (Jonas Ådahl) v6: * Fix style issue per check-style.py. v7: * Fix code style harder. (Jonas Ådahl) Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This commit is contained in:
parent
416285d1b7
commit
d43150573e
@ -763,6 +763,153 @@ meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer)
|
|||||||
return buffer->dma_buf.dma_buf;
|
return buffer->dma_buf.dma_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandDmaBufSource
|
||||||
|
{
|
||||||
|
GSource base;
|
||||||
|
|
||||||
|
MetaWaylandDmaBufSourceDispatch dispatch;
|
||||||
|
MetaWaylandBuffer *buffer;
|
||||||
|
gpointer user_data;
|
||||||
|
|
||||||
|
gpointer fd_tags[META_WAYLAND_DMA_BUF_MAX_FDS];
|
||||||
|
} MetaWaylandDmaBufSource;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_wayland_dma_buf_fd_readable (int fd)
|
||||||
|
{
|
||||||
|
GPollFD poll_fd;
|
||||||
|
|
||||||
|
poll_fd.fd = fd;
|
||||||
|
poll_fd.events = G_IO_IN;
|
||||||
|
poll_fd.revents = 0;
|
||||||
|
|
||||||
|
if (!g_poll (&poll_fd, 1, 0))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return (poll_fd.revents & (G_IO_IN | G_IO_NVAL)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_wayland_dma_buf_source_dispatch (GSource *base,
|
||||||
|
GSourceFunc callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaWaylandDmaBufSource *source;
|
||||||
|
MetaWaylandDmaBufBuffer *dma_buf;
|
||||||
|
gboolean ready;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
source = (MetaWaylandDmaBufSource *) base;
|
||||||
|
dma_buf = source->buffer->dma_buf.dma_buf;
|
||||||
|
ready = TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++)
|
||||||
|
{
|
||||||
|
gpointer fd_tag = source->fd_tags[i];
|
||||||
|
|
||||||
|
if (!fd_tag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!meta_wayland_dma_buf_fd_readable (dma_buf->fds[i]))
|
||||||
|
{
|
||||||
|
ready = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_source_remove_unix_fd (&source->base, fd_tag);
|
||||||
|
source->fd_tags[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ready)
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
|
||||||
|
source->dispatch (source->buffer, source->user_data);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_dma_buf_source_finalize (GSource *base)
|
||||||
|
{
|
||||||
|
MetaWaylandDmaBufSource *source;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
source = (MetaWaylandDmaBufSource *) base;
|
||||||
|
|
||||||
|
for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++)
|
||||||
|
{
|
||||||
|
gpointer fd_tag = source->fd_tags[i];
|
||||||
|
|
||||||
|
if (fd_tag)
|
||||||
|
{
|
||||||
|
g_source_remove_unix_fd (&source->base, fd_tag);
|
||||||
|
source->fd_tags[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&source->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSourceFuncs meta_wayland_dma_buf_source_funcs = {
|
||||||
|
.dispatch = meta_wayland_dma_buf_source_dispatch,
|
||||||
|
.finalize = meta_wayland_dma_buf_source_finalize
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_wayland_dma_buf_create_source:
|
||||||
|
* @buffer: A #MetaWaylandBuffer object
|
||||||
|
* @dispatch: Callback
|
||||||
|
* @user_data: User data for the callback
|
||||||
|
*
|
||||||
|
* Creates a GSource which will call the specified dispatch callback when all
|
||||||
|
* dma-buf file descriptors for the buffer have become readable.
|
||||||
|
*
|
||||||
|
* Returns: The new GSource (or
|
||||||
|
* %NULL if there are no dma-buf file descriptors, or they were all readable
|
||||||
|
* already)
|
||||||
|
*/
|
||||||
|
GSource *
|
||||||
|
meta_wayland_dma_buf_create_source (MetaWaylandBuffer *buffer,
|
||||||
|
MetaWaylandDmaBufSourceDispatch dispatch,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaWaylandDmaBufBuffer *dma_buf;
|
||||||
|
MetaWaylandDmaBufSource *source = NULL;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
dma_buf = buffer->dma_buf.dma_buf;
|
||||||
|
if (!dma_buf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++)
|
||||||
|
{
|
||||||
|
int fd = dma_buf->fds[i];
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (meta_wayland_dma_buf_fd_readable (fd))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!source)
|
||||||
|
{
|
||||||
|
source =
|
||||||
|
(MetaWaylandDmaBufSource *) g_source_new (&meta_wayland_dma_buf_source_funcs,
|
||||||
|
sizeof (*source));
|
||||||
|
source->buffer = g_object_ref (buffer);
|
||||||
|
source->dispatch = dispatch;
|
||||||
|
source->user_data = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
source->fd_tags[i] = g_source_add_unix_fd (&source->base, fd, G_IO_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!source)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &source->base;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
buffer_params_create_common (struct wl_client *client,
|
buffer_params_create_common (struct wl_client *client,
|
||||||
struct wl_resource *params_resource,
|
struct wl_resource *params_resource,
|
||||||
|
@ -57,6 +57,14 @@ meta_wayland_dma_buf_fds_for_wayland_buffer (MetaWaylandBuffer *buffer);
|
|||||||
MetaWaylandDmaBufBuffer *
|
MetaWaylandDmaBufBuffer *
|
||||||
meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer);
|
meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer);
|
||||||
|
|
||||||
|
typedef void (*MetaWaylandDmaBufSourceDispatch) (MetaWaylandBuffer *buffer,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GSource *
|
||||||
|
meta_wayland_dma_buf_create_source (MetaWaylandBuffer *buffer,
|
||||||
|
MetaWaylandDmaBufSourceDispatch dispatch,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
CoglScanout *
|
CoglScanout *
|
||||||
meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
|
meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
|
||||||
CoglOnscreen *onscreen);
|
CoglOnscreen *onscreen);
|
||||||
|
Loading…
Reference in New Issue
Block a user