[mutter] MetaWaylandSurface: Keep an extra buffer use count for role-less surfaces
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] MetaWaylandSurface: Keep an extra buffer use count for role-less surfaces
- Date: Tue, 29 Mar 2016 10:32:41 +0000 (UTC)
commit f44238a72f2879a2a9b13a50fd42752bb84ff1b9
Author: Jonas Ådahl <jadahl gmail com>
Date: Wed Mar 16 14:55:51 2016 +0800
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
src/wayland/meta-wayland-surface.c | 66 ++++++++++++++++++++++++++++++++----
src/wayland/meta-wayland-surface.h | 7 ++++
2 files changed, 66 insertions(+), 7 deletions(-)
---
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 7e1fb01..90ffd94 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -141,6 +141,10 @@ static void
meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role);
static void
+meta_wayland_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
+ MetaWaylandPendingState *pending);
+
+static void
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending);
@@ -163,6 +167,13 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
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;
}
else if (G_OBJECT_TYPE (surface->role) != role_type)
@@ -663,6 +674,19 @@ apply_pending_state (MetaWaylandSurface *surface,
MetaSurfaceActorWayland *surface_actor_wayland =
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)
{
gboolean switched_buffer;
@@ -708,13 +732,6 @@ apply_pending_state (MetaWaylandSurface *surface,
if (!cairo_region_is_empty (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_y += pending->dy;
@@ -752,8 +769,26 @@ apply_pending_state (MetaWaylandSurface *surface,
wl_list_insert_list (&surface->pending_frame_callback_list,
&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,
pending_state_signals[PENDING_STATE_SIGNAL_APPLIED],
0);
@@ -1147,6 +1182,12 @@ wl_surface_destructor (struct wl_resource *resource)
if (surface->window)
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)
meta_wayland_surface_unref_buffer_use_count (surface);
g_clear_object (&surface->buffer_ref.buffer);
@@ -2654,6 +2695,17 @@ meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *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
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
{
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index e7523d8..c817ed7 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -56,6 +56,8 @@ struct _MetaWaylandSurfaceRoleClass
GObjectClass parent_class;
void (*assigned) (MetaWaylandSurfaceRole *surface_role);
+ void (*pre_commit) (MetaWaylandSurfaceRole *surface_role,
+ MetaWaylandPendingState *pending);
void (*commit) (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending);
gboolean (*is_on_output) (MetaWaylandSurfaceRole *surface_role,
@@ -172,6 +174,11 @@ struct _MetaWaylandSurface
*/
struct wl_list pending_frame_callback_list;
+ /* Intermediate state for when no role has been assigned. */
+ struct {
+ MetaWaylandBuffer *buffer;
+ } unassigned;
+
struct {
const MetaWaylandDragDestFuncs *funcs;
} dnd;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]