Merge ~3v1n0/ubuntu/+source/mutter:ubuntu/bionic into ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/bionic
- Git
- lp:~3v1n0/ubuntu/+source/mutter
- ubuntu/bionic
- Merge into 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) |
||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt (community) | Approve | ||
Ubuntu Desktop | Pending | ||
Review via email: mp+366676@code.launchpad.net |
Commit message
Description of the change
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 : | # |
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
1 | diff --git a/debian/changelog b/debian/changelog | |||
2 | index 99219d6..a1467bf 100644 | |||
3 | --- a/debian/changelog | |||
4 | +++ b/debian/changelog | |||
5 | @@ -1,3 +1,21 @@ | |||
6 | 1 | mutter (3.28.3+git20190124-0ubuntu18.04.3) UNRELEASED; urgency=medium | ||
7 | 2 | |||
8 | 3 | * d/p/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch, | ||
9 | 4 | d/p/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch: | ||
10 | 5 | - Ensure switch display mode is cyclic (LP: #1772811) | ||
11 | 6 | * d/p/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch, | ||
12 | 7 | d/p/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch: | ||
13 | 8 | - Implement keycode remap to keysyms on virtual key devices (LP: #1827029) | ||
14 | 9 | |||
15 | 10 | [ Daniel van Vugt ] | ||
16 | 11 | * d/p/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch, | ||
17 | 12 | d/p/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch: | ||
18 | 13 | - Add support for high frame rate displays (LP: #1763892) | ||
19 | 14 | * d/p/clutter-Smooth-out-master-clock-to-smooth-visuals.patch: | ||
20 | 15 | - Dropped | ||
21 | 16 | |||
22 | 17 | -- Marco Trevisan (Treviño) <marco@ubuntu.com> Mon, 29 Apr 2019 23:29:24 -0500 | ||
23 | 18 | |||
24 | 1 | mutter (3.28.3+git20190124-0ubuntu18.04.2) bionic; urgency=medium | 19 | mutter (3.28.3+git20190124-0ubuntu18.04.2) bionic; urgency=medium |
25 | 2 | 20 | ||
26 | 3 | * control: Add Breaks on budgie-desktop verions broken by this upload. | 21 | * control: Add Breaks on budgie-desktop verions broken by this upload. |
27 | 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 | |||
28 | 4 | deleted file mode 100644 | 22 | deleted file mode 100644 |
29 | index 2239837..0000000 | |||
30 | --- a/debian/patches/clutter-Smooth-out-master-clock-to-smooth-visuals.patch | |||
31 | +++ /dev/null | |||
32 | @@ -1,225 +0,0 @@ | |||
33 | 1 | From: Daniel van Vugt <daniel.van.vugt@canonical.com> | ||
34 | 2 | Date: Fri, 16 Feb 2018 02:50:59 -0600 | ||
35 | 3 | Subject: clutter: Smooth out master clock to smooth visuals | ||
36 | 4 | |||
37 | 5 | Clutter's master clock was jittery because it included errors in cur_tick | ||
38 | 6 | such as dispatch delays due to other sources. Dispatch could also occur up | ||
39 | 7 | to 1ms early since GSource can only be timed to the millisecond. All of this | ||
40 | 8 | could impact the visual smoothness of animations as they are displayed on | ||
41 | 9 | the steady interval of the monitor, but spacially moving in less regular | ||
42 | 10 | steps derived from the dispatch times. | ||
43 | 11 | |||
44 | 12 | The simple fix is to ignore any jitter in dispatch timing. Try a little | ||
45 | 13 | bit harder to use a precise interval that will better match the display | ||
46 | 14 | hardware, and smoother visuals will follow. | ||
47 | 15 | |||
48 | 16 | Bug: https://gitlab.gnome.org/GNOME/mutter/issues/25 | ||
49 | 17 | Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/70 | ||
50 | 18 | --- | ||
51 | 19 | clutter/clutter/clutter-master-clock-default.c | 134 +++++++++++++++++-------- | ||
52 | 20 | 1 file changed, 93 insertions(+), 41 deletions(-) | ||
53 | 21 | |||
54 | 22 | diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c | ||
55 | 23 | index 7b2df0d..97b6d13 100644 | ||
56 | 24 | --- a/clutter/clutter/clutter-master-clock-default.c | ||
57 | 25 | +++ b/clutter/clutter/clutter-master-clock-default.c | ||
58 | 26 | @@ -69,8 +69,10 @@ struct _ClutterMasterClockDefault | ||
59 | 27 | /* the previous state of the clock, in usecs, used to compute the delta */ | ||
60 | 28 | gint64 prev_tick; | ||
61 | 29 | |||
62 | 30 | + /* the ideal frame interval in usecs (inverse of your max refresh rate) */ | ||
63 | 31 | + gint64 frame_interval; | ||
64 | 32 | + | ||
65 | 33 | #ifdef CLUTTER_ENABLE_DEBUG | ||
66 | 34 | - gint64 frame_budget; | ||
67 | 35 | gint64 remaining_budget; | ||
68 | 36 | #endif | ||
69 | 37 | |||
70 | 38 | @@ -264,6 +266,41 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock, | ||
71 | 39 | } | ||
72 | 40 | } | ||
73 | 41 | |||
74 | 42 | +static gint64 | ||
75 | 43 | +estimate_next_presentation_time (ClutterMasterClockDefault *master_clock) | ||
76 | 44 | +{ | ||
77 | 45 | + gint64 frame_phase, now, now_phase, undershoot; | ||
78 | 46 | + | ||
79 | 47 | + /* In future if this was updated from the backend's (maximum) refresh rate | ||
80 | 48 | + * then that would fix: https://bugzilla.gnome.org/show_bug.cgi?id=781296 | ||
81 | 49 | + */ | ||
82 | 50 | + master_clock->frame_interval = G_USEC_PER_SEC / | ||
83 | 51 | + clutter_get_default_frame_rate (); | ||
84 | 52 | + | ||
85 | 53 | + now = g_source_get_time (master_clock->source); | ||
86 | 54 | + now_phase = now % master_clock->frame_interval; | ||
87 | 55 | + | ||
88 | 56 | + /* To be precise we would like to use: | ||
89 | 57 | + * frame_phase = a_recent_hardware_presentation_time % frame_interval; | ||
90 | 58 | + * where hardware_presentation_time must be using the same clock as | ||
91 | 59 | + * g_source_get_time. Unfortunately they're different clocks right now | ||
92 | 60 | + * so we can't. | ||
93 | 61 | + * Alternatively, we could replace g_source_get_time in future with the | ||
94 | 62 | + * current time in the clutter/cogl presentation clock, but that function | ||
95 | 63 | + * also doesn't exist yet. | ||
96 | 64 | + * Until we can get either of those, zero is fine. It just means latency | ||
97 | 65 | + * will be suboptimal by half a frame on average. We still get maximum | ||
98 | 66 | + * smoothness this way... | ||
99 | 67 | + */ | ||
100 | 68 | + frame_phase = 0; | ||
101 | 69 | + | ||
102 | 70 | + undershoot = frame_phase - now_phase; | ||
103 | 71 | + if (undershoot < 0) | ||
104 | 72 | + undershoot += master_clock->frame_interval; | ||
105 | 73 | + | ||
106 | 74 | + return now + undershoot; | ||
107 | 75 | +} | ||
108 | 76 | + | ||
109 | 77 | /* | ||
110 | 78 | * master_clock_next_frame_delay: | ||
111 | 79 | * @master_clock: a #ClutterMasterClock | ||
112 | 80 | @@ -276,7 +313,8 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock, | ||
113 | 81 | static gint | ||
114 | 82 | master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock) | ||
115 | 83 | { | ||
116 | 84 | - gint64 now, next; | ||
117 | 85 | + gint64 now, target_presentation_time, ideal_render_start; /* timestamps */ | ||
118 | 86 | + gint64 ideal_prerender_time, lateness; /* deltas */ | ||
119 | 87 | gint swap_delay; | ||
120 | 88 | |||
121 | 89 | if (!master_clock_is_running (master_clock)) | ||
122 | 90 | @@ -307,46 +345,45 @@ master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock) | ||
123 | 91 | return 0; | ||
124 | 92 | } | ||
125 | 93 | |||
126 | 94 | - if (master_clock->prev_tick == 0) | ||
127 | 95 | - { | ||
128 | 96 | - /* If we weren't previously running, then draw the next frame | ||
129 | 97 | - * immediately | ||
130 | 98 | - */ | ||
131 | 99 | - CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately"); | ||
132 | 100 | - return 0; | ||
133 | 101 | - } | ||
134 | 102 | - | ||
135 | 103 | - /* Otherwise, wait at least 1/frame_rate seconds since we last | ||
136 | 104 | - * started a frame | ||
137 | 105 | - */ | ||
138 | 106 | now = g_source_get_time (master_clock->source); | ||
139 | 107 | |||
140 | 108 | - next = master_clock->prev_tick; | ||
141 | 109 | - | ||
142 | 110 | - /* If time has gone backwards then there's no way of knowing how | ||
143 | 111 | - long we should wait so let's just dispatch immediately */ | ||
144 | 112 | - if (now <= next) | ||
145 | 113 | + /* As first preference, try to carry on smoothly from the previous frame, | ||
146 | 114 | + * even if that means we start rendering frame 2 before frame 1 has been | ||
147 | 115 | + * presented. This is why we ignore estimate_next_presentation_time here... | ||
148 | 116 | + */ | ||
149 | 117 | + target_presentation_time = master_clock->prev_tick + | ||
150 | 118 | + master_clock->frame_interval; | ||
151 | 119 | + ideal_prerender_time = master_clock->frame_interval; | ||
152 | 120 | + ideal_render_start = target_presentation_time - ideal_prerender_time; | ||
153 | 121 | + lateness = now - ideal_render_start; | ||
154 | 122 | + | ||
155 | 123 | + /* If we just woke from idle then try to improve the smoothness of the first | ||
156 | 124 | + * two frames some more. Otherwise the first frame would appear too old | ||
157 | 125 | + * relative to the second frame. | ||
158 | 126 | + */ | ||
159 | 127 | + if (lateness >= master_clock->frame_interval) | ||
160 | 128 | { | ||
161 | 129 | - CLUTTER_NOTE (SCHEDULER, "Time has gone backwards"); | ||
162 | 130 | - | ||
163 | 131 | - return 0; | ||
164 | 132 | + target_presentation_time = estimate_next_presentation_time (master_clock); | ||
165 | 133 | + ideal_render_start = target_presentation_time - ideal_prerender_time; | ||
166 | 134 | + lateness = now - ideal_render_start; | ||
167 | 135 | } | ||
168 | 136 | |||
169 | 137 | - next += (1000000L / clutter_get_default_frame_rate ()); | ||
170 | 138 | - | ||
171 | 139 | - if (next <= now) | ||
172 | 140 | + if (lateness > 0) | ||
173 | 141 | { | ||
174 | 142 | - CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs", | ||
175 | 143 | - 1000000L / (gulong) clutter_get_default_frame_rate ()); | ||
176 | 144 | - | ||
177 | 145 | + CLUTTER_NOTE (SCHEDULER, "No wait required. We're already late."); | ||
178 | 146 | return 0; | ||
179 | 147 | } | ||
180 | 148 | else | ||
181 | 149 | { | ||
182 | 150 | - CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs", | ||
183 | 151 | - (next - now) / 1000); | ||
184 | 152 | - | ||
185 | 153 | - return (next - now) / 1000; | ||
186 | 154 | + /* We +1 here to avoid premature dispatches that would otherwise occur | ||
187 | 155 | + * repeatedly during the 1ms before 'ideal_render_start'. We don't care | ||
188 | 156 | + * if this makes the final dispatch 1ms late because the smoothing | ||
189 | 157 | + * algorithm corrects that, and it's much better than attempting to | ||
190 | 158 | + * render more frames than the hardware can physically display... | ||
191 | 159 | + */ | ||
192 | 160 | + gint millisec_delay = -lateness / 1000 + 1; | ||
193 | 161 | + CLUTTER_NOTE (SCHEDULER, "Waiting %dms", millisec_delay); | ||
194 | 162 | + return millisec_delay; | ||
195 | 163 | } | ||
196 | 164 | } | ||
197 | 165 | |||
198 | 166 | @@ -532,16 +569,34 @@ clutter_clock_dispatch (GSource *source, | ||
199 | 167 | ClutterMasterClockDefault *master_clock = clock_source->master_clock; | ||
200 | 168 | gboolean stages_updated = FALSE; | ||
201 | 169 | GSList *stages; | ||
202 | 170 | - | ||
203 | 171 | - CLUTTER_NOTE (SCHEDULER, "Master clock [tick]"); | ||
204 | 172 | + gint64 smooth_tick; | ||
205 | 173 | |||
206 | 174 | _clutter_threads_acquire_lock (); | ||
207 | 175 | |||
208 | 176 | /* Get the time to use for this frame */ | ||
209 | 177 | - master_clock->cur_tick = g_source_get_time (source); | ||
210 | 178 | + smooth_tick = estimate_next_presentation_time (master_clock); | ||
211 | 179 | + if (smooth_tick <= master_clock->prev_tick) | ||
212 | 180 | + { | ||
213 | 181 | + /* Ordinarily this will never happen. But after we fix bug 781296, it | ||
214 | 182 | + * could happen in the rare case when the ideal frame_interval changes, | ||
215 | 183 | + * such as video mode switching or hotplugging monitors. As such it is | ||
216 | 184 | + * not considered a bug (unless it's happening without mode switching | ||
217 | 185 | + * or hotplugging). | ||
218 | 186 | + */ | ||
219 | 187 | + CLUTTER_NOTE (SCHEDULER, "Master clock [tick] was premature (skipped)"); | ||
220 | 188 | + _clutter_threads_release_lock (); | ||
221 | 189 | + return G_SOURCE_CONTINUE; | ||
222 | 190 | + } | ||
223 | 191 | + | ||
224 | 192 | + master_clock->cur_tick = smooth_tick; | ||
225 | 193 | + if (master_clock->prev_tick) | ||
226 | 194 | + CLUTTER_NOTE (SCHEDULER, "Master clock [tick] %+ldus", | ||
227 | 195 | + (long) (master_clock->cur_tick - master_clock->prev_tick)); | ||
228 | 196 | + else | ||
229 | 197 | + CLUTTER_NOTE (SCHEDULER, "Master clock [tick] startup"); | ||
230 | 198 | |||
231 | 199 | #ifdef CLUTTER_ENABLE_DEBUG | ||
232 | 200 | - master_clock->remaining_budget = master_clock->frame_budget; | ||
233 | 201 | + master_clock->remaining_budget = master_clock->frame_interval; | ||
234 | 202 | #endif | ||
235 | 203 | |||
236 | 204 | /* We need to protect ourselves against stages being destroyed during | ||
237 | 205 | @@ -580,7 +635,7 @@ clutter_clock_dispatch (GSource *source, | ||
238 | 206 | |||
239 | 207 | _clutter_threads_release_lock (); | ||
240 | 208 | |||
241 | 209 | - return TRUE; | ||
242 | 210 | + return G_SOURCE_CONTINUE; | ||
243 | 211 | } | ||
244 | 212 | |||
245 | 213 | static void | ||
246 | 214 | @@ -612,10 +667,7 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self) | ||
247 | 215 | self->idle = FALSE; | ||
248 | 216 | self->ensure_next_iteration = FALSE; | ||
249 | 217 | self->paused = FALSE; | ||
250 | 218 | - | ||
251 | 219 | -#ifdef CLUTTER_ENABLE_DEBUG | ||
252 | 220 | - self->frame_budget = G_USEC_PER_SEC / 60; | ||
253 | 221 | -#endif | ||
254 | 222 | + self->frame_interval = G_USEC_PER_SEC / 60; /* Will be refined at runtime */ | ||
255 | 223 | |||
256 | 224 | g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW); | ||
257 | 225 | g_source_set_can_recurse (source, FALSE); | ||
258 | 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 | |||
259 | 226 | new file mode 100644 | 0 | new file mode 100644 |
260 | index 0000000..e2d3140 | |||
261 | --- /dev/null | |||
262 | +++ b/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch | |||
263 | @@ -0,0 +1,53 @@ | |||
264 | 1 | From: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
265 | 2 | Date: Tue, 22 Jan 2019 11:20:37 -0600 | ||
266 | 3 | Subject: clutter/x11: Consider remapped keys when guessing the keycode from | ||
267 | 4 | the keysym | ||
268 | 5 | |||
269 | 6 | Since e3e933c4 a keyval can be temporarily remapped to an unused keycode. Due to | ||
270 | 7 | some limitations in XTestFakeKeyEvent, the remapping has to be done in the first | ||
271 | 8 | xkb group/layout. In case there are two or more keyboard layouts enabled and the | ||
272 | 9 | selected keyboard layout is not the first, clutter_keymap_x11_keycode_for_keyval | ||
273 | 10 | will fail to retrieve the correct keycode for a remapped keyval. Let's use the | ||
274 | 11 | reserved_keycodes map in order to retrieve the correct keycode if needed. | ||
275 | 12 | |||
276 | 13 | Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/443 | ||
277 | 14 | |||
278 | 15 | GNOME-Bug: https://gitlab.gnome.org/GNOME/mutter/issues/443 | ||
279 | 16 | Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1827029 | ||
280 | 17 | Origin: https://gitlab.gnome.org/GNOME/mutter/commit/24b4c82 | ||
281 | 18 | Applied-Upstream: 3.28.4 | ||
282 | 19 | --- | ||
283 | 20 | clutter/clutter/x11/clutter-keymap-x11.c | 20 ++++++++++++++++++++ | ||
284 | 21 | 1 file changed, 20 insertions(+) | ||
285 | 22 | |||
286 | 23 | diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c | ||
287 | 24 | index 5dd40a9..f1bdf16 100644 | ||
288 | 25 | --- a/clutter/clutter/x11/clutter-keymap-x11.c | ||
289 | 26 | +++ b/clutter/clutter/x11/clutter-keymap-x11.c | ||
290 | 27 | @@ -1005,6 +1005,26 @@ clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11, | ||
291 | 28 | } | ||
292 | 29 | } | ||
293 | 30 | |||
294 | 31 | + if (!found) | ||
295 | 32 | + { | ||
296 | 33 | + GHashTableIter iter; | ||
297 | 34 | + gpointer key, value; | ||
298 | 35 | + | ||
299 | 36 | + g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes); | ||
300 | 37 | + while (!found && g_hash_table_iter_next (&iter, &key, &value)) | ||
301 | 38 | + { | ||
302 | 39 | + guint reserved_keycode = GPOINTER_TO_UINT (key); | ||
303 | 40 | + guint reserved_keysym = GPOINTER_TO_UINT (value); | ||
304 | 41 | + | ||
305 | 42 | + if (keyval == reserved_keysym) | ||
306 | 43 | + { | ||
307 | 44 | + *keycode_out = reserved_keycode; | ||
308 | 45 | + *level_out = 0; | ||
309 | 46 | + found = TRUE; | ||
310 | 47 | + } | ||
311 | 48 | + } | ||
312 | 49 | + } | ||
313 | 50 | + | ||
314 | 51 | g_free (keys); | ||
315 | 52 | return found; | ||
316 | 53 | } | ||
317 | 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 | |||
318 | 0 | new file mode 100644 | 54 | new file mode 100644 |
319 | index 0000000..944e1ea | |||
320 | --- /dev/null | |||
321 | +++ b/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch | |||
322 | @@ -0,0 +1,294 @@ | |||
323 | 1 | From: Andrea Azzarone <azzaronea@gmail.com> | ||
324 | 2 | Date: Fri, 13 Jul 2018 07:49:38 -0500 | ||
325 | 3 | Subject: clutter/x11: Implement keycode remap to keysyms on virtual key | ||
326 | 4 | devices | ||
327 | 5 | |||
328 | 6 | Keycode lookup can fail for serveral reasons, e.g. if there is no combination of | ||
329 | 7 | modifiers and keycodes that can produce the target keysym with the current | ||
330 | 8 | keyboard layout. | ||
331 | 9 | |||
332 | 10 | In case the keycode lookup fails, remap temporarily the keysym to an unused | ||
333 | 11 | keycodes. | ||
334 | 12 | |||
335 | 13 | Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/109 | ||
336 | 14 | |||
337 | 15 | GNOME-Bug: https://gitlab.gnome.org/GNOME/mutter/issues/109 | ||
338 | 16 | Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1827029 | ||
339 | 17 | Origin: https://gitlab.gnome.org/GNOME/mutter/commit/6198d389 | ||
340 | 18 | Applied-Upstream: 3.28.4 | ||
341 | 19 | --- | ||
342 | 20 | clutter/clutter/x11/clutter-keymap-x11.c | 167 +++++++++++++++++++++ | ||
343 | 21 | clutter/clutter/x11/clutter-keymap-x11.h | 6 +- | ||
344 | 22 | .../clutter/x11/clutter-virtual-input-device-x11.c | 19 ++- | ||
345 | 23 | 3 files changed, 186 insertions(+), 6 deletions(-) | ||
346 | 24 | |||
347 | 25 | diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c | ||
348 | 26 | index c34e676..5dd40a9 100644 | ||
349 | 27 | --- a/clutter/clutter/x11/clutter-keymap-x11.c | ||
350 | 28 | +++ b/clutter/clutter/x11/clutter-keymap-x11.c | ||
351 | 29 | @@ -79,6 +79,9 @@ struct _ClutterKeymapX11 | ||
352 | 30 | guint current_cache_serial; | ||
353 | 31 | DirectionCacheEntry group_direction_cache[4]; | ||
354 | 32 | int current_group; | ||
355 | 33 | + | ||
356 | 34 | + GHashTable *reserved_keycodes; | ||
357 | 35 | + GQueue *available_keycodes; | ||
358 | 36 | #endif | ||
359 | 37 | |||
360 | 38 | guint caps_lock_state : 1; | ||
361 | 39 | @@ -441,16 +444,100 @@ clutter_keymap_x11_set_property (GObject *gobject, | ||
362 | 40 | } | ||
363 | 41 | } | ||
364 | 42 | |||
365 | 43 | +#ifdef HAVE_XKB | ||
366 | 44 | +static void | ||
367 | 45 | +clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11) | ||
368 | 46 | +{ | ||
369 | 47 | + Display *dpy = clutter_x11_get_default_display (); | ||
370 | 48 | + GHashTableIter iter; | ||
371 | 49 | + gpointer key, value; | ||
372 | 50 | + | ||
373 | 51 | + g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes); | ||
374 | 52 | + while (g_hash_table_iter_next (&iter, &key, &value)) | ||
375 | 53 | + { | ||
376 | 54 | + guint reserved_keycode = GPOINTER_TO_UINT (key); | ||
377 | 55 | + guint reserved_keysym = GPOINTER_TO_UINT (value); | ||
378 | 56 | + guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0); | ||
379 | 57 | + | ||
380 | 58 | + /* If an available keycode is no longer mapped to the stored keysym, then | ||
381 | 59 | + * the keycode should not be considered available anymore and should be | ||
382 | 60 | + * removed both from the list of available and reserved keycodes. | ||
383 | 61 | + */ | ||
384 | 62 | + if (reserved_keysym != actual_keysym) | ||
385 | 63 | + { | ||
386 | 64 | + g_hash_table_iter_remove (&iter); | ||
387 | 65 | + g_queue_remove (keymap_x11->available_keycodes, key); | ||
388 | 66 | + } | ||
389 | 67 | + } | ||
390 | 68 | +} | ||
391 | 69 | + | ||
392 | 70 | +static gboolean | ||
393 | 71 | +clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11, | ||
394 | 72 | + KeyCode keycode, | ||
395 | 73 | + KeySym keysym) | ||
396 | 74 | +{ | ||
397 | 75 | + if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb) | ||
398 | 76 | + { | ||
399 | 77 | + Display *dpy = clutter_x11_get_default_display (); | ||
400 | 78 | + XkbDescPtr xkb = get_xkb (keymap_x11); | ||
401 | 79 | + XkbMapChangesRec changes; | ||
402 | 80 | + | ||
403 | 81 | + XFlush (dpy); | ||
404 | 82 | + | ||
405 | 83 | + xkb->device_spec = XkbUseCoreKbd; | ||
406 | 84 | + memset (&changes, 0, sizeof(changes)); | ||
407 | 85 | + | ||
408 | 86 | + if (keysym != NoSymbol) | ||
409 | 87 | + { | ||
410 | 88 | + int types[XkbNumKbdGroups] = { XkbOneLevelIndex }; | ||
411 | 89 | + XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes); | ||
412 | 90 | + XkbKeySymEntry (xkb, keycode, 0, 0) = keysym; | ||
413 | 91 | + } | ||
414 | 92 | + else | ||
415 | 93 | + { | ||
416 | 94 | + /* Reset to NoSymbol */ | ||
417 | 95 | + XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes); | ||
418 | 96 | + } | ||
419 | 97 | + | ||
420 | 98 | + changes.changed = XkbKeySymsMask | XkbKeyTypesMask; | ||
421 | 99 | + changes.first_key_sym = keycode; | ||
422 | 100 | + changes.num_key_syms = 1; | ||
423 | 101 | + changes.first_type = 0; | ||
424 | 102 | + changes.num_types = xkb->map->num_types; | ||
425 | 103 | + XkbChangeMap (dpy, xkb, &changes); | ||
426 | 104 | + | ||
427 | 105 | + XFlush (dpy); | ||
428 | 106 | + | ||
429 | 107 | + return TRUE; | ||
430 | 108 | + } | ||
431 | 109 | + | ||
432 | 110 | + return FALSE; | ||
433 | 111 | +} | ||
434 | 112 | +#endif | ||
435 | 113 | + | ||
436 | 114 | static void | ||
437 | 115 | clutter_keymap_x11_finalize (GObject *gobject) | ||
438 | 116 | { | ||
439 | 117 | ClutterKeymapX11 *keymap; | ||
440 | 118 | ClutterEventTranslator *translator; | ||
441 | 119 | + GHashTableIter iter; | ||
442 | 120 | + gpointer key, value; | ||
443 | 121 | |||
444 | 122 | keymap = CLUTTER_KEYMAP_X11 (gobject); | ||
445 | 123 | translator = CLUTTER_EVENT_TRANSLATOR (keymap); | ||
446 | 124 | |||
447 | 125 | #ifdef HAVE_XKB | ||
448 | 126 | + clutter_keymap_x11_refresh_reserved_keycodes (keymap); | ||
449 | 127 | + g_hash_table_iter_init (&iter, keymap->reserved_keycodes); | ||
450 | 128 | + while (g_hash_table_iter_next (&iter, &key, &value)) | ||
451 | 129 | + { | ||
452 | 130 | + guint keycode = GPOINTER_TO_UINT (key); | ||
453 | 131 | + clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol); | ||
454 | 132 | + } | ||
455 | 133 | + | ||
456 | 134 | + g_hash_table_destroy (keymap->reserved_keycodes); | ||
457 | 135 | + g_queue_free (keymap->available_keycodes); | ||
458 | 136 | + | ||
459 | 137 | _clutter_backend_remove_event_translator (keymap->backend, translator); | ||
460 | 138 | |||
461 | 139 | if (keymap->xkb_desc != NULL) | ||
462 | 140 | @@ -460,6 +547,7 @@ clutter_keymap_x11_finalize (GObject *gobject) | ||
463 | 141 | G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject); | ||
464 | 142 | } | ||
465 | 143 | |||
466 | 144 | + | ||
467 | 145 | static void | ||
468 | 146 | clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass) | ||
469 | 147 | { | ||
470 | 148 | @@ -483,6 +571,11 @@ clutter_keymap_x11_init (ClutterKeymapX11 *keymap) | ||
471 | 149 | { | ||
472 | 150 | keymap->current_direction = PANGO_DIRECTION_NEUTRAL; | ||
473 | 151 | keymap->current_group = -1; | ||
474 | 152 | + | ||
475 | 153 | +#ifdef HAVE_XKB | ||
476 | 154 | + keymap->reserved_keycodes = g_hash_table_new (NULL, NULL); | ||
477 | 155 | + keymap->available_keycodes = g_queue_new (); | ||
478 | 156 | +#endif | ||
479 | 157 | } | ||
480 | 158 | |||
481 | 159 | static ClutterTranslateReturn | ||
482 | 160 | @@ -766,6 +859,80 @@ clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11, | ||
483 | 161 | } | ||
484 | 162 | } | ||
485 | 163 | |||
486 | 164 | +#ifdef HAVE_XKB | ||
487 | 165 | +static guint | ||
488 | 166 | +clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11) | ||
489 | 167 | +{ | ||
490 | 168 | + if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb) | ||
491 | 169 | + { | ||
492 | 170 | + clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11); | ||
493 | 171 | + | ||
494 | 172 | + if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5) | ||
495 | 173 | + { | ||
496 | 174 | + Display *dpy = clutter_x11_get_default_display (); | ||
497 | 175 | + XkbDescPtr xkb = get_xkb (keymap_x11); | ||
498 | 176 | + guint i; | ||
499 | 177 | + | ||
500 | 178 | + for (i = xkb->max_key_code; i >= xkb->min_key_code; --i) | ||
501 | 179 | + { | ||
502 | 180 | + if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol) | ||
503 | 181 | + return i; | ||
504 | 182 | + } | ||
505 | 183 | + } | ||
506 | 184 | + | ||
507 | 185 | + return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes)); | ||
508 | 186 | + } | ||
509 | 187 | + | ||
510 | 188 | + return 0; | ||
511 | 189 | +} | ||
512 | 190 | +#endif | ||
513 | 191 | + | ||
514 | 192 | +gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11, | ||
515 | 193 | + guint keyval, | ||
516 | 194 | + guint *keycode_out) | ||
517 | 195 | +{ | ||
518 | 196 | + g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE); | ||
519 | 197 | + g_return_val_if_fail (keyval != 0, FALSE); | ||
520 | 198 | + g_return_val_if_fail (keycode_out != NULL, FALSE); | ||
521 | 199 | + | ||
522 | 200 | +#ifdef HAVE_XKB | ||
523 | 201 | + *keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11); | ||
524 | 202 | + | ||
525 | 203 | + if (*keycode_out == NoSymbol) | ||
526 | 204 | + { | ||
527 | 205 | + g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval); | ||
528 | 206 | + return FALSE; | ||
529 | 207 | + } | ||
530 | 208 | + | ||
531 | 209 | + if (!clutter_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval)) | ||
532 | 210 | + { | ||
533 | 211 | + g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval); | ||
534 | 212 | + return FALSE; | ||
535 | 213 | + } | ||
536 | 214 | + | ||
537 | 215 | + g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval)); | ||
538 | 216 | + g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out)); | ||
539 | 217 | + | ||
540 | 218 | + return TRUE; | ||
541 | 219 | +#else | ||
542 | 220 | + return FALSE; | ||
543 | 221 | +#endif | ||
544 | 222 | +} | ||
545 | 223 | + | ||
546 | 224 | +void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11, | ||
547 | 225 | + guint keycode) | ||
548 | 226 | +{ | ||
549 | 227 | + g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11)); | ||
550 | 228 | + | ||
551 | 229 | +#ifdef HAVE_XKB | ||
552 | 230 | + if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) || | ||
553 | 231 | + g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1) | ||
554 | 232 | + return; | ||
555 | 233 | + | ||
556 | 234 | + g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)); | ||
557 | 235 | +#endif | ||
558 | 236 | +} | ||
559 | 237 | + | ||
560 | 238 | void | ||
561 | 239 | clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, | ||
562 | 240 | uint32_t level, | ||
563 | 241 | diff --git a/clutter/clutter/x11/clutter-keymap-x11.h b/clutter/clutter/x11/clutter-keymap-x11.h | ||
564 | 242 | index 4b5b403..4decb44 100644 | ||
565 | 243 | --- a/clutter/clutter/x11/clutter-keymap-x11.h | ||
566 | 244 | +++ b/clutter/clutter/x11/clutter-keymap-x11.h | ||
567 | 245 | @@ -58,7 +58,11 @@ gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11, | ||
568 | 246 | void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, | ||
569 | 247 | uint32_t level, | ||
570 | 248 | gboolean enable); | ||
571 | 249 | - | ||
572 | 250 | +gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11, | ||
573 | 251 | + guint keyval, | ||
574 | 252 | + guint *keycode_out); | ||
575 | 253 | +void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11, | ||
576 | 254 | + guint keycode); | ||
577 | 255 | G_END_DECLS | ||
578 | 256 | |||
579 | 257 | #endif /* __CLUTTER_KEYMAP_X11_H__ */ | ||
580 | 258 | diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c | ||
581 | 259 | index e16ba3f..cab26c3 100644 | ||
582 | 260 | --- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c | ||
583 | 261 | +++ b/clutter/clutter/x11/clutter-virtual-input-device-x11.c | ||
584 | 262 | @@ -143,8 +143,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu | ||
585 | 263 | |||
586 | 264 | if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level)) | ||
587 | 265 | { | ||
588 | 266 | - g_warning ("No keycode found for keyval %x in current group", keyval); | ||
589 | 267 | - return; | ||
590 | 268 | + level = 0; | ||
591 | 269 | + | ||
592 | 270 | + if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode)) | ||
593 | 271 | + { | ||
594 | 272 | + g_warning ("No keycode found for keyval %x in current group", keyval); | ||
595 | 273 | + return; | ||
596 | 274 | + } | ||
597 | 275 | } | ||
598 | 276 | |||
599 | 277 | if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) && | ||
600 | 278 | @@ -155,9 +160,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu | ||
601 | 279 | (KeyCode) keycode, | ||
602 | 280 | key_state == CLUTTER_KEY_STATE_PRESSED, 0); | ||
603 | 281 | |||
604 | 282 | - if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) && | ||
605 | 283 | - key_state == CLUTTER_KEY_STATE_RELEASED) | ||
606 | 284 | - clutter_keymap_x11_latch_modifiers (keymap, level, FALSE); | ||
607 | 285 | + | ||
608 | 286 | + if (key_state == CLUTTER_KEY_STATE_RELEASED) | ||
609 | 287 | + { | ||
610 | 288 | + if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode)) | ||
611 | 289 | + clutter_keymap_x11_latch_modifiers (keymap, level, FALSE); | ||
612 | 290 | + clutter_keymap_x11_release_keycode_if_needed (keymap, keycode); | ||
613 | 291 | + } | ||
614 | 292 | } | ||
615 | 293 | |||
616 | 294 | static void | ||
617 | 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 | |||
618 | 0 | new file mode 100644 | 295 | new file mode 100644 |
619 | index 0000000..1e5958e | |||
620 | --- /dev/null | |||
621 | +++ b/debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch | |||
622 | @@ -0,0 +1,372 @@ | |||
623 | 1 | From: Daniel van Vugt <daniel.van.vugt@canonical.com> | ||
624 | 2 | Date: Fri, 3 May 2019 11:31:08 -0500 | ||
625 | 3 | Subject: renderer-native: Add hardware presentation timing | ||
626 | 4 | |||
627 | 5 | Add support for getting hardware presentation times from KMS (Wayland | ||
628 | 6 | sessions). Also implement cogl_get_clock_time which is required to compare | ||
629 | 7 | and judge the age of presentation timestamps. | ||
630 | 8 | |||
631 | 9 | For single monitor systems this is straightforward. For multi-monitor | ||
632 | 10 | systems though we have to choose a display to sync to. The compositor | ||
633 | 11 | already partially solves this for us in the case of only one display | ||
634 | 12 | updating because it will only use the subset of monitors that are | ||
635 | 13 | changing. In the case of multiple monitors consuming the same frame | ||
636 | 14 | concurrently however, we choose the fastest one (in use at the time). | ||
637 | 15 | |||
638 | 16 | Patch 1 of 2 | ||
639 | 17 | |||
640 | 18 | Origin: https://gitlab.gnome.org/vanvugt/mutter/commits/add-vsync-3.28 | ||
641 | 19 | Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=781296 | ||
642 | 20 | Bug-Ubuntu: https://bugs.launchpad.net/bugs/1763892 | ||
643 | 21 | Applied-Upstream: https://gitlab.gnome.org/vanvugt/mutter/commit/e9e4b2b7 | ||
644 | 22 | Forwarded: yes | ||
645 | 23 | Last-Update: 2019-03-13 | ||
646 | 24 | --- | ||
647 | 25 | src/Makefile.am | 25 ++++++++++- | ||
648 | 26 | src/backends/native/meta-gpu-kms.c | 69 +++++++++++++++++++++++++++--- | ||
649 | 27 | src/backends/native/meta-gpu-kms.h | 3 ++ | ||
650 | 28 | src/backends/native/meta-renderer-native.c | 38 +++++++++++++++- | ||
651 | 29 | src/meta-marshal.list | 1 + | ||
652 | 30 | 5 files changed, 128 insertions(+), 8 deletions(-) | ||
653 | 31 | create mode 100644 src/meta-marshal.list | ||
654 | 32 | |||
655 | 33 | diff --git a/src/Makefile.am b/src/Makefile.am | ||
656 | 34 | index bcb3505..13862e9 100644 | ||
657 | 35 | --- a/src/Makefile.am | ||
658 | 36 | +++ b/src/Makefile.am | ||
659 | 37 | @@ -51,6 +51,8 @@ mutter_built_sources = \ | ||
660 | 38 | $(dbus_login1_built_sources) \ | ||
661 | 39 | meta/meta-enum-types.h \ | ||
662 | 40 | meta-enum-types.c \ | ||
663 | 41 | + meta-marshal.c \ | ||
664 | 42 | + meta-marshal.h \ | ||
665 | 43 | $(NULL) | ||
666 | 44 | |||
667 | 45 | if HAVE_REMOTE_DESKTOP | ||
668 | 46 | @@ -653,6 +655,7 @@ EXTRA_DIST += \ | ||
669 | 47 | libmutter.pc.in \ | ||
670 | 48 | meta-enum-types.h.in \ | ||
671 | 49 | meta-enum-types.c.in \ | ||
672 | 50 | + meta-marshal.list \ | ||
673 | 51 | org.freedesktop.login1.xml \ | ||
674 | 52 | org.gnome.Mutter.DisplayConfig.xml \ | ||
675 | 53 | org.gnome.Mutter.IdleMonitor.xml \ | ||
676 | 54 | @@ -666,7 +669,10 @@ BUILT_SOURCES = \ | ||
677 | 55 | $(libmutterinclude_built_headers) | ||
678 | 56 | |||
679 | 57 | MUTTER_STAMP_FILES = stamp-meta-enum-types.h | ||
680 | 58 | -CLEANFILES += $(MUTTER_STAMP_FILES) | ||
681 | 59 | +CLEANFILES += \ | ||
682 | 60 | + $(MUTTER_STAMP_FILES) \ | ||
683 | 61 | + meta-marshal.c \ | ||
684 | 62 | + meta-marshal.h | ||
685 | 63 | |||
686 | 64 | meta/meta-enum-types.h: stamp-meta-enum-types.h Makefile | ||
687 | 65 | @true | ||
688 | 66 | @@ -760,3 +766,20 @@ endef | ||
689 | 67 | $(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@ | ||
690 | 68 | %-server-protocol.h : $(srcdir)/wayland/protocol/%.xml | ||
691 | 69 | $(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@ | ||
692 | 70 | + | ||
693 | 71 | +meta_marshal_opts = --prefix=meta_marshal --internal | ||
694 | 72 | + | ||
695 | 73 | +meta-marshal.h: meta-marshal.list | ||
696 | 74 | + $(AM_V_GEN)$(GLIB_GENMARSHAL) \ | ||
697 | 75 | + --header \ | ||
698 | 76 | + $(meta_marshal_opts) \ | ||
699 | 77 | + --output=$@ \ | ||
700 | 78 | + $< | ||
701 | 79 | + | ||
702 | 80 | +meta-marshal.c: meta-marshal.list meta-marshal.h | ||
703 | 81 | + $(AM_V_GEN)$(GLIB_GENMARSHAL) \ | ||
704 | 82 | + --include-header=meta-marshal.h \ | ||
705 | 83 | + $(meta_marshal_opts) \ | ||
706 | 84 | + --body \ | ||
707 | 85 | + --output=$@ \ | ||
708 | 86 | + $< | ||
709 | 87 | diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c | ||
710 | 88 | index 815caf5..02649c5 100644 | ||
711 | 89 | --- a/src/backends/native/meta-gpu-kms.c | ||
712 | 90 | +++ b/src/backends/native/meta-gpu-kms.c | ||
713 | 91 | @@ -27,6 +27,7 @@ | ||
714 | 92 | #include <errno.h> | ||
715 | 93 | #include <poll.h> | ||
716 | 94 | #include <string.h> | ||
717 | 95 | +#include <time.h> | ||
718 | 96 | #include <xf86drm.h> | ||
719 | 97 | #include <xf86drmMode.h> | ||
720 | 98 | |||
721 | 99 | @@ -51,6 +52,7 @@ typedef struct _MetaGpuKmsFlipClosureContainer | ||
722 | 100 | { | ||
723 | 101 | GClosure *flip_closure; | ||
724 | 102 | MetaGpuKms *gpu_kms; | ||
725 | 103 | + MetaCrtc *crtc; | ||
726 | 104 | } MetaGpuKmsFlipClosureContainer; | ||
727 | 105 | |||
728 | 106 | struct _MetaGpuKms | ||
729 | 107 | @@ -61,6 +63,8 @@ struct _MetaGpuKms | ||
730 | 108 | char *file_path; | ||
731 | 109 | GSource *source; | ||
732 | 110 | |||
733 | 111 | + clockid_t clock_id; | ||
734 | 112 | + | ||
735 | 113 | drmModeConnector **connectors; | ||
736 | 114 | unsigned int n_connectors; | ||
737 | 115 | |||
738 | 116 | @@ -166,18 +170,26 @@ meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms, | ||
739 | 117 | |||
740 | 118 | static void | ||
741 | 119 | invoke_flip_closure (GClosure *flip_closure, | ||
742 | 120 | - MetaGpuKms *gpu_kms) | ||
743 | 121 | + MetaGpuKms *gpu_kms, | ||
744 | 122 | + MetaCrtc *crtc, | ||
745 | 123 | + int64_t page_flip_time_ns) | ||
746 | 124 | { | ||
747 | 125 | GValue params[] = { | ||
748 | 126 | G_VALUE_INIT, | ||
749 | 127 | - G_VALUE_INIT | ||
750 | 128 | + G_VALUE_INIT, | ||
751 | 129 | + G_VALUE_INIT, | ||
752 | 130 | + G_VALUE_INIT, | ||
753 | 131 | }; | ||
754 | 132 | |||
755 | 133 | g_value_init (¶ms[0], G_TYPE_POINTER); | ||
756 | 134 | g_value_set_pointer (¶ms[0], flip_closure); | ||
757 | 135 | g_value_init (¶ms[1], G_TYPE_OBJECT); | ||
758 | 136 | g_value_set_object (¶ms[1], gpu_kms); | ||
759 | 137 | - g_closure_invoke (flip_closure, NULL, 2, params, NULL); | ||
760 | 138 | + g_value_init (¶ms[2], G_TYPE_OBJECT); | ||
761 | 139 | + g_value_set_object (¶ms[2], crtc); | ||
762 | 140 | + g_value_init (¶ms[3], G_TYPE_INT64); | ||
763 | 141 | + g_value_set_int64 (¶ms[3], page_flip_time_ns); | ||
764 | 142 | + g_closure_invoke (flip_closure, NULL, 4, params, NULL); | ||
765 | 143 | g_closure_unref (flip_closure); | ||
766 | 144 | } | ||
767 | 145 | |||
768 | 146 | @@ -217,6 +229,7 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms, | ||
769 | 147 | |||
770 | 148 | MetaGpuKmsFlipClosureContainer * | ||
771 | 149 | meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, | ||
772 | 150 | + MetaCrtc *crtc, | ||
773 | 151 | GClosure *flip_closure) | ||
774 | 152 | { | ||
775 | 153 | MetaGpuKmsFlipClosureContainer *closure_container; | ||
776 | 154 | @@ -224,7 +237,8 @@ meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, | ||
777 | 155 | closure_container = g_new0 (MetaGpuKmsFlipClosureContainer, 1); | ||
778 | 156 | *closure_container = (MetaGpuKmsFlipClosureContainer) { | ||
779 | 157 | .flip_closure = flip_closure, | ||
780 | 158 | - .gpu_kms = gpu_kms | ||
781 | 159 | + .gpu_kms = gpu_kms, | ||
782 | 160 | + .crtc = crtc | ||
783 | 161 | }; | ||
784 | 162 | |||
785 | 163 | return closure_container; | ||
786 | 164 | @@ -264,6 +278,7 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms, | ||
787 | 165 | int kms_fd = meta_gpu_kms_get_fd (gpu_kms); | ||
788 | 166 | |||
789 | 167 | closure_container = meta_gpu_kms_wrap_flip_closure (gpu_kms, | ||
790 | 168 | + crtc, | ||
791 | 169 | flip_closure); | ||
792 | 170 | |||
793 | 171 | ret = drmModePageFlip (kms_fd, | ||
794 | 172 | @@ -297,6 +312,23 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms, | ||
795 | 173 | return TRUE; | ||
796 | 174 | } | ||
797 | 175 | |||
798 | 176 | +static int64_t | ||
799 | 177 | +timespec_to_nanoseconds (const struct timespec *ts) | ||
800 | 178 | +{ | ||
801 | 179 | + const int64_t one_billion = 1000000000; | ||
802 | 180 | + | ||
803 | 181 | + return ((int64_t) ts->tv_sec) * one_billion + ts->tv_nsec; | ||
804 | 182 | +} | ||
805 | 183 | + | ||
806 | 184 | +static int64_t | ||
807 | 185 | +timeval_to_nanoseconds (const struct timeval *tv) | ||
808 | 186 | +{ | ||
809 | 187 | + int64_t usec = ((int64_t) tv->tv_sec) * G_USEC_PER_SEC + tv->tv_usec; | ||
810 | 188 | + int64_t nsec = usec * 1000; | ||
811 | 189 | + | ||
812 | 190 | + return nsec; | ||
813 | 191 | +} | ||
814 | 192 | + | ||
815 | 193 | static void | ||
816 | 194 | page_flip_handler (int fd, | ||
817 | 195 | unsigned int frame, | ||
818 | 196 | @@ -307,8 +339,12 @@ page_flip_handler (int fd, | ||
819 | 197 | MetaGpuKmsFlipClosureContainer *closure_container = user_data; | ||
820 | 198 | GClosure *flip_closure = closure_container->flip_closure; | ||
821 | 199 | MetaGpuKms *gpu_kms = closure_container->gpu_kms; | ||
822 | 200 | + struct timeval page_flip_time = {sec, usec}; | ||
823 | 201 | |||
824 | 202 | - invoke_flip_closure (flip_closure, gpu_kms); | ||
825 | 203 | + invoke_flip_closure (flip_closure, | ||
826 | 204 | + gpu_kms, | ||
827 | 205 | + closure_container->crtc, | ||
828 | 206 | + timeval_to_nanoseconds (&page_flip_time)); | ||
829 | 207 | meta_gpu_kms_flip_closure_container_free (closure_container); | ||
830 | 208 | } | ||
831 | 209 | |||
832 | 210 | @@ -381,6 +417,17 @@ meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms) | ||
833 | 211 | return gpu_kms->file_path; | ||
834 | 212 | } | ||
835 | 213 | |||
836 | 214 | +int64_t | ||
837 | 215 | +_meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms) | ||
838 | 216 | +{ | ||
839 | 217 | + struct timespec ts; | ||
840 | 218 | + | ||
841 | 219 | + if (clock_gettime (gpu_kms->clock_id, &ts)) | ||
842 | 220 | + return 0; | ||
843 | 221 | + | ||
844 | 222 | + return timespec_to_nanoseconds (&ts); | ||
845 | 223 | +} | ||
846 | 224 | + | ||
847 | 225 | void | ||
848 | 226 | meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms, | ||
849 | 227 | uint64_t state) | ||
850 | 228 | @@ -680,6 +727,17 @@ init_crtcs (MetaGpuKms *gpu_kms, | ||
851 | 229 | meta_gpu_take_crtcs (gpu, crtcs); | ||
852 | 230 | } | ||
853 | 231 | |||
854 | 232 | +static void | ||
855 | 233 | +init_frame_clock (MetaGpuKms *gpu_kms) | ||
856 | 234 | +{ | ||
857 | 235 | + uint64_t uses_monotonic; | ||
858 | 236 | + | ||
859 | 237 | + if (drmGetCap (gpu_kms->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &uses_monotonic) != 0) | ||
860 | 238 | + uses_monotonic = 0; | ||
861 | 239 | + | ||
862 | 240 | + gpu_kms->clock_id = uses_monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME; | ||
863 | 241 | +} | ||
864 | 242 | + | ||
865 | 243 | static void | ||
866 | 244 | init_outputs (MetaGpuKms *gpu_kms, | ||
867 | 245 | MetaKmsResources *resources) | ||
868 | 246 | @@ -809,6 +867,7 @@ meta_gpu_kms_read_current (MetaGpu *gpu, | ||
869 | 247 | init_modes (gpu_kms, resources.resources); | ||
870 | 248 | init_crtcs (gpu_kms, &resources); | ||
871 | 249 | init_outputs (gpu_kms, &resources); | ||
872 | 250 | + init_frame_clock (gpu_kms); | ||
873 | 251 | |||
874 | 252 | meta_kms_resources_release (&resources); | ||
875 | 253 | |||
876 | 254 | diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h | ||
877 | 255 | index 01c3f2c..c12246c 100644 | ||
878 | 256 | --- a/src/backends/native/meta-gpu-kms.h | ||
879 | 257 | +++ b/src/backends/native/meta-gpu-kms.h | ||
880 | 258 | @@ -81,6 +81,8 @@ int meta_gpu_kms_get_fd (MetaGpuKms *gpu_kms); | ||
881 | 259 | |||
882 | 260 | const char * meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms); | ||
883 | 261 | |||
884 | 262 | +int64_t _meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms); | ||
885 | 263 | + | ||
886 | 264 | void meta_gpu_kms_get_max_buffer_size (MetaGpuKms *gpu_kms, | ||
887 | 265 | int *max_width, | ||
888 | 266 | int *max_height); | ||
889 | 267 | @@ -97,6 +99,7 @@ gboolean meta_drm_mode_equal (const drmModeModeInfo *one, | ||
890 | 268 | float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *mode); | ||
891 | 269 | |||
892 | 270 | MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, | ||
893 | 271 | + MetaCrtc *crtc, | ||
894 | 272 | GClosure *flip_closure); | ||
895 | 273 | |||
896 | 274 | void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container); | ||
897 | 275 | diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c | ||
898 | 276 | index 470da88..0fd104b 100644 | ||
899 | 277 | --- a/src/backends/native/meta-renderer-native.c | ||
900 | 278 | +++ b/src/backends/native/meta-renderer-native.c | ||
901 | 279 | @@ -61,6 +61,7 @@ | ||
902 | 280 | #include "backends/native/meta-monitor-manager-kms.h" | ||
903 | 281 | #include "backends/native/meta-renderer-native.h" | ||
904 | 282 | #include "backends/native/meta-renderer-native-gles3.h" | ||
905 | 283 | +#include "meta-marshal.h" | ||
906 | 284 | #include "cogl/cogl.h" | ||
907 | 285 | #include "core/boxes-private.h" | ||
908 | 286 | |||
909 | 287 | @@ -1157,6 +1158,8 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen) | ||
910 | 288 | static void | ||
911 | 289 | on_crtc_flipped (GClosure *closure, | ||
912 | 290 | MetaGpuKms *gpu_kms, | ||
913 | 291 | + MetaCrtc *crtc, | ||
914 | 292 | + int64_t page_flip_time_ns, | ||
915 | 293 | MetaRendererView *view) | ||
916 | 294 | { | ||
917 | 295 | ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view); | ||
918 | 296 | @@ -1167,6 +1170,24 @@ on_crtc_flipped (GClosure *closure, | ||
919 | 297 | MetaOnscreenNative *onscreen_native = onscreen_egl->platform; | ||
920 | 298 | MetaRendererNative *renderer_native = onscreen_native->renderer_native; | ||
921 | 299 | MetaGpuKms *render_gpu = onscreen_native->render_gpu; | ||
922 | 300 | + CoglFrameInfo *frame_info; | ||
923 | 301 | + float refresh_rate; | ||
924 | 302 | + | ||
925 | 303 | + frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); | ||
926 | 304 | + refresh_rate = crtc && crtc->current_mode ? | ||
927 | 305 | + crtc->current_mode->refresh_rate : | ||
928 | 306 | + 0.0f; | ||
929 | 307 | + | ||
930 | 308 | + /* Only keep the frame info for the fastest CRTC in use, which may not be | ||
931 | 309 | + * the first one to complete a flip. By only telling the compositor about the | ||
932 | 310 | + * fastest monitor(s) we direct it to produce new frames fast enough to | ||
933 | 311 | + * satisfy all monitors. | ||
934 | 312 | + */ | ||
935 | 313 | + if (refresh_rate >= frame_info->refresh_rate) | ||
936 | 314 | + { | ||
937 | 315 | + frame_info->presentation_time = page_flip_time_ns; | ||
938 | 316 | + frame_info->refresh_rate = refresh_rate; | ||
939 | 317 | + } | ||
940 | 318 | |||
941 | 319 | if (gpu_kms != render_gpu) | ||
942 | 320 | { | ||
943 | 321 | @@ -1297,7 +1318,9 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native, | ||
944 | 322 | return FALSE; | ||
945 | 323 | |||
946 | 324 | closure_container = | ||
947 | 325 | - meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu, flip_closure); | ||
948 | 326 | + meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu, | ||
949 | 327 | + NULL, | ||
950 | 328 | + flip_closure); | ||
951 | 329 | |||
952 | 330 | acquire_attribs = (EGLAttrib[]) { | ||
953 | 331 | EGL_DRM_FLIP_EVENT_DATA_NV, | ||
954 | 332 | @@ -1540,7 +1563,7 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen) | ||
955 | 333 | flip_closure = g_cclosure_new (G_CALLBACK (on_crtc_flipped), | ||
956 | 334 | g_object_ref (view), | ||
957 | 335 | (GClosureNotify) flip_closure_destroyed); | ||
958 | 336 | - g_closure_set_marshal (flip_closure, g_cclosure_marshal_VOID__OBJECT); | ||
959 | 337 | + g_closure_set_marshal (flip_closure, meta_marshal_VOID__OBJECT_OBJECT_INT64); | ||
960 | 338 | |||
961 | 339 | /* Either flip the CRTC's of the monitor info, if we are drawing just part | ||
962 | 340 | * of the stage, or all of the CRTC's if we are drawing the whole stage. | ||
963 | 341 | @@ -2673,6 +2696,15 @@ meta_renderer_native_create_offscreen (MetaRendererNative *renderer, | ||
964 | 342 | return fb; | ||
965 | 343 | } | ||
966 | 344 | |||
967 | 345 | +static int64_t | ||
968 | 346 | +meta_renderer_native_get_clock_time (CoglContext *context) | ||
969 | 347 | +{ | ||
970 | 348 | + CoglRenderer *cogl_renderer = cogl_context_get_renderer (context); | ||
971 | 349 | + MetaGpuKms *gpu_kms = cogl_renderer->custom_winsys_user_data; | ||
972 | 350 | + | ||
973 | 351 | + return _meta_gpu_kms_get_current_time_ns (gpu_kms); | ||
974 | 352 | +} | ||
975 | 353 | + | ||
976 | 354 | static const CoglWinsysVtable * | ||
977 | 355 | get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) | ||
978 | 356 | { | ||
979 | 357 | @@ -2701,6 +2733,8 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) | ||
980 | 358 | vtable.onscreen_swap_buffers_with_damage = | ||
981 | 359 | meta_onscreen_native_swap_buffers_with_damage; | ||
982 | 360 | |||
983 | 361 | + vtable.context_get_clock_time = meta_renderer_native_get_clock_time; | ||
984 | 362 | + | ||
985 | 363 | vtable_inited = TRUE; | ||
986 | 364 | } | ||
987 | 365 | |||
988 | 366 | diff --git a/src/meta-marshal.list b/src/meta-marshal.list | ||
989 | 367 | new file mode 100644 | ||
990 | 368 | index 0000000..c1f4781 | ||
991 | 369 | --- /dev/null | ||
992 | 370 | +++ b/src/meta-marshal.list | ||
993 | 371 | @@ -0,0 +1 @@ | ||
994 | 372 | +VOID:OBJECT,OBJECT,INT64 | ||
995 | 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 | |||
996 | 0 | new file mode 100644 | 373 | new file mode 100644 |
997 | index 0000000..9a6a64d | |||
998 | --- /dev/null | |||
999 | +++ b/debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch | |||
1000 | @@ -0,0 +1,53 @@ | |||
1001 | 1 | From: Daniel van Vugt <daniel.van.vugt@canonical.com> | ||
1002 | 2 | Date: Fri, 3 May 2019 11:31:08 -0500 | ||
1003 | 3 | Subject: renderer-native: Advertise _FEATURE_SWAP_THROTTLE | ||
1004 | 4 | |||
1005 | 5 | Because it is implemented and always on. By advertising this fact | ||
1006 | 6 | the master clock is able to sync to the native refresh rate instead | ||
1007 | 7 | of always using the fallback of 60.00Hz. | ||
1008 | 8 | |||
1009 | 9 | Patch 2 of 2 | ||
1010 | 10 | |||
1011 | 11 | Origin: https://gitlab.gnome.org/vanvugt/mutter/commits/add-vsync-3.28 | ||
1012 | 12 | Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=781296 | ||
1013 | 13 | Bug-Ubuntu: https://bugs.launchpad.net/bugs/1763892 | ||
1014 | 14 | Applied-Upstream: https://gitlab.gnome.org/vanvugt/mutter/commit/e8c27603 | ||
1015 | 15 | Forwarded: yes | ||
1016 | 16 | Last-Update: 2019-03-13 | ||
1017 | 17 | --- | ||
1018 | 18 | src/backends/native/meta-renderer-native.c | 15 +++++++++++++-- | ||
1019 | 19 | 1 file changed, 13 insertions(+), 2 deletions(-) | ||
1020 | 20 | |||
1021 | 21 | diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c | ||
1022 | 22 | index 0fd104b..dce7981 100644 | ||
1023 | 23 | --- a/src/backends/native/meta-renderer-native.c | ||
1024 | 24 | +++ b/src/backends/native/meta-renderer-native.c | ||
1025 | 25 | @@ -1997,6 +1997,13 @@ meta_renderer_native_init_egl_context (CoglContext *cogl_context, | ||
1026 | 26 | COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, | ||
1027 | 27 | TRUE); | ||
1028 | 28 | |||
1029 | 29 | + /* COGL_WINSYS_FEATURE_SWAP_THROTTLE is always true for this renderer | ||
1030 | 30 | + * because we have the call to wait_for_pending_flips on every frame. | ||
1031 | 31 | + */ | ||
1032 | 32 | + COGL_FLAGS_SET (cogl_context->winsys_features, | ||
1033 | 33 | + COGL_WINSYS_FEATURE_SWAP_THROTTLE, | ||
1034 | 34 | + TRUE); | ||
1035 | 35 | + | ||
1036 | 36 | #ifdef HAVE_EGL_DEVICE | ||
1037 | 37 | if (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_EGL_DEVICE) | ||
1038 | 38 | COGL_FLAGS_SET (cogl_context->features, | ||
1039 | 39 | @@ -2625,8 +2632,12 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, | ||
1040 | 40 | } | ||
1041 | 41 | |||
1042 | 42 | onscreen = cogl_onscreen_new (context, width, height); | ||
1043 | 43 | - cogl_onscreen_set_swap_throttled (onscreen, | ||
1044 | 44 | - _clutter_get_sync_to_vblank ()); | ||
1045 | 45 | + | ||
1046 | 46 | + /* We have wait_for_pending_flips hardcoded, so throttling always. */ | ||
1047 | 47 | + cogl_onscreen_set_swap_throttled (onscreen, TRUE); | ||
1048 | 48 | + if (!_clutter_get_sync_to_vblank ()) | ||
1049 | 49 | + g_warning ("Request to disable sync-to-vblank is being ignored. " | ||
1050 | 50 | + "MetaRendererNative does not support disabling it."); | ||
1051 | 51 | |||
1052 | 52 | if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), error)) | ||
1053 | 53 | { | ||
1054 | 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 | |||
1055 | 0 | new file mode 100644 | 54 | new file mode 100644 |
1056 | index 0000000..5512752 | |||
1057 | --- /dev/null | |||
1058 | +++ b/debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch | |||
1059 | @@ -0,0 +1,37 @@ | |||
1060 | 1 | From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com> | ||
1061 | 2 | Date: Thu, 11 Oct 2018 08:16:26 -0500 | ||
1062 | 3 | Subject: monitor-manager: Don't use switch-config when ensuring configuration | ||
1063 | 4 | |||
1064 | 5 | Switch-configs are only to be used in certain circumstances (see | ||
1065 | 6 | meta_monitor_manager_can_switch_config()) so when ensuring | ||
1066 | 7 | configuration and attempting to create a linear configuration, use the | ||
1067 | 8 | linear configuration constructor function directly without going via the | ||
1068 | 9 | switch config method, otherwise we might incorrectly fall back to the | ||
1069 | 10 | fallback configuration (only enable primary monitor). | ||
1070 | 11 | |||
1071 | 12 | This is a regression introduced by 6267732bec97773. | ||
1072 | 13 | |||
1073 | 14 | Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/342 | ||
1074 | 15 | |||
1075 | 16 | Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1772811 | ||
1076 | 17 | Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/262 | ||
1077 | 18 | Applied-Upstream: yes, 3.32.0 | ||
1078 | 19 | --- | ||
1079 | 20 | src/backends/meta-monitor-manager.c | 4 +--- | ||
1080 | 21 | 1 file changed, 1 insertion(+), 3 deletions(-) | ||
1081 | 22 | |||
1082 | 23 | diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c | ||
1083 | 24 | index fde61eb..39ed813 100644 | ||
1084 | 25 | --- a/src/backends/meta-monitor-manager.c | ||
1085 | 26 | +++ b/src/backends/meta-monitor-manager.c | ||
1086 | 27 | @@ -582,9 +582,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) | ||
1087 | 28 | g_clear_object (&config); | ||
1088 | 29 | } | ||
1089 | 30 | |||
1090 | 31 | - config = | ||
1091 | 32 | - meta_monitor_config_manager_create_for_switch_config (manager->config_manager, | ||
1092 | 33 | - META_MONITOR_SWITCH_CONFIG_ALL_LINEAR); | ||
1093 | 34 | + config = meta_monitor_config_manager_create_linear (manager->config_manager); | ||
1094 | 35 | if (config) | ||
1095 | 36 | { | ||
1096 | 37 | if (!meta_monitor_manager_apply_monitors_config (manager, | ||
1097 | 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 | |||
1098 | 0 | new file mode 100644 | 38 | new file mode 100644 |
1099 | index 0000000..a791f59 | |||
1100 | --- /dev/null | |||
1101 | +++ b/debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch | |||
1102 | @@ -0,0 +1,198 @@ | |||
1103 | 1 | From: Daniel Drake <drake@endlessm.com> | ||
1104 | 2 | Date: Wed, 29 Aug 2018 19:34:53 -0500 | ||
1105 | 3 | Subject: monitor-manager: use MonitorsConfig to track switch_config | ||
1106 | 4 | |||
1107 | 5 | When constructing MetaMonitorsConfig objects, store which type | ||
1108 | 6 | of switch_config they are for (or UNKNOWN if it is not such | ||
1109 | 7 | type of config). | ||
1110 | 8 | |||
1111 | 9 | Stop unconditionally setting current_switch_config to UNKNOWN when | ||
1112 | 10 | handling monitors changed events. Instead, set it to the switch_config | ||
1113 | 11 | type stored in the MonitorsConfig in the codepath that updates logical | ||
1114 | 12 | state. In addition to being called in the hotplug case along the same | ||
1115 | 13 | code flow that generates monitors changed events, this is also called | ||
1116 | 14 | in the coldplug case where a secondary monitor was connected before | ||
1117 | 15 | mutter was started. | ||
1118 | 16 | |||
1119 | 17 | When creating the default linear display config, create it as a | ||
1120 | 18 | switch_config so that internal state gets updated to represent | ||
1121 | 19 | linear mode when this config is used. | ||
1122 | 20 | |||
1123 | 21 | The previous behaviour of unconditionally resetting current_switch_config | ||
1124 | 22 | to UNKNOWN was breaking the internal state machine for display config | ||
1125 | 23 | switching, causing misbehaviour in gnome-shell's switchMonitor UI when | ||
1126 | 24 | using display switch hotkeys. The lack of internal tracking when the | ||
1127 | 25 | displays are already in the default "Join Displays" linear mode was | ||
1128 | 26 | then causing the first display switch hotkey press to do nothing | ||
1129 | 27 | (it would attempt to select "Join Displays" mode, but that was already | ||
1130 | 28 | active). | ||
1131 | 29 | |||
1132 | 30 | Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/281 | ||
1133 | 31 | https://gitlab.gnome.org/GNOME/mutter/merge_requests/213 | ||
1134 | 32 | |||
1135 | 33 | Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1772811 | ||
1136 | 34 | Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/213 | ||
1137 | 35 | Applied-Upstream: yes, 3.30.1 | ||
1138 | 36 | --- | ||
1139 | 37 | src/backends/meta-monitor-config-manager.c | 36 +++++++++++++++++++++++++----- | ||
1140 | 38 | src/backends/meta-monitor-config-manager.h | 7 ++++++ | ||
1141 | 39 | src/backends/meta-monitor-manager.c | 25 ++++++++++++++++----- | ||
1142 | 40 | 3 files changed, 56 insertions(+), 12 deletions(-) | ||
1143 | 41 | |||
1144 | 42 | diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c | ||
1145 | 43 | index 197892b..ce61547 100644 | ||
1146 | 44 | --- a/src/backends/meta-monitor-config-manager.c | ||
1147 | 45 | +++ b/src/backends/meta-monitor-config-manager.c | ||
1148 | 46 | @@ -1007,6 +1007,7 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager | ||
1149 | 47 | MetaMonitorSwitchConfigType config_type) | ||
1150 | 48 | { | ||
1151 | 49 | MetaMonitorManager *monitor_manager = config_manager->monitor_manager; | ||
1152 | 50 | + MetaMonitorsConfig *config; | ||
1153 | 51 | |||
1154 | 52 | if (!meta_monitor_manager_can_switch_config (monitor_manager)) | ||
1155 | 53 | return NULL; | ||
1156 | 54 | @@ -1014,18 +1015,27 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager | ||
1157 | 55 | switch (config_type) | ||
1158 | 56 | { | ||
1159 | 57 | case META_MONITOR_SWITCH_CONFIG_ALL_MIRROR: | ||
1160 | 58 | - return create_for_switch_config_all_mirror (config_manager); | ||
1161 | 59 | + config = create_for_switch_config_all_mirror (config_manager); | ||
1162 | 60 | + break; | ||
1163 | 61 | case META_MONITOR_SWITCH_CONFIG_ALL_LINEAR: | ||
1164 | 62 | - return meta_monitor_config_manager_create_linear (config_manager); | ||
1165 | 63 | + config = meta_monitor_config_manager_create_linear (config_manager); | ||
1166 | 64 | + break; | ||
1167 | 65 | case META_MONITOR_SWITCH_CONFIG_EXTERNAL: | ||
1168 | 66 | - return create_for_switch_config_external (config_manager); | ||
1169 | 67 | + config = create_for_switch_config_external (config_manager); | ||
1170 | 68 | + break; | ||
1171 | 69 | case META_MONITOR_SWITCH_CONFIG_BUILTIN: | ||
1172 | 70 | - return create_for_switch_config_builtin (config_manager); | ||
1173 | 71 | + config = create_for_switch_config_builtin (config_manager); | ||
1174 | 72 | + break; | ||
1175 | 73 | case META_MONITOR_SWITCH_CONFIG_UNKNOWN: | ||
1176 | 74 | + default: | ||
1177 | 75 | g_warn_if_reached (); | ||
1178 | 76 | - break; | ||
1179 | 77 | + return NULL; | ||
1180 | 78 | } | ||
1181 | 79 | - return NULL; | ||
1182 | 80 | + | ||
1183 | 81 | + if (config) | ||
1184 | 82 | + _meta_monitors_config_set_switch_config (config, config_type); | ||
1185 | 83 | + | ||
1186 | 84 | + return config; | ||
1187 | 85 | } | ||
1188 | 86 | |||
1189 | 87 | void | ||
1190 | 88 | @@ -1217,6 +1227,19 @@ meta_monitors_config_key_equal (gconstpointer data_a, | ||
1191 | 89 | return TRUE; | ||
1192 | 90 | } | ||
1193 | 91 | |||
1194 | 92 | +MetaMonitorSwitchConfigType | ||
1195 | 93 | +_meta_monitors_config_get_switch_config (MetaMonitorsConfig *config) | ||
1196 | 94 | +{ | ||
1197 | 95 | + return config->switch_config; | ||
1198 | 96 | +} | ||
1199 | 97 | + | ||
1200 | 98 | +void | ||
1201 | 99 | +_meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, | ||
1202 | 100 | + MetaMonitorSwitchConfigType switch_config) | ||
1203 | 101 | +{ | ||
1204 | 102 | + config->switch_config = switch_config; | ||
1205 | 103 | +} | ||
1206 | 104 | + | ||
1207 | 105 | MetaMonitorsConfig * | ||
1208 | 106 | meta_monitors_config_new_full (GList *logical_monitor_configs, | ||
1209 | 107 | GList *disabled_monitor_specs, | ||
1210 | 108 | @@ -1232,6 +1255,7 @@ meta_monitors_config_new_full (GList *logical_monitor_con | ||
1211 | 109 | disabled_monitor_specs); | ||
1212 | 110 | config->layout_mode = layout_mode; | ||
1213 | 111 | config->flags = flags; | ||
1214 | 112 | + config->switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; | ||
1215 | 113 | |||
1216 | 114 | return config; | ||
1217 | 115 | } | ||
1218 | 116 | diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h | ||
1219 | 117 | index 269d8e1..4ac0b1d 100644 | ||
1220 | 118 | --- a/src/backends/meta-monitor-config-manager.h | ||
1221 | 119 | +++ b/src/backends/meta-monitor-config-manager.h | ||
1222 | 120 | @@ -69,6 +69,8 @@ struct _MetaMonitorsConfig | ||
1223 | 121 | MetaMonitorsConfigFlag flags; | ||
1224 | 122 | |||
1225 | 123 | MetaLogicalMonitorLayoutMode layout_mode; | ||
1226 | 124 | + | ||
1227 | 125 | + MetaMonitorSwitchConfigType switch_config; | ||
1228 | 126 | }; | ||
1229 | 127 | |||
1230 | 128 | #define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ()) | ||
1231 | 129 | @@ -124,6 +126,11 @@ MetaMonitorsConfig * meta_monitors_config_new (MetaMonitorManager *mon | ||
1232 | 130 | MetaLogicalMonitorLayoutMode layout_mode, | ||
1233 | 131 | MetaMonitorsConfigFlag flags); | ||
1234 | 132 | |||
1235 | 133 | +MetaMonitorSwitchConfigType _meta_monitors_config_get_switch_config (MetaMonitorsConfig *config); | ||
1236 | 134 | + | ||
1237 | 135 | +void _meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, | ||
1238 | 136 | + MetaMonitorSwitchConfigType switch_config); | ||
1239 | 137 | + | ||
1240 | 138 | unsigned int meta_monitors_config_key_hash (gconstpointer config_key); | ||
1241 | 139 | |||
1242 | 140 | gboolean meta_monitors_config_key_equal (gconstpointer config_key_a, | ||
1243 | 141 | diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c | ||
1244 | 142 | index ec18600..fde61eb 100644 | ||
1245 | 143 | --- a/src/backends/meta-monitor-manager.c | ||
1246 | 144 | +++ b/src/backends/meta-monitor-manager.c | ||
1247 | 145 | @@ -582,7 +582,9 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) | ||
1248 | 146 | g_clear_object (&config); | ||
1249 | 147 | } | ||
1250 | 148 | |||
1251 | 149 | - config = meta_monitor_config_manager_create_linear (manager->config_manager); | ||
1252 | 150 | + config = | ||
1253 | 151 | + meta_monitor_config_manager_create_for_switch_config (manager->config_manager, | ||
1254 | 152 | + META_MONITOR_SWITCH_CONFIG_ALL_LINEAR); | ||
1255 | 153 | if (config) | ||
1256 | 154 | { | ||
1257 | 155 | if (!meta_monitor_manager_apply_monitors_config (manager, | ||
1258 | 156 | @@ -2652,8 +2654,6 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager) | ||
1259 | 157 | static void | ||
1260 | 158 | meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager) | ||
1261 | 159 | { | ||
1262 | 160 | - manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; | ||
1263 | 161 | - | ||
1264 | 162 | meta_backend_monitors_changed (manager->backend); | ||
1265 | 163 | |||
1266 | 164 | g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0); | ||
1267 | 165 | @@ -2710,10 +2710,17 @@ meta_monitor_manager_update_logical_state (MetaMonitorManager *manager, | ||
1268 | 166 | MetaMonitorsConfig *config) | ||
1269 | 167 | { | ||
1270 | 168 | if (config) | ||
1271 | 169 | - manager->layout_mode = config->layout_mode; | ||
1272 | 170 | + { | ||
1273 | 171 | + manager->layout_mode = config->layout_mode; | ||
1274 | 172 | + manager->current_switch_config = | ||
1275 | 173 | + _meta_monitors_config_get_switch_config (config); | ||
1276 | 174 | + } | ||
1277 | 175 | else | ||
1278 | 176 | - manager->layout_mode = | ||
1279 | 177 | - meta_monitor_manager_get_default_layout_mode (manager); | ||
1280 | 178 | + { | ||
1281 | 179 | + manager->layout_mode = | ||
1282 | 180 | + meta_monitor_manager_get_default_layout_mode (manager); | ||
1283 | 181 | + manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; | ||
1284 | 182 | + } | ||
1285 | 183 | |||
1286 | 184 | meta_monitor_manager_rebuild_logical_monitors (manager, config); | ||
1287 | 185 | } | ||
1288 | 186 | @@ -2755,6 +2762,12 @@ void | ||
1289 | 187 | meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager, | ||
1290 | 188 | MetaMonitorsConfig *config) | ||
1291 | 189 | { | ||
1292 | 190 | + if (config) | ||
1293 | 191 | + manager->current_switch_config = | ||
1294 | 192 | + _meta_monitors_config_get_switch_config (config); | ||
1295 | 193 | + else | ||
1296 | 194 | + manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; | ||
1297 | 195 | + | ||
1298 | 196 | manager->layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; | ||
1299 | 197 | |||
1300 | 198 | meta_monitor_manager_rebuild_logical_monitors_derived (manager, config); | ||
1301 | diff --git a/debian/patches/series b/debian/patches/series | |||
1302 | index 198db5a..8ff6307 100644 | |||
1303 | --- a/debian/patches/series | |||
1304 | +++ b/debian/patches/series | |||
1305 | @@ -1,8 +1,13 @@ | |||
1306 | 1 | theme-use-gtk_render_icon_suface-to-paint-button-icon.patch | 1 | theme-use-gtk_render_icon_suface-to-paint-button-icon.patch |
1307 | 2 | theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch | 2 | theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch |
1308 | 3 | clutter-Smooth-out-master-clock-to-smooth-visuals.patch | ||
1309 | 4 | clutter-Fix-offscreen-effect-painting-of-clones.patch | 3 | clutter-Fix-offscreen-effect-painting-of-clones.patch |
1310 | 5 | bgo768531_workaround-startup-notifications.patch | 4 | bgo768531_workaround-startup-notifications.patch |
1311 | 5 | monitor-manager-use-MonitorsConfig-to-track-switch_config.patch | ||
1312 | 6 | monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch | ||
1313 | 7 | clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch | ||
1314 | 8 | clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch | ||
1315 | 9 | lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch | ||
1316 | 10 | lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch | ||
1317 | 6 | debian/synaptics-support.patch | 11 | debian/synaptics-support.patch |
1318 | 7 | debian/skip-failing-tests.patch | 12 | debian/skip-failing-tests.patch |
1319 | 8 | debian/skip-failing-tests-325.patch | 13 | debian/skip-failing-tests-325.patch |
Looking good.