-
Notifications
You must be signed in to change notification settings - Fork 0
/
2671.patch
247 lines (217 loc) · 9.88 KB
/
2671.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
From 935bdb3879f6a716dc5e28687804f6317f198978 Mon Sep 17 00:00:00 2001
From: Robert Mader <[email protected]>
Date: Tue, 18 Oct 2022 15:40:19 +0200
Subject: [PATCH 1/2] surface-actor-wayland: Clean up and optimize check for
primary view
Avoid some allocations, save some CPU cycles and make the code easier
to read.
Behaviourwise the only expected change is that now, if there are mapped
clones, we unconditionally choose the view with the highest refresh
rate the actor (or one of its clones) is on and don't check the
obscurred region any more.
Thus in some cases a client may receive a higher rate of frame callbacks
when obscurred on a faster view while a clone is present on a slower
one. The assumption is that cases like this are relatively rare and
that the reduction of code complexity, the reduction of allocations in
`meta_surface_actor_is_obscured_on_stage_view()` whenever the actor is
not fully obscurred and has clones on other views, as well as generally
fewer lookups and less code in most common cases, compensate for that.
---
src/compositor/meta-surface-actor-wayland.c | 77 ++++++++++++--------
src/compositor/meta-surface-actor-wayland.h | 4 +-
src/wayland/meta-wayland-presentation-time.c | 6 +-
src/wayland/meta-wayland.c | 6 +-
4 files changed, 54 insertions(+), 39 deletions(-)
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index b58f328dc3..1dcadde660 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -67,60 +67,79 @@ meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
#define UNOBSCURED_TRESHOLD 0.1
-ClutterStageView *
-meta_surface_actor_wayland_get_current_primary_view (MetaSurfaceActor *actor,
- ClutterStage *stage)
+gboolean
+meta_surface_actor_wayland_is_stage_view_current_primary_view (MetaSurfaceActor *actor,
+ ClutterStageView *stage_view)
{
ClutterStageView *current_primary_view = NULL;
float highest_refresh_rate = 0.f;
float biggest_unobscurred_fraction = 0.f;
GList *l;
- for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
+ if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
+ stage_view))
+ return FALSE;
+
+ if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)))
{
- ClutterStageView *stage_view = l->data;
- float refresh_rate;
- float unobscurred_fraction = 1.f;
+ ClutterStage *stage;
- if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)))
+ stage = CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (actor)));
+ for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
{
+ ClutterStageView *view = l->data;
+ float refresh_rate;
+
if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
- stage_view))
+ view))
continue;
- }
- else
- {
- if (l->next || biggest_unobscurred_fraction > 0.f)
- {
- if (meta_surface_actor_is_obscured_on_stage_view (actor,
- stage_view,
- &unobscurred_fraction))
- continue;
- }
- else
+
+ refresh_rate = clutter_stage_view_get_refresh_rate (view);
+ if (refresh_rate > highest_refresh_rate)
{
- if (meta_surface_actor_is_obscured (actor) ||
- !clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
- stage_view))
- continue;
+ current_primary_view = view;
+ highest_refresh_rate = refresh_rate;
}
}
- refresh_rate = clutter_stage_view_get_refresh_rate (stage_view);
+ return current_primary_view == stage_view;
+ }
+
+ l = clutter_actor_peek_stage_views (CLUTTER_ACTOR (actor));
+ g_assert (l != NULL);
+
+ if (!l->next)
+ {
+ g_warn_if_fail (l->data == stage_view);
+ return !meta_surface_actor_is_obscured (actor);
+ }
+
+ for (; l; l = l->next)
+ {
+ ClutterStageView *view = l->data;
+ float refresh_rate;
+ float unobscurred_fraction;
+
+ if (meta_surface_actor_is_obscured_on_stage_view (actor,
+ view,
+ &unobscurred_fraction))
+ continue;
+
+ refresh_rate = clutter_stage_view_get_refresh_rate (view);
if ((refresh_rate > highest_refresh_rate &&
- (unobscurred_fraction > UNOBSCURED_TRESHOLD ||
- biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD)) ||
+ (biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD ||
+ unobscurred_fraction > UNOBSCURED_TRESHOLD)) ||
(biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD &&
unobscurred_fraction > UNOBSCURED_TRESHOLD))
{
- current_primary_view = stage_view;
+ current_primary_view = view;
highest_refresh_rate = refresh_rate;
biggest_unobscurred_fraction = unobscurred_fraction;
}
}
- return current_primary_view;
+ return current_primary_view == stage_view;
}
static void
diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h
index 1a349af91f..1898147d55 100644
--- a/src/compositor/meta-surface-actor-wayland.h
+++ b/src/compositor/meta-surface-actor-wayland.h
@@ -44,8 +44,8 @@ MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface);
MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self);
void meta_surface_actor_wayland_surface_destroyed (MetaSurfaceActorWayland *self);
-ClutterStageView * meta_surface_actor_wayland_get_current_primary_view (MetaSurfaceActor *actor,
- ClutterStage *stage);
+gboolean meta_surface_actor_wayland_is_stage_view_current_primary_view (MetaSurfaceActor *actor,
+ ClutterStageView *stage_view);
G_END_DECLS
diff --git a/src/wayland/meta-wayland-presentation-time.c b/src/wayland/meta-wayland-presentation-time.c
index fb99445eb7..0025b62e1e 100644
--- a/src/wayland/meta-wayland-presentation-time.c
+++ b/src/wayland/meta-wayland-presentation-time.c
@@ -156,7 +156,6 @@ on_after_paint (ClutterStage *stage,
GList *l_cur = l;
MetaWaylandSurface *surface = l->data;
MetaSurfaceActor *actor;
- ClutterStageView *surface_primary_view;
l = l->next;
@@ -164,9 +163,8 @@ on_after_paint (ClutterStage *stage,
if (!actor)
continue;
- surface_primary_view =
- meta_surface_actor_wayland_get_current_primary_view (actor, stage);
- if (stage_view != surface_primary_view)
+ if (!meta_surface_actor_wayland_is_stage_view_current_primary_view (actor,
+ stage_view))
continue;
if (!wl_list_empty (&surface->presentation_time.feedback_list))
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 1db0838bb6..df70daa624 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -229,7 +229,6 @@ on_after_update (ClutterStage *stage,
MetaWaylandSurface *surface = l->data;
MetaSurfaceActor *actor;
MetaWaylandActorSurface *actor_surface;
- ClutterStageView *surface_primary_view;
l = l->next;
@@ -237,9 +236,8 @@ on_after_update (ClutterStage *stage,
if (!actor)
continue;
- surface_primary_view =
- meta_surface_actor_wayland_get_current_primary_view (actor, stage);
- if (stage_view != surface_primary_view)
+ if (!meta_surface_actor_wayland_is_stage_view_current_primary_view (actor,
+ stage_view))
continue;
actor_surface = META_WAYLAND_ACTOR_SURFACE (surface->role);
--
GitLab
From 81caa2f08e8d95ceba405b414802fb740d906fdf Mon Sep 17 00:00:00 2001
From: Robert Mader <[email protected]>
Date: Mon, 7 Nov 2022 17:07:06 +0100
Subject: [PATCH 2/2] wayland/actor-surface: Optimize update scheduling
This code path is important for "empty" commits to ensure we schedule
frame callbacks even if previous commits didn't cause stage redraws.
There is, however, no reason to schedule updates on all stage views
instead of only those the actor is on.
---
src/wayland/meta-wayland-actor-surface.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
index f4ad2d0e4f..a00ab4361e 100644
--- a/src/wayland/meta-wayland-actor-surface.c
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -307,10 +307,15 @@ meta_wayland_actor_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
priv->actor &&
!meta_surface_actor_is_obscured (priv->actor))
{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage = meta_backend_get_stage (backend);
+ GList *l;
- clutter_stage_schedule_update (CLUTTER_STAGE (stage));
+ for (l = clutter_actor_peek_stage_views (CLUTTER_ACTOR (priv->actor)); l;
+ l = l->next)
+ {
+ ClutterStageView *view = l->data;
+
+ clutter_stage_view_schedule_update (view);
+ }
}
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
--
GitLab