diff options
author | Rob Bradford <rob@linux.intel.com> | 2012-11-30 12:02:33 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2012-11-30 18:33:54 +0000 |
commit | 27bd971b743067bce607809e0a5cb26eab5c69a9 (patch) | |
tree | 556a6924f0b875000faeebd1d5e62d6312a5793d | |
parent | fce70605f2e2eb4229f3ac58060db05aa3e6ef56 (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.ac | 2 | ||||
-rw-r--r-- | ext/wayland/gstwaylandsink.c | 101 | ||||
-rw-r--r-- | ext/wayland/gstwaylandsink.h | 5 |
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, ®istry_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; }; |