You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1046 lines
42 KiB
1046 lines
42 KiB
2 years ago
|
From 4232f2056cd31811d047104d1223f3e5ced4b107 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||
|
Date: Thu, 16 Apr 2020 19:42:03 +0200
|
||
|
Subject: [PATCH 1/5] clutter/stage: Make clutter_stage_schedule_update()
|
||
|
always schedule
|
||
|
|
||
|
We could call clutter_stage_schedule_update() and it wouldn't actually
|
||
|
schedule anything, as the master frame clock only tries to reschedule if
|
||
|
1) there is an active timeline, 2) there are pending relayouts, 3) there
|
||
|
are pending redraws, or 4) there are pending events. Thus, a call to
|
||
|
clutter_stage_schedule_update() didn't have any effect if it was called
|
||
|
at the wrong time.
|
||
|
|
||
|
Fix this by adding a boolean state "needs_update" to the stage, set on
|
||
|
clutter_stage_schedule_update() and cleared on
|
||
|
_clutter_stage_do_update(), that will make the master clock reschedule
|
||
|
an update if it is TRUE.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1218
|
||
|
(cherry picked from commit b8003807b0772e97354302b5cc2825e0b22c6c83)
|
||
|
---
|
||
|
clutter/clutter/clutter-stage.c | 10 +++++++++-
|
||
|
1 file changed, 9 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
|
||
|
index aaa77d9ede..5a914a3d0b 100644
|
||
|
--- a/clutter/clutter/clutter-stage.c
|
||
|
+++ b/clutter/clutter/clutter-stage.c
|
||
|
@@ -152,6 +152,8 @@ struct _ClutterStagePrivate
|
||
|
|
||
|
int update_freeze_count;
|
||
|
|
||
|
+ gboolean needs_update;
|
||
|
+
|
||
|
guint relayout_pending : 1;
|
||
|
guint redraw_pending : 1;
|
||
|
guint is_fullscreen : 1;
|
||
|
@@ -1074,7 +1076,9 @@ _clutter_stage_needs_update (ClutterStage *stage)
|
||
|
|
||
|
priv = stage->priv;
|
||
|
|
||
|
- return priv->relayout_pending || priv->redraw_pending;
|
||
|
+ return priv->relayout_pending ||
|
||
|
+ priv->needs_update ||
|
||
|
+ priv->redraw_pending;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
@@ -1232,6 +1236,8 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||
|
|
||
|
priv->stage_was_relayout = FALSE;
|
||
|
|
||
|
+ priv->needs_update = FALSE;
|
||
|
+
|
||
|
/* if the stage is being destroyed, or if the destruction already
|
||
|
* happened and we don't have an StageWindow any more, then we
|
||
|
* should bail out
|
||
|
@@ -4080,6 +4086,8 @@ _clutter_stage_schedule_update (ClutterStage *stage)
|
||
|
if (stage_window == NULL)
|
||
|
return;
|
||
|
|
||
|
+ stage->priv->needs_update = TRUE;
|
||
|
+
|
||
|
return _clutter_stage_window_schedule_update (stage_window,
|
||
|
stage->priv->sync_delay);
|
||
|
}
|
||
|
--
|
||
|
2.31.1
|
||
|
|
||
|
|
||
|
From 2d4453cfdcaf0c6a9f492d2c2395dbfc8cf833db Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||
|
Date: Thu, 16 Apr 2020 19:11:37 +0200
|
||
|
Subject: [PATCH 2/5] clutter/stage: Make clutter_stage_schedule_update()
|
||
|
public API
|
||
|
|
||
|
It's effectively used by mutter by abusing a ClutterTimeline to scedule
|
||
|
updates. Timelines are not really suited in places that is done, as it
|
||
|
is really just about getting a single new update scheduled whenever
|
||
|
suitable, so expose the API so we can use it directly.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1218
|
||
|
(cherry picked from commit 99c9a14bc8058830232cd4e07c7bb897e84a8c9c)
|
||
|
---
|
||
|
clutter/clutter/clutter-master-clock-default.c | 4 ++--
|
||
|
clutter/clutter/clutter-stage-private.h | 1 -
|
||
|
clutter/clutter/clutter-stage.c | 16 ++++++++--------
|
||
|
clutter/clutter/clutter-stage.h | 3 +++
|
||
|
4 files changed, 13 insertions(+), 11 deletions(-)
|
||
|
|
||
|
diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c
|
||
|
index 0647c3a7fd..de7a1e2f4d 100644
|
||
|
--- a/clutter/clutter/clutter-master-clock-default.c
|
||
|
+++ b/clutter/clutter/clutter-master-clock-default.c
|
||
|
@@ -206,7 +206,7 @@ master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock)
|
||
|
stages = clutter_stage_manager_peek_stages (stage_manager);
|
||
|
|
||
|
for (l = stages; l != NULL; l = l->next)
|
||
|
- _clutter_stage_schedule_update (l->data);
|
||
|
+ clutter_stage_schedule_update (l->data);
|
||
|
}
|
||
|
|
||
|
static GSList *
|
||
|
@@ -259,7 +259,7 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
|
||
|
if (master_clock->timelines ||
|
||
|
_clutter_stage_has_queued_events (l->data) ||
|
||
|
_clutter_stage_needs_update (l->data))
|
||
|
- _clutter_stage_schedule_update (l->data);
|
||
|
+ clutter_stage_schedule_update (l->data);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
|
||
|
index 42474687ad..ea0ce5ec72 100644
|
||
|
--- a/clutter/clutter/clutter-stage-private.h
|
||
|
+++ b/clutter/clutter/clutter-stage-private.h
|
||
|
@@ -70,7 +70,6 @@ void _clutter_stage_queue_event (ClutterStage *stage,
|
||
|
gboolean _clutter_stage_has_queued_events (ClutterStage *stage);
|
||
|
void _clutter_stage_process_queued_events (ClutterStage *stage);
|
||
|
void _clutter_stage_update_input_devices (ClutterStage *stage);
|
||
|
-void _clutter_stage_schedule_update (ClutterStage *stage);
|
||
|
gint64 _clutter_stage_get_update_time (ClutterStage *stage);
|
||
|
void _clutter_stage_clear_update_time (ClutterStage *stage);
|
||
|
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
|
||
|
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
|
||
|
index 5a914a3d0b..74ff8b1337 100644
|
||
|
--- a/clutter/clutter/clutter-stage.c
|
||
|
+++ b/clutter/clutter/clutter-stage.c
|
||
|
@@ -921,7 +921,7 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
||
|
{
|
||
|
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
|
||
|
_clutter_master_clock_start_running (master_clock);
|
||
|
- _clutter_stage_schedule_update (stage);
|
||
|
+ clutter_stage_schedule_update (stage);
|
||
|
}
|
||
|
|
||
|
/* if needed, update the state of the input device of the event.
|
||
|
@@ -1295,7 +1295,7 @@ clutter_stage_real_queue_relayout (ClutterActor *self)
|
||
|
|
||
|
if (!priv->relayout_pending)
|
||
|
{
|
||
|
- _clutter_stage_schedule_update (stage);
|
||
|
+ clutter_stage_schedule_update (stage);
|
||
|
priv->relayout_pending = TRUE;
|
||
|
}
|
||
|
|
||
|
@@ -3788,7 +3788,7 @@ clutter_stage_ensure_redraw (ClutterStage *stage)
|
||
|
priv = stage->priv;
|
||
|
|
||
|
if (!priv->relayout_pending && !priv->redraw_pending)
|
||
|
- _clutter_stage_schedule_update (stage);
|
||
|
+ clutter_stage_schedule_update (stage);
|
||
|
|
||
|
priv->relayout_pending = TRUE;
|
||
|
priv->redraw_pending = TRUE;
|
||
|
@@ -4069,13 +4069,13 @@ clutter_stage_get_minimum_size (ClutterStage *stage,
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
- * _clutter_stage_schedule_update:
|
||
|
- * @window: a #ClutterStage actor
|
||
|
+ * clutter_stage_schedule_update:
|
||
|
+ * @stage: a #ClutterStage actor
|
||
|
*
|
||
|
* Schedules a redraw of the #ClutterStage at the next optimal timestamp.
|
||
|
*/
|
||
|
void
|
||
|
-_clutter_stage_schedule_update (ClutterStage *stage)
|
||
|
+clutter_stage_schedule_update (ClutterStage *stage)
|
||
|
{
|
||
|
ClutterStageWindow *stage_window;
|
||
|
|
||
|
@@ -4097,7 +4097,7 @@ _clutter_stage_schedule_update (ClutterStage *stage)
|
||
|
* @stage: a #ClutterStage actor
|
||
|
*
|
||
|
* Returns the earliest time in which the stage is ready to update. The update
|
||
|
- * time is set when _clutter_stage_schedule_update() is called. This can then
|
||
|
+ * time is set when clutter_stage_schedule_update() is called. This can then
|
||
|
* be used by e.g. the #ClutterMasterClock to know when the stage needs to be
|
||
|
* redrawn.
|
||
|
*
|
||
|
@@ -4267,7 +4267,7 @@ _clutter_stage_queue_actor_redraw (ClutterStage *stage,
|
||
|
|
||
|
CLUTTER_NOTE (PAINT, "First redraw request");
|
||
|
|
||
|
- _clutter_stage_schedule_update (stage);
|
||
|
+ clutter_stage_schedule_update (stage);
|
||
|
priv->redraw_pending = TRUE;
|
||
|
|
||
|
master_clock = _clutter_master_clock_get_default ();
|
||
|
diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h
|
||
|
index 9da63d211d..53e37ae3bc 100644
|
||
|
--- a/clutter/clutter/clutter-stage.h
|
||
|
+++ b/clutter/clutter/clutter-stage.h
|
||
|
@@ -265,6 +265,9 @@ CLUTTER_EXPORT
|
||
|
void clutter_stage_skip_sync_delay (ClutterStage *stage);
|
||
|
#endif
|
||
|
|
||
|
+CLUTTER_EXPORT
|
||
|
+void clutter_stage_schedule_update (ClutterStage *stage);
|
||
|
+
|
||
|
CLUTTER_EXPORT
|
||
|
gboolean clutter_stage_get_capture_final_size (ClutterStage *stage,
|
||
|
cairo_rectangle_int_t *rect,
|
||
|
--
|
||
|
2.31.1
|
||
|
|
||
|
|
||
|
From 1c4db591b6bb2ae9d649e8157eae24b875e7a22b Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||
|
Date: Mon, 28 Oct 2019 18:20:31 +0100
|
||
|
Subject: [PATCH 3/5] wayland/actor-surface: Always store away frame callbacks
|
||
|
on commit
|
||
|
|
||
|
We're expected by MetaWaylandSurface to always pick the frame callbacks
|
||
|
out from the pending state when committing (applying) so that no frame
|
||
|
callbacks are unaccounted for. We failed to do this if our actor for
|
||
|
some reason (e.g. associated window was unmanaged) was destroyed. To
|
||
|
handle this situation better, store away the frame callbacks until we
|
||
|
some later point in time need to pass them on forward.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/mutter/merge_requests/893
|
||
|
---
|
||
|
src/wayland/meta-wayland-actor-surface.c | 25 +++++++++++++++++++++++-
|
||
|
1 file changed, 24 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
|
||
|
index 2471de0a92..264565c575 100644
|
||
|
--- a/src/wayland/meta-wayland-actor-surface.c
|
||
|
+++ b/src/wayland/meta-wayland-actor-surface.c
|
||
|
@@ -35,6 +35,8 @@ typedef struct _MetaWaylandActorSurfacePrivate MetaWaylandActorSurfacePrivate;
|
||
|
struct _MetaWaylandActorSurfacePrivate
|
||
|
{
|
||
|
MetaSurfaceActor *actor;
|
||
|
+
|
||
|
+ struct wl_list frame_callback_list;
|
||
|
};
|
||
|
|
||
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandActorSurface,
|
||
|
@@ -56,6 +58,7 @@ meta_wayland_actor_surface_dispose (GObject *object)
|
||
|
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (object));
|
||
|
MetaWaylandSurface *surface =
|
||
|
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
|
||
|
+ MetaWaylandFrameCallback *cb, *next;
|
||
|
|
||
|
if (priv->actor)
|
||
|
{
|
||
|
@@ -66,6 +69,9 @@ meta_wayland_actor_surface_dispose (GObject *object)
|
||
|
g_clear_object (&priv->actor);
|
||
|
}
|
||
|
|
||
|
+ wl_list_for_each_safe (cb, next, &priv->frame_callback_list, link)
|
||
|
+ wl_resource_destroy (cb->resource);
|
||
|
+
|
||
|
G_OBJECT_CLASS (meta_wayland_actor_surface_parent_class)->dispose (object);
|
||
|
}
|
||
|
|
||
|
@@ -99,6 +105,9 @@ meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor
|
||
|
MetaSurfaceActorWayland *surface_actor_wayland =
|
||
|
META_SURFACE_ACTOR_WAYLAND (priv->actor);
|
||
|
|
||
|
+ 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_init (&pending->frame_callback_list);
|
||
|
@@ -253,10 +262,20 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||
|
{
|
||
|
MetaWaylandActorSurface *actor_surface =
|
||
|
META_WAYLAND_ACTOR_SURFACE (surface_role);
|
||
|
+ MetaWaylandActorSurfacePrivate *priv =
|
||
|
+ meta_wayland_actor_surface_get_instance_private (actor_surface);
|
||
|
MetaWaylandSurface *surface =
|
||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||
|
MetaWaylandSurface *toplevel_surface;
|
||
|
|
||
|
+ if (!priv->actor)
|
||
|
+ {
|
||
|
+ wl_list_insert_list (&priv->frame_callback_list,
|
||
|
+ &pending->frame_callback_list);
|
||
|
+ wl_list_init (&pending->frame_callback_list);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||
|
|
||
|
toplevel_surface = meta_wayland_surface_get_toplevel (surface);
|
||
|
@@ -307,8 +326,12 @@ meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surfac
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-meta_wayland_actor_surface_init (MetaWaylandActorSurface *role)
|
||
|
+meta_wayland_actor_surface_init (MetaWaylandActorSurface *actor_surface)
|
||
|
{
|
||
|
+ MetaWaylandActorSurfacePrivate *priv =
|
||
|
+ meta_wayland_actor_surface_get_instance_private (actor_surface);
|
||
|
+
|
||
|
+ wl_list_init (&priv->frame_callback_list);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
--
|
||
|
2.31.1
|
||
|
|
||
|
|
||
|
From 54e5cee1a8d1a94fb19b438a3c80fe72179a3c80 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||
|
Date: Fri, 6 Aug 2021 19:09:24 +0200
|
||
|
Subject: [PATCH 4/5] wayland/actor-surface: Always store away frame callbacks
|
||
|
on commit
|
||
|
|
||
|
We're expected by MetaWaylandSurface to always pick the frame callbacks
|
||
|
out from the pending state when committing (applying) so that no frame
|
||
|
callbacks are unaccounted for. We failed to do this if our actor for
|
||
|
some reason (e.g. associated window was unmanaged) was destroyed. To
|
||
|
handle this situation better, store away the frame callbacks until we
|
||
|
some later point in time need to pass them on forward.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/mutter/merge_requests/893
|
||
|
---
|
||
|
src/compositor/meta-surface-actor-wayland.c | 29 ---------
|
||
|
src/wayland/meta-wayland-actor-surface.c | 65 ++++++++++++++++-----
|
||
|
src/wayland/meta-wayland-actor-surface.h | 3 +
|
||
|
src/wayland/meta-wayland-cursor-surface.c | 4 +-
|
||
|
src/wayland/meta-wayland-dnd-surface.c | 11 +++-
|
||
|
src/wayland/meta-wayland-legacy-xdg-shell.c | 8 +--
|
||
|
src/wayland/meta-wayland-private.h | 2 +-
|
||
|
src/wayland/meta-wayland-subsurface.c | 2 -
|
||
|
src/wayland/meta-wayland-surface.c | 38 +++---------
|
||
|
src/wayland/meta-wayland-surface.h | 9 +--
|
||
|
src/wayland/meta-wayland-wl-shell.c | 3 -
|
||
|
src/wayland/meta-wayland-xdg-shell.c | 15 ++---
|
||
|
src/wayland/meta-wayland.c | 56 +++++++++++++-----
|
||
|
src/wayland/meta-wayland.h | 8 ++-
|
||
|
src/wayland/meta-xwayland.c | 45 --------------
|
||
|
15 files changed, 127 insertions(+), 171 deletions(-)
|
||
|
|
||
|
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
|
||
|
index a75c4dd096..480b51c61a 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,
|
||
|
@@ -91,13 +90,6 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
-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 MetaWindow *
|
||
|
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||
|
{
|
||
|
@@ -158,22 +150,6 @@ meta_surface_actor_wayland_get_preferred_height (ClutterActor *actor,
|
||
|
*natural_height_p *= scale;
|
||
|
}
|
||
|
|
||
|
-static void
|
||
|
-meta_surface_actor_wayland_paint (ClutterActor *actor)
|
||
|
-{
|
||
|
- MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||
|
-
|
||
|
- if (self->surface)
|
||
|
- {
|
||
|
- 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);
|
||
|
-}
|
||
|
-
|
||
|
static void
|
||
|
meta_surface_actor_wayland_dispose (GObject *object)
|
||
|
{
|
||
|
@@ -190,9 +166,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);
|
||
|
}
|
||
|
|
||
|
@@ -205,7 +178,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||
|
|
||
|
actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
|
||
|
actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
|
||
|
- 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;
|
||
|
@@ -232,7 +204,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 264565c575..037dd901ab 100644
|
||
|
--- a/src/wayland/meta-wayland-actor-surface.c
|
||
|
+++ b/src/wayland/meta-wayland-actor-surface.c
|
||
|
@@ -84,16 +84,22 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||
|
GList *l;
|
||
|
|
||
|
- 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);
|
||
|
-
|
||
|
for (l = surface->subsurfaces; l; l = l->next)
|
||
|
{
|
||
|
ClutterActor *subsurface_actor =
|
||
|
CLUTTER_ACTOR (meta_wayland_surface_get_actor (l->data));
|
||
|
clutter_actor_add_child (CLUTTER_ACTOR (priv->actor), subsurface_actor);
|
||
|
}
|
||
|
+
|
||
|
+ 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
|
||
|
@@ -102,15 +108,40 @@ 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);
|
||
|
|
||
|
- 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);
|
||
|
+ if (!priv->actor)
|
||
|
+ return;
|
||
|
+
|
||
|
+ if (wl_list_empty (&pending->frame_callback_list))
|
||
|
+ return;
|
||
|
+
|
||
|
+ 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);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
static double
|
||
|
@@ -268,12 +299,14 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||
|
MetaWaylandSurface *toplevel_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;
|
||
|
+ MetaBackend *backend = meta_get_backend ();
|
||
|
+ ClutterActor *stage = meta_backend_get_stage (backend);
|
||
|
+
|
||
|
+ 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 444b3b1785..e79f1caff5 100644
|
||
|
--- a/src/wayland/meta-wayland-actor-surface.h
|
||
|
+++ b/src/wayland/meta-wayland-actor-surface.h
|
||
|
@@ -46,4 +46,7 @@ void meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surf
|
||
|
void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
|
||
|
MetaWaylandPendingState *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 d46b3511fa..6b791eb378 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 2aad6dcd5d..8ddeb2a7bd 100644
|
||
|
--- a/src/wayland/meta-wayland-dnd-surface.c
|
||
|
+++ b/src/wayland/meta-wayland-dnd-surface.c
|
||
|
@@ -21,6 +21,8 @@
|
||
|
|
||
|
#include "wayland/meta-wayland-dnd-surface.h"
|
||
|
|
||
|
+#include "wayland/meta-wayland.h"
|
||
|
+
|
||
|
struct _MetaWaylandSurfaceRoleDND
|
||
|
{
|
||
|
MetaWaylandActorSurface parent;
|
||
|
@@ -36,7 +38,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
|
||
|
@@ -46,7 +52,8 @@ dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||
|
MetaWaylandSurface *surface =
|
||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||
|
|
||
|
- meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||
|
+ meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
|
||
|
+ surface);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
diff --git a/src/wayland/meta-wayland-legacy-xdg-shell.c b/src/wayland/meta-wayland-legacy-xdg-shell.c
|
||
|
index 8230641770..b78552f31b 100644
|
||
|
--- a/src/wayland/meta-wayland-legacy-xdg-shell.c
|
||
|
+++ b/src/wayland/meta-wayland-legacy-xdg-shell.c
|
||
|
@@ -659,6 +659,8 @@ meta_wayland_zxdg_toplevel_v6_commit (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);
|
||
|
@@ -670,7 +672,7 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
|
||
|
window = surface->window;
|
||
|
if (!window)
|
||
|
{
|
||
|
- meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
|
||
|
+ meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
@@ -1220,14 +1222,10 @@ meta_wayland_zxdg_surface_v6_send_configure (MetaWaylandZxdgSurfaceV6 *xdg_surfa
|
||
|
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 5bcb0ea4f9..215d0967f6 100644
|
||
|
--- a/src/wayland/meta-wayland-private.h
|
||
|
+++ b/src/wayland/meta-wayland-private.h
|
||
|
@@ -67,7 +67,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 e0fa0a48b2..c7059b99a2 100644
|
||
|
--- a/src/wayland/meta-wayland-subsurface.c
|
||
|
+++ b/src/wayland/meta-wayland-subsurface.c
|
||
|
@@ -239,8 +239,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);
|
||
|
if (surface->sub.parent)
|
||
|
{
|
||
|
wl_list_remove (&surface->sub.parent_destroy_listener.link);
|
||
|
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
|
||
|
index 6ffcd6a7fb..a76ab28c24 100644
|
||
|
--- a/src/wayland/meta-wayland-surface.c
|
||
|
+++ b/src/wayland/meta-wayland-surface.c
|
||
|
@@ -358,15 +358,6 @@ surface_process_damage (MetaWaylandSurface *surface,
|
||
|
cairo_region_destroy (transformed_region);
|
||
|
}
|
||
|
|
||
|
-void
|
||
|
-meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
|
||
|
- MetaWaylandPendingState *pending)
|
||
|
-{
|
||
|
- wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||
|
- &pending->frame_callback_list);
|
||
|
- wl_list_init (&pending->frame_callback_list);
|
||
|
-}
|
||
|
-
|
||
|
void
|
||
|
meta_wayland_surface_destroy_window (MetaWaylandSurface *surface)
|
||
|
{
|
||
|
@@ -656,15 +647,6 @@ parent_surface_state_applied (gpointer data,
|
||
|
meta_wayland_subsurface_parent_state_applied (subsurface);
|
||
|
}
|
||
|
|
||
|
-void
|
||
|
-meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
|
||
|
- MetaWaylandPendingState *pending)
|
||
|
-{
|
||
|
- wl_list_insert_list (&surface->pending_frame_callback_list,
|
||
|
- &pending->frame_callback_list);
|
||
|
- wl_list_init (&pending->frame_callback_list);
|
||
|
-}
|
||
|
-
|
||
|
void
|
||
|
meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
|
||
|
MetaWaylandPendingState *pending)
|
||
|
@@ -810,7 +792,9 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
- meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
|
||
|
+ wl_list_insert_list (surface->unassigned.pending_frame_callback_list.prev,
|
||
|
+ &pending->frame_callback_list);
|
||
|
+ wl_list_init (&pending->frame_callback_list);
|
||
|
|
||
|
if (pending->newly_attached)
|
||
|
{
|
||
|
@@ -1352,12 +1336,14 @@ 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)
|
||
|
@@ -1401,7 +1387,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
||
|
surface->resource = wl_resource_create (client, &wl_surface_interface, wl_resource_get_version (compositor_resource), id);
|
||
|
wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor);
|
||
|
|
||
|
- wl_list_init (&surface->pending_frame_callback_list);
|
||
|
+ wl_list_init (&surface->unassigned.pending_frame_callback_list);
|
||
|
|
||
|
sync_drag_dest_funcs (surface);
|
||
|
|
||
|
@@ -1809,14 +1795,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 e244a3fdf7..776431fca2 100644
|
||
|
--- a/src/wayland/meta-wayland-surface.h
|
||
|
+++ b/src/wayland/meta-wayland-surface.h
|
||
|
@@ -160,13 +160,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;
|
||
|
|
||
|
@@ -274,9 +270,6 @@ MetaWaylandSurface *meta_wayland_surface_get_toplevel (MetaWaylandSurface *surfa
|
||
|
|
||
|
MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
|
||
|
|
||
|
-void meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
|
||
|
- MetaWaylandPendingState *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 539fb9858e..e80db17e78 100644
|
||
|
--- a/src/wayland/meta-wayland-wl-shell.c
|
||
|
+++ b/src/wayland/meta-wayland-wl-shell.c
|
||
|
@@ -100,9 +100,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 fa0207a03c..4a4995c425 100644
|
||
|
--- a/src/wayland/meta-wayland-xdg-shell.c
|
||
|
+++ b/src/wayland/meta-wayland-xdg-shell.c
|
||
|
@@ -684,6 +684,8 @@ meta_wayland_xdg_toplevel_commit (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);
|
||
|
@@ -695,15 +697,12 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
||
|
window = surface->window;
|
||
|
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);
|
||
|
@@ -1037,6 +1036,8 @@ meta_wayland_xdg_popup_commit (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);
|
||
|
@@ -1048,7 +1049,7 @@ meta_wayland_xdg_popup_commit (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;
|
||
|
}
|
||
|
|
||
|
@@ -1313,14 +1314,10 @@ meta_wayland_xdg_surface_send_configure (MetaWaylandXdgSurface *xdg_surface)
|
||
|
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 129da8e20d..4cb9ca650d 100644
|
||
|
--- a/src/wayland/meta-wayland.c
|
||
|
+++ b/src/wayland/meta-wayland.c
|
||
|
@@ -194,15 +194,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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -249,16 +269,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
|
||
|
@@ -309,8 +335,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 2a0aa11400..c5e5924891 100644
|
||
|
--- a/src/wayland/meta-wayland.h
|
||
|
+++ b/src/wayland/meta-wayland.h
|
||
|
@@ -64,9 +64,11 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp
|
||
|
META_EXPORT_TEST
|
||
|
void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor);
|
||
|
|
||
|
-META_EXPORT_TEST
|
||
|
-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);
|
||
|
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
|
||
|
index 275aeb78cb..6e4b9a8ffd 100644
|
||
|
--- a/src/wayland/meta-xwayland.c
|
||
|
+++ b/src/wayland/meta-xwayland.c
|
||
|
@@ -788,49 +788,6 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-static void
|
||
|
-xwayland_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
||
|
-{
|
||
|
- MetaWaylandSurface *surface =
|
||
|
- meta_wayland_surface_role_get_surface (surface_role);
|
||
|
- MetaWaylandSurfaceRoleClass *surface_role_class =
|
||
|
- META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_xwayland_parent_class);
|
||
|
-
|
||
|
- /* See comment in xwayland_surface_commit for why we reply even though the
|
||
|
- * surface may not be drawn the next frame.
|
||
|
- */
|
||
|
- wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||
|
- &surface->pending_frame_callback_list);
|
||
|
- wl_list_init (&surface->pending_frame_callback_list);
|
||
|
-
|
||
|
- surface_role_class->assigned (surface_role);
|
||
|
-}
|
||
|
-
|
||
|
-static void
|
||
|
-xwayland_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||
|
- MetaWaylandPendingState *pending)
|
||
|
-{
|
||
|
- MetaWaylandSurface *surface =
|
||
|
- meta_wayland_surface_role_get_surface (surface_role);
|
||
|
- MetaWaylandSurfaceRoleClass *surface_role_class =
|
||
|
- META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_xwayland_parent_class);
|
||
|
-
|
||
|
- /* For Xwayland windows, throttling frames when the window isn't actually
|
||
|
- * drawn is less useful, because Xwayland still has to do the drawing sent
|
||
|
- * from the application - the throttling would only be of sending us damage
|
||
|
- * messages, so we simplify and send frame callbacks after the next paint of
|
||
|
- * the screen, whether the window was drawn or not.
|
||
|
- *
|
||
|
- * Currently it may take a few frames before we draw the window, for not
|
||
|
- * completely understood reasons, and in that case, not thottling frame
|
||
|
- * callbacks to drawing has the happy side effect that we avoid showing the
|
||
|
- * user the initial black frame from when the window is mapped empty.
|
||
|
- */
|
||
|
- meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||
|
-
|
||
|
- surface_role_class->commit (surface_role, pending);
|
||
|
-}
|
||
|
-
|
||
|
static MetaWaylandSurface *
|
||
|
xwayland_surface_get_toplevel (MetaWaylandSurfaceRole *surface_role)
|
||
|
{
|
||
|
@@ -848,8 +805,6 @@ meta_wayland_surface_role_xwayland_class_init (MetaWaylandSurfaceRoleXWaylandCla
|
||
|
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||
|
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||
|
|
||
|
- surface_role_class->assigned = xwayland_surface_assigned;
|
||
|
- surface_role_class->commit = xwayland_surface_commit;
|
||
|
surface_role_class->get_toplevel = xwayland_surface_get_toplevel;
|
||
|
|
||
|
xwayland_surface_signals[XWAYLAND_SURFACE_WINDOW_ASSOCIATED] =
|
||
|
--
|
||
|
2.31.1
|
||
|
|
||
|
|
||
|
From 076ac20d34db128aea8ffe0dc3c2791918667c43 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||
|
Date: Fri, 6 Aug 2021 19:46:06 +0200
|
||
|
Subject: [PATCH 5/5] wayland: Respond to frame callbacks even if the paint was
|
||
|
empty
|
||
|
|
||
|
---
|
||
|
src/compositor/compositor.c | 10 +++++-----
|
||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
|
||
|
index ce2c1b8a3b..8331737d1a 100644
|
||
|
--- a/src/compositor/compositor.c
|
||
|
+++ b/src/compositor/compositor.c
|
||
|
@@ -467,11 +467,6 @@ after_stage_paint (ClutterStage *stage,
|
||
|
|
||
|
for (l = compositor->windows; l; l = l->next)
|
||
|
meta_window_actor_post_paint (l->data);
|
||
|
-
|
||
|
-#ifdef HAVE_WAYLAND
|
||
|
- if (meta_is_wayland_compositor ())
|
||
|
- meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
|
||
|
-#endif
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -1404,6 +1399,11 @@ meta_post_paint_func (gpointer data)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
+#ifdef HAVE_WAYLAND
|
||
|
+ if (meta_is_wayland_compositor ())
|
||
|
+ meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
|
||
|
+#endif
|
||
|
+
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.31.1
|
||
|
|