diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c index 11db63211..3fc536208 100644 --- a/src/wayland/meta-wayland-buffer.c +++ b/src/wayland/meta-wayland-buffer.c @@ -30,6 +30,8 @@ #include #include +G_DEFINE_TYPE (MetaWaylandBuffer, meta_wayland_buffer, G_TYPE_OBJECT); + static void meta_wayland_buffer_destroy_handler (struct wl_listener *listener, void *data) @@ -37,32 +39,16 @@ meta_wayland_buffer_destroy_handler (struct wl_listener *listener, MetaWaylandBuffer *buffer = wl_container_of (listener, buffer, destroy_listener); + buffer->resource = NULL; wl_signal_emit (&buffer->destroy_signal, buffer); - g_slice_free (MetaWaylandBuffer, buffer); -} - -void -meta_wayland_buffer_ref (MetaWaylandBuffer *buffer) -{ - buffer->ref_count++; -} - -void -meta_wayland_buffer_unref (MetaWaylandBuffer *buffer) -{ - buffer->ref_count--; - - if (buffer->ref_count == 0) - { - g_warn_if_fail (buffer->use_count == 0); - - g_clear_pointer (&buffer->texture, cogl_object_unref); - } + g_object_unref (buffer); } void meta_wayland_buffer_ref_use_count (MetaWaylandBuffer *buffer) { + g_warn_if_fail (buffer->resource); + buffer->use_count++; } @@ -73,7 +59,7 @@ meta_wayland_buffer_unref_use_count (MetaWaylandBuffer *buffer) buffer->use_count--; - if (buffer->use_count == 0) + if (buffer->use_count == 0 && buffer->resource) wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE); } @@ -93,7 +79,7 @@ meta_wayland_buffer_from_resource (struct wl_resource *resource) } else { - buffer = g_slice_new0 (MetaWaylandBuffer); + buffer = g_object_new (META_TYPE_WAYLAND_BUFFER, NULL); buffer->resource = resource; wl_signal_init (&buffer->destroy_signal); @@ -113,6 +99,7 @@ meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer) struct wl_shm_buffer *shm_buffer; g_return_val_if_fail (buffer->use_count != 0, NULL); + g_return_val_if_fail (buffer->resource, NULL); if (buffer->texture) goto out; @@ -172,3 +159,26 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer, wl_shm_buffer_end_access (shm_buffer); } } + +static void +meta_wayland_buffer_finalize (GObject *object) +{ + MetaWaylandBuffer *buffer = META_WAYLAND_BUFFER (object); + + g_clear_pointer (&buffer->texture, cogl_object_unref); + + G_OBJECT_CLASS (meta_wayland_buffer_parent_class)->finalize (object); +} + +static void +meta_wayland_buffer_init (MetaWaylandBuffer *buffer) +{ +} + +static void +meta_wayland_buffer_class_init (MetaWaylandBufferClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_buffer_finalize; +} diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h index fda534bc1..e9b0aa2d3 100644 --- a/src/wayland/meta-wayland-buffer.h +++ b/src/wayland/meta-wayland-buffer.h @@ -33,18 +33,21 @@ struct _MetaWaylandBuffer { + GObject parent; + struct wl_resource *resource; struct wl_signal destroy_signal; struct wl_listener destroy_listener; CoglTexture *texture; - uint32_t ref_count; uint32_t use_count; }; +#define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandBuffer, meta_wayland_buffer, + META, WAYLAND_BUFFER, GObject); + MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); -void meta_wayland_buffer_ref (MetaWaylandBuffer *buffer); -void meta_wayland_buffer_unref (MetaWaylandBuffer *buffer); void meta_wayland_buffer_ref_use_count (MetaWaylandBuffer *buffer); void meta_wayland_buffer_unref_use_count (MetaWaylandBuffer *buffer); CoglTexture * meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index cff4373ec..f3621a944 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -201,28 +201,9 @@ surface_set_buffer (MetaWaylandSurface *surface, return; if (surface->buffer) - { - wl_list_remove (&surface->buffer_destroy_listener.link); + surface_stop_using_buffer (surface); - surface_stop_using_buffer (surface); - meta_wayland_buffer_unref (surface->buffer); - } - - surface->buffer = buffer; - - if (surface->buffer) - { - meta_wayland_buffer_ref (surface->buffer); - wl_signal_add (&surface->buffer->destroy_signal, &surface->buffer_destroy_listener); - } -} - -static void -surface_handle_buffer_destroy (struct wl_listener *listener, void *data) -{ - MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener); - - surface_set_buffer (surface, NULL); + g_set_object (&surface->buffer, buffer); } static void @@ -1192,7 +1173,6 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface->resource = wl_resource_create (client, &wl_surface_interface, wl_resource_get_version (compositor_resource), id); wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor); - surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); wl_list_init (&surface->pending_frame_callback_list); diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 4a2c24422..a153176e7 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -153,7 +153,6 @@ struct _MetaWaylandSurface MetaWindow *window; MetaWaylandBuffer *buffer; gboolean using_buffer; - struct wl_listener buffer_destroy_listener; cairo_region_t *input_region; cairo_region_t *opaque_region; int scale;