wayland: decouple wl_buffer from frame

This patch takes out the wayland's buffer from the the frame structure. The
buffer is queued to wayland and destroyed in the "release" callback. The
frame is freed in the surface's "done" callback.

In this way a buffer may be leaked but not the whole frame structure.

- surface 'done' callback is used to throttle the rendering operation and to
  unallocate the frame, but not the buffer.
- buffer 'release' callback is used to destroy wl_buffer.

Original-patch-by: Zhao Halley <halley.zhao@intel.com>
* code rebase
* kept the the event_queue for buffer's proxy

Signed-off-by: Víctor Manuel Jáquez Leal <victorx.jaquez@intel.com>

https://bugzilla.gnome.org/show_bug.cgi?id=749078
This commit is contained in:
Víctor Manuel Jáquez Leal 2015-05-07 10:36:17 +02:00
parent 77ab913ee6
commit 62c3888b76

View file

@ -55,7 +55,6 @@ struct _FrameState
GstVaapiWindow *window;
GstVaapiSurface *surface;
GstVaapiVideoPool *surface_pool;
struct wl_buffer *buffer;
struct wl_callback *callback;
};
@ -71,7 +70,6 @@ frame_state_new (GstVaapiWindow * window)
frame->window = window;
frame->surface = NULL;
frame->surface_pool = NULL;
frame->buffer = NULL;
frame->callback = NULL;
return frame;
}
@ -89,11 +87,6 @@ frame_state_free (FrameState * frame)
}
gst_vaapi_video_pool_replace (&frame->surface_pool, NULL);
if (frame->buffer) {
wl_buffer_destroy (frame->buffer);
frame->buffer = NULL;
}
if (frame->callback) {
wl_callback_destroy (frame->callback);
frame->callback = NULL;
@ -162,11 +155,10 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window)
{
GstVaapiWindowWaylandPrivate *const priv =
GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
struct wl_display *const wl_display =
GST_VAAPI_OBJECT_NATIVE_DISPLAY (window);
while (priv->frame_pending) {
struct wl_display *const wl_display =
GST_VAAPI_OBJECT_NATIVE_DISPLAY (window);
if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0)
return FALSE;
}
@ -328,8 +320,11 @@ frame_done_callback (void *data, struct wl_callback *callback, uint32_t time)
GstVaapiWindowWaylandPrivate *const priv =
GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window);
if (priv->frame == frame)
if (priv->frame == frame) {
priv->frame_pending = FALSE;
frame_state_free (frame);
priv->frame = NULL;
}
}
static const struct wl_callback_listener frame_callback_listener = {
@ -339,7 +334,7 @@ static const struct wl_callback_listener frame_callback_listener = {
static void
frame_release_callback (void *data, struct wl_buffer *wl_buffer)
{
frame_state_free (data);
wl_buffer_destroy (wl_buffer);
}
static const struct wl_buffer_listener frame_buffer_listener = {
@ -500,9 +495,11 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window,
priv->opaque_region = NULL;
}
frame->buffer = buffer;
/* @TODO: It is not OK to use internal event_queue here, since there
* may still be a WL_BUFFER_RELEASE event when we destroy the
* event_queue in gst_vaapi_window_wayland_destroy (). */
wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue);
wl_buffer_add_listener (buffer, &frame_buffer_listener, frame);
wl_buffer_add_listener (buffer, &frame_buffer_listener, NULL);
frame->callback = wl_surface_frame (priv->surface);
wl_callback_add_listener (frame->callback, &frame_callback_listener, frame);