summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2020-04-27 15:43:19 +0200
committerJonas Ådahl <jadahl@gmail.com>2020-09-30 09:51:43 +0200
commitf7c997d801b92f1216ba78e9f78a4cc04de51ce3 (patch)
treeb756d0206c33bda45994f448d7930121e6547217
parent231c2649a705d1831e976a41431a33a0337c33e2 (diff)
downloadmutter-f7c997d801b92f1216ba78e9f78a4cc04de51ce3.tar.gz
wayland: Drive frame callbacks from stage updates
Don't tie frame callbacks to actor painting, as it may end up in situations where we miss sending frame callbacks when we should have. An example of this is when a surface is partially off screen, and then reports damage that is fully off screen. When this happen, we are likely not to repaint anything, thus we won't send any frame callbacks even though it's "suitable" for rendering again, as the surface is not on a separate workspace or fully obscured. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/817 Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1152 https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1218 (cherry picked from commit 066bc5986d04204788880e372f259d6048cc1ae6)
-rw-r--r--src/compositor/meta-surface-actor-wayland.c35
-rw-r--r--src/wayland/meta-wayland-actor-surface.c66
-rw-r--r--src/wayland/meta-wayland-actor-surface.h3
-rw-r--r--src/wayland/meta-wayland-cursor-surface.c4
-rw-r--r--src/wayland/meta-wayland-dnd-surface.c10
-rw-r--r--src/wayland/meta-wayland-legacy-xdg-shell.c8
-rw-r--r--src/wayland/meta-wayland-private.h2
-rw-r--r--src/wayland/meta-wayland-subsurface.c3
-rw-r--r--src/wayland/meta-wayland-surface.c38
-rw-r--r--src/wayland/meta-wayland-surface.h9
-rw-r--r--src/wayland/meta-wayland-wl-shell.c3
-rw-r--r--src/wayland/meta-wayland-xdg-shell.c15
-rw-r--r--src/wayland/meta-wayland.c56
-rw-r--r--src/wayland/meta-wayland.h7
14 files changed, 122 insertions, 137 deletions
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index 2e540084e..e8d946e98 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -42,7 +42,6 @@ struct _MetaSurfaceActorWayland
MetaSurfaceActor parent;
MetaWaylandSurface *surface;
- struct wl_list frame_callback_list;
};
G_DEFINE_TYPE (MetaSurfaceActorWayland,
@@ -72,37 +71,10 @@ meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
return meta_shaped_texture_is_opaque (stex);
}
-void
-meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
- struct wl_list *frame_callbacks)
-{
- wl_list_insert_list (&self->frame_callback_list, frame_callbacks);
-}
-
-static void
-meta_surface_actor_wayland_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context)
-{
- MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
-
- if (self->surface &&
- !meta_surface_actor_is_obscured (META_SURFACE_ACTOR (actor)))
- {
- MetaWaylandCompositor *compositor = self->surface->compositor;
-
- wl_list_insert_list (&compositor->frame_callbacks, &self->frame_callback_list);
- wl_list_init (&self->frame_callback_list);
- }
-
- CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor,
- paint_context);
-}
-
static void
meta_surface_actor_wayland_dispose (GObject *object)
{
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
- MetaWaylandFrameCallback *cb, *next;
MetaShapedTexture *stex;
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
@@ -116,9 +88,6 @@ meta_surface_actor_wayland_dispose (GObject *object)
self->surface = NULL;
}
- wl_list_for_each_safe (cb, next, &self->frame_callback_list, link)
- wl_resource_destroy (cb->resource);
-
G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object);
}
@@ -126,11 +95,8 @@ static void
meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
{
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- actor_class->paint = meta_surface_actor_wayland_paint;
-
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque;
@@ -150,7 +116,6 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
g_assert (meta_is_wayland_compositor ());
- wl_list_init (&self->frame_callback_list);
self->surface = surface;
g_object_add_weak_pointer (G_OBJECT (self->surface),
(gpointer *) &self->surface);
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
index 6b030fa7b..f631f63ce 100644
--- a/src/wayland/meta-wayland-actor-surface.c
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -104,9 +104,15 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
- meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
- &surface->pending_frame_callback_list);
- wl_list_init (&surface->pending_frame_callback_list);
+ if (wl_list_empty (&surface->unassigned.pending_frame_callback_list))
+ return;
+
+ wl_list_insert_list (priv->frame_callback_list.prev,
+ &surface->unassigned.pending_frame_callback_list);
+ wl_list_init (&surface->unassigned.pending_frame_callback_list);
+
+ meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
+ surface);
}
void
@@ -115,18 +121,37 @@ meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (actor_surface);
- MetaSurfaceActorWayland *surface_actor_wayland =
- META_SURFACE_ACTOR_WAYLAND (priv->actor);
+ MetaWaylandSurfaceRole *surface_role =
+ META_WAYLAND_SURFACE_ROLE (actor_surface);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
- if (!priv->actor)
+ if (wl_list_empty (&pending->frame_callback_list))
return;
- meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland,
- &priv->frame_callback_list);
- wl_list_init (&priv->frame_callback_list);
- meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland,
- &pending->frame_callback_list);
+ wl_list_insert_list (priv->frame_callback_list.prev,
+ &pending->frame_callback_list);
wl_list_init (&pending->frame_callback_list);
+
+ meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
+ surface);
+}
+
+void
+meta_wayland_actor_surface_emit_frame_callbacks (MetaWaylandActorSurface *actor_surface,
+ uint32_t timestamp_ms)
+{
+ MetaWaylandActorSurfacePrivate *priv =
+ meta_wayland_actor_surface_get_instance_private (actor_surface);
+
+ while (!wl_list_empty (&priv->frame_callback_list))
+ {
+ MetaWaylandFrameCallback *callback =
+ wl_container_of (priv->frame_callback_list.next, callback, link);
+
+ wl_callback_send_done (callback->resource, timestamp_ms);
+ wl_resource_destroy (callback->resource);
+ }
}
double
@@ -262,18 +287,17 @@ meta_wayland_actor_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (actor_surface);
- if (!priv->actor)
+ if (!wl_list_empty (&pending->frame_callback_list) &&
+ priv->actor &&
+ !meta_surface_actor_is_obscured (priv->actor))
{
- wl_list_insert_list (&priv->frame_callback_list,
- &pending->frame_callback_list);
- wl_list_init (&pending->frame_callback_list);
- return;
- }
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaBackend *backend = surface->compositor->backend;
+ ClutterActor *stage = meta_backend_get_stage (backend);
- if (!wl_list_empty (&pending->frame_callback_list) &&
- cairo_region_is_empty (pending->surface_damage) &&
- cairo_region_is_empty (pending->buffer_damage))
- clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->actor));
+ clutter_stage_schedule_update (CLUTTER_STAGE (stage));
+ }
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
diff --git a/src/wayland/meta-wayland-actor-surface.h b/src/wayland/meta-wayland-actor-surface.h
index caa3cbe31..bd0cca275 100644
--- a/src/wayland/meta-wayland-actor-surface.h
+++ b/src/wayland/meta-wayland-actor-surface.h
@@ -48,4 +48,7 @@ void meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surf
void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
MetaWaylandSurfaceState *pending);
+void meta_wayland_actor_surface_emit_frame_callbacks (MetaWaylandActorSurface *actor_surface,
+ uint32_t timestamp_ms);
+
#endif /* META_WAYLAND_ACTOR_SURFACE_H */
diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c
index d8ac1413e..95f8186df 100644
--- a/src/wayland/meta-wayland-cursor-surface.c
+++ b/src/wayland/meta-wayland-cursor-surface.c
@@ -124,8 +124,8 @@ meta_wayland_cursor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
meta_wayland_cursor_surface_get_instance_private (cursor_surface);
wl_list_insert_list (&priv->frame_callbacks,
- &surface->pending_frame_callback_list);
- wl_list_init (&surface->pending_frame_callback_list);
+ &surface->unassigned.pending_frame_callback_list);
+ wl_list_init (&surface->unassigned.pending_frame_callback_list);
}
static void
diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c
index b735c1388..c3b0f7557 100644
--- a/src/wayland/meta-wayland-dnd-surface.c
+++ b/src/wayland/meta-wayland-dnd-surface.c
@@ -23,6 +23,7 @@
#include "backends/meta-logical-monitor.h"
#include "compositor/meta-feedback-actor-private.h"
+#include "wayland/meta-wayland.h"
struct _MetaWaylandSurfaceRoleDND
{
@@ -42,7 +43,11 @@ dnd_surface_assigned (MetaWaylandSurfaceRole *surface_role)
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
- meta_wayland_surface_queue_pending_frame_callbacks (surface);
+ if (wl_list_empty (&surface->unassigned.pending_frame_callback_list))
+ return;
+
+ meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
+ surface);
}
static void
@@ -56,7 +61,8 @@ dnd_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceRoleClass *surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_dnd_parent_class);
- meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
+ meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
+ surface);
surface_role_dnd->pending_offset_x = pending->dx;
surface_role_dnd->pending_offset_y = pending->dy;
diff --git a/src/wayland/meta-wayland-legacy-xdg-shell.c b/src/wayland/meta-wayland-legacy-xdg-shell.c
index ec997b5e0..e8eda4ca2 100644
--- a/src/wayland/meta-wayland-legacy-xdg-shell.c
+++ b/src/wayland/meta-wayland-legacy-xdg-shell.c
@@ -658,6 +658,8 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel);
MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv =
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
+ MetaWaylandActorSurface *actor_surface =
+ META_WAYLAND_ACTOR_SURFACE (xdg_surface);
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
@@ -666,7 +668,7 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
window = meta_wayland_surface_get_window (surface);
if (!window)
{
- meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
+ meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
return;
}
@@ -1251,14 +1253,10 @@ meta_wayland_zxdg_surface_v6_send_configure (MetaWaylandZxdgSurfaceV6 *xdg
static void
zxdg_surface_v6_destructor (struct wl_resource *resource)
{
- MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);
MetaWaylandZxdgSurfaceV6 *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandZxdgSurfaceV6Private *priv =
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
- meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
- surface);
-
priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces,
xdg_surface);
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index a7e5604fc..727009b07 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -79,7 +79,7 @@ struct _MetaWaylandCompositor
struct wl_display *wayland_display;
char *display_name;
GHashTable *outputs;
- struct wl_list frame_callbacks;
+ GList *frame_callback_surfaces;
MetaXWaylandManager xwayland_manager;
diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c
index 3eb0ae289..054822dbb 100644
--- a/src/wayland/meta-wayland-subsurface.c
+++ b/src/wayland/meta-wayland-subsurface.c
@@ -363,9 +363,6 @@ wl_subsurface_destructor (struct wl_resource *resource)
{
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
- meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
- surface);
-
g_node_unlink (surface->subsurface_branch_node);
unparent_actor (surface);
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index a696bdc1e..f6cfc2ac0 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -356,15 +356,6 @@ surface_process_damage (MetaWaylandSurface *surface,
cairo_region_destroy (transformed_region);
}
-void
-meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
- MetaWaylandSurfaceState *pending)
-{
- wl_list_insert_list (&surface->compositor->frame_callbacks,
- &pending->frame_callback_list);
- wl_list_init (&pending->frame_callback_list);
-}
-
MetaWaylandBuffer *
meta_wayland_surface_get_buffer (MetaWaylandSurface *surface)
{
@@ -597,15 +588,6 @@ meta_wayland_surface_state_class_init (MetaWaylandSurfaceStateClass *klass)
G_TYPE_NONE, 0);
}
-void
-meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
- MetaWaylandSurfaceState *pending)
-{
- wl_list_insert_list (&surface->pending_frame_callback_list,
- &pending->frame_callback_list);
- wl_list_init (&pending->frame_callback_list);
-}
-
static void
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
MetaWaylandSurfaceState *state)
@@ -735,7 +717,9 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
}
else
{
- meta_wayland_surface_cache_pending_frame_callbacks (surface, state);
+ wl_list_insert_list (surface->unassigned.pending_frame_callback_list.prev,
+ &state->frame_callback_list);
+ wl_list_init (&state->frame_callback_list);
if (state->newly_attached)
{
@@ -1295,14 +1279,16 @@ wl_surface_destructor (struct wl_resource *resource)
if (surface->input_region)
cairo_region_destroy (surface->input_region);
- meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
+ meta_wayland_compositor_remove_frame_callback_surface (compositor, surface);
g_hash_table_foreach (surface->outputs_to_destroy_notify_id,
surface_output_disconnect_signal,
surface);
g_hash_table_unref (surface->outputs_to_destroy_notify_id);
- wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
+ wl_list_for_each_safe (cb, next,
+ &surface->unassigned.pending_frame_callback_list,
+ link)
wl_resource_destroy (cb->resource);
if (surface->resource)
@@ -1349,7 +1335,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
surface,
wl_surface_destructor);
- wl_list_init (&surface->pending_frame_callback_list);
+ wl_list_init (&surface->unassigned.pending_frame_callback_list);
surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL);
surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL);
@@ -1817,14 +1803,6 @@ meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role)
return priv->surface;
}
-void
-meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface)
-{
- wl_list_insert_list (&surface->compositor->frame_callbacks,
- &surface->pending_frame_callback_list);
- wl_list_init (&surface->pending_frame_callback_list);
-}
-
cairo_region_t *
meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface)
{
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 4e1caa041..222d60dbf 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -166,13 +166,9 @@ struct _MetaWaylandSurface
/* Buffer renderer state. */
gboolean buffer_held;
- /* List of pending frame callbacks that needs to stay queued longer than one
- * commit sequence, such as when it has not yet been assigned a role.
- */
- struct wl_list pending_frame_callback_list;
-
/* Intermediate state for when no role has been assigned. */
struct {
+ struct wl_list pending_frame_callback_list;
MetaWaylandBuffer *buffer;
} unassigned;
@@ -286,9 +282,6 @@ gboolean meta_wayland_surface_should_cache_state (MetaWaylandSurface
MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
-void meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
- MetaWaylandSurfaceState *pending);
-
void meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface);
void meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
diff --git a/src/wayland/meta-wayland-wl-shell.c b/src/wayland/meta-wayland-wl-shell.c
index 3215f4394..5b52f80f7 100644
--- a/src/wayland/meta-wayland-wl-shell.c
+++ b/src/wayland/meta-wayland-wl-shell.c
@@ -103,9 +103,6 @@ wl_shell_surface_destructor (struct wl_resource *resource)
surface_from_wl_shell_surface_resource (resource);
GList *l;
- meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
- surface);
-
if (wl_shell_surface->popup)
meta_wayland_popup_dismiss (wl_shell_surface->popup);
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
index 8bc0f88eb..2c0c20b92 100644
--- a/src/wayland/meta-wayland-xdg-shell.c
+++ b/src/wayland/meta-wayland-xdg-shell.c
@@ -744,6 +744,8 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_toplevel);
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
+ MetaWaylandActorSurface *actor_surface =
+ META_WAYLAND_ACTOR_SURFACE (xdg_toplevel);
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
@@ -752,15 +754,12 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
window = meta_wayland_surface_get_window (surface);
if (!window)
{
- meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
+ meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
return;
}
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
{
- MetaWaylandActorSurface *actor_surface =
- META_WAYLAND_ACTOR_SURFACE (xdg_toplevel);
-
meta_wayland_xdg_surface_reset (xdg_surface);
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface,
pending);
@@ -1114,6 +1113,8 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
+ MetaWaylandActorSurface *actor_surface =
+ META_WAYLAND_ACTOR_SURFACE (xdg_popup);
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
@@ -1124,7 +1125,7 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
{
meta_wayland_xdg_surface_reset (xdg_surface);
- meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
+ meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
return;
}
@@ -1419,14 +1420,10 @@ meta_wayland_xdg_surface_send_configure (MetaWaylandXdgSurface *xdg_sur
static void
xdg_surface_destructor (struct wl_resource *resource)
{
- MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);
MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandXdgSurfacePrivate *priv =
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
- meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
- surface);
-
priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces,
xdg_surface);
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index b37d9fdcf..e4b09cbfc 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -197,15 +197,35 @@ meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
void
meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor)
{
- gint64 current_time = g_get_monotonic_time ();
+ GList *l;
+ int64_t now_us;
- while (!wl_list_empty (&compositor->frame_callbacks))
+ now_us = g_get_monotonic_time ();
+
+ l = compositor->frame_callback_surfaces;
+ while (l)
{
- MetaWaylandFrameCallback *callback =
- wl_container_of (compositor->frame_callbacks.next, callback, link);
+ GList *l_cur = l;
+ MetaWaylandSurface *surface = l->data;
+ MetaSurfaceActor *actor;
+ MetaWaylandActorSurface *actor_surface;
+
+ l = l->next;
+
+ actor = meta_wayland_surface_get_actor (surface);
+ if (!actor)
+ continue;
+
+ if (!clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)) &&
+ meta_surface_actor_is_obscured (actor))
+ continue;
- wl_callback_send_done (callback->resource, current_time / 1000);
- wl_resource_destroy (callback->resource);
+ actor_surface = META_WAYLAND_ACTOR_SURFACE (surface->role);
+ meta_wayland_actor_surface_emit_frame_callbacks (actor_surface,
+ now_us / 1000);
+
+ compositor->frame_callback_surfaces =
+ g_list_delete_link (compositor->frame_callback_surfaces, l_cur);
}
}
@@ -252,16 +272,22 @@ meta_wayland_compositor_update_key_state (MetaWaylandCompositor *compositor,
}
void
-meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor,
- MetaWaylandSurface *surface)
+meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor,
+ MetaWaylandSurface *surface)
{
- MetaWaylandFrameCallback *callback, *next;
+ if (g_list_find (compositor->frame_callback_surfaces, surface))
+ return;
- wl_list_for_each_safe (callback, next, &compositor->frame_callbacks, link)
- {
- if (callback->surface == surface)
- wl_resource_destroy (callback->resource);
- }
+ compositor->frame_callback_surfaces =
+ g_list_prepend (compositor->frame_callback_surfaces, surface);
+}
+
+void
+meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor,
+ MetaWaylandSurface *surface)
+{
+ compositor->frame_callback_surfaces =
+ g_list_remove (compositor->frame_callback_surfaces, surface);
}
static void
@@ -313,8 +339,6 @@ meta_wayland_log_func (const char *fmt,
static void
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
{
- wl_list_init (&compositor->frame_callbacks);
-
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
wl_log_set_handler_server (meta_wayland_log_func);
diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h
index 4164563e8..3549fb2d5 100644
--- a/src/wayland/meta-wayland.h
+++ b/src/wayland/meta-wayland.h
@@ -62,8 +62,11 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp
void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor);
-void meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor,
- MetaWaylandSurface *surface);
+void meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor,
+ MetaWaylandSurface *surface);
+
+void meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor,
+ MetaWaylandSurface *surface);
META_EXPORT_TEST
const char *meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor);