mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 17:40:40 -05:00
wayland: release buffer after processing commit
When a client is ready for the compositor to read a surface's shared memory buffer, it tells the compositor via wl_surface_commit. From that point forward, the baton is given to the compositor: it knows it can read the buffer without worring about the client making changes out from under it. After the compositor has uploaded the pixel contents to the video card it is supposed to release the buffer back to the client so that the client can reuse it for future use. At the moment, mutter only releases the buffer when a new buffer is attached. This is problematic, since it means the client has to have a second buffer prepared before the compositor gives the first one back. Preparing the second buffer potentially involves copying megabytes of pixel data, so that's suboptimal, and there's no reason mutter couldn't release the buffer earlier. This commit changes mutter to release a surface's buffer as soon as it's done processing the commit request. https://bugzilla.gnome.org/show_bug.cgi?id=761312
This commit is contained in:
parent
3cdcd3e9c1
commit
0165cb6974
@ -54,10 +54,31 @@ meta_wayland_buffer_unref (MetaWaylandBuffer *buffer)
|
||||
if (buffer->ref_count == 0)
|
||||
{
|
||||
g_clear_pointer (&buffer->texture, cogl_object_unref);
|
||||
wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
|
||||
|
||||
if (buffer->accessible)
|
||||
meta_wayland_buffer_release_control (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_take_control (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (buffer->accessible)
|
||||
meta_fatal ("buffer control taken twice");
|
||||
|
||||
buffer->accessible = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_release_control (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (!buffer->accessible)
|
||||
meta_fatal ("buffer released when not in control");
|
||||
|
||||
wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
|
||||
buffer->accessible = FALSE;
|
||||
}
|
||||
|
||||
MetaWaylandBuffer *
|
||||
meta_wayland_buffer_from_resource (struct wl_resource *resource)
|
||||
{
|
||||
@ -93,6 +114,9 @@ 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");
|
||||
|
||||
if (buffer->texture)
|
||||
goto out;
|
||||
|
||||
@ -126,6 +150,9 @@ 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");
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||
|
||||
if (shm_buffer)
|
||||
|
@ -39,11 +39,15 @@ struct _MetaWaylandBuffer
|
||||
|
||||
CoglTexture *texture;
|
||||
uint32_t ref_count;
|
||||
|
||||
uint32_t accessible : 1;
|
||||
};
|
||||
|
||||
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);
|
||||
CoglTexture * meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
cairo_region_t *region);
|
||||
|
@ -596,6 +596,7 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
|
||||
if (pending->buffer)
|
||||
{
|
||||
meta_wayland_buffer_take_control (pending->buffer);
|
||||
CoglTexture *texture = meta_wayland_buffer_ensure_texture (pending->buffer);
|
||||
meta_surface_actor_wayland_set_texture (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), texture);
|
||||
}
|
||||
@ -607,6 +608,9 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
if (!cairo_region_is_empty (pending->damage))
|
||||
surface_process_damage (surface, pending->damage);
|
||||
|
||||
if (pending->buffer)
|
||||
meta_wayland_buffer_release_control (pending->buffer);
|
||||
|
||||
surface->offset_x += pending->dx;
|
||||
surface->offset_y += pending->dy;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user