mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-05 18:22:23 +00:00
waylandsink: Keep per display wayland buffer caches
Instead of attaching a single wayland wl_buffer to each GStBuffer as qdata, keep a separate cache for each display. A unique wl_buffer and associated metadata is created for each display. This allows for sharing of GstBuffer objects between multiple displays, such as when using tee elements. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1401>
This commit is contained in:
parent
7b3c101ced
commit
ff5f264045
5 changed files with 44 additions and 26 deletions
|
@ -655,7 +655,7 @@ render_last_buffer (GstWaylandSink * sink, gboolean redraw)
|
|||
struct wl_surface *surface;
|
||||
struct wl_callback *callback;
|
||||
|
||||
wlbuffer = gst_buffer_get_wl_buffer (sink->last_buffer);
|
||||
wlbuffer = gst_buffer_get_wl_buffer (sink->display, sink->last_buffer);
|
||||
surface = gst_wl_window_get_wl_surface (sink->window);
|
||||
|
||||
sink->redraw_pending = TRUE;
|
||||
|
@ -723,7 +723,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
if (G_UNLIKELY (sink->window->render_rectangle.w == 0))
|
||||
goto no_window_size;
|
||||
|
||||
wlbuffer = gst_buffer_get_wl_buffer (buffer);
|
||||
wlbuffer = gst_buffer_get_wl_buffer (sink->display, buffer);
|
||||
|
||||
if (G_LIKELY (wlbuffer && wlbuffer->display == sink->display)) {
|
||||
GST_LOG_OBJECT (sink, "buffer %p has a wl_buffer from our display, "
|
||||
|
@ -807,7 +807,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
if (ret != GST_FLOW_OK)
|
||||
goto no_buffer;
|
||||
|
||||
wlbuffer = gst_buffer_get_wl_buffer (to_render);
|
||||
wlbuffer = gst_buffer_get_wl_buffer (sink->display, to_render);
|
||||
|
||||
/* attach a wl_buffer if there isn't one yet */
|
||||
if (G_UNLIKELY (!wlbuffer)) {
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
* ----------------- ------------- ---------------
|
||||
*
|
||||
* A GstBufferPool normally holds references to its GstBuffers and each buffer
|
||||
* holds a reference to a GstWlBuffer (saved in the GstMiniObject qdata).
|
||||
* holds a reference to a GstWlBuffer (saved in the GstMiniObject weak ref data).
|
||||
* When a GstBuffer is in use, it holds a reference back to the pool and the
|
||||
* pool doesn't hold a reference to the GstBuffer. When the GstBuffer is unrefed
|
||||
* externally, it returns back to the pool and the pool holds again a reference
|
||||
|
@ -83,8 +83,6 @@ GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
|
|||
|
||||
G_DEFINE_TYPE (GstWlBuffer, gst_wl_buffer, G_TYPE_OBJECT);
|
||||
|
||||
static G_DEFINE_QUARK (GstWlBufferQDataQuark, gst_wl_buffer_qdata);
|
||||
|
||||
static void
|
||||
gst_wl_buffer_dispose (GObject * gobject)
|
||||
{
|
||||
|
@ -97,7 +95,7 @@ gst_wl_buffer_dispose (GObject * gobject)
|
|||
* block and in the end the display will increase the refcount
|
||||
* of this GstWlBuffer, so it will not be finalized */
|
||||
if (self->display)
|
||||
gst_wl_display_unregister_buffer (self->display, self);
|
||||
gst_wl_display_unregister_buffer (self->display, self->gstbuffer);
|
||||
|
||||
G_OBJECT_CLASS (gst_wl_buffer_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
@ -150,7 +148,6 @@ static void
|
|||
gstbuffer_disposed (GstWlBuffer * self)
|
||||
{
|
||||
g_assert (!self->used_by_compositor);
|
||||
self->gstbuffer = NULL;
|
||||
|
||||
GST_TRACE_OBJECT (self, "owning GstBuffer was finalized");
|
||||
|
||||
|
@ -170,25 +167,25 @@ gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer,
|
|||
self->wlbuffer = wlbuffer;
|
||||
self->display = display;
|
||||
|
||||
gst_wl_display_register_buffer (self->display, self);
|
||||
gst_wl_display_register_buffer (self->display, self->gstbuffer, self);
|
||||
|
||||
wl_buffer_add_listener (self->wlbuffer, &buffer_listener, self);
|
||||
|
||||
gst_mini_object_set_qdata ((GstMiniObject *) gstbuffer,
|
||||
gst_wl_buffer_qdata_quark (), self, (GDestroyNotify) gstbuffer_disposed);
|
||||
gst_mini_object_weak_ref (GST_MINI_OBJECT (gstbuffer),
|
||||
(GstMiniObjectNotify) gstbuffer_disposed, self);
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
GstWlBuffer *
|
||||
gst_buffer_get_wl_buffer (GstBuffer * gstbuffer)
|
||||
gst_buffer_get_wl_buffer (GstWlDisplay * display, GstBuffer * gstbuffer)
|
||||
{
|
||||
return gst_mini_object_get_qdata ((GstMiniObject *) gstbuffer,
|
||||
gst_wl_buffer_qdata_quark ());
|
||||
return gst_wl_display_lookup_buffer (display, gstbuffer);
|
||||
}
|
||||
|
||||
void
|
||||
gst_wl_buffer_force_release_and_unref (GstWlBuffer * self)
|
||||
gst_wl_buffer_force_release_and_unref (GstBuffer * buf, GstWlBuffer * self)
|
||||
{
|
||||
/* Force a buffer release.
|
||||
* At this point, the GstWlDisplay has killed its event loop,
|
||||
|
@ -212,6 +209,7 @@ gst_wl_buffer_force_release_and_unref (GstWlBuffer * self)
|
|||
wl_buffer_destroy (self->wlbuffer);
|
||||
self->wlbuffer = NULL;
|
||||
self->display = NULL;
|
||||
self->gstbuffer = NULL;
|
||||
|
||||
/* remove the reference that the caller (GstWlDisplay) owns */
|
||||
g_object_unref (self);
|
||||
|
|
|
@ -56,9 +56,9 @@ GType gst_wl_buffer_get_type (void);
|
|||
|
||||
GstWlBuffer * gst_buffer_add_wl_buffer (GstBuffer * gstbuffer,
|
||||
struct wl_buffer * wlbuffer, GstWlDisplay * display);
|
||||
GstWlBuffer * gst_buffer_get_wl_buffer (GstBuffer * gstbuffer);
|
||||
GstWlBuffer * gst_buffer_get_wl_buffer (GstWlDisplay * display, GstBuffer * gstbuffer);
|
||||
|
||||
void gst_wl_buffer_force_release_and_unref (GstWlBuffer * self);
|
||||
void gst_wl_buffer_force_release_and_unref (GstBuffer *buf, GstWlBuffer * self);
|
||||
|
||||
void gst_wl_buffer_attach (GstWlBuffer * self, struct wl_surface *surface);
|
||||
|
||||
|
|
|
@ -52,6 +52,12 @@ gst_wl_display_init (GstWlDisplay * self)
|
|||
g_mutex_init (&self->buffers_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_wl_ref_wl_buffer (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
g_object_ref (value);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_wl_display_finalize (GObject * gobject)
|
||||
{
|
||||
|
@ -65,7 +71,7 @@ gst_wl_display_finalize (GObject * gobject)
|
|||
* at the same time, take their ownership */
|
||||
g_mutex_lock (&self->buffers_mutex);
|
||||
self->shutting_down = TRUE;
|
||||
g_hash_table_foreach (self->buffers, (GHFunc) g_object_ref, NULL);
|
||||
g_hash_table_foreach (self->buffers, gst_wl_ref_wl_buffer, NULL);
|
||||
g_mutex_unlock (&self->buffers_mutex);
|
||||
|
||||
g_hash_table_foreach (self->buffers,
|
||||
|
@ -379,24 +385,36 @@ gst_wl_display_new_existing (struct wl_display * display,
|
|||
}
|
||||
|
||||
void
|
||||
gst_wl_display_register_buffer (GstWlDisplay * self, gpointer buf)
|
||||
gst_wl_display_register_buffer (GstWlDisplay * self, gpointer gstbuffer,
|
||||
gpointer wlbuffer)
|
||||
{
|
||||
g_assert (!self->shutting_down);
|
||||
|
||||
GST_TRACE_OBJECT (self, "registering GstWlBuffer %p", buf);
|
||||
GST_TRACE_OBJECT (self, "registering GstWlBuffer %p to GstBuffer %p",
|
||||
wlbuffer, gstbuffer);
|
||||
|
||||
g_mutex_lock (&self->buffers_mutex);
|
||||
g_hash_table_add (self->buffers, buf);
|
||||
g_hash_table_replace (self->buffers, gstbuffer, wlbuffer);
|
||||
g_mutex_unlock (&self->buffers_mutex);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_wl_display_lookup_buffer (GstWlDisplay * self, gpointer gstbuffer)
|
||||
{
|
||||
gpointer wlbuffer;
|
||||
g_mutex_lock (&self->buffers_mutex);
|
||||
wlbuffer = g_hash_table_lookup (self->buffers, gstbuffer);
|
||||
g_mutex_unlock (&self->buffers_mutex);
|
||||
return wlbuffer;
|
||||
}
|
||||
|
||||
void
|
||||
gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer buf)
|
||||
gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer gstbuffer)
|
||||
{
|
||||
GST_TRACE_OBJECT (self, "unregistering GstWlBuffer %p", buf);
|
||||
GST_TRACE_OBJECT (self, "unregistering GstWlBuffer owned by %p", gstbuffer);
|
||||
|
||||
g_mutex_lock (&self->buffers_mutex);
|
||||
if (G_LIKELY (!self->shutting_down))
|
||||
g_hash_table_remove (self->buffers, buf);
|
||||
g_hash_table_remove (self->buffers, gstbuffer);
|
||||
g_mutex_unlock (&self->buffers_mutex);
|
||||
}
|
||||
|
|
|
@ -85,8 +85,10 @@ GstWlDisplay *gst_wl_display_new_existing (struct wl_display * display,
|
|||
gboolean take_ownership, GError ** error);
|
||||
|
||||
/* see wlbuffer.c for explanation */
|
||||
void gst_wl_display_register_buffer (GstWlDisplay * self, gpointer buf);
|
||||
void gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer buf);
|
||||
void gst_wl_display_register_buffer (GstWlDisplay * self, gpointer gstbuffer,
|
||||
gpointer wlbuffer);
|
||||
void gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer gstbuffer);
|
||||
gpointer gst_wl_display_lookup_buffer (GstWlDisplay * self, gpointer gstbuffer);
|
||||
|
||||
gboolean gst_wl_display_check_format_for_shm (GstWlDisplay * display,
|
||||
GstVideoFormat format);
|
||||
|
|
Loading…
Reference in a new issue