wayland: change accessible boolean to use_count counter
Since a buffer can be used by multiple surfaces at once, we need to release the buffer only after all surfaces are finished with it. Currently we track whether or not to release the buffer based on the accessible boolean. This commit changes it to a counter to accomodate multiple users. Also, each surface needs to know whether not it is done with the buffer, so this commit adds a buffer_used boolean to the surface state. https://bugzilla.gnome.org/show_bug.cgi?id=761613
This commit is contained in:
parent
e097bc8353
commit
bed82427c6
@ -51,32 +51,30 @@ void
|
||||
meta_wayland_buffer_unref (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
buffer->ref_count--;
|
||||
|
||||
if (buffer->ref_count == 0)
|
||||
{
|
||||
g_clear_pointer (&buffer->texture, cogl_object_unref);
|
||||
g_warn_if_fail (buffer->use_count == 0);
|
||||
|
||||
if (buffer->accessible)
|
||||
meta_wayland_buffer_release_control (buffer);
|
||||
g_clear_pointer (&buffer->texture, cogl_object_unref);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_take_control (MetaWaylandBuffer *buffer)
|
||||
meta_wayland_buffer_ref_use_count (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (buffer->accessible)
|
||||
meta_fatal ("buffer control taken twice");
|
||||
|
||||
buffer->accessible = TRUE;
|
||||
buffer->use_count++;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_release_control (MetaWaylandBuffer *buffer)
|
||||
meta_wayland_buffer_unref_use_count (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (!buffer->accessible)
|
||||
meta_fatal ("buffer released when not in control");
|
||||
g_return_if_fail (buffer->use_count != 0);
|
||||
|
||||
buffer->use_count--;
|
||||
|
||||
if (buffer->use_count == 0)
|
||||
wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
|
||||
buffer->accessible = FALSE;
|
||||
}
|
||||
|
||||
MetaWaylandBuffer *
|
||||
@ -114,8 +112,7 @@ meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer)
|
||||
CoglTexture *texture;
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
|
||||
if (!buffer->accessible)
|
||||
meta_warning ("attempted to process damage on uncommitted buffer");
|
||||
g_return_val_if_fail (buffer->use_count != 0, NULL);
|
||||
|
||||
if (buffer->texture)
|
||||
goto out;
|
||||
@ -150,8 +147,7 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
{
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
|
||||
if (!buffer->accessible)
|
||||
meta_warning ("attempted to process damage on uncommitted buffer");
|
||||
g_return_if_fail (buffer->use_count != 0);
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||
|
||||
|
@ -39,15 +39,14 @@ struct _MetaWaylandBuffer
|
||||
|
||||
CoglTexture *texture;
|
||||
uint32_t ref_count;
|
||||
|
||||
uint32_t accessible : 1;
|
||||
uint32_t use_count;
|
||||
};
|
||||
|
||||
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_take_control (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_release_control (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);
|
||||
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
cairo_region_t *region);
|
||||
|
@ -174,6 +174,25 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
surface_use_buffer (MetaWaylandSurface *surface)
|
||||
{
|
||||
g_return_if_fail (!surface->using_buffer);
|
||||
|
||||
meta_wayland_buffer_ref_use_count (surface->buffer);
|
||||
surface->using_buffer = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_stop_using_buffer (MetaWaylandSurface *surface)
|
||||
{
|
||||
if (!surface->using_buffer)
|
||||
return;
|
||||
|
||||
meta_wayland_buffer_unref_use_count (surface->buffer);
|
||||
surface->using_buffer = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_set_buffer (MetaWaylandSurface *surface,
|
||||
MetaWaylandBuffer *buffer)
|
||||
@ -184,6 +203,8 @@ surface_set_buffer (MetaWaylandSurface *surface,
|
||||
if (surface->buffer)
|
||||
{
|
||||
wl_list_remove (&surface->buffer_destroy_listener.link);
|
||||
|
||||
surface_stop_using_buffer (surface);
|
||||
meta_wayland_buffer_unref (surface->buffer);
|
||||
}
|
||||
|
||||
@ -657,11 +678,11 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
|
||||
surface_set_buffer (surface, pending->buffer);
|
||||
|
||||
if (pending->buffer)
|
||||
if (pending->buffer && !surface->using_buffer)
|
||||
{
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (pending->buffer->resource);
|
||||
|
||||
meta_wayland_buffer_take_control (pending->buffer);
|
||||
surface_use_buffer (surface);
|
||||
CoglTexture *texture = meta_wayland_buffer_ensure_texture (pending->buffer);
|
||||
meta_surface_actor_wayland_set_texture (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), texture);
|
||||
|
||||
@ -679,7 +700,7 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
surface_process_damage (surface, pending->damage);
|
||||
|
||||
if (release_new_buffer)
|
||||
meta_wayland_buffer_release_control (pending->buffer);
|
||||
surface_stop_using_buffer (surface);
|
||||
|
||||
surface->offset_x += pending->dx;
|
||||
surface->offset_y += pending->dy;
|
||||
|
@ -152,6 +152,7 @@ struct _MetaWaylandSurface
|
||||
MetaWaylandSurfaceRole *role;
|
||||
MetaWindow *window;
|
||||
MetaWaylandBuffer *buffer;
|
||||
gboolean using_buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
cairo_region_t *input_region;
|
||||
cairo_region_t *opaque_region;
|
||||
|
Loading…
Reference in New Issue
Block a user