summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Bradford <rob@linux.intel.com>2012-11-30 12:02:33 +0000
committerTim-Philipp Müller <tim.muller@collabora.co.uk>2012-11-30 18:33:54 +0000
commit27bd971b743067bce607809e0a5cb26eab5c69a9 (patch)
tree556a6924f0b875000faeebd1d5e62d6312a5793d
parentfce70605f2e2eb4229f3ac58060db05aa3e6ef56 (diff)
waylandsink: Port to 1.0 protocol
- The globals are now notified through a wl_registry object - Since surface state is double buffered in the compositor it is now necessary to call wl_surface_commit to atomically update surface state - Implement the ping/pong protocol which the compositor uses to check the client is still alive - SHM buffers are now allocated through a pool - It is necessary to make the surface top level before the contents will be presented by the compositor - Adopt the new event handling - through wl_display_dispatch - Update the configure check to look for Wayland 1.0 https://bugzilla.gnome.org/show_bug.cgi?id=688407
-rw-r--r--configure.ac2
-rw-r--r--ext/wayland/gstwaylandsink.c101
-rw-r--r--ext/wayland/gstwaylandsink.h5
3 files changed, 71 insertions, 37 deletions
diff --git a/configure.ac b/configure.ac
index 554e913b1..98faf9c8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -989,7 +989,7 @@ AG_GST_CHECK_FEATURE(DIRECTFB, [directfb], dfbvideosink , [
dnl **** Wayland ****
translit(dnm, m, l) AM_CONDITIONAL(USE_WAYLAND, true)
AG_GST_CHECK_FEATURE(WAYLAND, [wayland sink], wayland , [
- PKG_CHECK_MODULES(WAYLAND, wayland-client >= 0.1, [
+ PKG_CHECK_MODULES(WAYLAND, wayland-client >= 1.0.0, [
AC_CHECK_HEADER(wayland-client.h, HAVE_WAYLAND_CLIENT="yes", HAVE_WAYLAND_CLIENT="no")
AC_CHECK_HEADER(wayland-client-protocol.h, HAVE_WAYLAND_CLIENT_PROTOCOL="yes", HAVE_WAYLAND_CLIENT_PROTOCOL="no")
if test "x$HAVE_WAYLAND_CLIENT" = "xno"; then
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index a2016fddf..7d5b21eee 100644
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -98,10 +98,9 @@ static void gst_wayland_bufferpool_clear (GstWaylandSink * sink);
static void
gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer);
-static int event_mask_update (uint32_t mask, void *data);
static struct display *create_display (void);
-static void display_handle_global (struct wl_display *display, uint32_t id,
- const char *interface, uint32_t version, void *data);
+static void registry_handle_global (void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface, uint32_t version);
static void redraw (void *data, struct wl_callback *callback, uint32_t time);
static void create_window (GstWaylandSink * sink, struct display *display,
int width, int height);
@@ -253,7 +252,7 @@ destroy_display (struct display *display)
wl_compositor_destroy (display->compositor);
wl_display_flush (display->display);
- wl_display_destroy (display->display);
+ wl_display_disconnect (display->display);
free (display);
}
@@ -299,16 +298,6 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink)
return gst_caps_copy (gst_static_pad_template_get_caps (&sink_template));
}
-static int
-event_mask_update (uint32_t mask, void *data)
-{
- struct display *d = data;
-
- d->mask = mask;
-
- return 0;
-}
-
static void
shm_format (void *data, struct wl_shm *wl_shm, uint32_t format)
{
@@ -322,22 +311,27 @@ struct wl_shm_listener shm_listenter = {
};
static void
-display_handle_global (struct wl_display *display, uint32_t id,
- const char *interface, uint32_t version, void *data)
+registry_handle_global (void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface, uint32_t version)
{
struct display *d = data;
if (strcmp (interface, "wl_compositor") == 0) {
- d->compositor = wl_display_bind (display, id, &wl_compositor_interface);
+ d->compositor =
+ wl_registry_bind (registry, id, &wl_compositor_interface, 1);
} else if (strcmp (interface, "wl_shell") == 0) {
- d->shell = wl_display_bind (display, id, &wl_shell_interface);
+ d->shell = wl_registry_bind (registry, id, &wl_shell_interface, 1);
} else if (strcmp (interface, "wl_shm") == 0) {
- d->shm = wl_display_bind (display, id, &wl_shm_interface);
+ d->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1);
wl_shm_add_listener (d->shm, &shm_listenter, d);
}
-
}
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ NULL
+};
+
static struct display *
create_display (void)
{
@@ -351,10 +345,16 @@ create_display (void)
return NULL;
}
- wl_display_add_global_listener (display->display,
- display_handle_global, display);
+ display->registry = wl_display_get_registry (display->display);
+ wl_registry_add_listener (display->registry, &registry_listener, display);
+
+ wl_display_roundtrip (display->display);
+
+ if (!display->shm) {
+ GST_ERROR ("No wl_shm global received");
+ return NULL;
+ }
- wl_display_iterate (display->display, WL_DISPLAY_READABLE);
wl_display_roundtrip (display->display);
if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
@@ -362,8 +362,6 @@ create_display (void)
return NULL;
}
- wl_display_get_fd (display->display, event_mask_update, display);
-
return display;
}
@@ -375,6 +373,7 @@ wayland_buffer_create (GstWaylandSink * sink)
static void *data;
static int init = 0;
GstWlBuffer *wbuffer;
+ struct wl_shm_pool *shm_pool;
GST_DEBUG_OBJECT (sink, "Creating wayland-shm buffers");
@@ -407,8 +406,10 @@ wayland_buffer_create (GstWaylandSink * sink)
exit (0);
}
- wbuffer->wbuffer = wl_shm_create_buffer (sink->display->shm, fd,
+ shm_pool = wl_shm_create_pool (sink->display->shm, fd, size);
+ wbuffer->wbuffer = wl_shm_pool_create_buffer (shm_pool, 0,
sink->video_width, sink->video_height, stride, WL_SHM_FORMAT_XRGB8888);
+ wbuffer->pool = shm_pool;
close (fd);
@@ -426,6 +427,16 @@ gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer)
gst_object_unref (sink);
}
+ if (buffer->wbuffer) {
+ wl_buffer_destroy (buffer->wbuffer);
+ buffer->wbuffer = NULL;
+ }
+
+ if (buffer->pool) {
+ wl_shm_pool_destroy (buffer->pool);
+ buffer->pool = NULL;
+ }
+
GST_MINI_OBJECT_CLASS (gst_wlbuffer_parent_class)->finalize (GST_MINI_OBJECT
(buffer));
}
@@ -525,13 +536,35 @@ static const struct wl_callback_listener frame_listener;
static void
redraw (void *data, struct wl_callback *callback, uint32_t time)
{
-
GstWaylandSink *sink = (GstWaylandSink *) data;
sink->render_finish = TRUE;
}
static void
+ping (void *data, struct wl_shell_surface *shell_surface, uint32_t serial)
+{
+ wl_shell_surface_pong (shell_surface, serial);
+}
+
+static void
+configure (void *data, struct wl_shell_surface *shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+}
+
+static void
+popup_done (void *data, struct wl_shell_surface *shell_surface)
+{
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+ ping,
+ configure,
+ popup_done
+};
+
+static void
create_window (GstWaylandSink * sink, struct display *display, int width,
int height)
{
@@ -550,11 +583,12 @@ create_window (GstWaylandSink * sink, struct display *display, int width,
window->shell_surface = wl_shell_get_shell_surface (display->shell,
window->surface);
- /* wl_shell_surface_set_toplevel (window->shell_surface); */
-#ifdef WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT
+ wl_shell_surface_add_listener (window->shell_surface, &shell_surface_listener,
+ sink);
+ wl_shell_surface_set_toplevel (window->shell_surface);
+
wl_shell_surface_set_fullscreen (window->shell_surface,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
-#endif
sink->window = window;
@@ -653,10 +687,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
sink->render_finish = FALSE;
- wl_buffer_damage (sink->window->buffer, 0, 0, res.w, res.h);
-
wl_surface_attach (sink->window->surface, sink->window->buffer, 0, 0);
-
wl_surface_damage (sink->window->surface, 0, 0, res.w, res.h);
if (sink->callback)
@@ -664,12 +695,14 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
sink->callback = wl_surface_frame (sink->window->surface);
wl_callback_add_listener (sink->callback, &frame_listener, sink);
- wl_display_iterate (sink->display->display, sink->display->mask);
+ wl_surface_commit (sink->window->surface);
} else
GST_LOG_OBJECT (sink,
"Waiting to get the signal from compositor to render the next frame..");
+ wl_display_dispatch (sink->display->display);
+
return GST_FLOW_OK;
}
diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
index f9c1ca87c..2513c90c8 100644
--- a/ext/wayland/gstwaylandsink.h
+++ b/ext/wayland/gstwaylandsink.h
@@ -59,8 +59,8 @@ struct display
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_shm *shm;
+ struct wl_registry *registry;
uint32_t formats;
- uint32_t mask;
};
struct window
@@ -86,7 +86,8 @@ struct _GstWlBuffer {
GstBuffer buffer; /* Extending GstBuffer */
struct wl_buffer *wbuffer;
-
+ struct wl_shm_pool *pool;
+
GstWaylandSink *wlsink;
};