Merge ~3v1n0/ubuntu/+source/mutter:ubuntu/bionic into ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/bionic

Proposed by Marco Trevisan (Treviño)
Status: Merged
Merged at revision: b154de179b5d063103bf958fb30e4544e2527d55
Proposed branch: ~3v1n0/ubuntu/+source/mutter:ubuntu/bionic
Merge into: ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/bionic
Diff against target: 1319 lines (+1031/-226)
9 files modified
debian/changelog (+18/-0)
debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch (+53/-0)
debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch (+294/-0)
debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch (+372/-0)
debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch (+53/-0)
debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch (+37/-0)
debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch (+198/-0)
debian/patches/series (+6/-1)
dev/null (+0/-225)
Reviewer Review Type Date Requested Status
Daniel van Vugt (community) Approve
Ubuntu Desktop Pending
Review via email: mp+366676@code.launchpad.net
To post a comment you must log in.
ce3f911... by Marco Trevisan (Treviño)

debian/patches: Ignore new symbols added in switch-config

No need to export new symbols for this one

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looking good.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

It looks like this has landed. Please close this MP.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 99219d6..a1467bf 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,21 @@
1mutter (3.28.3+git20190124-0ubuntu18.04.3) UNRELEASED; urgency=medium
2
3 * d/p/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch,
4 d/p/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch:
5 - Ensure switch display mode is cyclic (LP: #1772811)
6 * d/p/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch,
7 d/p/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch:
8 - Implement keycode remap to keysyms on virtual key devices (LP: #1827029)
9
10 [ Daniel van Vugt ]
11 * d/p/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch,
12 d/p/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch:
13 - Add support for high frame rate displays (LP: #1763892)
14 * d/p/clutter-Smooth-out-master-clock-to-smooth-visuals.patch:
15 - Dropped
16
17 -- Marco Trevisan (Treviño) <marco@ubuntu.com> Mon, 29 Apr 2019 23:29:24 -0500
18
1mutter (3.28.3+git20190124-0ubuntu18.04.2) bionic; urgency=medium19mutter (3.28.3+git20190124-0ubuntu18.04.2) bionic; urgency=medium
220
3 * control: Add Breaks on budgie-desktop verions broken by this upload.21 * control: Add Breaks on budgie-desktop verions broken by this upload.
diff --git a/debian/patches/clutter-Smooth-out-master-clock-to-smooth-visuals.patch b/debian/patches/clutter-Smooth-out-master-clock-to-smooth-visuals.patch
4deleted file mode 10064422deleted file mode 100644
index 2239837..0000000
--- a/debian/patches/clutter-Smooth-out-master-clock-to-smooth-visuals.patch
+++ /dev/null
@@ -1,225 +0,0 @@
1From: Daniel van Vugt <daniel.van.vugt@canonical.com>
2Date: Fri, 16 Feb 2018 02:50:59 -0600
3Subject: clutter: Smooth out master clock to smooth visuals
4
5Clutter's master clock was jittery because it included errors in cur_tick
6such as dispatch delays due to other sources. Dispatch could also occur up
7to 1ms early since GSource can only be timed to the millisecond. All of this
8could impact the visual smoothness of animations as they are displayed on
9the steady interval of the monitor, but spacially moving in less regular
10steps derived from the dispatch times.
11
12The simple fix is to ignore any jitter in dispatch timing. Try a little
13bit harder to use a precise interval that will better match the display
14hardware, and smoother visuals will follow.
15
16Bug: https://gitlab.gnome.org/GNOME/mutter/issues/25
17Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/70
18---
19 clutter/clutter/clutter-master-clock-default.c | 134 +++++++++++++++++--------
20 1 file changed, 93 insertions(+), 41 deletions(-)
21
22diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c
23index 7b2df0d..97b6d13 100644
24--- a/clutter/clutter/clutter-master-clock-default.c
25+++ b/clutter/clutter/clutter-master-clock-default.c
26@@ -69,8 +69,10 @@ struct _ClutterMasterClockDefault
27 /* the previous state of the clock, in usecs, used to compute the delta */
28 gint64 prev_tick;
29
30+ /* the ideal frame interval in usecs (inverse of your max refresh rate) */
31+ gint64 frame_interval;
32+
33 #ifdef CLUTTER_ENABLE_DEBUG
34- gint64 frame_budget;
35 gint64 remaining_budget;
36 #endif
37
38@@ -264,6 +266,41 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
39 }
40 }
41
42+static gint64
43+estimate_next_presentation_time (ClutterMasterClockDefault *master_clock)
44+{
45+ gint64 frame_phase, now, now_phase, undershoot;
46+
47+ /* In future if this was updated from the backend's (maximum) refresh rate
48+ * then that would fix: https://bugzilla.gnome.org/show_bug.cgi?id=781296
49+ */
50+ master_clock->frame_interval = G_USEC_PER_SEC /
51+ clutter_get_default_frame_rate ();
52+
53+ now = g_source_get_time (master_clock->source);
54+ now_phase = now % master_clock->frame_interval;
55+
56+ /* To be precise we would like to use:
57+ * frame_phase = a_recent_hardware_presentation_time % frame_interval;
58+ * where hardware_presentation_time must be using the same clock as
59+ * g_source_get_time. Unfortunately they're different clocks right now
60+ * so we can't.
61+ * Alternatively, we could replace g_source_get_time in future with the
62+ * current time in the clutter/cogl presentation clock, but that function
63+ * also doesn't exist yet.
64+ * Until we can get either of those, zero is fine. It just means latency
65+ * will be suboptimal by half a frame on average. We still get maximum
66+ * smoothness this way...
67+ */
68+ frame_phase = 0;
69+
70+ undershoot = frame_phase - now_phase;
71+ if (undershoot < 0)
72+ undershoot += master_clock->frame_interval;
73+
74+ return now + undershoot;
75+}
76+
77 /*
78 * master_clock_next_frame_delay:
79 * @master_clock: a #ClutterMasterClock
80@@ -276,7 +313,8 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
81 static gint
82 master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock)
83 {
84- gint64 now, next;
85+ gint64 now, target_presentation_time, ideal_render_start; /* timestamps */
86+ gint64 ideal_prerender_time, lateness; /* deltas */
87 gint swap_delay;
88
89 if (!master_clock_is_running (master_clock))
90@@ -307,46 +345,45 @@ master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock)
91 return 0;
92 }
93
94- if (master_clock->prev_tick == 0)
95- {
96- /* If we weren't previously running, then draw the next frame
97- * immediately
98- */
99- CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
100- return 0;
101- }
102-
103- /* Otherwise, wait at least 1/frame_rate seconds since we last
104- * started a frame
105- */
106 now = g_source_get_time (master_clock->source);
107
108- next = master_clock->prev_tick;
109-
110- /* If time has gone backwards then there's no way of knowing how
111- long we should wait so let's just dispatch immediately */
112- if (now <= next)
113+ /* As first preference, try to carry on smoothly from the previous frame,
114+ * even if that means we start rendering frame 2 before frame 1 has been
115+ * presented. This is why we ignore estimate_next_presentation_time here...
116+ */
117+ target_presentation_time = master_clock->prev_tick +
118+ master_clock->frame_interval;
119+ ideal_prerender_time = master_clock->frame_interval;
120+ ideal_render_start = target_presentation_time - ideal_prerender_time;
121+ lateness = now - ideal_render_start;
122+
123+ /* If we just woke from idle then try to improve the smoothness of the first
124+ * two frames some more. Otherwise the first frame would appear too old
125+ * relative to the second frame.
126+ */
127+ if (lateness >= master_clock->frame_interval)
128 {
129- CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");
130-
131- return 0;
132+ target_presentation_time = estimate_next_presentation_time (master_clock);
133+ ideal_render_start = target_presentation_time - ideal_prerender_time;
134+ lateness = now - ideal_render_start;
135 }
136
137- next += (1000000L / clutter_get_default_frame_rate ());
138-
139- if (next <= now)
140+ if (lateness > 0)
141 {
142- CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
143- 1000000L / (gulong) clutter_get_default_frame_rate ());
144-
145+ CLUTTER_NOTE (SCHEDULER, "No wait required. We're already late.");
146 return 0;
147 }
148 else
149 {
150- CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
151- (next - now) / 1000);
152-
153- return (next - now) / 1000;
154+ /* We +1 here to avoid premature dispatches that would otherwise occur
155+ * repeatedly during the 1ms before 'ideal_render_start'. We don't care
156+ * if this makes the final dispatch 1ms late because the smoothing
157+ * algorithm corrects that, and it's much better than attempting to
158+ * render more frames than the hardware can physically display...
159+ */
160+ gint millisec_delay = -lateness / 1000 + 1;
161+ CLUTTER_NOTE (SCHEDULER, "Waiting %dms", millisec_delay);
162+ return millisec_delay;
163 }
164 }
165
166@@ -532,16 +569,34 @@ clutter_clock_dispatch (GSource *source,
167 ClutterMasterClockDefault *master_clock = clock_source->master_clock;
168 gboolean stages_updated = FALSE;
169 GSList *stages;
170-
171- CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
172+ gint64 smooth_tick;
173
174 _clutter_threads_acquire_lock ();
175
176 /* Get the time to use for this frame */
177- master_clock->cur_tick = g_source_get_time (source);
178+ smooth_tick = estimate_next_presentation_time (master_clock);
179+ if (smooth_tick <= master_clock->prev_tick)
180+ {
181+ /* Ordinarily this will never happen. But after we fix bug 781296, it
182+ * could happen in the rare case when the ideal frame_interval changes,
183+ * such as video mode switching or hotplugging monitors. As such it is
184+ * not considered a bug (unless it's happening without mode switching
185+ * or hotplugging).
186+ */
187+ CLUTTER_NOTE (SCHEDULER, "Master clock [tick] was premature (skipped)");
188+ _clutter_threads_release_lock ();
189+ return G_SOURCE_CONTINUE;
190+ }
191+
192+ master_clock->cur_tick = smooth_tick;
193+ if (master_clock->prev_tick)
194+ CLUTTER_NOTE (SCHEDULER, "Master clock [tick] %+ldus",
195+ (long) (master_clock->cur_tick - master_clock->prev_tick));
196+ else
197+ CLUTTER_NOTE (SCHEDULER, "Master clock [tick] startup");
198
199 #ifdef CLUTTER_ENABLE_DEBUG
200- master_clock->remaining_budget = master_clock->frame_budget;
201+ master_clock->remaining_budget = master_clock->frame_interval;
202 #endif
203
204 /* We need to protect ourselves against stages being destroyed during
205@@ -580,7 +635,7 @@ clutter_clock_dispatch (GSource *source,
206
207 _clutter_threads_release_lock ();
208
209- return TRUE;
210+ return G_SOURCE_CONTINUE;
211 }
212
213 static void
214@@ -612,10 +667,7 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self)
215 self->idle = FALSE;
216 self->ensure_next_iteration = FALSE;
217 self->paused = FALSE;
218-
219-#ifdef CLUTTER_ENABLE_DEBUG
220- self->frame_budget = G_USEC_PER_SEC / 60;
221-#endif
222+ self->frame_interval = G_USEC_PER_SEC / 60; /* Will be refined at runtime */
223
224 g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW);
225 g_source_set_can_recurse (source, FALSE);
diff --git a/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch b/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch
226new file mode 1006440new file mode 100644
index 0000000..e2d3140
--- /dev/null
+++ b/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch
@@ -0,0 +1,53 @@
1From: Andrea Azzarone <andrea.azzarone@canonical.com>
2Date: Tue, 22 Jan 2019 11:20:37 -0600
3Subject: clutter/x11: Consider remapped keys when guessing the keycode from
4 the keysym
5
6Since e3e933c4 a keyval can be temporarily remapped to an unused keycode. Due to
7some limitations in XTestFakeKeyEvent, the remapping has to be done in the first
8xkb group/layout. In case there are two or more keyboard layouts enabled and the
9selected keyboard layout is not the first, clutter_keymap_x11_keycode_for_keyval
10will fail to retrieve the correct keycode for a remapped keyval. Let's use the
11reserved_keycodes map in order to retrieve the correct keycode if needed.
12
13Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/443
14
15GNOME-Bug: https://gitlab.gnome.org/GNOME/mutter/issues/443
16Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1827029
17Origin: https://gitlab.gnome.org/GNOME/mutter/commit/24b4c82
18Applied-Upstream: 3.28.4
19---
20 clutter/clutter/x11/clutter-keymap-x11.c | 20 ++++++++++++++++++++
21 1 file changed, 20 insertions(+)
22
23diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c
24index 5dd40a9..f1bdf16 100644
25--- a/clutter/clutter/x11/clutter-keymap-x11.c
26+++ b/clutter/clutter/x11/clutter-keymap-x11.c
27@@ -1005,6 +1005,26 @@ clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
28 }
29 }
30
31+ if (!found)
32+ {
33+ GHashTableIter iter;
34+ gpointer key, value;
35+
36+ g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
37+ while (!found && g_hash_table_iter_next (&iter, &key, &value))
38+ {
39+ guint reserved_keycode = GPOINTER_TO_UINT (key);
40+ guint reserved_keysym = GPOINTER_TO_UINT (value);
41+
42+ if (keyval == reserved_keysym)
43+ {
44+ *keycode_out = reserved_keycode;
45+ *level_out = 0;
46+ found = TRUE;
47+ }
48+ }
49+ }
50+
51 g_free (keys);
52 return found;
53 }
diff --git a/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch b/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch
0new file mode 10064454new file mode 100644
index 0000000..944e1ea
--- /dev/null
+++ b/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch
@@ -0,0 +1,294 @@
1From: Andrea Azzarone <azzaronea@gmail.com>
2Date: Fri, 13 Jul 2018 07:49:38 -0500
3Subject: clutter/x11: Implement keycode remap to keysyms on virtual key
4 devices
5
6Keycode lookup can fail for serveral reasons, e.g. if there is no combination of
7modifiers and keycodes that can produce the target keysym with the current
8keyboard layout.
9
10In case the keycode lookup fails, remap temporarily the keysym to an unused
11keycodes.
12
13Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/109
14
15GNOME-Bug: https://gitlab.gnome.org/GNOME/mutter/issues/109
16Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1827029
17Origin: https://gitlab.gnome.org/GNOME/mutter/commit/6198d389
18Applied-Upstream: 3.28.4
19---
20 clutter/clutter/x11/clutter-keymap-x11.c | 167 +++++++++++++++++++++
21 clutter/clutter/x11/clutter-keymap-x11.h | 6 +-
22 .../clutter/x11/clutter-virtual-input-device-x11.c | 19 ++-
23 3 files changed, 186 insertions(+), 6 deletions(-)
24
25diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c
26index c34e676..5dd40a9 100644
27--- a/clutter/clutter/x11/clutter-keymap-x11.c
28+++ b/clutter/clutter/x11/clutter-keymap-x11.c
29@@ -79,6 +79,9 @@ struct _ClutterKeymapX11
30 guint current_cache_serial;
31 DirectionCacheEntry group_direction_cache[4];
32 int current_group;
33+
34+ GHashTable *reserved_keycodes;
35+ GQueue *available_keycodes;
36 #endif
37
38 guint caps_lock_state : 1;
39@@ -441,16 +444,100 @@ clutter_keymap_x11_set_property (GObject *gobject,
40 }
41 }
42
43+#ifdef HAVE_XKB
44+static void
45+clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11)
46+{
47+ Display *dpy = clutter_x11_get_default_display ();
48+ GHashTableIter iter;
49+ gpointer key, value;
50+
51+ g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
52+ while (g_hash_table_iter_next (&iter, &key, &value))
53+ {
54+ guint reserved_keycode = GPOINTER_TO_UINT (key);
55+ guint reserved_keysym = GPOINTER_TO_UINT (value);
56+ guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0);
57+
58+ /* If an available keycode is no longer mapped to the stored keysym, then
59+ * the keycode should not be considered available anymore and should be
60+ * removed both from the list of available and reserved keycodes.
61+ */
62+ if (reserved_keysym != actual_keysym)
63+ {
64+ g_hash_table_iter_remove (&iter);
65+ g_queue_remove (keymap_x11->available_keycodes, key);
66+ }
67+ }
68+}
69+
70+static gboolean
71+clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11,
72+ KeyCode keycode,
73+ KeySym keysym)
74+{
75+ if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
76+ {
77+ Display *dpy = clutter_x11_get_default_display ();
78+ XkbDescPtr xkb = get_xkb (keymap_x11);
79+ XkbMapChangesRec changes;
80+
81+ XFlush (dpy);
82+
83+ xkb->device_spec = XkbUseCoreKbd;
84+ memset (&changes, 0, sizeof(changes));
85+
86+ if (keysym != NoSymbol)
87+ {
88+ int types[XkbNumKbdGroups] = { XkbOneLevelIndex };
89+ XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes);
90+ XkbKeySymEntry (xkb, keycode, 0, 0) = keysym;
91+ }
92+ else
93+ {
94+ /* Reset to NoSymbol */
95+ XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes);
96+ }
97+
98+ changes.changed = XkbKeySymsMask | XkbKeyTypesMask;
99+ changes.first_key_sym = keycode;
100+ changes.num_key_syms = 1;
101+ changes.first_type = 0;
102+ changes.num_types = xkb->map->num_types;
103+ XkbChangeMap (dpy, xkb, &changes);
104+
105+ XFlush (dpy);
106+
107+ return TRUE;
108+ }
109+
110+ return FALSE;
111+}
112+#endif
113+
114 static void
115 clutter_keymap_x11_finalize (GObject *gobject)
116 {
117 ClutterKeymapX11 *keymap;
118 ClutterEventTranslator *translator;
119+ GHashTableIter iter;
120+ gpointer key, value;
121
122 keymap = CLUTTER_KEYMAP_X11 (gobject);
123 translator = CLUTTER_EVENT_TRANSLATOR (keymap);
124
125 #ifdef HAVE_XKB
126+ clutter_keymap_x11_refresh_reserved_keycodes (keymap);
127+ g_hash_table_iter_init (&iter, keymap->reserved_keycodes);
128+ while (g_hash_table_iter_next (&iter, &key, &value))
129+ {
130+ guint keycode = GPOINTER_TO_UINT (key);
131+ clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol);
132+ }
133+
134+ g_hash_table_destroy (keymap->reserved_keycodes);
135+ g_queue_free (keymap->available_keycodes);
136+
137 _clutter_backend_remove_event_translator (keymap->backend, translator);
138
139 if (keymap->xkb_desc != NULL)
140@@ -460,6 +547,7 @@ clutter_keymap_x11_finalize (GObject *gobject)
141 G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject);
142 }
143
144+
145 static void
146 clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass)
147 {
148@@ -483,6 +571,11 @@ clutter_keymap_x11_init (ClutterKeymapX11 *keymap)
149 {
150 keymap->current_direction = PANGO_DIRECTION_NEUTRAL;
151 keymap->current_group = -1;
152+
153+#ifdef HAVE_XKB
154+ keymap->reserved_keycodes = g_hash_table_new (NULL, NULL);
155+ keymap->available_keycodes = g_queue_new ();
156+#endif
157 }
158
159 static ClutterTranslateReturn
160@@ -766,6 +859,80 @@ clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11,
161 }
162 }
163
164+#ifdef HAVE_XKB
165+static guint
166+clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11)
167+{
168+ if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
169+ {
170+ clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11);
171+
172+ if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5)
173+ {
174+ Display *dpy = clutter_x11_get_default_display ();
175+ XkbDescPtr xkb = get_xkb (keymap_x11);
176+ guint i;
177+
178+ for (i = xkb->max_key_code; i >= xkb->min_key_code; --i)
179+ {
180+ if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol)
181+ return i;
182+ }
183+ }
184+
185+ return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes));
186+ }
187+
188+ return 0;
189+}
190+#endif
191+
192+gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
193+ guint keyval,
194+ guint *keycode_out)
195+{
196+ g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE);
197+ g_return_val_if_fail (keyval != 0, FALSE);
198+ g_return_val_if_fail (keycode_out != NULL, FALSE);
199+
200+#ifdef HAVE_XKB
201+ *keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11);
202+
203+ if (*keycode_out == NoSymbol)
204+ {
205+ g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval);
206+ return FALSE;
207+ }
208+
209+ if (!clutter_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
210+ {
211+ g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval);
212+ return FALSE;
213+ }
214+
215+ g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval));
216+ g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out));
217+
218+ return TRUE;
219+#else
220+ return FALSE;
221+#endif
222+}
223+
224+void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
225+ guint keycode)
226+{
227+ g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11));
228+
229+#ifdef HAVE_XKB
230+ if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) ||
231+ g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1)
232+ return;
233+
234+ g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode));
235+#endif
236+}
237+
238 void
239 clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
240 uint32_t level,
241diff --git a/clutter/clutter/x11/clutter-keymap-x11.h b/clutter/clutter/x11/clutter-keymap-x11.h
242index 4b5b403..4decb44 100644
243--- a/clutter/clutter/x11/clutter-keymap-x11.h
244+++ b/clutter/clutter/x11/clutter-keymap-x11.h
245@@ -58,7 +58,11 @@ gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
246 void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
247 uint32_t level,
248 gboolean enable);
249-
250+gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
251+ guint keyval,
252+ guint *keycode_out);
253+void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
254+ guint keycode);
255 G_END_DECLS
256
257 #endif /* __CLUTTER_KEYMAP_X11_H__ */
258diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c
259index e16ba3f..cab26c3 100644
260--- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c
261+++ b/clutter/clutter/x11/clutter-virtual-input-device-x11.c
262@@ -143,8 +143,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
263
264 if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
265 {
266- g_warning ("No keycode found for keyval %x in current group", keyval);
267- return;
268+ level = 0;
269+
270+ if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
271+ {
272+ g_warning ("No keycode found for keyval %x in current group", keyval);
273+ return;
274+ }
275 }
276
277 if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
278@@ -155,9 +160,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
279 (KeyCode) keycode,
280 key_state == CLUTTER_KEY_STATE_PRESSED, 0);
281
282- if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
283- key_state == CLUTTER_KEY_STATE_RELEASED)
284- clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
285+
286+ if (key_state == CLUTTER_KEY_STATE_RELEASED)
287+ {
288+ if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode))
289+ clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
290+ clutter_keymap_x11_release_keycode_if_needed (keymap, keycode);
291+ }
292 }
293
294 static void
diff --git a/debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch b/debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch
0new file mode 100644295new file mode 100644
index 0000000..1e5958e
--- /dev/null
+++ b/debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch
@@ -0,0 +1,372 @@
1From: Daniel van Vugt <daniel.van.vugt@canonical.com>
2Date: Fri, 3 May 2019 11:31:08 -0500
3Subject: renderer-native: Add hardware presentation timing
4
5Add support for getting hardware presentation times from KMS (Wayland
6sessions). Also implement cogl_get_clock_time which is required to compare
7and judge the age of presentation timestamps.
8
9For single monitor systems this is straightforward. For multi-monitor
10systems though we have to choose a display to sync to. The compositor
11already partially solves this for us in the case of only one display
12updating because it will only use the subset of monitors that are
13changing. In the case of multiple monitors consuming the same frame
14concurrently however, we choose the fastest one (in use at the time).
15
16Patch 1 of 2
17
18Origin: https://gitlab.gnome.org/vanvugt/mutter/commits/add-vsync-3.28
19Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=781296
20Bug-Ubuntu: https://bugs.launchpad.net/bugs/1763892
21Applied-Upstream: https://gitlab.gnome.org/vanvugt/mutter/commit/e9e4b2b7
22Forwarded: yes
23Last-Update: 2019-03-13
24---
25 src/Makefile.am | 25 ++++++++++-
26 src/backends/native/meta-gpu-kms.c | 69 +++++++++++++++++++++++++++---
27 src/backends/native/meta-gpu-kms.h | 3 ++
28 src/backends/native/meta-renderer-native.c | 38 +++++++++++++++-
29 src/meta-marshal.list | 1 +
30 5 files changed, 128 insertions(+), 8 deletions(-)
31 create mode 100644 src/meta-marshal.list
32
33diff --git a/src/Makefile.am b/src/Makefile.am
34index bcb3505..13862e9 100644
35--- a/src/Makefile.am
36+++ b/src/Makefile.am
37@@ -51,6 +51,8 @@ mutter_built_sources = \
38 $(dbus_login1_built_sources) \
39 meta/meta-enum-types.h \
40 meta-enum-types.c \
41+ meta-marshal.c \
42+ meta-marshal.h \
43 $(NULL)
44
45 if HAVE_REMOTE_DESKTOP
46@@ -653,6 +655,7 @@ EXTRA_DIST += \
47 libmutter.pc.in \
48 meta-enum-types.h.in \
49 meta-enum-types.c.in \
50+ meta-marshal.list \
51 org.freedesktop.login1.xml \
52 org.gnome.Mutter.DisplayConfig.xml \
53 org.gnome.Mutter.IdleMonitor.xml \
54@@ -666,7 +669,10 @@ BUILT_SOURCES = \
55 $(libmutterinclude_built_headers)
56
57 MUTTER_STAMP_FILES = stamp-meta-enum-types.h
58-CLEANFILES += $(MUTTER_STAMP_FILES)
59+CLEANFILES += \
60+ $(MUTTER_STAMP_FILES) \
61+ meta-marshal.c \
62+ meta-marshal.h
63
64 meta/meta-enum-types.h: stamp-meta-enum-types.h Makefile
65 @true
66@@ -760,3 +766,20 @@ endef
67 $(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@
68 %-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
69 $(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@
70+
71+meta_marshal_opts = --prefix=meta_marshal --internal
72+
73+meta-marshal.h: meta-marshal.list
74+ $(AM_V_GEN)$(GLIB_GENMARSHAL) \
75+ --header \
76+ $(meta_marshal_opts) \
77+ --output=$@ \
78+ $<
79+
80+meta-marshal.c: meta-marshal.list meta-marshal.h
81+ $(AM_V_GEN)$(GLIB_GENMARSHAL) \
82+ --include-header=meta-marshal.h \
83+ $(meta_marshal_opts) \
84+ --body \
85+ --output=$@ \
86+ $<
87diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
88index 815caf5..02649c5 100644
89--- a/src/backends/native/meta-gpu-kms.c
90+++ b/src/backends/native/meta-gpu-kms.c
91@@ -27,6 +27,7 @@
92 #include <errno.h>
93 #include <poll.h>
94 #include <string.h>
95+#include <time.h>
96 #include <xf86drm.h>
97 #include <xf86drmMode.h>
98
99@@ -51,6 +52,7 @@ typedef struct _MetaGpuKmsFlipClosureContainer
100 {
101 GClosure *flip_closure;
102 MetaGpuKms *gpu_kms;
103+ MetaCrtc *crtc;
104 } MetaGpuKmsFlipClosureContainer;
105
106 struct _MetaGpuKms
107@@ -61,6 +63,8 @@ struct _MetaGpuKms
108 char *file_path;
109 GSource *source;
110
111+ clockid_t clock_id;
112+
113 drmModeConnector **connectors;
114 unsigned int n_connectors;
115
116@@ -166,18 +170,26 @@ meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
117
118 static void
119 invoke_flip_closure (GClosure *flip_closure,
120- MetaGpuKms *gpu_kms)
121+ MetaGpuKms *gpu_kms,
122+ MetaCrtc *crtc,
123+ int64_t page_flip_time_ns)
124 {
125 GValue params[] = {
126 G_VALUE_INIT,
127- G_VALUE_INIT
128+ G_VALUE_INIT,
129+ G_VALUE_INIT,
130+ G_VALUE_INIT,
131 };
132
133 g_value_init (&params[0], G_TYPE_POINTER);
134 g_value_set_pointer (&params[0], flip_closure);
135 g_value_init (&params[1], G_TYPE_OBJECT);
136 g_value_set_object (&params[1], gpu_kms);
137- g_closure_invoke (flip_closure, NULL, 2, params, NULL);
138+ g_value_init (&params[2], G_TYPE_OBJECT);
139+ g_value_set_object (&params[2], crtc);
140+ g_value_init (&params[3], G_TYPE_INT64);
141+ g_value_set_int64 (&params[3], page_flip_time_ns);
142+ g_closure_invoke (flip_closure, NULL, 4, params, NULL);
143 g_closure_unref (flip_closure);
144 }
145
146@@ -217,6 +229,7 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
147
148 MetaGpuKmsFlipClosureContainer *
149 meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
150+ MetaCrtc *crtc,
151 GClosure *flip_closure)
152 {
153 MetaGpuKmsFlipClosureContainer *closure_container;
154@@ -224,7 +237,8 @@ meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
155 closure_container = g_new0 (MetaGpuKmsFlipClosureContainer, 1);
156 *closure_container = (MetaGpuKmsFlipClosureContainer) {
157 .flip_closure = flip_closure,
158- .gpu_kms = gpu_kms
159+ .gpu_kms = gpu_kms,
160+ .crtc = crtc
161 };
162
163 return closure_container;
164@@ -264,6 +278,7 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
165 int kms_fd = meta_gpu_kms_get_fd (gpu_kms);
166
167 closure_container = meta_gpu_kms_wrap_flip_closure (gpu_kms,
168+ crtc,
169 flip_closure);
170
171 ret = drmModePageFlip (kms_fd,
172@@ -297,6 +312,23 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
173 return TRUE;
174 }
175
176+static int64_t
177+timespec_to_nanoseconds (const struct timespec *ts)
178+{
179+ const int64_t one_billion = 1000000000;
180+
181+ return ((int64_t) ts->tv_sec) * one_billion + ts->tv_nsec;
182+}
183+
184+static int64_t
185+timeval_to_nanoseconds (const struct timeval *tv)
186+{
187+ int64_t usec = ((int64_t) tv->tv_sec) * G_USEC_PER_SEC + tv->tv_usec;
188+ int64_t nsec = usec * 1000;
189+
190+ return nsec;
191+}
192+
193 static void
194 page_flip_handler (int fd,
195 unsigned int frame,
196@@ -307,8 +339,12 @@ page_flip_handler (int fd,
197 MetaGpuKmsFlipClosureContainer *closure_container = user_data;
198 GClosure *flip_closure = closure_container->flip_closure;
199 MetaGpuKms *gpu_kms = closure_container->gpu_kms;
200+ struct timeval page_flip_time = {sec, usec};
201
202- invoke_flip_closure (flip_closure, gpu_kms);
203+ invoke_flip_closure (flip_closure,
204+ gpu_kms,
205+ closure_container->crtc,
206+ timeval_to_nanoseconds (&page_flip_time));
207 meta_gpu_kms_flip_closure_container_free (closure_container);
208 }
209
210@@ -381,6 +417,17 @@ meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms)
211 return gpu_kms->file_path;
212 }
213
214+int64_t
215+_meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms)
216+{
217+ struct timespec ts;
218+
219+ if (clock_gettime (gpu_kms->clock_id, &ts))
220+ return 0;
221+
222+ return timespec_to_nanoseconds (&ts);
223+}
224+
225 void
226 meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
227 uint64_t state)
228@@ -680,6 +727,17 @@ init_crtcs (MetaGpuKms *gpu_kms,
229 meta_gpu_take_crtcs (gpu, crtcs);
230 }
231
232+static void
233+init_frame_clock (MetaGpuKms *gpu_kms)
234+{
235+ uint64_t uses_monotonic;
236+
237+ if (drmGetCap (gpu_kms->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &uses_monotonic) != 0)
238+ uses_monotonic = 0;
239+
240+ gpu_kms->clock_id = uses_monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME;
241+}
242+
243 static void
244 init_outputs (MetaGpuKms *gpu_kms,
245 MetaKmsResources *resources)
246@@ -809,6 +867,7 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
247 init_modes (gpu_kms, resources.resources);
248 init_crtcs (gpu_kms, &resources);
249 init_outputs (gpu_kms, &resources);
250+ init_frame_clock (gpu_kms);
251
252 meta_kms_resources_release (&resources);
253
254diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h
255index 01c3f2c..c12246c 100644
256--- a/src/backends/native/meta-gpu-kms.h
257+++ b/src/backends/native/meta-gpu-kms.h
258@@ -81,6 +81,8 @@ int meta_gpu_kms_get_fd (MetaGpuKms *gpu_kms);
259
260 const char * meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms);
261
262+int64_t _meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms);
263+
264 void meta_gpu_kms_get_max_buffer_size (MetaGpuKms *gpu_kms,
265 int *max_width,
266 int *max_height);
267@@ -97,6 +99,7 @@ gboolean meta_drm_mode_equal (const drmModeModeInfo *one,
268 float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *mode);
269
270 MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
271+ MetaCrtc *crtc,
272 GClosure *flip_closure);
273
274 void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container);
275diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
276index 470da88..0fd104b 100644
277--- a/src/backends/native/meta-renderer-native.c
278+++ b/src/backends/native/meta-renderer-native.c
279@@ -61,6 +61,7 @@
280 #include "backends/native/meta-monitor-manager-kms.h"
281 #include "backends/native/meta-renderer-native.h"
282 #include "backends/native/meta-renderer-native-gles3.h"
283+#include "meta-marshal.h"
284 #include "cogl/cogl.h"
285 #include "core/boxes-private.h"
286
287@@ -1157,6 +1158,8 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
288 static void
289 on_crtc_flipped (GClosure *closure,
290 MetaGpuKms *gpu_kms,
291+ MetaCrtc *crtc,
292+ int64_t page_flip_time_ns,
293 MetaRendererView *view)
294 {
295 ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view);
296@@ -1167,6 +1170,24 @@ on_crtc_flipped (GClosure *closure,
297 MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
298 MetaRendererNative *renderer_native = onscreen_native->renderer_native;
299 MetaGpuKms *render_gpu = onscreen_native->render_gpu;
300+ CoglFrameInfo *frame_info;
301+ float refresh_rate;
302+
303+ frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
304+ refresh_rate = crtc && crtc->current_mode ?
305+ crtc->current_mode->refresh_rate :
306+ 0.0f;
307+
308+ /* Only keep the frame info for the fastest CRTC in use, which may not be
309+ * the first one to complete a flip. By only telling the compositor about the
310+ * fastest monitor(s) we direct it to produce new frames fast enough to
311+ * satisfy all monitors.
312+ */
313+ if (refresh_rate >= frame_info->refresh_rate)
314+ {
315+ frame_info->presentation_time = page_flip_time_ns;
316+ frame_info->refresh_rate = refresh_rate;
317+ }
318
319 if (gpu_kms != render_gpu)
320 {
321@@ -1297,7 +1318,9 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
322 return FALSE;
323
324 closure_container =
325- meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu, flip_closure);
326+ meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu,
327+ NULL,
328+ flip_closure);
329
330 acquire_attribs = (EGLAttrib[]) {
331 EGL_DRM_FLIP_EVENT_DATA_NV,
332@@ -1540,7 +1563,7 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
333 flip_closure = g_cclosure_new (G_CALLBACK (on_crtc_flipped),
334 g_object_ref (view),
335 (GClosureNotify) flip_closure_destroyed);
336- g_closure_set_marshal (flip_closure, g_cclosure_marshal_VOID__OBJECT);
337+ g_closure_set_marshal (flip_closure, meta_marshal_VOID__OBJECT_OBJECT_INT64);
338
339 /* Either flip the CRTC's of the monitor info, if we are drawing just part
340 * of the stage, or all of the CRTC's if we are drawing the whole stage.
341@@ -2673,6 +2696,15 @@ meta_renderer_native_create_offscreen (MetaRendererNative *renderer,
342 return fb;
343 }
344
345+static int64_t
346+meta_renderer_native_get_clock_time (CoglContext *context)
347+{
348+ CoglRenderer *cogl_renderer = cogl_context_get_renderer (context);
349+ MetaGpuKms *gpu_kms = cogl_renderer->custom_winsys_user_data;
350+
351+ return _meta_gpu_kms_get_current_time_ns (gpu_kms);
352+}
353+
354 static const CoglWinsysVtable *
355 get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
356 {
357@@ -2701,6 +2733,8 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
358 vtable.onscreen_swap_buffers_with_damage =
359 meta_onscreen_native_swap_buffers_with_damage;
360
361+ vtable.context_get_clock_time = meta_renderer_native_get_clock_time;
362+
363 vtable_inited = TRUE;
364 }
365
366diff --git a/src/meta-marshal.list b/src/meta-marshal.list
367new file mode 100644
368index 0000000..c1f4781
369--- /dev/null
370+++ b/src/meta-marshal.list
371@@ -0,0 +1 @@
372+VOID:OBJECT,OBJECT,INT64
diff --git a/debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch b/debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch
0new file mode 100644373new file mode 100644
index 0000000..9a6a64d
--- /dev/null
+++ b/debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch
@@ -0,0 +1,53 @@
1From: Daniel van Vugt <daniel.van.vugt@canonical.com>
2Date: Fri, 3 May 2019 11:31:08 -0500
3Subject: renderer-native: Advertise _FEATURE_SWAP_THROTTLE
4
5Because it is implemented and always on. By advertising this fact
6the master clock is able to sync to the native refresh rate instead
7of always using the fallback of 60.00Hz.
8
9Patch 2 of 2
10
11Origin: https://gitlab.gnome.org/vanvugt/mutter/commits/add-vsync-3.28
12Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=781296
13Bug-Ubuntu: https://bugs.launchpad.net/bugs/1763892
14Applied-Upstream: https://gitlab.gnome.org/vanvugt/mutter/commit/e8c27603
15Forwarded: yes
16Last-Update: 2019-03-13
17---
18 src/backends/native/meta-renderer-native.c | 15 +++++++++++++--
19 1 file changed, 13 insertions(+), 2 deletions(-)
20
21diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
22index 0fd104b..dce7981 100644
23--- a/src/backends/native/meta-renderer-native.c
24+++ b/src/backends/native/meta-renderer-native.c
25@@ -1997,6 +1997,13 @@ meta_renderer_native_init_egl_context (CoglContext *cogl_context,
26 COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
27 TRUE);
28
29+ /* COGL_WINSYS_FEATURE_SWAP_THROTTLE is always true for this renderer
30+ * because we have the call to wait_for_pending_flips on every frame.
31+ */
32+ COGL_FLAGS_SET (cogl_context->winsys_features,
33+ COGL_WINSYS_FEATURE_SWAP_THROTTLE,
34+ TRUE);
35+
36 #ifdef HAVE_EGL_DEVICE
37 if (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_EGL_DEVICE)
38 COGL_FLAGS_SET (cogl_context->features,
39@@ -2625,8 +2632,12 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native,
40 }
41
42 onscreen = cogl_onscreen_new (context, width, height);
43- cogl_onscreen_set_swap_throttled (onscreen,
44- _clutter_get_sync_to_vblank ());
45+
46+ /* We have wait_for_pending_flips hardcoded, so throttling always. */
47+ cogl_onscreen_set_swap_throttled (onscreen, TRUE);
48+ if (!_clutter_get_sync_to_vblank ())
49+ g_warning ("Request to disable sync-to-vblank is being ignored. "
50+ "MetaRendererNative does not support disabling it.");
51
52 if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), error))
53 {
diff --git a/debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch b/debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch
0new file mode 10064454new file mode 100644
index 0000000..5512752
--- /dev/null
+++ b/debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch
@@ -0,0 +1,37 @@
1From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
2Date: Thu, 11 Oct 2018 08:16:26 -0500
3Subject: monitor-manager: Don't use switch-config when ensuring configuration
4
5Switch-configs are only to be used in certain circumstances (see
6meta_monitor_manager_can_switch_config()) so when ensuring
7configuration and attempting to create a linear configuration, use the
8linear configuration constructor function directly without going via the
9switch config method, otherwise we might incorrectly fall back to the
10fallback configuration (only enable primary monitor).
11
12This is a regression introduced by 6267732bec97773.
13
14Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/342
15
16Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1772811
17Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/262
18Applied-Upstream: yes, 3.32.0
19---
20 src/backends/meta-monitor-manager.c | 4 +---
21 1 file changed, 1 insertion(+), 3 deletions(-)
22
23diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
24index fde61eb..39ed813 100644
25--- a/src/backends/meta-monitor-manager.c
26+++ b/src/backends/meta-monitor-manager.c
27@@ -582,9 +582,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
28 g_clear_object (&config);
29 }
30
31- config =
32- meta_monitor_config_manager_create_for_switch_config (manager->config_manager,
33- META_MONITOR_SWITCH_CONFIG_ALL_LINEAR);
34+ config = meta_monitor_config_manager_create_linear (manager->config_manager);
35 if (config)
36 {
37 if (!meta_monitor_manager_apply_monitors_config (manager,
diff --git a/debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch b/debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch
0new file mode 10064438new file mode 100644
index 0000000..a791f59
--- /dev/null
+++ b/debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch
@@ -0,0 +1,198 @@
1From: Daniel Drake <drake@endlessm.com>
2Date: Wed, 29 Aug 2018 19:34:53 -0500
3Subject: monitor-manager: use MonitorsConfig to track switch_config
4
5When constructing MetaMonitorsConfig objects, store which type
6of switch_config they are for (or UNKNOWN if it is not such
7type of config).
8
9Stop unconditionally setting current_switch_config to UNKNOWN when
10handling monitors changed events. Instead, set it to the switch_config
11type stored in the MonitorsConfig in the codepath that updates logical
12state. In addition to being called in the hotplug case along the same
13code flow that generates monitors changed events, this is also called
14in the coldplug case where a secondary monitor was connected before
15mutter was started.
16
17When creating the default linear display config, create it as a
18switch_config so that internal state gets updated to represent
19linear mode when this config is used.
20
21The previous behaviour of unconditionally resetting current_switch_config
22to UNKNOWN was breaking the internal state machine for display config
23switching, causing misbehaviour in gnome-shell's switchMonitor UI when
24using display switch hotkeys. The lack of internal tracking when the
25displays are already in the default "Join Displays" linear mode was
26then causing the first display switch hotkey press to do nothing
27(it would attempt to select "Join Displays" mode, but that was already
28active).
29
30Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/281
31https://gitlab.gnome.org/GNOME/mutter/merge_requests/213
32
33Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1772811
34Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/213
35Applied-Upstream: yes, 3.30.1
36---
37 src/backends/meta-monitor-config-manager.c | 36 +++++++++++++++++++++++++-----
38 src/backends/meta-monitor-config-manager.h | 7 ++++++
39 src/backends/meta-monitor-manager.c | 25 ++++++++++++++++-----
40 3 files changed, 56 insertions(+), 12 deletions(-)
41
42diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
43index 197892b..ce61547 100644
44--- a/src/backends/meta-monitor-config-manager.c
45+++ b/src/backends/meta-monitor-config-manager.c
46@@ -1007,6 +1007,7 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager
47 MetaMonitorSwitchConfigType config_type)
48 {
49 MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
50+ MetaMonitorsConfig *config;
51
52 if (!meta_monitor_manager_can_switch_config (monitor_manager))
53 return NULL;
54@@ -1014,18 +1015,27 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager
55 switch (config_type)
56 {
57 case META_MONITOR_SWITCH_CONFIG_ALL_MIRROR:
58- return create_for_switch_config_all_mirror (config_manager);
59+ config = create_for_switch_config_all_mirror (config_manager);
60+ break;
61 case META_MONITOR_SWITCH_CONFIG_ALL_LINEAR:
62- return meta_monitor_config_manager_create_linear (config_manager);
63+ config = meta_monitor_config_manager_create_linear (config_manager);
64+ break;
65 case META_MONITOR_SWITCH_CONFIG_EXTERNAL:
66- return create_for_switch_config_external (config_manager);
67+ config = create_for_switch_config_external (config_manager);
68+ break;
69 case META_MONITOR_SWITCH_CONFIG_BUILTIN:
70- return create_for_switch_config_builtin (config_manager);
71+ config = create_for_switch_config_builtin (config_manager);
72+ break;
73 case META_MONITOR_SWITCH_CONFIG_UNKNOWN:
74+ default:
75 g_warn_if_reached ();
76- break;
77+ return NULL;
78 }
79- return NULL;
80+
81+ if (config)
82+ _meta_monitors_config_set_switch_config (config, config_type);
83+
84+ return config;
85 }
86
87 void
88@@ -1217,6 +1227,19 @@ meta_monitors_config_key_equal (gconstpointer data_a,
89 return TRUE;
90 }
91
92+MetaMonitorSwitchConfigType
93+_meta_monitors_config_get_switch_config (MetaMonitorsConfig *config)
94+{
95+ return config->switch_config;
96+}
97+
98+void
99+_meta_monitors_config_set_switch_config (MetaMonitorsConfig *config,
100+ MetaMonitorSwitchConfigType switch_config)
101+{
102+ config->switch_config = switch_config;
103+}
104+
105 MetaMonitorsConfig *
106 meta_monitors_config_new_full (GList *logical_monitor_configs,
107 GList *disabled_monitor_specs,
108@@ -1232,6 +1255,7 @@ meta_monitors_config_new_full (GList *logical_monitor_con
109 disabled_monitor_specs);
110 config->layout_mode = layout_mode;
111 config->flags = flags;
112+ config->switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
113
114 return config;
115 }
116diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
117index 269d8e1..4ac0b1d 100644
118--- a/src/backends/meta-monitor-config-manager.h
119+++ b/src/backends/meta-monitor-config-manager.h
120@@ -69,6 +69,8 @@ struct _MetaMonitorsConfig
121 MetaMonitorsConfigFlag flags;
122
123 MetaLogicalMonitorLayoutMode layout_mode;
124+
125+ MetaMonitorSwitchConfigType switch_config;
126 };
127
128 #define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ())
129@@ -124,6 +126,11 @@ MetaMonitorsConfig * meta_monitors_config_new (MetaMonitorManager *mon
130 MetaLogicalMonitorLayoutMode layout_mode,
131 MetaMonitorsConfigFlag flags);
132
133+MetaMonitorSwitchConfigType _meta_monitors_config_get_switch_config (MetaMonitorsConfig *config);
134+
135+void _meta_monitors_config_set_switch_config (MetaMonitorsConfig *config,
136+ MetaMonitorSwitchConfigType switch_config);
137+
138 unsigned int meta_monitors_config_key_hash (gconstpointer config_key);
139
140 gboolean meta_monitors_config_key_equal (gconstpointer config_key_a,
141diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
142index ec18600..fde61eb 100644
143--- a/src/backends/meta-monitor-manager.c
144+++ b/src/backends/meta-monitor-manager.c
145@@ -582,7 +582,9 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
146 g_clear_object (&config);
147 }
148
149- config = meta_monitor_config_manager_create_linear (manager->config_manager);
150+ config =
151+ meta_monitor_config_manager_create_for_switch_config (manager->config_manager,
152+ META_MONITOR_SWITCH_CONFIG_ALL_LINEAR);
153 if (config)
154 {
155 if (!meta_monitor_manager_apply_monitors_config (manager,
156@@ -2652,8 +2654,6 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
157 static void
158 meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
159 {
160- manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
161-
162 meta_backend_monitors_changed (manager->backend);
163
164 g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0);
165@@ -2710,10 +2710,17 @@ meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
166 MetaMonitorsConfig *config)
167 {
168 if (config)
169- manager->layout_mode = config->layout_mode;
170+ {
171+ manager->layout_mode = config->layout_mode;
172+ manager->current_switch_config =
173+ _meta_monitors_config_get_switch_config (config);
174+ }
175 else
176- manager->layout_mode =
177- meta_monitor_manager_get_default_layout_mode (manager);
178+ {
179+ manager->layout_mode =
180+ meta_monitor_manager_get_default_layout_mode (manager);
181+ manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
182+ }
183
184 meta_monitor_manager_rebuild_logical_monitors (manager, config);
185 }
186@@ -2755,6 +2762,12 @@ void
187 meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager,
188 MetaMonitorsConfig *config)
189 {
190+ if (config)
191+ manager->current_switch_config =
192+ _meta_monitors_config_get_switch_config (config);
193+ else
194+ manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
195+
196 manager->layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
197
198 meta_monitor_manager_rebuild_logical_monitors_derived (manager, config);
diff --git a/debian/patches/series b/debian/patches/series
index 198db5a..8ff6307 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,8 +1,13 @@
1theme-use-gtk_render_icon_suface-to-paint-button-icon.patch1theme-use-gtk_render_icon_suface-to-paint-button-icon.patch
2theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch2theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch
3clutter-Smooth-out-master-clock-to-smooth-visuals.patch
4clutter-Fix-offscreen-effect-painting-of-clones.patch3clutter-Fix-offscreen-effect-painting-of-clones.patch
5bgo768531_workaround-startup-notifications.patch4bgo768531_workaround-startup-notifications.patch
5monitor-manager-use-MonitorsConfig-to-track-switch_config.patch
6monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch
7clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch
8clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch
9lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch
10lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch
6debian/synaptics-support.patch11debian/synaptics-support.patch
7debian/skip-failing-tests.patch12debian/skip-failing-tests.patch
8debian/skip-failing-tests-325.patch13debian/skip-failing-tests-325.patch

Subscribers

People subscribed via source and target branches