import mutter-3.32.2-26.el8

This commit is contained in:
CentOS Sources 2020-01-21 12:51:34 -05:00 committed by Stepan Oksanichenko
parent 1e5a152a7b
commit bcb64bfb82
33 changed files with 3679 additions and 32 deletions

View File

@ -1,4 +1,4 @@
From 2b45c3e37da7a590227e965d8a18e89337b791ba Mon Sep 17 00:00:00 2001
From d0ad5ea18bb02112837bcdf7270d58d8ad235a4d Mon Sep 17 00:00:00 2001
From: "Owen W. Taylor" <otaylor@fishsoup.net>
Date: Thu, 8 May 2014 18:44:15 -0400
Subject: [PATCH] Add support for quad-buffer stereo
@ -21,7 +21,7 @@ texture_from_pixmap.
src/compositor/compositor-private.h | 9 ++
src/compositor/compositor.c | 125 +++++++++++++++
src/compositor/meta-shaped-texture-private.h | 5 +-
src/compositor/meta-shaped-texture.c | 86 ++++++++++-
src/compositor/meta-shaped-texture.c | 84 +++++++++-
src/compositor/meta-surface-actor-wayland.c | 2 +-
src/compositor/meta-surface-actor-x11.c | 54 ++++++-
src/compositor/meta-surface-actor-x11.h | 5 +
@ -32,7 +32,7 @@ texture_from_pixmap.
src/core/stereo.h | 28 ++++
src/meson.build | 2 +
src/wayland/meta-wayland-surface.c | 2 +-
14 files changed, 483 insertions(+), 20 deletions(-)
14 files changed, 481 insertions(+), 20 deletions(-)
create mode 100644 src/core/stereo.c
create mode 100644 src/core/stereo.h
@ -265,7 +265,7 @@ index a86a2bff0..d0efdd4dc 100644
gboolean is_y_inverted);
void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index ea8daa03d..9665ce2b6 100644
index ea8daa03d..9a00ccd6d 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -102,8 +102,10 @@ struct _MetaShapedTexture
@ -279,17 +279,15 @@ index ea8daa03d..9665ce2b6 100644
CoglTexture *mask_texture;
CoglSnippet *snippet;
@@ -193,6 +195,9 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
@@ -192,6 +194,7 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
clutter_backend_get_cogl_context (clutter_backend);
stex->paint_tower = meta_texture_tower_new ();
+ stex->paint_tower = meta_texture_tower_new ();
+ stex->paint_tower_right = NULL; /* demand create */
+
stex->texture = NULL;
stex->mask_texture = NULL;
stex->create_mipmaps = TRUE;
@@ -335,6 +340,9 @@ meta_shaped_texture_dispose (GObject *object)
@@ -335,6 +338,9 @@ meta_shaped_texture_dispose (GObject *object)
meta_texture_tower_free (stex->paint_tower);
stex->paint_tower = NULL;
@ -299,7 +297,7 @@ index ea8daa03d..9665ce2b6 100644
g_clear_pointer (&stex->texture, cogl_object_unref);
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
@@ -611,8 +619,9 @@ paint_clipped_rectangle (MetaShapedTexture *stex,
@@ -611,8 +617,9 @@ paint_clipped_rectangle (MetaShapedTexture *stex,
}
static void
@ -311,7 +309,7 @@ index ea8daa03d..9665ce2b6 100644
{
int width, height;
@@ -620,10 +629,13 @@ set_cogl_texture (MetaShapedTexture *stex,
@@ -620,10 +627,13 @@ set_cogl_texture (MetaShapedTexture *stex,
if (stex->texture)
cogl_object_unref (stex->texture);
@ -325,7 +323,7 @@ index ea8daa03d..9665ce2b6 100644
if (cogl_tex != NULL)
{
@@ -637,6 +649,9 @@ set_cogl_texture (MetaShapedTexture *stex,
@@ -637,6 +647,9 @@ set_cogl_texture (MetaShapedTexture *stex,
height = 0;
}
@ -335,7 +333,7 @@ index ea8daa03d..9665ce2b6 100644
if (stex->tex_width != width ||
stex->tex_height != height)
{
@@ -650,8 +665,23 @@ set_cogl_texture (MetaShapedTexture *stex,
@@ -650,8 +663,23 @@ set_cogl_texture (MetaShapedTexture *stex,
* previous buffer. We only queue a redraw in response to surface
* damage. */
@ -360,7 +358,7 @@ index ea8daa03d..9665ce2b6 100644
}
static gboolean
@@ -927,7 +957,9 @@ meta_shaped_texture_paint (ClutterActor *actor)
@@ -927,7 +955,9 @@ meta_shaped_texture_paint (ClutterActor *actor)
{
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
CoglTexture *paint_tex;
@ -370,7 +368,7 @@ index ea8daa03d..9665ce2b6 100644
if (!stex->texture)
return;
@@ -989,7 +1021,32 @@ meta_shaped_texture_paint (ClutterActor *actor)
@@ -989,7 +1019,32 @@ meta_shaped_texture_paint (ClutterActor *actor)
return;
fb = cogl_get_draw_framebuffer ();
@ -404,7 +402,7 @@ index ea8daa03d..9665ce2b6 100644
}
static void
@@ -1063,6 +1120,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
@@ -1063,6 +1118,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
stex->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ? stex->texture : NULL;
meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
@ -417,7 +415,7 @@ index ea8daa03d..9665ce2b6 100644
}
}
@@ -1256,6 +1319,12 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
@@ -1256,6 +1317,12 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
clip.y,
clip.width,
clip.height);
@ -430,7 +428,7 @@ index ea8daa03d..9665ce2b6 100644
stex->prev_invalidation = stex->last_invalidation;
stex->last_invalidation = g_get_monotonic_time ();
@@ -1302,17 +1371,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
@@ -1302,17 +1369,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
}
/**
@ -905,5 +903,5 @@ index da0acfcbb..ddad1a45c 100644
meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted);
g_clear_pointer (&snippet, cogl_object_unref);
--
2.21.0
2.23.0

View File

@ -0,0 +1,68 @@
From abfc64268d4135663fb46c5f3529cd5f082a5c20 Mon Sep 17 00:00:00 2001
From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
Date: Sun, 20 Oct 2019 12:04:31 +0200
Subject: [PATCH] EGL: Include EGL/eglmesaext.h
The eglext.h shipped by libglvnd does not include the Mesa extensions,
unlike the header shipped in Mesa.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/876
---
cogl/cogl/meson.build | 2 +-
src/backends/meta-egl-ext.h | 1 +
src/backends/meta-egl.c | 1 +
src/backends/meta-egl.h | 1 +
4 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index cb940420a..8032669e4 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -48,7 +48,7 @@ cogl_gl_header_h = configure_file(
built_headers += [cogl_gl_header_h]
if have_egl
- cogl_egl_includes_string = '#include <EGL/egl.h>\n#include <EGL/eglext.h>'
+ cogl_egl_includes_string = '#include <EGL/egl.h>\n#include <EGL/eglext.h>\n#include <EGL/eglmesaext.h>'
else
cogl_egl_includes_string = ''
endif
diff --git a/src/backends/meta-egl-ext.h b/src/backends/meta-egl-ext.h
index 8705e7d5b..db0b74f76 100644
--- a/src/backends/meta-egl-ext.h
+++ b/src/backends/meta-egl-ext.h
@@ -29,6 +29,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <EGL/eglmesaext.h>
/*
* This is a little different to the tests shipped with EGL implementations,
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
index 8b953449a..a28eef4ca 100644
--- a/src/backends/meta-egl.c
+++ b/src/backends/meta-egl.c
@@ -26,6 +26,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <EGL/eglmesaext.h>
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h
index ff37f124f..81b53b32d 100644
--- a/src/backends/meta-egl.h
+++ b/src/backends/meta-egl.h
@@ -27,6 +27,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <EGL/eglmesaext.h>
#include <glib-object.h>
#define META_EGL_ERROR meta_egl_error_quark ()
--
2.23.0

View File

@ -0,0 +1,80 @@
From eeff82f534f81b086d10d53124362d9e316e2cf9 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 12 Dec 2019 18:05:08 +0100
Subject: [PATCH] backends: Always enable tap-to-click/drag on opaque Wacom
tablets
Touch-wise, those are essentially giant touchpads, but have no buttons
associated to the "touchpad" device (There may be pad buttons, but
those are not mouse buttons).
Without tap-to-click/drag, touch in those devices is somewhat useless
out of the box. Have them always enable these features, despite the
setting.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/968
---
src/backends/meta-input-settings.c | 33 ++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index 2e6672d9c..28dc387ef 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -517,6 +517,33 @@ update_touchpad_disable_while_typing (MetaInputSettings *input_settings,
}
}
+static gboolean
+device_is_tablet_touchpad (MetaInputSettings *input_settings,
+ ClutterInputDevice *device)
+{
+#ifdef HAVE_LIBWACOM
+ WacomIntegrationFlags flags = 0;
+ WacomDevice *wacom_device;
+
+ if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
+ return FALSE;
+
+ wacom_device =
+ meta_input_settings_get_tablet_wacom_device (input_settings,
+ device);
+ if (wacom_device)
+ {
+ flags = libwacom_get_integration_flags (wacom_device);
+
+ if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
+ WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0)
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
static void
update_touchpad_tap_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device)
@@ -531,7 +558,8 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
- enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
if (device)
{
@@ -561,7 +589,8 @@ update_touchpad_tap_and_drag_enabled (MetaInputSettings *input_settings,
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
- enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag");
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag");
if (device)
{
--
2.23.0

View File

@ -0,0 +1,96 @@
From f14730e7307679cb979aa521b20f246dfc5082da Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 13 Dec 2019 15:26:05 +0100
Subject: [PATCH] backends: Check both input settings and mapper for tablet
monitors
The upper layers (OSDs basically) want to know the monitor that a
tablet is currently assigned to, not the monitor just as configured
through settings.
This broke proper OSD positioning for display-attached tablets since
commit 87858a4e01d9, as the MetaInputMapper kicks in precisely when
there is no configured monitor for the given device.
Consulting both about the assigned output will make OSDs pop up
again in the right place.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/971
---
src/backends/meta-input-mapper-private.h | 3 +++
src/backends/meta-input-mapper.c | 26 ++++++++++++++++++++++++
src/backends/meta-input-settings.c | 11 ++++++++--
3 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h
index 34314577f..cdfdccde9 100644
--- a/src/backends/meta-input-mapper-private.h
+++ b/src/backends/meta-input-mapper-private.h
@@ -42,5 +42,8 @@ ClutterInputDevice *
meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
MetaLogicalMonitor *logical_monitor,
ClutterInputDeviceType device_type);
+MetaLogicalMonitor *
+meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
+ ClutterInputDevice *device);
#endif /* META_INPUT_MAPPER_H */
diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c
index acc9b1618..571b3983c 100644
--- a/src/backends/meta-input-mapper.c
+++ b/src/backends/meta-input-mapper.c
@@ -684,3 +684,29 @@ meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
return NULL;
}
+
+MetaLogicalMonitor *
+meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
+ ClutterInputDevice *device)
+{
+ MetaMapperOutputInfo *output;
+ MetaLogicalMonitor *logical_monitor;
+ GHashTableIter iter;
+ GList *l;
+
+ g_hash_table_iter_init (&iter, mapper->output_devices);
+
+ while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor,
+ (gpointer *) &output))
+ {
+ for (l = output->input_devices; l; l = l->next)
+ {
+ MetaMapperInputInfo *input = l->data;
+
+ if (input->device == device)
+ return logical_monitor;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index b7aec8d6d..a923aa971 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -1922,8 +1922,15 @@ meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
if (!info)
return NULL;
- meta_input_settings_find_monitor (settings, info->settings, device,
- NULL, &logical_monitor);
+ logical_monitor =
+ meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device);
+
+ if (!logical_monitor)
+ {
+ meta_input_settings_find_monitor (settings, info->settings, device,
+ NULL, &logical_monitor);
+ }
+
return logical_monitor;
}
--
2.23.0

View File

@ -0,0 +1,30 @@
From e512c397a640994807f239c570333e9942717ef5 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 13 Dec 2019 17:01:44 +0100
Subject: [PATCH] backends: Consider pen/eraser devices when looking for
matching WacomDevice
Those device types are still in use through the X11 backend, breaking some
checks around on that backend...
https://gitlab.gnome.org/GNOME/mutter/merge_requests/972
---
src/backends/meta-input-settings.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index 2e6672d9c..18ae52dd7 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -1589,6 +1589,8 @@ check_add_mappable_device (MetaInputSettings *input_settings,
#ifdef HAVE_LIBWACOM
if (device_type == CLUTTER_TABLET_DEVICE ||
+ device_type == CLUTTER_PEN_DEVICE ||
+ device_type == CLUTTER_ERASER_DEVICE ||
device_type == CLUTTER_PAD_DEVICE)
{
WacomError *error = libwacom_error_new ();
--
2.23.0

View File

@ -0,0 +1,118 @@
From a8f12e7afdb35ebda581cee6a32b295cb6e643ec Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 13 Dec 2019 14:22:12 +0100
Subject: [PATCH] backends/x11: Observe multiple pad mode switch buttons in a
group
Some tablets like the Cintiq 24HDT have several mode switch buttons
per group. Those are meant to jump straight to a given mode, however
we just handle cycling across modes (as most other tablets have a
single mode switch button per group).
So spice up the mode switch handling so we handle multiple mode
switch buttons, assigning each of them a mode. If the device only
has one mode switch button, we do the old-fashioned cycling.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/970
---
.../clutter/x11/clutter-input-device-xi2.c | 71 ++++++++++++++++---
1 file changed, 60 insertions(+), 11 deletions(-)
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
index 1254aca3a..c33adffc2 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.c
+++ b/clutter/clutter/x11/clutter-input-device-xi2.c
@@ -318,6 +318,57 @@ clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
return g_array_index (device_xi2->group_modes, guint, group);
}
+static gboolean
+pad_switch_mode (ClutterInputDevice *device,
+ uint32_t button,
+ uint32_t group,
+ uint32_t *mode)
+{
+ ClutterInputDeviceXI2 *device_x11 = CLUTTER_INPUT_DEVICE_XI2 (device);
+ uint32_t n_buttons, n_modes, button_group, next_mode, i;
+ GList *switch_buttons = NULL;
+
+ n_buttons = libwacom_get_num_buttons (device_x11->wacom_device);
+
+ for (i = 0; i < n_buttons; i++)
+ {
+ button_group = clutter_input_device_xi2_get_button_group (device, i);
+ if (button_group == group)
+ switch_buttons = g_list_prepend (switch_buttons, GINT_TO_POINTER (button));
+ }
+
+ switch_buttons = g_list_reverse (switch_buttons);
+ n_modes = clutter_input_device_get_group_n_modes (device, group);
+
+ if (g_list_length (switch_buttons) > 1)
+ {
+ /* If there's multiple switch buttons, we don't toggle but assign a mode
+ * to each of those buttons.
+ */
+ next_mode = g_list_position (switch_buttons, GINT_TO_POINTER (button));
+ }
+ else if (switch_buttons)
+ {
+ uint32_t cur_mode;
+
+ /* If there is a single button, have it toggle across modes */
+ cur_mode = g_array_index (device_x11->group_modes, uint32_t, group);
+ next_mode = (cur_mode + 1) % n_modes;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ g_list_free (switch_buttons);
+
+ if (next_mode < 0 || next_mode > n_modes)
+ return FALSE;
+
+ *mode = next_mode;
+ return TRUE;
+}
+
void
clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
guint button,
@@ -330,23 +381,21 @@ clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
gboolean is_mode_switch = FALSE;
button_group = clutter_input_device_xi2_get_button_group (device, button);
- is_mode_switch = button_group >= 0;
- /* Assign all non-mode-switch buttons to group 0 so far */
- button_group = MAX (0, button_group);
-
- if (button_group >= device_xi2->group_modes->len)
- return;
+ if (button_group < 0 || button_group >= device_xi2->group_modes->len)
+ {
+ *group = *mode = 0;
+ return;
+ }
group_mode = &g_array_index (device_xi2->group_modes, guint, button_group);
- if (is_mode_switch && state)
+ if (state)
{
- guint next, n_modes;
+ uint32_t next_mode;
- n_modes = clutter_input_device_get_group_n_modes (device, button_group);
- next = (*group_mode + 1) % n_modes;
- *group_mode = next;
+ if (pad_switch_mode (device, button, button_group, &next_mode))
+ *group_mode = next_mode;
}
if (group)
--
2.23.0

View File

@ -0,0 +1,37 @@
From 251ef4ff4bacefac211e21873e10da7fa067dd68 Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Fri, 26 Apr 2019 12:23:18 +0300
Subject: [PATCH 01/12] cogl: Remove unused OFFSCREEN_BLIT feature flag
This named constant is never used anywhere.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit c08a24bb40ad7aa7746e86251c9dbe6c264b4d7c)
---
cogl/cogl/cogl-types.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
index 690daa16a..69d304cf0 100644
--- a/cogl/cogl/cogl-types.h
+++ b/cogl/cogl/cogl-types.h
@@ -325,7 +325,6 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
* @COGL_FEATURE_SHADERS_GLSL: GLSL support
* @COGL_FEATURE_OFFSCREEN: FBO support
* @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs
- * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs
* @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
* @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
* @COGL_FEATURE_VBOS: VBO support
@@ -368,7 +367,6 @@ typedef enum
COGL_FEATURE_SHADERS_GLSL = (1 << 5),
COGL_FEATURE_OFFSCREEN = (1 << 6),
COGL_FEATURE_OFFSCREEN_MULTISAMPLE = (1 << 7),
- COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8),
COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9),
COGL_FEATURE_STENCIL_BUFFER = (1 << 10),
COGL_FEATURE_VBOS = (1 << 11),
--
2.21.0

View File

@ -0,0 +1,64 @@
From 5cab6bac4d4fb06e60d3198dc654a5d70fa6240e Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 16 Dec 2019 13:53:26 +0100
Subject: [PATCH] core: Let pad mode switch events always go through
MetaInputSettings
We used to inhibit all pad actions while the OSD is shown, but one we
would actually want to handle are mode switches while the OSD is open.
So it has an opportunity to catch up to the mode switch.
This lets MetaInputSettings reflect the mode switch (eg. when querying
action labels), so the OSD has an opportunity to update the current
actions.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/975
---
src/core/events.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/src/core/events.c b/src/core/events.c
index d383778629..44f28d0b97 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -256,13 +256,31 @@ meta_display_handle_event (MetaDisplay *display,
}
#endif
- if (!display->current_pad_osd &&
- (event->type == CLUTTER_PAD_BUTTON_PRESS ||
- event->type == CLUTTER_PAD_BUTTON_RELEASE ||
- event->type == CLUTTER_PAD_RING ||
- event->type == CLUTTER_PAD_STRIP))
+ if (event->type == CLUTTER_PAD_BUTTON_PRESS ||
+ event->type == CLUTTER_PAD_BUTTON_RELEASE ||
+ event->type == CLUTTER_PAD_RING ||
+ event->type == CLUTTER_PAD_STRIP)
{
- if (meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend),
+ gboolean handle_pad_event = TRUE;
+ gboolean is_mode_switch = FALSE;
+
+ if (event->type == CLUTTER_PAD_BUTTON_PRESS ||
+ event->type == CLUTTER_PAD_BUTTON_RELEASE)
+ {
+ ClutterInputDevice *pad;
+ uint32_t button;
+
+ pad = clutter_event_get_source_device (event);
+ button = clutter_event_get_button (event);
+
+ is_mode_switch =
+ clutter_input_device_get_mode_switch_button_group (pad, button) >= 0;
+ }
+
+ handle_pad_event = !display->current_pad_osd || is_mode_switch;
+
+ if (handle_pad_event &&
+ meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend),
event))
{
bypass_wayland = bypass_clutter = TRUE;
--
2.24.0

View File

@ -0,0 +1,122 @@
From f108395c32351cda8722130e0e2970827b18e5a9 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 2 Oct 2019 16:49:28 +0200
Subject: [PATCH] events: Sync pending pointer events without a window
Mutter issues a synchronous grab on the pointer for unfocused client
windows to be able to catch the button events first and raise/focus
client windows accordingly.
When there is a synchronous grab in effect, all events are queued until
the grabbing client releases the event queue as it processes the events.
Mutter does release the events in its event handler function but does so
only if it is able to find the window matching the event. If the window
is a shell widget, that matching may fail and therefore Mutter will not
release the events, hence causing a freeze in pointer events delivery.
To avoid the issue, make sure we sync the pointer events in case we
can't find a matching window.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/821
---
src/core/events.c | 62 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 51 insertions(+), 11 deletions(-)
diff --git a/src/core/events.c b/src/core/events.c
index 5b8e49fc7..831cb007b 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -50,6 +50,12 @@
#define IS_KEY_EVENT(e) ((e)->type == CLUTTER_KEY_PRESS || \
(e)->type == CLUTTER_KEY_RELEASE)
+typedef enum
+{
+ EVENTS_UNFREEZE_SYNC,
+ EVENTS_UNFREEZE_REPLAY,
+} EventsUnfreezeMethod;
+
static gboolean
stage_has_key_focus (void)
{
@@ -167,6 +173,43 @@ sequence_is_pointer_emulated (MetaDisplay *display,
return FALSE;
}
+static void
+maybe_unfreeze_pointer_events (MetaBackend *backend,
+ const ClutterEvent *event,
+ EventsUnfreezeMethod unfreeze_method)
+{
+ Display *xdisplay;
+ int event_mode;
+ int device_id;
+
+ if (event->type != CLUTTER_BUTTON_PRESS)
+ return;
+
+ if (!META_IS_BACKEND_X11 (backend))
+ return;
+
+ device_id = clutter_event_get_device_id (event);
+ switch (unfreeze_method)
+ {
+ case EVENTS_UNFREEZE_SYNC:
+ event_mode = XISyncDevice;
+ meta_verbose ("Syncing events time %u device %i\n",
+ (unsigned int) event->button.time, device_id);
+ break;
+ case EVENTS_UNFREEZE_REPLAY:
+ event_mode = XIReplayDevice;
+ meta_verbose ("Replaying events time %u device %i\n",
+ (unsigned int) event->button.time, device_id);
+ break;
+ default:
+ g_assert_not_reached ();
+ return;
+ }
+
+ xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+ XIAllowEvents (xdisplay, device_id, event_mode, event->button.time);
+}
+
static gboolean
meta_display_handle_event (MetaDisplay *display,
const ClutterEvent *event)
@@ -366,17 +409,7 @@ meta_display_handle_event (MetaDisplay *display,
{
/* Only replay button press events, since that's where we
* have the synchronous grab. */
- if (event->type == CLUTTER_BUTTON_PRESS)
- {
- if (META_IS_BACKEND_X11 (backend))
- {
- Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
- meta_verbose ("Allowing events time %u\n",
- (unsigned int)event->button.time);
- XIAllowEvents (xdisplay, clutter_event_get_device_id (event),
- XIReplayDevice, event->button.time);
- }
- }
+ maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY);
/* If the focus window has an active close dialog let clutter
* events go through, so fancy clutter dialogs can get to handle
@@ -392,6 +425,13 @@ meta_display_handle_event (MetaDisplay *display,
goto out;
}
+ else
+ {
+ /* We could not match the event with a window, make sure we sync
+ * the pointer to discard the sequence and don't keep events frozen.
+ */
+ maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_SYNC);
+ }
out:
/* If the compositor has a grab, don't pass that through to Wayland */
--
2.23.0

View File

@ -0,0 +1,136 @@
From 80f79e0cc7509b79b38193a006b0d98d03432044 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 5 Aug 2019 14:39:21 -0400
Subject: [PATCH] iconcache: Avoid xrender picture formats when creating cairo
surface
If an application provides its window icon via wmhints, then mutter
loads the pixmap specified by the application into a cairo xlib surface. When
creating the surface it specifies the visual, indirectly, via an XRender
picture format.
This is suboptimal, since XRender picture formats don't have a way to specify
16bpp depth, which an application may be using.
In particular, applications are likely to use 16bpp depth pixmaps for their
icons, if the video card offers a 16bpp framebuffer/root window.
This commit drops the XRender middleman, and just tells cairo a visual to use
directly.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/715
---
src/x11/iconcache.c | 31 ++++++-------------------------
1 file changed, 6 insertions(+), 25 deletions(-)
diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c
index 15d72da65..521c77b8d 100644
--- a/src/x11/iconcache.c
+++ b/src/x11/iconcache.c
@@ -261,97 +261,78 @@ get_pixmap_geometry (MetaX11Display *x11_display,
Pixmap pixmap,
int *w,
int *h,
int *d)
{
Window root_ignored;
int x_ignored, y_ignored;
guint width, height;
guint border_width_ignored;
guint depth;
if (w)
*w = 1;
if (h)
*h = 1;
if (d)
*d = 1;
XGetGeometry (x11_display->xdisplay,
pixmap, &root_ignored, &x_ignored, &y_ignored,
&width, &height, &border_width_ignored, &depth);
if (w)
*w = width;
if (h)
*h = height;
if (d)
*d = depth;
}
-static int
-standard_pict_format_for_depth (int depth)
-{
- switch (depth)
- {
- case 1:
- return PictStandardA1;
- case 24:
- return PictStandardRGB24;
- case 32:
- return PictStandardARGB32;
- default:
- g_assert_not_reached ();
- }
- return 0;
-}
-
-static XRenderPictFormat *
-pict_format_for_depth (Display *xdisplay, int depth)
-{
- return XRenderFindStandardFormat (xdisplay, standard_pict_format_for_depth (depth));
-}
-
static cairo_surface_t *
surface_from_pixmap (Display *xdisplay, Pixmap xpixmap,
int width, int height)
{
Window root_return;
+ XVisualInfo visual_info;
int x_ret, y_ret;
unsigned int w_ret, h_ret, bw_ret, depth_ret;
if (!XGetGeometry (xdisplay, xpixmap, &root_return,
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
return NULL;
- return cairo_xlib_surface_create_with_xrender_format (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay),
- pict_format_for_depth (xdisplay, depth_ret), w_ret, h_ret);
+ if (!XMatchVisualInfo (xdisplay, DefaultScreen (xdisplay),
+ depth_ret, TrueColor, &visual_info))
+ return NULL;
+
+ return cairo_xlib_surface_create (xdisplay, xpixmap, visual_info.visual, w_ret, h_ret);
}
static gboolean
try_pixmap_and_mask (MetaX11Display *x11_display,
Pixmap src_pixmap,
Pixmap src_mask,
cairo_surface_t **iconp)
{
Display *xdisplay = x11_display->xdisplay;
cairo_surface_t *icon, *mask = NULL;
int w, h, d;
if (src_pixmap == None)
return FALSE;
meta_x11_error_trap_push (x11_display);
get_pixmap_geometry (x11_display, src_pixmap, &w, &h, &d);
icon = surface_from_pixmap (xdisplay, src_pixmap, w, h);
if (icon && src_mask != None)
{
get_pixmap_geometry (x11_display, src_mask, &w, &h, &d);
if (d == 1)
mask = surface_from_pixmap (xdisplay, src_mask, w, h);
}
meta_x11_error_trap_pop (x11_display);
--
2.21.0

View File

@ -0,0 +1,114 @@
From 078547521dd709d41ac3791322f711030ccc50e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 19:03:50 +0100
Subject: [PATCH 1/2] monitor-manager-xrandr: Move dpms state and screen size
updating into helpers
To be used by no-Xrandr fallback path.
---
src/backends/x11/meta-gpu-xrandr.c | 37 +++++++++++++------
.../x11/meta-monitor-manager-xrandr.c | 18 ++++++---
2 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
index 90b33d486..1884278ca 100644
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ b/src/backends/x11/meta-gpu-xrandr.c
@@ -91,6 +91,30 @@ meta_gpu_xrandr_poll_hardware (MetaGpu *gpu)
gpu_xrandr->need_hardware_poll = TRUE;
}
+static void
+update_screen_size (MetaGpuXrandr *gpu_xrandr)
+{
+ MetaGpu *gpu = META_GPU (gpu_xrandr);
+ MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+ MetaMonitorManagerXrandr *monitor_manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (monitor_manager);
+ Display *xdisplay =
+ meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr);
+ int min_width, min_height;
+ Screen *screen;
+
+ XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
+ &min_width,
+ &min_height,
+ &gpu_xrandr->max_screen_width,
+ &gpu_xrandr->max_screen_height);
+
+ screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay));
+ /* This is updated because we called XRRUpdateConfiguration. */
+ monitor_manager->screen_width = WidthOfScreen (screen);
+ monitor_manager->screen_height = HeightOfScreen (screen);
+}
+
static gboolean
meta_gpu_xrandr_read_current (MetaGpu *gpu,
GError **error)
@@ -105,8 +129,6 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
RROutput primary_output;
unsigned int i, j;
GList *l;
- int min_width, min_height;
- Screen *screen;
GList *outputs = NULL;
GList *modes = NULL;
GList *crtcs = NULL;
@@ -115,16 +137,7 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
XRRFreeScreenResources (gpu_xrandr->resources);
gpu_xrandr->resources = NULL;
- XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
- &min_width,
- &min_height,
- &gpu_xrandr->max_screen_width,
- &gpu_xrandr->max_screen_height);
-
- screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay));
- /* This is updated because we called XRRUpdateConfiguration. */
- monitor_manager->screen_width = WidthOfScreen (screen);
- monitor_manager->screen_height = HeightOfScreen (screen);
+ update_screen_size (gpu_xrandr);
if (gpu_xrandr->need_hardware_poll)
{
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index b8d6342b6..7a0b43ac4 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -146,12 +146,9 @@ x11_dpms_state_to_power_save (CARD16 dpms_state)
}
static void
-meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
+meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr)
{
- MetaMonitorManagerXrandr *manager_xrandr =
- META_MONITOR_MANAGER_XRANDR (manager);
- MetaMonitorManagerClass *parent_class =
- META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class);
+ MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
Display *xdisplay = meta_monitor_manager_xrandr_get_xdisplay (manager_xrandr);
BOOL dpms_capable, dpms_enabled;
CARD16 dpms_state;
@@ -167,6 +164,17 @@ meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
power_save_mode = META_POWER_SAVE_UNSUPPORTED;
meta_monitor_manager_power_save_mode_changed (manager, power_save_mode);
+}
+
+static void
+meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
+{
+ MetaMonitorManagerXrandr *manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (manager);
+ MetaMonitorManagerClass *parent_class =
+ META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class);
+
+ meta_monitor_manager_xrandr_update_dpms_state (manager_xrandr);
parent_class->read_current_state (manager);
}
--
2.23.0

View File

@ -0,0 +1,109 @@
From f2b3dd318f1165849b45a86251724939b100ef7d Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 28 Oct 2019 18:07:31 +0100
Subject: [PATCH] wayland: Check stylus serials on
meta_wayland_seat_can_popup()
This allows xdg_popup.grab() to work with styli. Without this check
we would bail out and emit xdg_popup.popup_done, leaving stylus users
unable to interact with popup menus, comboboxes, etc...
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/886
---
src/wayland/meta-wayland-seat.c | 10 +++++++++-
src/wayland/meta-wayland-tablet-seat.c | 17 +++++++++++++++++
src/wayland/meta-wayland-tablet-seat.h | 2 ++
src/wayland/meta-wayland-tablet-tool.c | 7 +++++++
src/wayland/meta-wayland-tablet-tool.h | 2 ++
5 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index 91fe376ff..cf41d6eb8 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -504,9 +504,17 @@ gboolean
meta_wayland_seat_can_popup (MetaWaylandSeat *seat,
uint32_t serial)
{
+ MetaWaylandCompositor *compositor;
+ MetaWaylandTabletSeat *tablet_seat;
+
+ compositor = meta_wayland_compositor_get_default ();
+ tablet_seat =
+ meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
+
return (meta_wayland_pointer_can_popup (seat->pointer, serial) ||
meta_wayland_keyboard_can_popup (seat->keyboard, serial) ||
- meta_wayland_touch_can_popup (seat->touch, serial));
+ meta_wayland_touch_can_popup (seat->touch, serial) ||
+ meta_wayland_tablet_seat_can_popup (tablet_seat, serial));
}
gboolean
diff --git a/src/wayland/meta-wayland-tablet-seat.c b/src/wayland/meta-wayland-tablet-seat.c
index b4bc4aa58..b1964714a 100644
--- a/src/wayland/meta-wayland-tablet-seat.c
+++ b/src/wayland/meta-wayland-tablet-seat.c
@@ -552,3 +552,20 @@ meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat,
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &pad))
meta_wayland_tablet_pad_set_focus (pad, surface);
}
+
+gboolean
+meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat,
+ uint32_t serial)
+{
+ MetaWaylandTabletTool *tool;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, tablet_seat->tools);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tool))
+ {
+ if (meta_wayland_tablet_tool_can_popup (tool, serial))
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/src/wayland/meta-wayland-tablet-seat.h b/src/wayland/meta-wayland-tablet-seat.h
index c083dec5f..e3be5f264 100644
--- a/src/wayland/meta-wayland-tablet-seat.h
+++ b/src/wayland/meta-wayland-tablet-seat.h
@@ -75,5 +75,7 @@ MetaWaylandTablet *meta_wayland_tablet_seat_lookup_paired_tablet (MetaWaylan
MetaWaylandTabletPad *pad);
GList *meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat,
MetaWaylandTablet *tablet);
+gboolean meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat,
+ uint32_t serial);
#endif /* META_WAYLAND_TABLET_SEAT_H */
diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
index c02831d73..065c834bb 100644
--- a/src/wayland/meta-wayland-tablet-tool.c
+++ b/src/wayland/meta-wayland-tablet-tool.c
@@ -1018,3 +1018,10 @@ meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
return ((tool->down_serial == serial || tool->button_serial == serial) &&
tablet_tool_can_grab_surface (tool, surface));
}
+
+gboolean
+meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool,
+ uint32_t serial)
+{
+ return tool->down_serial == serial || tool->button_serial == serial;
+}
diff --git a/src/wayland/meta-wayland-tablet-tool.h b/src/wayland/meta-wayland-tablet-tool.h
index 71bc86643..315e26bde 100644
--- a/src/wayland/meta-wayland-tablet-tool.h
+++ b/src/wayland/meta-wayland-tablet-tool.h
@@ -85,5 +85,7 @@ void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *t
gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
MetaWaylandSurface *surface,
uint32_t serial);
+gboolean meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool,
+ uint32_t serial);
#endif /* META_WAYLAND_TABLET_TOOL_H */
--
2.23.0

View File

@ -0,0 +1,83 @@
From eca25ab6a12770a2a767458d9b0129d4fde3995c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 13 Nov 2018 08:31:52 +0100
Subject: [PATCH 1/2] workspace: Focus only ancestors that are focusable
When destroying a window that has a parent, we initially try to focus one of
its ancestors. However if no ancestor can be focused, then we should instead
focus the default focus window instead of trying to request focus for a window
that can't get focus anyways.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/308
(cherry picked from commit eccc791f3b3451216f957e67fec47a73b65ed2b2)
---
src/core/workspace.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/core/workspace.c b/src/core/workspace.c
index f2b2c2c48..58fcfa78c 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -85,6 +85,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData
MetaRectangle logical_monitor_work_area;
} MetaWorkspaceLogicalMonitorData;
+typedef struct _MetaWorkspaceFocusableAncestorData
+{
+ MetaWorkspace *workspace;
+ MetaWindow *out_window;
+} MetaWorkspaceFocusableAncestorData;
+
static MetaWorkspaceLogicalMonitorData *
meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace,
MetaLogicalMonitor *logical_monitor)
@@ -1322,13 +1328,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
}
static gboolean
-record_ancestor (MetaWindow *window,
- void *data)
+find_focusable_ancestor (MetaWindow *window,
+ gpointer user_data)
{
- MetaWindow **result = data;
+ MetaWorkspaceFocusableAncestorData *data = user_data;
+
+ if (!window->unmanaging && meta_window_is_focusable (window) &&
+ meta_window_located_on_workspace (window, data->workspace) &&
+ meta_window_showing_on_its_workspace (window))
+ {
+ data->out_window = window;
+ return FALSE;
+ }
- *result = window;
- return FALSE; /* quit with the first ancestor we find */
+ return TRUE;
}
/* Focus ancestor of not_this_one if there is one */
@@ -1350,11 +1363,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
if (not_this_one)
{
MetaWindow *ancestor;
- ancestor = NULL;
- meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
- if (ancestor != NULL &&
- meta_window_located_on_workspace (ancestor, workspace) &&
- meta_window_showing_on_its_workspace (ancestor))
+ MetaWorkspaceFocusableAncestorData data;
+
+ data = (MetaWorkspaceFocusableAncestorData) {
+ .workspace = workspace,
+ };
+ meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data);
+ ancestor = data.out_window;
+
+ if (ancestor)
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s, ancestor of %s\n",
--
2.21.0

View File

@ -0,0 +1,53 @@
From 57b3a2ea620f754cfd38f1ed4851dd8223efbcab Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 28 Nov 2019 22:50:36 +0100
Subject: [PATCH] x11: Check wacom button flags to determine whether button is
mode switch
Checking the leds is not really accurate, since some devices have mode
switch buttons without leds. Check in the button flags whether they are
mode switch buttons for any of ring/ring2/strip/strip2, and return the
appropriate group.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/952
---
.../clutter/x11/clutter-input-device-xi2.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
index 1254aca3ae..4e5e2fd12c 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.c
+++ b/clutter/clutter/x11/clutter-input-device-xi2.c
@@ -155,14 +155,25 @@ clutter_input_device_xi2_get_button_group (ClutterInputDevice *device,
if (device_xi2->wacom_device)
{
+ WacomButtonFlags flags;
+
if (button >= libwacom_get_num_buttons (device_xi2->wacom_device))
return -1;
- return libwacom_get_button_led_group (device_xi2->wacom_device,
- 'A' + button);
+ flags = libwacom_get_button_flag (device_xi2->wacom_device,
+ 'A' + button);
+
+ if (flags &
+ (WACOM_BUTTON_RING_MODESWITCH |
+ WACOM_BUTTON_TOUCHSTRIP_MODESWITCH))
+ return 0;
+ if (flags &
+ (WACOM_BUTTON_RING2_MODESWITCH |
+ WACOM_BUTTON_TOUCHSTRIP2_MODESWITCH))
+ return 1;
}
- else
- return -1;
+
+ return -1;
}
#endif
--
2.24.0

View File

@ -0,0 +1,42 @@
From 801da0dab1d2928578e9b191ee1684bcc7154081 Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Tue, 30 Apr 2019 17:01:04 +0300
Subject: [PATCH 02/12] cogl: Fix doc for _cogl_blit_framebuffer
Commit 38921701e533b7fda38a236cc45aec2ed3afef8a added explicit source and
destination parameters. Fix the documentation to match.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit fc0ce11fcd997af12fc2253eeb37e03cebb5964f)
---
cogl/cogl/cogl-framebuffer-private.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index 296788c2b..de886b64f 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2007,2008,2009 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -377,9 +378,8 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* @width: Width of region to copy
* @height: Height of region to copy
*
- * This blits a region of the color buffer of the current draw buffer
- * to the current read buffer. The draw and read buffers can be set up
- * using _cogl_push_framebuffers(). This function should only be
+ * This blits a region of the color buffer of the source buffer
+ * to the destination buffer. This function should only be
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
* advertised. The two buffers must both be offscreen and have the
* same format.
--
2.21.0

View File

@ -0,0 +1,185 @@
From 85484d8f5d75764ab74308da7b21411c3fe4a2da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 3 Oct 2018 10:50:47 +0200
Subject: [PATCH 2/2] monitor-manager/xrandr: Create dummy screen sized monitor
if no RANDR
When there is no RANDR support enabled in the X server, we wont get
notified of any monitors, resulting in mutter believing we're being
headless. To get at least something working, although with no way
configuration ability, lets pretend the whole screen is just a single
monitor with a single output, crtc and mode.
---
src/backends/x11/meta-gpu-xrandr.c | 60 +++++++++++++++++++
.../x11/meta-monitor-manager-xrandr.c | 22 ++++++-
.../x11/meta-monitor-manager-xrandr.h | 4 ++
3 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
index 1884278ca..22e7e70e0 100644
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ b/src/backends/x11/meta-gpu-xrandr.c
@@ -115,6 +115,63 @@ update_screen_size (MetaGpuXrandr *gpu_xrandr)
monitor_manager->screen_height = HeightOfScreen (screen);
}
+static gboolean
+read_current_fallback (MetaGpuXrandr *gpu_xrandr,
+ MetaMonitorManagerXrandr *monitor_manager_xrandr)
+{
+ MetaGpu *gpu = META_GPU (gpu_xrandr);
+ MetaMonitorManager *monitor_manager =
+ META_MONITOR_MANAGER (monitor_manager_xrandr);
+ MetaCrtcMode *mode;
+ MetaCrtc *crtc;
+ MetaOutput *output;
+
+ meta_monitor_manager_xrandr_update_dpms_state (monitor_manager_xrandr);
+ update_screen_size (gpu_xrandr);
+
+ mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
+ mode->mode_id = 0;
+ mode->width = monitor_manager->screen_width;
+ mode->height = monitor_manager->screen_height;
+ mode->refresh_rate = 60.0;
+ mode->name = g_strdup_printf ("%dx%d", mode->width, mode->height);
+
+ meta_gpu_take_modes (gpu, g_list_prepend (NULL, mode));
+
+ crtc = g_object_new (META_TYPE_CRTC, NULL);
+ crtc->gpu = gpu;
+ crtc->crtc_id = 0;
+ crtc->rect = (MetaRectangle) { .width = mode->width, .height = mode->height };
+ crtc->current_mode = mode;
+
+ meta_gpu_take_crtcs (gpu, g_list_prepend (NULL, crtc));
+
+ output = g_object_new (META_TYPE_OUTPUT, NULL);
+ output->gpu = gpu;
+ output->winsys_id = 0;
+ output->name = g_strdup ("X11 Screen");
+ output->vendor = g_strdup ("unknown");
+ output->product = g_strdup ("unknown");
+ output->serial = g_strdup ("unknown");
+ output->hotplug_mode_update = TRUE;
+ output->suggested_x = -1;
+ output->suggested_y = -1;
+ output->connector_type = META_CONNECTOR_TYPE_Unknown;
+ output->modes = g_new0 (MetaCrtcMode *, 1);
+ output->modes[0] = mode;
+ output->n_modes = 1;
+ output->preferred_mode = mode;
+ output->possible_crtcs = g_new0 (MetaCrtc *, 1);
+ output->possible_crtcs[0] = crtc;
+ output->n_possible_crtcs = 1;
+ meta_output_assign_crtc (output, crtc);
+ output->is_primary = TRUE;
+
+ meta_gpu_take_outputs (gpu, g_list_prepend (NULL, output));
+
+ return TRUE;
+}
+
static gboolean
meta_gpu_xrandr_read_current (MetaGpu *gpu,
GError **error)
@@ -133,6 +190,9 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
GList *modes = NULL;
GList *crtcs = NULL;
+ if (!meta_monitor_manager_xrandr_has_randr (monitor_manager_xrandr))
+ return read_current_fallback (gpu_xrandr, monitor_manager_xrandr);
+
if (gpu_xrandr->resources)
XRRFreeScreenResources (gpu_xrandr->resources);
gpu_xrandr->resources = NULL;
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 7a0b43ac4..d6306faeb 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -75,6 +75,7 @@ struct _MetaMonitorManagerXrandr
guint logind_watch_id;
guint logind_signal_sub_id;
+ gboolean has_randr;
gboolean has_randr15;
/*
@@ -114,6 +115,12 @@ meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xran
return manager_xrandr->xdisplay;
}
+gboolean
+meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr)
+{
+ return manager_xrandr->has_randr;
+}
+
gboolean
meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr)
{
@@ -145,7 +152,7 @@ x11_dpms_state_to_power_save (CARD16 dpms_state)
}
}
-static void
+void
meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
@@ -637,9 +644,18 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
MetaMonitorsConfigMethod method,
GError **error)
{
+ MetaMonitorManagerXrandr *manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (manager);
GPtrArray *crtc_infos;
GPtrArray *output_infos;
+ if (!manager_xrandr->has_randr)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Tried to change configuration without XRANDR support");
+ return FALSE;
+ }
+
if (!config)
{
meta_monitor_manager_xrandr_rebuild_derived (manager, NULL);
@@ -1105,11 +1121,15 @@ meta_monitor_manager_xrandr_constructed (GObject *object)
&manager_xrandr->rr_event_base,
&manager_xrandr->rr_error_base))
{
+ g_warning ("No RANDR support, monitor configuration disabled");
return;
}
else
{
int major_version, minor_version;
+
+ manager_xrandr->has_randr = TRUE;
+
/* We only use ScreenChangeNotify, but GDK uses the others,
and we don't want to step on its toes */
XRRSelectInput (manager_xrandr->xdisplay,
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.h b/src/backends/x11/meta-monitor-manager-xrandr.h
index d55b3d2b8..dc75134a5 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.h
+++ b/src/backends/x11/meta-monitor-manager-xrandr.h
@@ -33,9 +33,13 @@ G_DECLARE_FINAL_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr,
Display * meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr);
+gboolean meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr);
+
gboolean meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr);
gboolean meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager,
XEvent *event);
+void meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr);
+
#endif /* META_MONITOR_MANAGER_XRANDR_H */
--
2.23.0

View File

@ -0,0 +1,42 @@
From 9a8bb8a205656ca1089444a041c99c5591477642 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 3 May 2019 18:10:47 +0000
Subject: [PATCH 2/2] window: Emit an error and return when trying to activate
an unmanaged
If something (i.e. gnome-shell or an extension) tries to activate an unmanaged
window, we should warn about this and avoid to perform further actions as this
could lead to a crash of mutter, since the window has not valid flags (like
workspace) set anymore at this stage.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/580
https://gitlab.gnome.org/GNOME/mutter/merge_requests/564
(cherry picked from commit a6fc656e917fd48b8708b8d9f4bf9f8b15581313)
---
src/core/window.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/core/window.c b/src/core/window.c
index d2c24506b..725cca7ce 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3683,6 +3683,13 @@ meta_window_activate_full (MetaWindow *window,
{
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
gboolean allow_workspace_switch;
+
+ if (window->unmanaging)
+ {
+ g_warning ("Trying to activate unmanaged window '%s'", window->desc);
+ return;
+ }
+
meta_topic (META_DEBUG_FOCUS,
"_NET_ACTIVE_WINDOW message sent for %s at time %u "
"by client type %u.\n",
--
2.21.0

View File

@ -1,4 +1,4 @@
From 9f566208d584ec4d8da797390b6806157c7d2402 Mon Sep 17 00:00:00 2001
From c5020c3d303ab211a970d88638e7d723034688db Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 10 Jan 2019 10:47:19 -0500
Subject: [PATCH 3/9] backend: add signals for reporting suspend and resume
@ -9,14 +9,24 @@ to MetaBackend.
It's preliminary work needed for tracking when to purge
and recreate all textures (needed by nvidia).
---
src/backends/meta-backend.c | 83 ++++++++++++++++++++++++++++++++-----
1 file changed, 72 insertions(+), 11 deletions(-)
src/backends/meta-backend.c | 98 ++++++++++++++++++++++++++++++----
src/org.freedesktop.login1.xml | 1 +
2 files changed, 88 insertions(+), 11 deletions(-)
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 5d71977c6..c980cf150 100644
index 5d71977c6..f59b899b7 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -87,6 +87,8 @@ enum
@@ -53,6 +53,8 @@
#include <stdlib.h>
+#include <gio/gunixfdlist.h>
+
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-idle-monitor-private.h"
#include "backends/meta-input-settings-private.h"
@@ -87,6 +89,8 @@ enum
LAST_DEVICE_CHANGED,
LID_IS_CLOSED_CHANGED,
@ -25,7 +35,7 @@ index 5d71977c6..c980cf150 100644
N_SIGNALS
};
@@ -745,6 +747,20 @@ meta_backend_class_init (MetaBackendClass *klass)
@@ -745,6 +749,20 @@ meta_backend_class_init (MetaBackendClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
@ -46,7 +56,7 @@ index 5d71977c6..c980cf150 100644
mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
@@ -768,15 +784,53 @@ meta_backend_create_renderer (MetaBackend *backend,
@@ -768,15 +786,66 @@ meta_backend_create_renderer (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
}
@ -55,7 +65,9 @@ index 5d71977c6..c980cf150 100644
+{
+ MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+ g_autoptr (GVariant) fd_variant = NULL;
+ g_autoptr (GUnixFDList) fd_list = NULL;
+ g_autoptr (GError) error = NULL;
+ int handle, fd;
+
+ if (priv->inhibit_sleep_fd >= 0)
+ return;
@ -65,7 +77,9 @@ index 5d71977c6..c980cf150 100644
+ "Display Server",
+ "Prepare for suspend",
+ "delay",
+ NULL,
+ &fd_variant,
+ &fd_list,
+ priv->cancellable,
+ &error))
+ {
@ -73,7 +87,16 @@ index 5d71977c6..c980cf150 100644
+ return;
+ }
+
+ priv->inhibit_sleep_fd = g_variant_get_handle (fd_variant);
+ handle = g_variant_get_handle (fd_variant);
+ fd = g_unix_fd_list_get (fd_list, handle, &error);
+
+ if (fd < 0)
+ {
+ g_warning ("Failed to fetch sleep inhibitor fd: %s", error->message);
+ return;
+ }
+
+ priv->inhibit_sleep_fd = fd;
+}
+
+static void
@ -104,7 +127,7 @@ index 5d71977c6..c980cf150 100644
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
}
@@ -803,6 +857,7 @@ system_bus_gotten_cb (GObject *object,
@@ -803,6 +872,7 @@ system_bus_gotten_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
@ -112,7 +135,7 @@ index 5d71977c6..c980cf150 100644
MetaBackendPrivate *priv;
g_autoptr (GError) error = NULL;
GDBusConnection *bus;
@@ -814,15 +869,21 @@ system_bus_gotten_cb (GObject *object,
@@ -814,15 +884,21 @@ system_bus_gotten_cb (GObject *object,
priv = meta_backend_get_instance_private (user_data);
priv->system_bus = bus;
priv->logind_proxy = get_logind_proxy (priv->cancellable, &error);
@ -141,6 +164,18 @@ index 5d71977c6..c980cf150 100644
}
static gboolean
diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml
index 1ecfd976f..7db8f373c 100644
--- a/src/org.freedesktop.login1.xml
+++ b/src/org.freedesktop.login1.xml
@@ -46,6 +46,7 @@
<interface name="org.freedesktop.login1.Manager">
<method name="Inhibit">
+ <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
<arg name="what" type="s" direction="in"/>
<arg name="who" type="s" direction="in"/>
<arg name="why" type="s" direction="in"/>
--
2.21.0

View File

@ -0,0 +1,77 @@
From 04d921c2c1da571c8c61a4ca12a380bc3b9623fe Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Mon, 6 May 2019 13:40:31 +0300
Subject: [PATCH 03/12] cogl: Replace ANGLE with GLES3 and NV framebuffer_blit
ANGLE extensions are only provided by Google's Almost Native Graphics Layer
Engine (ANGLE) implementation. Therefore they do not seem too useful for
Mutter.
The reason to drop GL_ANGLE_framebuffer_blit support is that it has more
limitations compared to the glBlitFramebuffer in GL_EXT_framebuffer_blit,
GL_NV_framebuffer_bit, OpenGL 3.0 and OpenGL ES 3.0. Most importantly, the
ANGLE version cannot flip the image while copying, which limits
_cogl_blit_framebuffer to only off-screen <-> off-screen copies. Follow-up work
will need off-screen <-> on-screen copies.
Instead of adding yet more capability flags to Cogl, dropping ANGLE support
seems appropriate.
The NV extension is added to the list of glBlitFramebuffer providers because it
provides the same support as ANGLE and more.
Likewise OpenGL ES 3.0 is added to the list of glBlitFramebuffer providers
because e.g. Mesa GLES implementation usually provides it and that makes it
widely available, again surpassing the ANGLE supported features.
Follow-up patches will lift some of the Cogl assumptions of what
glBlitFramebuffer cannot do.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit 3e68c9e8faa78298039fa3583898f18550740812)
---
cogl/cogl/cogl-framebuffer-private.h | 3 +--
cogl/cogl/gl-prototypes/cogl-all-functions.h | 5 +++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index de886b64f..3aab852c4 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -387,8 +387,7 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* Note that this function differs a lot from the glBlitFramebuffer
* function provided by the GL_EXT_framebuffer_blit extension. Notably
* it doesn't support having different sizes for the source and
- * destination rectangle. This isn't supported by the corresponding
- * GL_ANGLE_framebuffer_blit extension on GLES2.0 and it doesn't seem
+ * destination rectangle. This doesn't seem
* like a particularly useful feature. If the application wanted to
* scale the results it may make more sense to draw a primitive
* instead.
diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h
index 924ee349d..0af126059 100644
--- a/cogl/cogl/gl-prototypes/cogl-all-functions.h
+++ b/cogl/cogl/gl-prototypes/cogl-all-functions.h
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2009, 2011 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -132,8 +133,8 @@ COGL_EXT_END ()
COGL_EXT_BEGIN (offscreen_blit, 3, 0,
- 0, /* not in either GLES */
- "EXT\0ANGLE\0",
+ COGL_EXT_IN_GLES3,
+ "EXT\0NV\0",
"framebuffer_blit\0")
COGL_EXT_FUNCTION (void, glBlitFramebuffer,
(GLint srcX0,
--
2.21.0

View File

@ -0,0 +1,100 @@
From 6c6c6ad5412f5bb13592630d7cb3b7aed25d159b Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Mon, 6 May 2019 14:09:16 +0300
Subject: [PATCH 04/12] cogl: Relax formats on glBlitFramebuffer
Depends on: "cogl: Replace ANGLE with GLES3 and NV framebuffer_blit"
As a possible ANGLE implementation is not longer limiting the pixel format
matching, lift the requirement of having the same pixel format.
We still cannot do a premult <-> non-premult conversion during a blit, so guard
against that.
This will be useful in follow-up work to copy from onscreen primary GPU
framebuffer to an offscreen secondary GPU framebuffer if the formats do not
match exactly.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit 6df34eb4b7c65210f4066f7eb9bd462278b7279b)
---
cogl/cogl/cogl-blit.c | 10 ++++++----
cogl/cogl/cogl-framebuffer-private.h | 8 ++++++--
cogl/cogl/cogl-framebuffer.c | 6 ++++--
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c
index 74f404f3d..a61eb66d2 100644
--- a/cogl/cogl/cogl-blit.c
+++ b/cogl/cogl/cogl-blit.c
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2011 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -152,10 +153,11 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
CoglFramebuffer *dst_fb, *src_fb;
CoglError *ignore_error = NULL;
- /* We can only blit between FBOs if both textures are the same
- format and the blit framebuffer extension is supported */
- if ((_cogl_texture_get_format (data->src_tex) & ~COGL_A_BIT) !=
- (_cogl_texture_get_format (data->dst_tex) & ~COGL_A_BIT) ||
+ /* We can only blit between FBOs if both textures have the same
+ premult convention and the blit framebuffer extension is
+ supported. */
+ if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) !=
+ (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) ||
!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT))
return FALSE;
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index 3aab852c4..b06fbaee1 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -381,8 +381,12 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* This blits a region of the color buffer of the source buffer
* to the destination buffer. This function should only be
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
- * advertised. The two buffers must both be offscreen and have the
- * same format.
+ * advertised. The two buffers must both be offscreen.
+ *
+ * The two buffers must have the same value types (e.g. floating-point,
+ * unsigned int, signed int, or fixed-point), but color formats do not
+ * need to match. This limitation comes from OpenGL ES 3.0 definition
+ * of glBlitFramebuffer.
*
* Note that this function differs a lot from the glBlitFramebuffer
* function provided by the GL_EXT_framebuffer_blit extension. Notably
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index bd8a7fa42..0bc225945 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2007,2008,2009,2012 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -1468,8 +1469,9 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
support this */
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (src));
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest));
- /* The buffers must be the same format */
- _COGL_RETURN_IF_FAIL (src->internal_format == dest->internal_format);
+ /* The buffers must use the same premult convention */
+ _COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) ==
+ (dest->internal_format & COGL_PREMULT_BIT));
/* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */
--
2.21.0

View File

@ -0,0 +1,145 @@
From e4b2234d9918e9d3357ac3c7ca3898599725d3da Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Mon, 6 May 2019 15:08:29 +0300
Subject: [PATCH 05/12] cogl: Allow glBlitFramebuffer between
onscreen/offscreen
Depends on "cogl: Replace ANGLE with GLES3 and NV framebuffer_blit"
Allow blitting between onscreen and offscreen framebuffers by doing the y-flip
as necessary. This was not possible with ANGLE, but now with ANGLE gone,
glBlitFramebuffer supports flipping the copied image.
This will be useful in follow-up work to copy from onscreen primary GPU
framebuffer to an offscreen secondary GPU framebuffer.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit 45289b3d65e308117f1bc8fe6a4c88c1baaacca7)
---
cogl/cogl/cogl-framebuffer-private.h | 14 +++----
cogl/cogl/cogl-framebuffer.c | 46 ++++++++++++++++++-----
cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 5 +--
3 files changed, 43 insertions(+), 22 deletions(-)
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index b06fbaee1..f68153d8b 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -381,7 +381,11 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* This blits a region of the color buffer of the source buffer
* to the destination buffer. This function should only be
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
- * advertised. The two buffers must both be offscreen.
+ * advertised.
+ *
+ * The source and destination rectangles are defined in offscreen
+ * framebuffer orientation. When copying between an offscreen and
+ * onscreen framebuffers, the image is y-flipped accordingly.
*
* The two buffers must have the same value types (e.g. floating-point,
* unsigned int, signed int, or fixed-point), but color formats do not
@@ -396,14 +400,6 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* scale the results it may make more sense to draw a primitive
* instead.
*
- * We can only really support blitting between two offscreen buffers
- * for this function on GLES2.0. This is because we effectively render
- * upside down to offscreen buffers to maintain Cogl's representation
- * of the texture coordinate system where 0,0 is the top left of the
- * texture. If we were to blit from an offscreen to an onscreen buffer
- * then we would need to mirror the blit along the x-axis but the GLES
- * extension does not support this.
- *
* The GL function is documented to be affected by the scissor. This
* function therefore ensure that an empty clip stack is flushed
* before performing the blit which means the scissor is effectively
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index 0bc225945..90976a611 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -1460,15 +1460,12 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
int height)
{
CoglContext *ctx = src->context;
+ int src_x1, src_y1, src_x2, src_y2;
+ int dst_x1, dst_y1, dst_x2, dst_y2;
_COGL_RETURN_IF_FAIL (_cogl_has_private_feature
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
- /* We can only support blitting between offscreen buffers because
- otherwise we would need to mirror the image and GLES2.0 doesn't
- support this */
- _COGL_RETURN_IF_FAIL (cogl_is_offscreen (src));
- _COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest));
/* The buffers must use the same premult convention */
_COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) ==
(dest->internal_format & COGL_PREMULT_BIT));
@@ -1492,10 +1489,41 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
* as changed */
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
- ctx->glBlitFramebuffer (src_x, src_y,
- src_x + width, src_y + height,
- dst_x, dst_y,
- dst_x + width, dst_y + height,
+ /* Offscreens we do the normal way, onscreens need an y-flip. Even if
+ * we consider offscreens to be rendered upside-down, the offscreen
+ * orientation is in this function's API. */
+ if (cogl_is_offscreen (src))
+ {
+ src_x1 = src_x;
+ src_y1 = src_y;
+ src_x2 = src_x + width;
+ src_y2 = src_y + height;
+ }
+ else
+ {
+ src_x1 = src_x;
+ src_y1 = cogl_framebuffer_get_height (src) - src_y;
+ src_x2 = src_x + width;
+ src_y2 = src_y1 - height;
+ }
+
+ if (cogl_is_offscreen (dest))
+ {
+ dst_x1 = dst_x;
+ dst_y1 = dst_y;
+ dst_x2 = dst_x + width;
+ dst_y2 = dst_y + height;
+ }
+ else
+ {
+ dst_x1 = dst_x;
+ dst_y1 = cogl_framebuffer_get_height (dest) - dst_y;
+ dst_x2 = dst_x + width;
+ dst_y2 = dst_y1 - height;
+ }
+
+ ctx->glBlitFramebuffer (src_x1, src_y1, src_x2, src_y2,
+ dst_x1, dst_y1, dst_x2, dst_y2,
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
}
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
index 5402a7075..83e1d263a 100644
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -400,12 +400,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
else
{
/* NB: Currently we only take advantage of binding separate
- * read/write buffers for offscreen framebuffer blit
- * purposes. */
+ * read/write buffers for framebuffer blit purposes. */
_COGL_RETURN_IF_FAIL (_cogl_has_private_feature
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
- _COGL_RETURN_IF_FAIL (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
- _COGL_RETURN_IF_FAIL (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
_cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
--
2.21.0

View File

@ -0,0 +1,115 @@
From 579c85d17b17fc7ad3d6c88af39932ce8faeaabe Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Mon, 6 May 2019 15:58:33 +0300
Subject: [PATCH 06/12] cogl: Rename feature OFFSCREEN_BLIT to BLIT_FRAMEBUFFER
The feature is not limited to offscreen framebuffer blits anymore since
"cogl: Allow glBlitFramebuffer between onscreen/offscreen".
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit 55c084e6e1059d8f94c699b01c408523ed504196)
---
cogl/cogl/cogl-blit.c | 2 +-
cogl/cogl/cogl-framebuffer-private.h | 2 +-
cogl/cogl/cogl-framebuffer.c | 2 +-
cogl/cogl/cogl-private.h | 2 +-
cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 2 +-
cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 2 +-
cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c
index a61eb66d2..c561b2e45 100644
--- a/cogl/cogl/cogl-blit.c
+++ b/cogl/cogl/cogl-blit.c
@@ -158,7 +158,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
supported. */
if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) !=
(_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) ||
- !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT))
+ !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER))
return FALSE;
dst_offscreen = _cogl_offscreen_new_with_texture_full
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index f68153d8b..cb1f87354 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -380,7 +380,7 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
*
* This blits a region of the color buffer of the source buffer
* to the destination buffer. This function should only be
- * called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
+ * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is
* advertised.
*
* The source and destination rectangles are defined in offscreen
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index 90976a611..5cc4eada4 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -1464,7 +1464,7 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
int dst_x1, dst_y1, dst_x2, dst_y2;
_COGL_RETURN_IF_FAIL (_cogl_has_private_feature
- (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
+ (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER));
/* The buffers must use the same premult convention */
_COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) ==
diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h
index 9f918b851..d9fbe68c7 100644
--- a/cogl/cogl/cogl-private.h
+++ b/cogl/cogl/cogl-private.h
@@ -42,7 +42,7 @@ typedef enum
{
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
COGL_PRIVATE_FEATURE_MESA_PACK_INVERT,
- COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT,
+ COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER,
COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES,
COGL_PRIVATE_FEATURE_PBOS,
COGL_PRIVATE_FEATURE_VBOS,
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
index 83e1d263a..90d08954d 100644
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -402,7 +402,7 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
/* NB: Currently we only take advantage of binding separate
* read/write buffers for framebuffer blit purposes. */
_COGL_RETURN_IF_FAIL (_cogl_has_private_feature
- (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
+ (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER));
_cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
index 4d46844d5..e06e27961 100644
--- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -467,7 +467,7 @@ _cogl_driver_update_features (CoglContext *ctx,
if (ctx->glBlitFramebuffer)
COGL_FLAGS_SET (private_features,
- COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE);
+ COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE);
if (ctx->glRenderbufferStorageMultisampleIMG)
{
diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
index 23158d5c7..bcb0bdf07 100644
--- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -326,7 +326,7 @@ _cogl_driver_update_features (CoglContext *context,
if (context->glBlitFramebuffer)
COGL_FLAGS_SET (private_features,
- COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE);
+ COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE);
if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
{
--
2.21.0

View File

@ -0,0 +1,261 @@
From be13d3c844a6623563ae4e74dbb3409baf16fc9c Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Mon, 3 Dec 2018 14:34:41 +0200
Subject: [PATCH 07/12] cogl: Expose cogl_blit_framebuffer
The function will be used in copying from a primary GPU framebuffer to a
secondary GPU framebuffer using the primary GPU specifically when the
secondary GPU is not render-capable.
To allow falling back in case glBlitFramebuffer cannot be used, add boolean
return value, and GError argument for debugging purposes.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit 6061abbf90cd1d62e262ebf3636470d2219e04a7)
---
cogl/cogl/cogl-blit.c | 11 ++---
cogl/cogl/cogl-framebuffer-private.h | 55 -----------------------
cogl/cogl/cogl-framebuffer.c | 40 +++++++++++------
cogl/cogl/cogl-framebuffer.h | 66 +++++++++++++++++++++++++++-
4 files changed, 98 insertions(+), 74 deletions(-)
diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c
index c561b2e45..ae5a8a345 100644
--- a/cogl/cogl/cogl-blit.c
+++ b/cogl/cogl/cogl-blit.c
@@ -207,11 +207,12 @@ _cogl_blit_framebuffer_blit (CoglBlitData *data,
int width,
int height)
{
- _cogl_blit_framebuffer (data->src_fb,
- data->dest_fb,
- src_x, src_y,
- dst_x, dst_y,
- width, height);
+ cogl_blit_framebuffer (data->src_fb,
+ data->dest_fb,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height,
+ NULL);
}
static void
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index cb1f87354..7d71fb1dc 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -367,61 +367,6 @@ void
_cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer);
-/*
- * _cogl_blit_framebuffer:
- * @src: The source #CoglFramebuffer
- * @dest: The destination #CoglFramebuffer
- * @src_x: Source x position
- * @src_y: Source y position
- * @dst_x: Destination x position
- * @dst_y: Destination y position
- * @width: Width of region to copy
- * @height: Height of region to copy
- *
- * This blits a region of the color buffer of the source buffer
- * to the destination buffer. This function should only be
- * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is
- * advertised.
- *
- * The source and destination rectangles are defined in offscreen
- * framebuffer orientation. When copying between an offscreen and
- * onscreen framebuffers, the image is y-flipped accordingly.
- *
- * The two buffers must have the same value types (e.g. floating-point,
- * unsigned int, signed int, or fixed-point), but color formats do not
- * need to match. This limitation comes from OpenGL ES 3.0 definition
- * of glBlitFramebuffer.
- *
- * Note that this function differs a lot from the glBlitFramebuffer
- * function provided by the GL_EXT_framebuffer_blit extension. Notably
- * it doesn't support having different sizes for the source and
- * destination rectangle. This doesn't seem
- * like a particularly useful feature. If the application wanted to
- * scale the results it may make more sense to draw a primitive
- * instead.
- *
- * The GL function is documented to be affected by the scissor. This
- * function therefore ensure that an empty clip stack is flushed
- * before performing the blit which means the scissor is effectively
- * ignored.
- *
- * The function also doesn't support specifying the buffers to copy
- * and instead only the color buffer is copied. When copying the depth
- * or stencil buffers the extension on GLES2.0 only supports copying
- * the full buffer which would be awkward to document with this
- * API. If we wanted to support that feature it may be better to have
- * a separate function to copy the entire buffer for a given mask.
- */
-void
-_cogl_blit_framebuffer (CoglFramebuffer *src,
- CoglFramebuffer *dest,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height);
-
void
_cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer);
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index 5cc4eada4..6d35c6b13 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -1449,26 +1449,38 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
return ret;
}
-void
-_cogl_blit_framebuffer (CoglFramebuffer *src,
- CoglFramebuffer *dest,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height)
+gboolean
+cogl_blit_framebuffer (CoglFramebuffer *src,
+ CoglFramebuffer *dest,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height,
+ GError **error)
{
CoglContext *ctx = src->context;
int src_x1, src_y1, src_x2, src_y2;
int dst_x1, dst_y1, dst_x2, dst_y2;
- _COGL_RETURN_IF_FAIL (_cogl_has_private_feature
- (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER));
+ if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER))
+ {
+ g_set_error_literal (error, COGL_SYSTEM_ERROR,
+ COGL_SYSTEM_ERROR_UNSUPPORTED,
+ "Cogl BLIT_FRAMEBUFFER is not supported by the system.");
+ return FALSE;
+ }
/* The buffers must use the same premult convention */
- _COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) ==
- (dest->internal_format & COGL_PREMULT_BIT));
+ if ((src->internal_format & COGL_PREMULT_BIT) !=
+ (dest->internal_format & COGL_PREMULT_BIT))
+ {
+ g_set_error_literal (error, COGL_SYSTEM_ERROR,
+ COGL_SYSTEM_ERROR_UNSUPPORTED,
+ "cogl_blit_framebuffer premult mismatch.");
+ return FALSE;
+ }
/* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */
@@ -1526,6 +1538,8 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
dst_x1, dst_y1, dst_x2, dst_y2,
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
+
+ return TRUE;
}
void
diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h
index 48a77e1ed..230a78627 100644
--- a/cogl/cogl/cogl-framebuffer.h
+++ b/cogl/cogl/cogl-framebuffer.h
@@ -3,7 +3,8 @@
*
* A Low Level GPU Graphics and Utilities API
*
- * Copyright (C) 2011 Intel Corporation.
+ * Copyright (C) 2007,2008,2009,2011 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -1846,6 +1847,69 @@ typedef enum /*< prefix=COGL_FRAMEBUFFER_ERROR >*/
gboolean
cogl_is_framebuffer (void *object);
+/**
+ * cogl_blit_framebuffer:
+ * @src: The source #CoglFramebuffer
+ * @dest: The destination #CoglFramebuffer
+ * @src_x: Source x position
+ * @src_y: Source y position
+ * @dst_x: Destination x position
+ * @dst_y: Destination y position
+ * @width: Width of region to copy
+ * @height: Height of region to copy
+ * @error: optional error object
+ *
+ * @return FALSE for an immediately detected error, TRUE otherwise.
+ *
+ * This blits a region of the color buffer of the source buffer
+ * to the destination buffer. This function should only be
+ * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is
+ * advertised.
+ *
+ * The source and destination rectangles are defined in offscreen
+ * framebuffer orientation. When copying between an offscreen and
+ * onscreen framebuffers, the image is y-flipped accordingly.
+ *
+ * The two buffers must have the same value types (e.g. floating-point,
+ * unsigned int, signed int, or fixed-point), but color formats do not
+ * need to match. This limitation comes from OpenGL ES 3.0 definition
+ * of glBlitFramebuffer.
+ *
+ * Note that this function differs a lot from the glBlitFramebuffer
+ * function provided by the GL_EXT_framebuffer_blit extension. Notably
+ * it doesn't support having different sizes for the source and
+ * destination rectangle. This doesn't seem
+ * like a particularly useful feature. If the application wanted to
+ * scale the results it may make more sense to draw a primitive
+ * instead.
+ *
+ * The GL function is documented to be affected by the scissor. This
+ * function therefore ensure that an empty clip stack is flushed
+ * before performing the blit which means the scissor is effectively
+ * ignored.
+ *
+ * The function also doesn't support specifying the buffers to copy
+ * and instead only the color buffer is copied. When copying the depth
+ * or stencil buffers the extension on GLES2.0 only supports copying
+ * the full buffer which would be awkward to document with this
+ * API. If we wanted to support that feature it may be better to have
+ * a separate function to copy the entire buffer for a given mask.
+ *
+ * The @c error argument is optional, it can be NULL. If it is not NULL
+ * and this function returns FALSE, an error object with a code from
+ * COGL_SYSTEM_ERROR will be created.
+ */
+gboolean
+cogl_blit_framebuffer (CoglFramebuffer *src,
+ CoglFramebuffer *dest,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height,
+ GError **error);
+
G_END_DECLS
#endif /* __COGL_FRAMEBUFFER_H */
--
2.21.0

View File

@ -0,0 +1,42 @@
From bbeb161e8ab31bbef3c7d378e9a8d4ecc786c25d Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Thu, 26 Sep 2019 10:20:36 +0200
Subject: [PATCH 08/12] clutter/stage-view: Use cogl_blit_framebuffer() for
shadow FB
If there is no transformation, use `cogl_blit_framebuffer()` as a
shortcut in `clutter_stage_view_blit_offscreen()`, that dramatically
improves performance when using a shadow framebuffer.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/809
(cherry picked from commit 3400c555a032832a689c208486891352a6cb92de)
---
clutter/clutter/clutter-stage-view.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index cd6cd35cb..00cbfd1ce 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -126,6 +126,18 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view,
clutter_stage_view_get_instance_private (view);
CoglMatrix matrix;
+ clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
+ if (cogl_matrix_is_identity (&matrix))
+ {
+ if (cogl_blit_framebuffer (priv->offscreen,
+ priv->framebuffer,
+ rect->x, rect->y,
+ rect->x, rect->y,
+ rect->width, rect->height,
+ NULL))
+ return;
+ }
+
clutter_stage_view_ensure_offscreen_blit_pipeline (view);
cogl_framebuffer_push_matrix (priv->framebuffer);
--
2.21.0

View File

@ -0,0 +1,49 @@
From 46bb54bcd9c90f90dd170355209f8c379680d5c1 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 1 Oct 2019 14:16:25 +0200
Subject: [PATCH 09/12] clutter/stage-view: Ignore clipping rectangle for
offscreen blit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In `clutter_stage_view_blit_offscreen()`, the given clipping rectangle
is in “view” coordinates whereas we intend to copy the whole actual
framebuffer, meaning that we cannot use the clipping rectangle.
Use the actual framebuffer size, starting at (0, 0) instead.
That fixes the issue with partial repainting with shadow framebuffer
when fractional scaling is enabled.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/820
(cherry picked from commit 0a3f25c3039b586f5b5721e91136c5d2fccecca1)
---
clutter/clutter/clutter-stage-view.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 00cbfd1ce..503c31e78 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -129,11 +129,14 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view,
clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
if (cogl_matrix_is_identity (&matrix))
{
+ int fb_width = cogl_framebuffer_get_width (priv->framebuffer);
+ int fb_height = cogl_framebuffer_get_height (priv->framebuffer);
+
if (cogl_blit_framebuffer (priv->offscreen,
priv->framebuffer,
- rect->x, rect->y,
- rect->x, rect->y,
- rect->width, rect->height,
+ 0, 0,
+ 0, 0,
+ fb_width, fb_height,
NULL))
return;
}
--
2.21.0

View File

@ -0,0 +1,34 @@
From 4c7fe200e05f9a028d440ed2032961d1b798c83b Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 1 Oct 2019 15:54:47 +0200
Subject: [PATCH 10/12] cogl: Flush journal before blitting
Make sure to submit all pending primitives before blitting, otherwise
rendering from the shell may be incomplete leaving partial drawing of
the shell widgets.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/820
(cherry picked from commit 0cdf13ac12c570d38737fddb68946157c0b7a4d2)
---
cogl/cogl/cogl-framebuffer.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index 6d35c6b13..948cd112d 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -1482,6 +1482,11 @@ cogl_blit_framebuffer (CoglFramebuffer *src,
return FALSE;
}
+ /* Make sure any batched primitives get submitted to the driver
+ * before blitting
+ */
+ _cogl_framebuffer_flush_journal (src);
+
/* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */
_cogl_framebuffer_flush_state (dest,
--
2.21.0

View File

@ -0,0 +1,304 @@
From cf8f1fb8478e4b76c91e825d1537396b014689a0 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 22 Oct 2019 17:03:03 +0200
Subject: [PATCH 11/12] clutter/stage-view: Separate offscreen and shadowfb
Previously, we would use a single offscreen framebuffer for both
transformations and when a shadow framebuffer should be used, but that
can be dreadfully slow when using software rendering with a discrete GPU
due to bandwidth limitations.
Keep the offscreen framebuffer for transformations only and add another
intermediate shadow framebuffer used as a copy of the onscreen
framebuffer.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/917
(cherry picked from commit 2b8b450fe16c21f0f37a1779560c0e5da61a9b89)
---
clutter/clutter/clutter-stage-view.c | 162 +++++++++++++++++-----
clutter/clutter/cogl/clutter-stage-cogl.c | 6 +-
2 files changed, 128 insertions(+), 40 deletions(-)
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 503c31e78..c536ac720 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -29,6 +29,7 @@ enum
PROP_LAYOUT,
PROP_FRAMEBUFFER,
PROP_OFFSCREEN,
+ PROP_SHADOWFB,
PROP_SCALE,
PROP_LAST
@@ -43,7 +44,10 @@ typedef struct _ClutterStageViewPrivate
CoglFramebuffer *framebuffer;
CoglOffscreen *offscreen;
- CoglPipeline *pipeline;
+ CoglPipeline *offscreen_pipeline;
+
+ CoglOffscreen *shadowfb;
+ CoglPipeline *shadowfb_pipeline;
guint dirty_viewport : 1;
guint dirty_projection : 1;
@@ -69,6 +73,8 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view)
if (priv->offscreen)
return priv->offscreen;
+ else if (priv->shadowfb)
+ return priv->shadowfb;
else
return priv->framebuffer;
}
@@ -82,6 +88,24 @@ clutter_stage_view_get_onscreen (ClutterStageView *view)
return priv->framebuffer;
}
+static CoglPipeline *
+clutter_stage_view_create_framebuffer_pipeline (CoglFramebuffer *framebuffer)
+{
+ CoglPipeline *pipeline;
+
+ pipeline = cogl_pipeline_new (cogl_framebuffer_get_context (framebuffer));
+
+ cogl_pipeline_set_layer_filters (pipeline, 0,
+ COGL_PIPELINE_FILTER_NEAREST,
+ COGL_PIPELINE_FILTER_NEAREST);
+ cogl_pipeline_set_layer_texture (pipeline, 0,
+ cogl_offscreen_get_texture (framebuffer));
+ cogl_pipeline_set_layer_wrap_mode (pipeline, 0,
+ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+
+ return pipeline;
+}
+
static void
clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view)
{
@@ -92,71 +116,122 @@ clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view)
g_assert (priv->offscreen != NULL);
- if (priv->pipeline)
+ if (priv->offscreen_pipeline)
return;
- priv->pipeline =
- cogl_pipeline_new (cogl_framebuffer_get_context (priv->offscreen));
- cogl_pipeline_set_layer_filters (priv->pipeline, 0,
- COGL_PIPELINE_FILTER_NEAREST,
- COGL_PIPELINE_FILTER_NEAREST);
- cogl_pipeline_set_layer_texture (priv->pipeline, 0,
- cogl_offscreen_get_texture (priv->offscreen));
- cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+ priv->offscreen_pipeline =
+ clutter_stage_view_create_framebuffer_pipeline (priv->offscreen);
if (view_class->setup_offscreen_blit_pipeline)
- view_class->setup_offscreen_blit_pipeline (view, priv->pipeline);
+ view_class->setup_offscreen_blit_pipeline (view, priv->offscreen_pipeline);
}
-void
-clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
+static void
+clutter_stage_view_ensure_shadowfb_blit_pipeline (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
- g_clear_pointer (&priv->pipeline, cogl_object_unref);
+ if (priv->shadowfb_pipeline)
+ return;
+
+ priv->shadowfb_pipeline =
+ clutter_stage_view_create_framebuffer_pipeline (priv->shadowfb);
}
void
-clutter_stage_view_blit_offscreen (ClutterStageView *view,
- const cairo_rectangle_int_t *rect)
+clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
+
+ g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
+}
+
+static void
+clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
+ const cairo_rectangle_int_t *rect,
+ CoglPipeline *pipeline,
+ CoglFramebuffer *src_framebuffer,
+ CoglFramebuffer *dst_framebuffer,
+ gboolean can_blit)
+{
CoglMatrix matrix;
- clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
- if (cogl_matrix_is_identity (&matrix))
+ /* First, try with blit */
+ if (can_blit)
{
- int fb_width = cogl_framebuffer_get_width (priv->framebuffer);
- int fb_height = cogl_framebuffer_get_height (priv->framebuffer);
-
- if (cogl_blit_framebuffer (priv->offscreen,
- priv->framebuffer,
+ if (cogl_blit_framebuffer (src_framebuffer,
+ dst_framebuffer,
0, 0,
0, 0,
- fb_width, fb_height,
+ cogl_framebuffer_get_width (dst_framebuffer),
+ cogl_framebuffer_get_height (dst_framebuffer),
NULL))
return;
}
- clutter_stage_view_ensure_offscreen_blit_pipeline (view);
- cogl_framebuffer_push_matrix (priv->framebuffer);
+ /* If blit fails, fallback to the slower painting method */
+ cogl_framebuffer_push_matrix (dst_framebuffer);
- /* Set transform so 0,0 is on the top left corner and 1,1 on
- * the bottom right corner.
- */
cogl_matrix_init_identity (&matrix);
cogl_matrix_translate (&matrix, -1, 1, 0);
cogl_matrix_scale (&matrix, 2, -2, 0);
- cogl_framebuffer_set_projection_matrix (priv->framebuffer, &matrix);
+ cogl_framebuffer_set_projection_matrix (dst_framebuffer, &matrix);
- cogl_framebuffer_draw_rectangle (priv->framebuffer,
- priv->pipeline,
+ cogl_framebuffer_draw_rectangle (dst_framebuffer,
+ pipeline,
0, 0, 1, 1);
- cogl_framebuffer_pop_matrix (priv->framebuffer);
+ cogl_framebuffer_pop_matrix (dst_framebuffer);
+}
+
+void
+clutter_stage_view_blit_offscreen (ClutterStageView *view,
+ const cairo_rectangle_int_t *rect)
+{
+ ClutterStageViewPrivate *priv =
+ clutter_stage_view_get_instance_private (view);
+
+ if (priv->offscreen)
+ {
+ gboolean can_blit;
+ CoglMatrix matrix;
+
+ clutter_stage_view_ensure_offscreen_blit_pipeline (view);
+ clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
+ can_blit = cogl_matrix_is_identity (&matrix);
+
+ if (priv->shadowfb)
+ {
+ clutter_stage_view_copy_to_framebuffer (view,
+ rect,
+ priv->offscreen_pipeline,
+ priv->offscreen,
+ priv->shadowfb,
+ can_blit);
+ }
+ else
+ {
+ clutter_stage_view_copy_to_framebuffer (view,
+ rect,
+ priv->offscreen_pipeline,
+ priv->offscreen,
+ priv->framebuffer,
+ can_blit);
+ }
+ }
+
+ if (priv->shadowfb)
+ {
+ clutter_stage_view_ensure_shadowfb_blit_pipeline (view);
+ clutter_stage_view_copy_to_framebuffer (view,
+ rect,
+ priv->shadowfb_pipeline,
+ priv->shadowfb,
+ priv->framebuffer,
+ TRUE);
+ }
}
float
@@ -256,6 +331,9 @@ clutter_stage_view_get_property (GObject *object,
case PROP_OFFSCREEN:
g_value_set_boxed (value, priv->offscreen);
break;
+ case PROP_SHADOWFB:
+ g_value_set_boxed (value, priv->shadowfb);
+ break;
case PROP_SCALE:
g_value_set_float (value, priv->scale);
break;
@@ -301,6 +379,9 @@ clutter_stage_view_set_property (GObject *object,
case PROP_OFFSCREEN:
priv->offscreen = g_value_dup_boxed (value);
break;
+ case PROP_SHADOWFB:
+ priv->shadowfb = g_value_dup_boxed (value);
+ break;
case PROP_SCALE:
priv->scale = g_value_get_float (value);
break;
@@ -317,8 +398,10 @@ clutter_stage_view_dispose (GObject *object)
clutter_stage_view_get_instance_private (view);
g_clear_pointer (&priv->framebuffer, cogl_object_unref);
+ g_clear_pointer (&priv->shadowfb, cogl_object_unref);
g_clear_pointer (&priv->offscreen, cogl_object_unref);
- g_clear_pointer (&priv->pipeline, cogl_object_unref);
+ g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
+ g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref);
G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
}
@@ -373,6 +456,15 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ obj_props[PROP_SHADOWFB] =
+ g_param_spec_boxed ("shadowfb",
+ "Shadow framebuffer",
+ "Framebuffer used as intermediate shadow buffer",
+ COGL_TYPE_HANDLE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
obj_props[PROP_SCALE] =
g_param_spec_float ("scale",
"View scale",
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index e0c39185b..eab76e52f 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -477,11 +477,7 @@ paint_stage (ClutterStageCogl *stage_cogl,
_clutter_stage_maybe_setup_viewport (stage, view);
_clutter_stage_paint_view (stage, view, clip);
- if (clutter_stage_view_get_onscreen (view) !=
- clutter_stage_view_get_framebuffer (view))
- {
- clutter_stage_view_blit_offscreen (view, clip);
- }
+ clutter_stage_view_blit_offscreen (view, clip);
}
static void
--
2.21.0

View File

@ -0,0 +1,98 @@
From ca3e9e3b3b84fe95affbe5485212c6ecfa1a4b51 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 22 Oct 2019 17:05:46 +0200
Subject: [PATCH 12/12] renderer-native: Separate offscreen and shadowfb
Create the intermediate shadow framebuffer for use exclusively when a
shadowfb is required.
Keep the previous offscreen framebuffer is as an intermediate
framebuffer for transformations only.
This way, we can apply transformations between in-memory framebuffers
prior to blit the result to screen, and achieve acceptable performance
even with software rendering on discrete GPU.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/917
(cherry picked from commit 551641c74822ca2e3c685e49603836ebf5397df2)
---
src/backends/native/meta-renderer-native.c | 29 ++++++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 3cd01bcb7..ffb64a6bd 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -3287,7 +3287,6 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native,
static CoglOffscreen *
meta_renderer_native_create_offscreen (MetaRendererNative *renderer,
CoglContext *context,
- MetaMonitorTransform transform,
gint view_width,
gint view_height,
GError **error)
@@ -3489,6 +3488,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
MetaMonitorTransform view_transform;
CoglOnscreen *onscreen = NULL;
CoglOffscreen *offscreen = NULL;
+ CoglOffscreen *shadowfb = NULL;
float scale;
int width, height;
MetaRendererView *view;
@@ -3515,18 +3515,35 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
if (!onscreen)
g_error ("Failed to allocate onscreen framebuffer: %s", error->message);
- if (view_transform != META_MONITOR_TRANSFORM_NORMAL ||
- should_force_shadow_fb (renderer_native,
- renderer_native->primary_gpu_kms))
+ if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
{
offscreen = meta_renderer_native_create_offscreen (renderer_native,
cogl_context,
- view_transform,
width,
height,
&error);
if (!offscreen)
g_error ("Failed to allocate back buffer texture: %s", error->message);
+
+ }
+
+ if (should_force_shadow_fb (renderer_native,
+ renderer_native->primary_gpu_kms))
+ {
+ int shadow_width;
+ int shadow_height;
+
+ /* The shadowfb must be the same size as the on-screen framebuffer */
+ shadow_width = cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen));
+ shadow_height = cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen));
+
+ shadowfb = meta_renderer_native_create_offscreen (renderer_native,
+ cogl_context,
+ shadow_width,
+ shadow_height,
+ &error);
+ if (!shadowfb)
+ g_error ("Failed to allocate shadow buffer texture: %s", error->message);
}
view = g_object_new (META_TYPE_RENDERER_VIEW,
@@ -3534,10 +3551,12 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
"scale", scale,
"framebuffer", onscreen,
"offscreen", offscreen,
+ "shadowfb", shadowfb,
"logical-monitor", logical_monitor,
"transform", view_transform,
NULL);
g_clear_pointer (&offscreen, cogl_object_unref);
+ g_clear_pointer (&shadowfb, cogl_object_unref);
meta_onscreen_native_set_view (onscreen, view);
--
2.21.0

View File

@ -352,7 +352,7 @@ index 12a592c75..80e5ed10e 100644
g_object_unref (settings);
return;
}
+ else if (!is_device_libinput (device))
+ else if (!is_device_libinput (device) && device_type != CLUTTER_PAD_DEVICE)
+ {
+ change_x_device_left_handed (device, enabled);
+ return;

View File

@ -0,0 +1,128 @@
From 35333114a991440d671e3642170aa080df45a171 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 16 Sep 2019 16:17:48 +0200
Subject: [PATCH 1/3] idle-monitor: Make helper function static
It wasn't used outside the file, so no reason to not have it static.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/799
---
src/backends/meta-idle-monitor-private.h | 1 -
src/backends/meta-idle-monitor.c | 8 ++++----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/backends/meta-idle-monitor-private.h b/src/backends/meta-idle-monitor-private.h
index 93948b14b..cc08f8c8e 100644
--- a/src/backends/meta-idle-monitor-private.h
+++ b/src/backends/meta-idle-monitor-private.h
@@ -54,7 +54,6 @@ struct _MetaIdleMonitorClass
GObjectClass parent_class;
};
-void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch);
void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor);
#endif /* META_IDLE_MONITOR_PRIVATE_H */
diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c
index e83d6c778..de1c7e0ba 100644
--- a/src/backends/meta-idle-monitor.c
+++ b/src/backends/meta-idle-monitor.c
@@ -54,8 +54,8 @@ static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT)
-void
-_meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch)
+static void
+meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch)
{
MetaIdleMonitor *monitor;
guint id;
@@ -324,7 +324,7 @@ idle_monitor_dispatch_timeout (GSource *source,
if (ready_time > now)
return G_SOURCE_CONTINUE;
- _meta_idle_monitor_watch_fire (watch);
+ meta_idle_monitor_watch_fire (watch);
g_source_set_ready_time (watch->timeout_source, -1);
return G_SOURCE_CONTINUE;
@@ -511,7 +511,7 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor)
if (watch->timeout_msec == 0)
{
- _meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
+ meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
}
else
{
--
2.23.0
From 07276cf94d84489d450c17b7dec5a8075c60440a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 16 Sep 2019 16:36:05 +0200
Subject: [PATCH 2/3] idle-monitor: Remove redundant type cast
No need to type cast a `MetaIdleMonitorWatch *` to a
`MetaIdleMonitorWatch *`.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/799
---
src/backends/meta-idle-monitor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c
index de1c7e0ba..e5124abc1 100644
--- a/src/backends/meta-idle-monitor.c
+++ b/src/backends/meta-idle-monitor.c
@@ -511,7 +511,7 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor)
if (watch->timeout_msec == 0)
{
- meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
+ meta_idle_monitor_watch_fire (watch);
}
else
{
--
2.23.0
From 73c1f387765ef528c7323e6e7ca3c05899cfcc4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 16 Sep 2019 16:36:51 +0200
Subject: [PATCH 3/3] idle-monitor: Reset timeout before firing watch
The watch might be removed during firing, meaning the source is
destroyed after returning. Avoid use-after-free by unsetting the timeout
before firing. Returning G_SOURCE_CONTINUE in that case is harmless, as
source is destroyed.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/796
https://gitlab.gnome.org/GNOME/mutter/merge_requests/799
---
src/backends/meta-idle-monitor.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c
index e5124abc1..9fa481742 100644
--- a/src/backends/meta-idle-monitor.c
+++ b/src/backends/meta-idle-monitor.c
@@ -324,9 +324,10 @@ idle_monitor_dispatch_timeout (GSource *source,
if (ready_time > now)
return G_SOURCE_CONTINUE;
- meta_idle_monitor_watch_fire (watch);
g_source_set_ready_time (watch->timeout_source, -1);
+ meta_idle_monitor_watch_fire (watch);
+
return G_SOURCE_CONTINUE;
}
--
2.23.0

View File

@ -0,0 +1,365 @@
From 2fd3910c29d2af2a7c64b82f075cd3647d7e4bee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 18 Mar 2019 17:08:11 +0100
Subject: [PATCH 1/2] monitor-config-manager: Use current mode when deriving
current config
Instead of overriding the existing mode with the preferred mode of the monitor,
use the one already configured. Also use the MetaMonitor API for deriving the
position of the monitor in the screen coordinate space.
---
src/backends/meta-monitor-config-manager.c | 77 +++++++++++++---------
1 file changed, 47 insertions(+), 30 deletions(-)
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index c09edbe00..a3387aa0f 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -592,20 +592,19 @@ create_monitor_config (MetaMonitor *monitor,
}
static MetaLogicalMonitorConfig *
-create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
- MetaMonitor *monitor,
- int x,
- int y,
- MetaLogicalMonitorConfig *primary_logical_monitor_config,
- MetaLogicalMonitorLayoutMode layout_mode)
+create_logical_monitor_config (MetaMonitorManager *monitor_manager,
+ MetaMonitor *monitor,
+ MetaMonitorMode *mode,
+ int x,
+ int y,
+ MetaLogicalMonitorConfig *primary_logical_monitor_config,
+ MetaLogicalMonitorLayoutMode layout_mode)
{
- MetaMonitorMode *mode;
int width, height;
float scale;
MetaMonitorConfig *monitor_config;
MetaLogicalMonitorConfig *logical_monitor_config;
- mode = meta_monitor_get_preferred_mode (monitor);
meta_monitor_mode_get_resolution (mode, &width, &height);
if ((meta_monitor_manager_get_capabilities (monitor_manager) &
@@ -645,22 +644,40 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_ma
}
static MetaLogicalMonitorConfig *
-create_logical_monitor_config_from_output (MetaMonitorManager *monitor_manager,
- MetaMonitor *monitor,
- MetaLogicalMonitorConfig *primary_logical_monitor_config,
- MetaLogicalMonitorLayoutMode layout_mode)
+create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
+ MetaMonitor *monitor,
+ int x,
+ int y,
+ MetaLogicalMonitorConfig *primary_logical_monitor_config,
+ MetaLogicalMonitorLayoutMode layout_mode)
{
- MetaOutput *output;
- MetaCrtc *crtc;
+ return create_logical_monitor_config (monitor_manager,
+ monitor,
+ meta_monitor_get_preferred_mode (monitor),
+ x, y,
+ primary_logical_monitor_config,
+ layout_mode);
+}
- output = meta_monitor_get_main_output (monitor);
- crtc = meta_output_get_assigned_crtc (output);
- return create_preferred_logical_monitor_config (monitor_manager,
- monitor,
- crtc->rect.x,
- crtc->rect.y,
- primary_logical_monitor_config,
- layout_mode);
+static MetaLogicalMonitorConfig *
+create_logical_monitor_config_from_monitor (MetaMonitorManager *monitor_manager,
+ MetaMonitor *monitor,
+ MetaLogicalMonitorConfig *primary_logical_monitor_config,
+ MetaLogicalMonitorLayoutMode layout_mode)
+{
+ MetaRectangle monitor_layout;
+ MetaMonitorMode *mode;
+
+ meta_monitor_derive_layout (monitor, &monitor_layout);
+ mode = meta_monitor_get_current_mode (monitor);
+
+ return create_logical_monitor_config (monitor_manager,
+ monitor,
+ mode,
+ monitor_layout.x,
+ monitor_layout.y,
+ primary_logical_monitor_config,
+ layout_mode);
}
MetaMonitorsConfig *
@@ -688,10 +705,10 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
primary_logical_monitor_config =
- create_logical_monitor_config_from_output (monitor_manager,
- primary_monitor,
- NULL,
- layout_mode);
+ create_logical_monitor_config_from_monitor (monitor_manager,
+ primary_monitor,
+ NULL,
+ layout_mode);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
@@ -710,10 +727,10 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man
continue;
logical_monitor_config =
- create_logical_monitor_config_from_output (monitor_manager,
- monitor,
- primary_logical_monitor_config,
- layout_mode);
+ create_logical_monitor_config_from_monitor (monitor_manager,
+ monitor,
+ primary_logical_monitor_config,
+ layout_mode);
logical_monitor_configs = g_list_append (logical_monitor_configs,
logical_monitor_config);
--
2.21.0
From d8c34e4cd7e500567e72e0f219295d7c2162dcf3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 18 Mar 2019 17:10:37 +0100
Subject: [PATCH 2/2] monitor-manager: Don't try to derive current config on
non-X11
This commit also reworks the initial config state reading some. Appart from
avoiding trying to inherit from backends where it doesn't make sense, it does
the following changes:
* Replace the name "initial" with "inherited", as the initial config in the
context of monitor management is the one used initialization. E.g. if there is
a applicable configuration in monitors.xml, the initial config is taken from
there.
* Don't make "_create_()" functions have side effects. Previously
meta_monitor_config_manager_create_initial() also set state on the config
manager object. Instead, add a meta_monitor_config_manager_ensure_inherited()
and meta_monitor_manager_get_inherited_config() function to make things more
explicit.
* Don't recreate "is-applicable" logic, just use the existing helper.
---
src/backends/meta-monitor-config-manager.c | 39 +++++++++++--------
src/backends/meta-monitor-config-manager.h | 5 +++
src/backends/meta-monitor-manager-private.h | 4 +-
src/backends/meta-monitor-manager.c | 32 ++++++++-------
.../x11/meta-monitor-manager-xrandr.c | 3 +-
5 files changed, 49 insertions(+), 34 deletions(-)
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index a3387aa0f..bc1a39db8 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -42,7 +42,7 @@ struct _MetaMonitorConfigManager
MetaMonitorConfigStore *config_store;
MetaMonitorsConfig *current_config;
- MetaMonitorsConfig *initial_config;
+ MetaMonitorsConfig *inherited_config;
GQueue config_history;
};
@@ -680,11 +680,10 @@ create_logical_monitor_config_from_monitor (MetaMonitorManager *monito
layout_mode);
}
-MetaMonitorsConfig *
-meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager)
+static MetaMonitorsConfig *
+meta_monitor_config_manager_derive_current (MetaMonitorConfigManager *config_manager)
{
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
- MetaMonitorsConfig *initial_config;
GList *logical_monitor_configs;
MetaMonitor *primary_monitor;
MetaLogicalMonitorLayoutMode layout_mode;
@@ -692,12 +691,6 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man
GList *monitors;
GList *l;
- if (config_manager->initial_config != NULL)
- return g_object_ref (config_manager->initial_config);
-
- if (meta_monitor_config_store_get_config_count (config_manager->config_store) > 0)
- return NULL;
-
primary_monitor = find_primary_monitor (monitor_manager);
if (!primary_monitor || !meta_monitor_is_active (primary_monitor))
return NULL;
@@ -736,14 +729,26 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man
logical_monitor_config);
}
- initial_config = meta_monitors_config_new (monitor_manager,
- logical_monitor_configs,
- layout_mode,
- META_MONITORS_CONFIG_FLAG_NONE);
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
+ META_MONITORS_CONFIG_FLAG_NONE);
+}
+
+void
+meta_monitor_config_manager_ensure_inherited_config (MetaMonitorConfigManager *config_manager)
+{
+ if (config_manager->inherited_config)
+ return;
- config_manager->initial_config = g_object_ref (initial_config);
+ config_manager->inherited_config =
+ meta_monitor_config_manager_derive_current (config_manager);
+}
- return initial_config;
+MetaMonitorsConfig *
+meta_monitor_config_manager_get_inherited_config (MetaMonitorConfigManager *config_manager)
+{
+ return config_manager->inherited_config;
}
MetaMonitorsConfig *
@@ -1282,7 +1287,7 @@ meta_monitor_config_manager_dispose (GObject *object)
META_MONITOR_CONFIG_MANAGER (object);
g_clear_object (&config_manager->current_config);
- g_clear_object (&config_manager->initial_config);
+ g_clear_object (&config_manager->inherited_config);
meta_monitor_config_manager_clear_history (config_manager);
G_OBJECT_CLASS (meta_monitor_config_manager_parent_class)->dispose (object);
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 409611bb0..bb847b96e 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -96,6 +96,11 @@ MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigMa
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager);
+
+void meta_monitor_config_manager_ensure_inherited_config (MetaMonitorConfigManager *config_manager);
+
+MetaMonitorsConfig * meta_monitor_config_manager_get_inherited_config (MetaMonitorConfigManager *config_manager);
+
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager);
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index cdb8f4209..223b5dfbd 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -44,7 +44,8 @@ typedef enum _MetaMonitorManagerCapability
META_MONITOR_MANAGER_CAPABILITY_NONE = 0,
META_MONITOR_MANAGER_CAPABILITY_MIRRORING = (1 << 0),
META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 1),
- META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 2)
+ META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 2),
+ META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT = (1 << 3),
} MetaMonitorManagerCapability;
/* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */
@@ -133,6 +134,7 @@ struct _MetaMonitorManager
int persistent_timeout_id;
MetaMonitorConfigManager *config_manager;
+ MetaMonitorsConfig *initial_config;
GnomePnpIds *pnp_ids;
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index bb4b44188..076dca8cb 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -531,14 +531,21 @@ should_use_stored_config (MetaMonitorManager *manager)
!meta_monitor_manager_has_hotplug_mode_update (manager));
}
+static gboolean
+can_derive_current_config (MetaMonitorManager *manager)
+{
+ MetaMonitorManagerCapability capabilities;
+
+ capabilities = meta_monitor_manager_get_capabilities (manager);
+ return !!(capabilities & META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT);
+}
+
MetaMonitorsConfig *
meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
{
- g_autoptr (MetaMonitorsConfig) initial_config = NULL;
MetaMonitorsConfig *config = NULL;
GError *error = NULL;
gboolean use_stored_config;
- MetaMonitorsConfigKey *current_state_key;
MetaMonitorsConfigMethod method;
MetaMonitorsConfigMethod fallback_method =
META_MONITORS_CONFIG_METHOD_TEMPORARY;
@@ -549,17 +556,8 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
else
method = META_MONITORS_CONFIG_METHOD_TEMPORARY;
- initial_config = meta_monitor_config_manager_create_initial (manager->config_manager);
-
- if (initial_config)
- {
- current_state_key = meta_create_monitors_config_key_for_current_state (manager);
-
- /* don't ever reuse initial configuration, if the monitor topology changed
- */
- if (current_state_key && !meta_monitors_config_key_equal (current_state_key, initial_config->key))
- g_clear_object (&initial_config);
- }
+ if (can_derive_current_config (manager))
+ meta_monitor_config_manager_ensure_inherited_config (manager->config_manager);
if (use_stored_config)
{
@@ -628,9 +626,13 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
g_clear_object (&config);
}
- config = g_steal_pointer (&initial_config);
- if (config)
+ config =
+ meta_monitor_config_manager_get_inherited_config (manager->config_manager);
+ if (config &&
+ meta_monitor_manager_is_config_complete (manager, config))
{
+ config = g_object_ref (config);
+
if (!meta_monitor_manager_apply_monitors_config (manager,
config,
method,
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index d60f00325..b8d6342b6 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -999,7 +999,8 @@ static MetaMonitorManagerCapability
meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager)
{
return (META_MONITOR_MANAGER_CAPABILITY_MIRRORING |
- META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
+ META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED |
+ META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT);
}
static gboolean
--
2.21.0

View File

@ -0,0 +1,374 @@
From 05bca153bb92c5daa5b961214ff7f80af88cb7cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 24 Oct 2019 21:19:36 +0200
Subject: [PATCH 1/2] display: Move finishing of touch sequence to the backend
We need to manipulate an X11 grab when a touch sequence ends; move that
logic to where it belongs - in the X11 backend.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/886
---
src/backends/meta-backend-private.h | 16 ++++++++++++
src/backends/meta-backend.c | 14 +++++++++++
src/backends/x11/meta-backend-x11.c | 23 +++++++++++++++++
src/core/display.c | 33 +++++++++++--------------
src/core/meta-gesture-tracker-private.h | 9 +------
5 files changed, 69 insertions(+), 26 deletions(-)
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index 7eba1806b..81ec81e5f 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -49,6 +49,14 @@
#define DEFAULT_XKB_RULES_FILE "evdev"
#define DEFAULT_XKB_MODEL "pc105+inet"
+typedef enum
+{
+ META_SEQUENCE_NONE,
+ META_SEQUENCE_ACCEPTED,
+ META_SEQUENCE_REJECTED,
+ META_SEQUENCE_PENDING_END
+} MetaSequenceState;
+
struct _MetaBackendClass
{
GObjectClass parent_class;
@@ -71,6 +79,10 @@ struct _MetaBackendClass
int device_id,
uint32_t timestamp);
+ void (* finish_touch_sequence) (MetaBackend *backend,
+ ClutterEventSequence *sequence,
+ MetaSequenceState state);
+
void (* warp_pointer) (MetaBackend *backend,
int x,
int y);
@@ -135,6 +147,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend,
int device_id,
uint32_t timestamp);
+void meta_backend_finish_touch_sequence (MetaBackend *backend,
+ ClutterEventSequence *sequence,
+ MetaSequenceState state);
+
void meta_backend_warp_pointer (MetaBackend *backend,
int x,
int y);
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index c980cf150..bb7d66f2a 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -1086,6 +1086,20 @@ meta_backend_ungrab_device (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
}
+/**
+ * meta_backend_finish_touch_sequence: (skip)
+ */
+void
+meta_backend_finish_touch_sequence (MetaBackend *backend,
+ ClutterEventSequence *sequence,
+ MetaSequenceState state)
+{
+ if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence)
+ META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend,
+ sequence,
+ state);
+}
+
/**
* meta_backend_warp_pointer: (skip)
*/
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index c10365f9d..cdefa50a9 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -591,6 +591,28 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
return (ret == Success);
}
+static void
+meta_backend_x11_finish_touch_sequence (MetaBackend *backend,
+ ClutterEventSequence *sequence,
+ MetaSequenceState state)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+ int event_mode;
+
+ if (state == META_SEQUENCE_ACCEPTED)
+ event_mode = XIAcceptTouch;
+ else if (state == META_SEQUENCE_REJECTED)
+ event_mode = XIRejectTouch;
+ else
+ g_return_if_reached ();
+
+ XIAllowTouchEvents (priv->xdisplay,
+ META_VIRTUAL_CORE_POINTER_ID,
+ clutter_x11_event_sequence_get_touch_detail (sequence),
+ DefaultRootWindow (priv->xdisplay), event_mode);
+}
+
static void
meta_backend_x11_warp_pointer (MetaBackend *backend,
int x,
@@ -776,6 +798,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->post_init = meta_backend_x11_post_init;
backend_class->grab_device = meta_backend_x11_grab_device;
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
+ backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence;
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
backend_class->get_keymap = meta_backend_x11_get_keymap;
diff --git a/src/core/display.c b/src/core/display.c
index 4c8907f40..eb7dc43b6 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -42,6 +42,7 @@
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xfixes.h>
+#include "backends/meta-backend-private.h"
#include "backends/meta-cursor-sprite-xcursor.h"
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-idle-monitor-dbus.h"
@@ -598,27 +599,23 @@ gesture_tracker_state_changed (MetaGestureTracker *tracker,
MetaSequenceState state,
MetaDisplay *display)
{
- if (meta_is_wayland_compositor ())
+ switch (state)
{
- if (state == META_SEQUENCE_ACCEPTED)
- meta_display_cancel_touch (display);
- }
- else
- {
- MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
- int event_mode;
+ case META_SEQUENCE_NONE:
+ case META_SEQUENCE_PENDING_END:
+ return;
+ case META_SEQUENCE_ACCEPTED:
+ meta_display_cancel_touch (display);
- if (state == META_SEQUENCE_ACCEPTED)
- event_mode = XIAcceptTouch;
- else if (state == META_SEQUENCE_REJECTED)
- event_mode = XIRejectTouch;
- else
- return;
+ /* Intentional fall-through */
+ case META_SEQUENCE_REJECTED:
+ {
+ MetaBackend *backend;
- XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
- META_VIRTUAL_CORE_POINTER_ID,
- clutter_x11_event_sequence_get_touch_detail (sequence),
- DefaultRootWindow (display->x11_display->xdisplay), event_mode);
+ backend = meta_get_backend ();
+ meta_backend_finish_touch_sequence (backend, sequence, state);
+ break;
+ }
}
}
diff --git a/src/core/meta-gesture-tracker-private.h b/src/core/meta-gesture-tracker-private.h
index a9db35ebc..e7bfc5472 100644
--- a/src/core/meta-gesture-tracker-private.h
+++ b/src/core/meta-gesture-tracker-private.h
@@ -26,6 +26,7 @@
#include <glib-object.h>
+#include "backends/meta-backend-private.h"
#include "clutter/clutter.h"
#include "meta/window.h"
@@ -39,14 +40,6 @@
typedef struct _MetaGestureTracker MetaGestureTracker;
typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass;
-typedef enum
-{
- META_SEQUENCE_NONE,
- META_SEQUENCE_ACCEPTED,
- META_SEQUENCE_REJECTED,
- META_SEQUENCE_PENDING_END
-} MetaSequenceState;
-
struct _MetaGestureTracker
{
GObject parent_instance;
--
2.23.0
From 8cf4f500defb421d5c96f2c1f9fcf7bb5545d70d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 25 Oct 2019 10:06:55 +0200
Subject: [PATCH 2/2] x11: Limit touch replay pointer events to when replaying
When a touch sequence was rejected, the emulated pointer events would be
replayed with old timestamps. This caused issues with grabs as they
would be ignored due to being too old. This was mitigated by making sure
device event timestamps never travelled back in time by tampering with
any event that had a timestamp seemingly in the past.
This failed when the most recent timestamp that had been received were
much older than the timestamp of the new event. This could for example
happen when a session was left not interacted with for 40+ days or so;
when interacted with again, as any new timestamp would according to
XSERVER_TIME_IS_BEFORE() still be in the past compared to the "most
recent" one. The effect is that we'd always use the `latest_evtime` for
all new device events without ever updating it.
The end result of this was that passive grabs would become active when
interacted with, but would then newer be released, as the timestamps to
XIAllowEvents() would out of date, resulting in the desktop effectively
freezing, as the Shell would have an active pointer grab.
To avoid the situation where we get stuck with an old `latest_evtime`
timestamp, limit the tampering with device event timestamp to 1) only
pointer events, and 2) only during the replay sequence. The second part
is implemented by sending an asynchronous message via the X server after
rejecting a touch sequence, only potentially tampering with the device
event timestamps until the reply. This should avoid the stuck timestamp
as in those situations, we'll always have a relatively up to date
`latest_evtime` meaning XSERVER_TIME_IS_BEFORE() will not get confused.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/886
---
src/backends/x11/meta-backend-x11.c | 71 +++++++++++++++++++++++------
1 file changed, 58 insertions(+), 13 deletions(-)
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index cdefa50a9..821b30f5b 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -66,6 +66,10 @@ struct _MetaBackendX11Private
XSyncAlarm user_active_alarm;
XSyncCounter counter;
+ int current_touch_replay_sync_serial;
+ int pending_touch_replay_sync_serial;
+ Atom touch_replay_sync_atom;
+
int xinput_opcode;
int xinput_event_base;
int xinput_error_base;
@@ -174,6 +178,26 @@ meta_backend_x11_translate_device_event (MetaBackendX11 *x11,
backend_x11_class->translate_device_event (x11, device_event);
}
+static void
+maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11,
+ XIDeviceEvent *device_event)
+{
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+
+ if (!device_event->send_event &&
+ device_event->time != META_CURRENT_TIME &&
+ priv->current_touch_replay_sync_serial !=
+ priv->pending_touch_replay_sync_serial &&
+ XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
+ {
+ /* Emulated pointer events received after XIRejectTouch is received
+ * on a passive touch grab will contain older timestamps, update those
+ * so we dont get InvalidTime at grabs.
+ */
+ device_event->time = priv->latest_evtime;
+ }
+}
+
static void
translate_device_event (MetaBackendX11 *x11,
XIDeviceEvent *device_event)
@@ -183,19 +207,7 @@ translate_device_event (MetaBackendX11 *x11,
meta_backend_x11_translate_device_event (x11, device_event);
if (!device_event->send_event && device_event->time != META_CURRENT_TIME)
- {
- if (XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
- {
- /* Emulated pointer events received after XIRejectTouch is received
- * on a passive touch grab will contain older timestamps, update those
- * so we dont get InvalidTime at grabs.
- */
- device_event->time = priv->latest_evtime;
- }
-
- /* Update the internal latest evtime, for any possible later use */
- priv->latest_evtime = device_event->time;
- }
+ priv->latest_evtime = device_event->time;
}
static void
@@ -260,6 +272,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
+ maybe_translate_touch_replay_pointer_event (x11,
+ (XIDeviceEvent *) input_event);
+ /* Intentional fall-through */
case XI_KeyPress:
case XI_KeyRelease:
case XI_TouchBegin:
@@ -327,6 +342,17 @@ handle_host_xevent (MetaBackend *backend,
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
gboolean bypass_clutter = FALSE;
+ switch (event->type)
+ {
+ case ClientMessage:
+ if (event->xclient.window == meta_backend_x11_get_xwindow (x11) &&
+ event->xclient.message_type == priv->touch_replay_sync_atom)
+ priv->current_touch_replay_sync_serial = event->xclient.data.l[0];
+ break;
+ default:
+ break;
+ }
+
XGetEventData (priv->xdisplay, &event->xcookie);
{
@@ -534,6 +560,10 @@ meta_backend_x11_post_init (MetaBackend *backend)
monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed), backend);
+
+ priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay,
+ "_MUTTER_TOUCH_SEQUENCE_SYNC",
+ False);
}
static ClutterBackend *
@@ -611,6 +641,21 @@ meta_backend_x11_finish_touch_sequence (MetaBackend *backend,
META_VIRTUAL_CORE_POINTER_ID,
clutter_x11_event_sequence_get_touch_detail (sequence),
DefaultRootWindow (priv->xdisplay), event_mode);
+
+ if (state == META_SEQUENCE_REJECTED)
+ {
+ XClientMessageEvent ev;
+
+ ev = (XClientMessageEvent) {
+ .type = ClientMessage,
+ .window = meta_backend_x11_get_xwindow (x11),
+ .message_type = priv->touch_replay_sync_atom,
+ .format = 32,
+ .data.l[0] = ++priv->pending_touch_replay_sync_serial,
+ };
+ XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11),
+ False, 0, (XEvent *) &ev);
+ }
}
static void
--
2.23.0

View File

@ -8,7 +8,7 @@
Name: mutter
Version: 3.32.2
Release: 4%{?dist}
Release: 26%{?dist}
Summary: Window and compositing manager based on Clutter
License: GPLv2+
@ -57,6 +57,60 @@ Patch112: add-support-for-plain-old-x-device-configuration.patch
Patch113: 0001-main-be-more-aggressive-in-assuming-X11-backend.patch
Patch114: 0001-clutter-Only-reset-scroll-axes-on-slave-devices.patch
# Inherit xorg.conf (rhbz#1690506)
Patch115: inherit-xrandr-metamodes.patch
# Fix test blocker when running on cirrus (rhbz#1735382)
Patch116: 0001-iconcache-Avoid-xrender-picture-formats-when-creatin.patch
# Don't focus or activate unmanaging windows (rhbz#1741547)
Patch117: 0001-workspace-Focus-only-ancestors-that-are-focusable.patch
Patch118: 0002-window-Emit-an-error-and-return-when-trying-to-activ.patch
# Don't freeze on rapid input (rhbz#1759525)
Patch119: 0001-events-Sync-pending-pointer-events-without-a-window.patch
# Don't freeze if input happens after many days of inactivity (rhbz#1766649)
Patch120: input-after-long-idle-fix.patch
# Fix invalid read in idle monitor (rhbz#1766695)
Patch121: idle-monitor-reset-fix.patch
# Improve shadow-fb performance on llvmpipe
# https://bugzilla.redhat.com/1737553
Patch201: 0001-cogl-Remove-unused-OFFSCREEN_BLIT-feature-flag.patch
Patch202: 0002-cogl-Fix-doc-for-_cogl_blit_framebuffer.patch
Patch203: 0003-cogl-Replace-ANGLE-with-GLES3-and-NV-framebuffer_bli.patch
Patch204: 0004-cogl-Relax-formats-on-glBlitFramebuffer.patch
Patch205: 0005-cogl-Allow-glBlitFramebuffer-between-onscreen-offscr.patch
Patch206: 0006-cogl-Rename-feature-OFFSCREEN_BLIT-to-BLIT_FRAMEBUFF.patch
Patch207: 0007-cogl-Expose-cogl_blit_framebuffer.patch
Patch208: 0008-clutter-stage-view-Use-cogl_blit_framebuffer-for-sha.patch
Patch209: 0009-clutter-stage-view-Ignore-clipping-rectangle-for-off.patch
Patch210: 0010-cogl-Flush-journal-before-blitting.patch
Patch211: 0011-clutter-stage-view-Separate-offscreen-and-shadowfb.patch
Patch212: 0012-renderer-native-Separate-offscreen-and-shadowfb.patch
# Handle lack of RANDR (#1776530)
Patch250: 0001-monitor-manager-xrandr-Move-dpms-state-and-screen-si.patch
Patch251: 0002-monitor-manager-xrandr-Create-dummy-screen-sized-mon.patch
# Fix build due to egl.pc provider change
Patch260: 0001-EGL-Include-EGL-eglmesaext.h.patch
# Fix popups with styli
Patch261: 0001-wayland-Check-stylus-serials-on-meta_wayland_seat_ca.patch
# Fix led-less pad mode switch buttons
Patch262: 0001-x11-Check-wacom-button-flags-to-determine-whether-bu.patch
# Wacom fixes
Patch263: 0001-backends-Consider-pen-eraser-devices-when-looking-fo.patch
Patch264: 0001-backends-Always-enable-tap-to-click-drag-on-opaque-W.patch
Patch265: 0001-backends-x11-Observe-multiple-pad-mode-switch-button.patch
Patch266: 0001-backends-Check-both-input-settings-and-mapper-for-ta.patch
Patch267: 0001-core-Let-pad-mode-switch-events-always-go-through-Me.patch
BuildRequires: chrpath
BuildRequires: pango-devel
BuildRequires: startup-notification-devel
@ -198,6 +252,95 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop
%{_datadir}/mutter-%{mutter_api_version}/tests
%changelog
* Mon Dec 16 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-26
- Let pad OSD update on mode switching
Resolves: #1716774
* Fri Dec 13 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-25
- Fix Wacom OSDs so they appear on the right monitor
Resolves: #1777556
* Fri Dec 13 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-24
- Handle multiple mode switch buttons in Cintiq 27QHD
Resolves: #1687979
* Fri Dec 13 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-23
- Enable tapping features by default on standalone Wacom tablets
Resolves: #1716754
* Fri Dec 13 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-22
- Fix detection of Wacom tablet features on X11
Resolves: #1759619
* Wed Dec 04 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-21
- Fix mode switch pad buttons without LEDs
Resolves: #1666070
* Mon Dec 01 2019 Tomas Pelka <tpelka@redhat.com> - 3.32.2-20
- Need rebuild in correct build target
Resolves: #1730891
* Fri Nov 29 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-19
- Fix pop ups with stylus input
Resolves: #1730891
* Wed Nov 27 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-18
- Revert memory leak fix
Resolves: #1777911
* Wed Nov 27 2019 Florian Müllner <fmuellner@redhat.com> - 3.32.2-17
- Fix some memory leaks
Resolves: #1719819
* Wed Nov 27 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-16
- Fix build due to egl.pc provider change
Related: #1776530
* Wed Nov 27 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-15
- Handle lack of RANDR
Resolves: #1776530
* Mon Nov 4 2019 Olivier Fourdan <ofourdan@redhat.com> - 3.32.2-14
- Backports shadow FB improvements on llvmpipe
Resolves: #1737553
* Wed Oct 30 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-13
- Fix invalid read in idle monitor
Resolves: #1766695
* Wed Oct 30 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-12
- Don't freeze if input happens after many days of inactivity
Resolves: #1766649
* Fri Oct 25 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-11
- Don't freeze on rapid input
Resolves: #1759525
* Fri Aug 16 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-10
- Don't focus or activate unmanaging windows
Resolves: #1741547
* Mon Aug 05 2019 Ray Strode <rstrode@redhat.com> - 3.32.2-9
- Another 16bpp graphics card crash
Related: #1735382
Resolves: #1737326
* Fri Aug 02 2019 Ray Strode <rstrode@redhat.com> - 3.32.2-8
- Fix crash in window icon handling on 16bpp graphics cards
Resolves: #1735382
* Tue Jul 23 2019 Ray Strode <rstrode@redhat.com> - 3.32.2-7
- Fix bug leading to 100% cpu usage on suspend/resume
Resolves: #1724551
* Mon Jul 15 2019 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-6
- Don't ignore current mode when deriving current config
Resolves: #1690506
* Thu Jun 20 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.32.2-5
- Ensure pad XDevices do not get buttons remapped
Resolves: #1687949
* Wed Jun 12 2019 Florian Müllner <fmuellner@redhat.com> - 3.32.2-4
- Expose workspace layout as properties
Related: #1704360