mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
MetaWaylandSurface: Keep an extra buffer use count for role-less surfaces
Whether a surface needs to keep the committed wl_buffer un-released depends on what role the surface gets assigned to. For example a cursor role may need an unreleased shm buffer in order to create a hw cursor from it. In order to support this, keep a separate reference and use count to the buffer on behalf of the in the future assigned role, and release those references after the surface was assigned a role. A role that needs its own references and use counts, must in its assign function make sure to add those. https://bugzilla.gnome.org/show_bug.cgi?id=762828
This commit is contained in:
parent
10a0114856
commit
f44238a72f
@ -140,6 +140,10 @@ G_DEFINE_TYPE (MetaWaylandSurfaceRoleDND,
|
|||||||
static void
|
static void
|
||||||
meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role);
|
meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role);
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandPendingState *pending);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandPendingState *pending);
|
MetaWaylandPendingState *pending);
|
||||||
@ -163,6 +167,13 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
|||||||
|
|
||||||
meta_wayland_surface_role_assigned (surface->role);
|
meta_wayland_surface_role_assigned (surface->role);
|
||||||
|
|
||||||
|
/* Release the use count held on behalf of the just assigned role. */
|
||||||
|
if (surface->unassigned.buffer)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
|
g_clear_object (&surface->unassigned.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (G_OBJECT_TYPE (surface->role) != role_type)
|
else if (G_OBJECT_TYPE (surface->role) != role_type)
|
||||||
@ -663,6 +674,19 @@ apply_pending_state (MetaWaylandSurface *surface,
|
|||||||
MetaSurfaceActorWayland *surface_actor_wayland =
|
MetaSurfaceActorWayland *surface_actor_wayland =
|
||||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||||
|
|
||||||
|
if (surface->role)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_role_pre_commit (surface->role, pending);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pending->newly_attached && surface->unassigned.buffer)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
|
g_clear_object (&surface->unassigned.buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pending->newly_attached)
|
if (pending->newly_attached)
|
||||||
{
|
{
|
||||||
gboolean switched_buffer;
|
gboolean switched_buffer;
|
||||||
@ -708,13 +732,6 @@ apply_pending_state (MetaWaylandSurface *surface,
|
|||||||
if (!cairo_region_is_empty (pending->damage))
|
if (!cairo_region_is_empty (pending->damage))
|
||||||
surface_process_damage (surface, pending->damage);
|
surface_process_damage (surface, pending->damage);
|
||||||
|
|
||||||
/* If we have a buffer that we are not using, decrease the use count so it may
|
|
||||||
* be released if no-one else has a use-reference to it.
|
|
||||||
*/
|
|
||||||
if (pending->newly_attached &&
|
|
||||||
!surface->buffer_held && surface->buffer_ref.buffer)
|
|
||||||
meta_wayland_surface_unref_buffer_use_count (surface);
|
|
||||||
|
|
||||||
surface->offset_x += pending->dx;
|
surface->offset_x += pending->dx;
|
||||||
surface->offset_y += pending->dy;
|
surface->offset_y += pending->dy;
|
||||||
|
|
||||||
@ -752,8 +769,26 @@ apply_pending_state (MetaWaylandSurface *surface,
|
|||||||
wl_list_insert_list (&surface->pending_frame_callback_list,
|
wl_list_insert_list (&surface->pending_frame_callback_list,
|
||||||
&pending->frame_callback_list);
|
&pending->frame_callback_list);
|
||||||
wl_list_init (&pending->frame_callback_list);
|
wl_list_init (&pending->frame_callback_list);
|
||||||
|
|
||||||
|
if (pending->newly_attached)
|
||||||
|
{
|
||||||
|
/* The need to keep the wl_buffer from being released depends on what
|
||||||
|
* role the surface is given. That means we need to also keep a use
|
||||||
|
* count for wl_buffer's that are used by unassigned wl_surface's.
|
||||||
|
*/
|
||||||
|
g_set_object (&surface->unassigned.buffer, surface->buffer_ref.buffer);
|
||||||
|
if (surface->unassigned.buffer)
|
||||||
|
meta_wayland_surface_ref_buffer_use_count (surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we have a buffer that we are not using, decrease the use count so it may
|
||||||
|
* be released if no-one else has a use-reference to it.
|
||||||
|
*/
|
||||||
|
if (pending->newly_attached &&
|
||||||
|
!surface->buffer_held && surface->buffer_ref.buffer)
|
||||||
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
|
|
||||||
g_signal_emit (pending,
|
g_signal_emit (pending,
|
||||||
pending_state_signals[PENDING_STATE_SIGNAL_APPLIED],
|
pending_state_signals[PENDING_STATE_SIGNAL_APPLIED],
|
||||||
0);
|
0);
|
||||||
@ -1147,6 +1182,12 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||||||
if (surface->window)
|
if (surface->window)
|
||||||
destroy_window (surface);
|
destroy_window (surface);
|
||||||
|
|
||||||
|
if (surface->unassigned.buffer)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
|
g_clear_object (&surface->unassigned.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
if (surface->buffer_held)
|
if (surface->buffer_held)
|
||||||
meta_wayland_surface_unref_buffer_use_count (surface);
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
g_clear_object (&surface->buffer_ref.buffer);
|
g_clear_object (&surface->buffer_ref.buffer);
|
||||||
@ -2653,6 +2694,17 @@ meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
|||||||
META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->assigned (surface_role);
|
META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->assigned (surface_role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandPendingState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRoleClass *klass;
|
||||||
|
|
||||||
|
klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
|
||||||
|
if (klass->pre_commit)
|
||||||
|
klass->pre_commit (surface_role, pending);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandPendingState *pending)
|
MetaWaylandPendingState *pending)
|
||||||
|
@ -56,6 +56,8 @@ struct _MetaWaylandSurfaceRoleClass
|
|||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (*assigned) (MetaWaylandSurfaceRole *surface_role);
|
void (*assigned) (MetaWaylandSurfaceRole *surface_role);
|
||||||
|
void (*pre_commit) (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandPendingState *pending);
|
||||||
void (*commit) (MetaWaylandSurfaceRole *surface_role,
|
void (*commit) (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandPendingState *pending);
|
MetaWaylandPendingState *pending);
|
||||||
gboolean (*is_on_output) (MetaWaylandSurfaceRole *surface_role,
|
gboolean (*is_on_output) (MetaWaylandSurfaceRole *surface_role,
|
||||||
@ -172,6 +174,11 @@ struct _MetaWaylandSurface
|
|||||||
*/
|
*/
|
||||||
struct wl_list pending_frame_callback_list;
|
struct wl_list pending_frame_callback_list;
|
||||||
|
|
||||||
|
/* Intermediate state for when no role has been assigned. */
|
||||||
|
struct {
|
||||||
|
MetaWaylandBuffer *buffer;
|
||||||
|
} unassigned;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const MetaWaylandDragDestFuncs *funcs;
|
const MetaWaylandDragDestFuncs *funcs;
|
||||||
} dnd;
|
} dnd;
|
||||||
|
Loading…
Reference in New Issue
Block a user