waylandsink: remove the manual synchronization from pause/resume_rendering and use subsurface sync/desync

Previously, in order to change the surface size we had to let the pipeline
redraw it, which at first also involved re-negotiating caps, etc, so a
synchronization with the pipeline was absolutely necessary.

At the moment, we are using wl_viewport, which separates the surface size
from the buffer size and it also allows us to commit a surface resize without
attaching a new buffer, so it is enough to just do:

gst_wayland_video_pause_rendering():
	wl_subsurface_set_sync()
gst_video_overlay_set_render_rectangle():
	wl_subsurface_set_position()
	wl_viewport_set_destination()
	wl_surface_damage()
	wl_surface_commit()
... commit the parent surface ...
gst_wayland_video_resume_rendering():
	wl_subsurface_set_desync()

This is enough to synchronize a surface resize and the pipeline can continue
drawing independently. Now of course, the names pause/resume_rendering are
bad. I will rename them in another commit.
This commit is contained in:
George Kiagiadakis 2014-05-29 12:27:46 +03:00
parent c17521c096
commit 06639dd727
2 changed files with 12 additions and 25 deletions

View file

@ -164,7 +164,6 @@ gst_wayland_sink_init (GstWaylandSink * sink)
{
g_mutex_init (&sink->display_lock);
g_mutex_init (&sink->render_lock);
g_cond_init (&sink->render_cond);
}
static void
@ -230,7 +229,6 @@ gst_wayland_sink_finalize (GObject * object)
g_mutex_clear (&sink->display_lock);
g_mutex_clear (&sink->render_lock);
g_cond_clear (&sink->render_cond);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -665,10 +663,6 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
GST_LOG_OBJECT (sink, "render buffer %p", buffer);
/* surface is resizing - drop buffers until finished */
if (sink->drawing_frozen)
goto done;
/* drop buffers until we get a frame callback */
if (g_atomic_int_get (&sink->redraw_pending) == TRUE)
goto done;
@ -711,10 +705,6 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
gst_buffer_replace (&sink->last_buffer, to_render);
render_last_buffer (sink);
/* notify _resume_rendering() in case it's waiting */
sink->rendered = TRUE;
g_cond_broadcast (&sink->render_cond);
if (buffer != to_render)
gst_buffer_unref (to_render);
goto done;
@ -851,7 +841,13 @@ gst_wayland_sink_pause_rendering (GstWaylandVideo * video)
g_return_if_fail (sink != NULL);
g_mutex_lock (&sink->render_lock);
sink->drawing_frozen = TRUE;
if (!sink->window || !sink->window->subsurface) {
g_mutex_unlock (&sink->render_lock);
GST_INFO_OBJECT (sink, "pause_rendering called without window, ignoring");
return;
}
wl_subsurface_set_sync (sink->window->subsurface);
g_mutex_unlock (&sink->render_lock);
}
@ -864,19 +860,13 @@ gst_wayland_sink_resume_rendering (GstWaylandVideo * video)
GST_DEBUG_OBJECT (sink, "resuming rendering");
g_mutex_lock (&sink->render_lock);
sink->drawing_frozen = FALSE;
if (GST_STATE (sink) == GST_STATE_PLAYING) {
sink->rendered = FALSE;
while (sink->rendered == FALSE)
g_cond_wait (&sink->render_cond, &sink->render_lock);
GST_DEBUG_OBJECT (sink, "synchronized with render()");
} else if (sink->window && sink->last_buffer &&
g_atomic_int_get (&sink->redraw_pending) == FALSE) {
render_last_buffer (sink);
GST_DEBUG_OBJECT (sink, "last buffer redrawn");
if (!sink->window || !sink->window->subsurface) {
g_mutex_unlock (&sink->render_lock);
GST_INFO_OBJECT (sink, "resume_rendering called without window, ignoring");
return;
}
wl_subsurface_set_desync (sink->window->subsurface);
g_mutex_unlock (&sink->render_lock);
}

View file

@ -63,10 +63,7 @@ struct _GstWaylandSink
gchar *display_name;
gboolean redraw_pending;
gboolean drawing_frozen;
gboolean rendered;
GMutex render_lock;
GCond render_cond;
GstBuffer *last_buffer;
};