import mutter-3.32.2-35.el8_2

This commit is contained in:
CentOS Sources 2020-04-28 12:08:38 -04:00 committed by Andrew Lukoshko
parent 24a5739380
commit dc2087df87
11 changed files with 22 additions and 1564 deletions

View File

@ -1,4 +1,4 @@
From d0ad5ea18bb02112837bcdf7270d58d8ad235a4d Mon Sep 17 00:00:00 2001 From 8d7356fd7439f94f163438d55f2b2d3d918de96d Mon Sep 17 00:00:00 2001
From: "Owen W. Taylor" <otaylor@fishsoup.net> From: "Owen W. Taylor" <otaylor@fishsoup.net>
Date: Thu, 8 May 2014 18:44:15 -0400 Date: Thu, 8 May 2014 18:44:15 -0400
Subject: [PATCH] Add support for quad-buffer stereo Subject: [PATCH] Add support for quad-buffer stereo
@ -265,10 +265,10 @@ index a86a2bff0..d0efdd4dc 100644
gboolean is_y_inverted); gboolean is_y_inverted);
void meta_shaped_texture_set_snippet (MetaShapedTexture *stex, void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index ea8daa03d..9a00ccd6d 100644 index d64e214e5..e77a32109 100644
--- a/src/compositor/meta-shaped-texture.c --- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c
@@ -102,8 +102,10 @@ struct _MetaShapedTexture @@ -88,8 +88,10 @@ struct _MetaShapedTexture
ClutterActor parent; ClutterActor parent;
MetaTextureTower *paint_tower; MetaTextureTower *paint_tower;
@ -279,15 +279,15 @@ index ea8daa03d..9a00ccd6d 100644
CoglTexture *mask_texture; CoglTexture *mask_texture;
CoglSnippet *snippet; CoglSnippet *snippet;
@@ -192,6 +194,7 @@ meta_shaped_texture_init (MetaShapedTexture *stex) @@ -160,6 +162,7 @@ static void
clutter_backend_get_cogl_context (clutter_backend); meta_shaped_texture_init (MetaShapedTexture *stex)
{
stex->paint_tower = meta_texture_tower_new (); stex->paint_tower = meta_texture_tower_new ();
+ stex->paint_tower_right = NULL; /* demand create */ + stex->paint_tower_right = NULL; /* demand create */
stex->texture = NULL; stex->texture = NULL;
stex->mask_texture = NULL; stex->mask_texture = NULL;
@@ -335,6 +338,9 @@ meta_shaped_texture_dispose (GObject *object) @@ -297,6 +300,9 @@ meta_shaped_texture_dispose (GObject *object)
meta_texture_tower_free (stex->paint_tower); meta_texture_tower_free (stex->paint_tower);
stex->paint_tower = NULL; stex->paint_tower = NULL;
@ -297,7 +297,7 @@ index ea8daa03d..9a00ccd6d 100644
g_clear_pointer (&stex->texture, cogl_object_unref); g_clear_pointer (&stex->texture, cogl_object_unref);
g_clear_pointer (&stex->opaque_region, cairo_region_destroy); g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
@@ -611,8 +617,9 @@ paint_clipped_rectangle (MetaShapedTexture *stex, @@ -507,8 +513,9 @@ paint_clipped_rectangle (MetaShapedTexture *stex,
} }
static void static void
@ -309,21 +309,19 @@ index ea8daa03d..9a00ccd6d 100644
{ {
int width, height; int width, height;
@@ -620,10 +627,13 @@ set_cogl_texture (MetaShapedTexture *stex, @@ -516,8 +523,11 @@ set_cogl_texture (MetaShapedTexture *stex,
if (stex->texture) if (stex->texture)
cogl_object_unref (stex->texture); cogl_object_unref (stex->texture);
+ if (stex->texture_right) + if (stex->texture_right)
+ cogl_object_unref (stex->texture_right); + cogl_object_unref (stex->texture_right);
g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
stex->texture = cogl_tex; stex->texture = cogl_tex;
+ stex->texture_right = cogl_tex_right; + stex->texture_right = cogl_tex_right;
if (cogl_tex != NULL) if (cogl_tex != NULL)
{ {
@@ -637,6 +647,9 @@ set_cogl_texture (MetaShapedTexture *stex, @@ -531,6 +541,9 @@ set_cogl_texture (MetaShapedTexture *stex,
height = 0; height = 0;
} }
@ -333,7 +331,7 @@ index ea8daa03d..9a00ccd6d 100644
if (stex->tex_width != width || if (stex->tex_width != width ||
stex->tex_height != height) stex->tex_height != height)
{ {
@@ -650,8 +663,23 @@ set_cogl_texture (MetaShapedTexture *stex, @@ -544,8 +557,23 @@ set_cogl_texture (MetaShapedTexture *stex,
* previous buffer. We only queue a redraw in response to surface * previous buffer. We only queue a redraw in response to surface
* damage. */ * damage. */
@ -358,7 +356,7 @@ index ea8daa03d..9a00ccd6d 100644
} }
static gboolean static gboolean
@@ -927,7 +955,9 @@ meta_shaped_texture_paint (ClutterActor *actor) @@ -779,7 +807,9 @@ meta_shaped_texture_paint (ClutterActor *actor)
{ {
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor); MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
CoglTexture *paint_tex; CoglTexture *paint_tex;
@ -368,7 +366,7 @@ index ea8daa03d..9a00ccd6d 100644
if (!stex->texture) if (!stex->texture)
return; return;
@@ -989,7 +1019,32 @@ meta_shaped_texture_paint (ClutterActor *actor) @@ -841,7 +871,32 @@ meta_shaped_texture_paint (ClutterActor *actor)
return; return;
fb = cogl_get_draw_framebuffer (); fb = cogl_get_draw_framebuffer ();
@ -402,7 +400,7 @@ index ea8daa03d..9a00ccd6d 100644
} }
static void static void
@@ -1063,6 +1118,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, @@ -915,6 +970,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
stex->create_mipmaps = create_mipmaps; stex->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ? stex->texture : NULL; base_texture = create_mipmaps ? stex->texture : NULL;
meta_texture_tower_set_base_texture (stex->paint_tower, base_texture); meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
@ -415,7 +413,7 @@ index ea8daa03d..9a00ccd6d 100644
} }
} }
@@ -1256,6 +1317,12 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, @@ -1046,6 +1107,12 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
clip.y, clip.y,
clip.width, clip.width,
clip.height); clip.height);
@ -428,7 +426,7 @@ index ea8daa03d..9a00ccd6d 100644
stex->prev_invalidation = stex->last_invalidation; stex->prev_invalidation = stex->last_invalidation;
stex->last_invalidation = g_get_monotonic_time (); stex->last_invalidation = g_get_monotonic_time ();
@@ -1302,17 +1369,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, @@ -1092,17 +1159,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
} }
/** /**
@ -903,5 +901,5 @@ index da0acfcbb..ddad1a45c 100644
meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted); meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted);
g_clear_pointer (&snippet, cogl_object_unref); g_clear_pointer (&snippet, cogl_object_unref);
-- --
2.23.0 2.25.1

View File

@ -1,136 +0,0 @@
From 78bb1fff1155462638b0d6037ccddf1328482842 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 11:01:38 -0500
Subject: [PATCH 1/9] cogl: add new UNSTABLE_TEXTURES feature
The proprietary nvidia driver garbles texture memory on suspend.
Before we can address that, we need to be able to detect it.
This commit adds a new UNSTABLE_TEXTURES feature that gets set if
the proprietary nvidia driver is in use.
---
cogl/cogl/cogl-context.h | 1 +
cogl/cogl/cogl-types.h | 5 ++++-
cogl/cogl/winsys/cogl-winsys-egl.c | 11 +++++++++++
cogl/cogl/winsys/cogl-winsys-glx.c | 13 +++++++++++--
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h
index d4104625e..a20c54549 100644
--- a/cogl/cogl/cogl-context.h
+++ b/cogl/cogl/cogl-context.h
@@ -261,6 +261,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_TEXTURE_RG,
COGL_FEATURE_ID_BUFFER_AGE,
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
+ COGL_FEATURE_ID_UNSTABLE_TEXTURES,
/*< private >*/
_COGL_N_FEATURE_IDS /*< skip >*/
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
index 690daa16a..5b980a43c 100644
--- a/cogl/cogl/cogl-types.h
+++ b/cogl/cogl/cogl-types.h
@@ -354,6 +354,8 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
* supported with CoglBufferAccess including write support.
* @COGL_FEATURE_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering the
* depth buffer to a texture.
+ * @COGL_FEATURE_UNSTABLE_TEXTURES: Whether textures require redrawing on
+ * resume or not.
*
* Flags for the supported features.
*
@@ -383,7 +385,8 @@ typedef enum
COGL_FEATURE_MAP_BUFFER_FOR_READ = (1 << 21),
COGL_FEATURE_MAP_BUFFER_FOR_WRITE = (1 << 22),
COGL_FEATURE_ONSCREEN_MULTIPLE = (1 << 23),
- COGL_FEATURE_DEPTH_TEXTURE = (1 << 24)
+ COGL_FEATURE_DEPTH_TEXTURE = (1 << 24),
+ COGL_FEATURE_UNSTABLE_TEXTURES = (1 << 25)
} CoglFeatureFlags;
/**
diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c
index 903c6492d..dd450d4f3 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl.c
@@ -499,6 +499,7 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
CoglRenderer *renderer = context->display->renderer;
CoglDisplayEGL *egl_display = context->display->winsys;
CoglRendererEGL *egl_renderer = renderer->winsys;
+ CoglGpuInfo *info;
context->winsys = g_new0 (CoglContextEGL, 1);
@@ -511,6 +512,16 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
if (!_cogl_context_update_features (context, error))
return FALSE;
+ info = &context->gpu;
+
+ if (info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
+ {
+ context->feature_flags |= COGL_FEATURE_UNSTABLE_TEXTURES;
+ COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_UNSTABLE_TEXTURES,
+ TRUE);
+ }
+
if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
{
COGL_FLAGS_SET (context->winsys_features,
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 235cfe81f..7e87dc15f 100644
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -830,12 +830,15 @@ update_winsys_features (CoglContext *context, CoglError **error)
{
CoglGLXDisplay *glx_display = context->display->winsys;
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
+ CoglGpuInfo *info;
_COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context, FALSE);
if (!_cogl_context_update_features (context, error))
return FALSE;
+ info = &context->gpu;
+
memcpy (context->winsys_features,
glx_renderer->base_winsys_features,
sizeof (context->winsys_features));
@@ -848,7 +851,6 @@ update_winsys_features (CoglContext *context, CoglError **error)
if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer)
{
- CoglGpuInfo *info = &context->gpu;
CoglGpuInfoArchitecture arch = info->architecture;
COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE);
@@ -897,7 +899,6 @@ update_winsys_features (CoglContext *context, CoglError **error)
}
else
{
- CoglGpuInfo *info = &context->gpu;
if (glx_display->have_vblank_counter &&
context->display->renderer->xlib_enable_threaded_swap_wait &&
info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
@@ -919,6 +920,14 @@ update_winsys_features (CoglContext *context, CoglError **error)
}
}
+ if (info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
+ {
+ context->feature_flags |= COGL_FEATURE_UNSTABLE_TEXTURES;
+ COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_UNSTABLE_TEXTURES,
+ TRUE);
+ }
+
/* We'll manually handle queueing dirty events in response to
* Expose events from X */
COGL_FLAGS_SET (context->private_features,
--
2.21.0

View File

@ -1,163 +0,0 @@
From 063db6c9a7504a4d7baae28f7899bd661c459c41 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 14 Jan 2019 11:11:01 -0500
Subject: [PATCH 2/9] backend: switch to using generated logind proxy
Right now we listen to prepare-for-sleep using
raw gdbus calls.
This commit switches it over to use a generated
proxy, which will become useful in a future commit,
for adding suspending inhibitors.
---
src/backends/meta-backend.c | 60 ++++++++++++++++++++++------------
src/org.freedesktop.login1.xml | 13 ++++++++
2 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 23ab2faec..5d71977c6 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -65,6 +65,7 @@
#include "meta/main.h"
#include "meta/meta-backend.h"
#include "meta/util.h"
+#include "meta-dbus-login1.h"
#ifdef HAVE_REMOTE_DESKTOP
#include "backends/meta-dbus-session-watcher.h"
@@ -145,10 +146,12 @@ struct _MetaBackendPrivate
GDBusProxy *upower_proxy;
gboolean lid_is_closed;
- guint sleep_signal_id;
GCancellable *cancellable;
GDBusConnection *system_bus;
+ Login1Manager *logind_proxy;
+ int inhibit_sleep_fd;
+
gboolean was_headless;
};
typedef struct _MetaBackendPrivate MetaBackendPrivate;
@@ -156,6 +159,10 @@ typedef struct _MetaBackendPrivate MetaBackendPrivate;
static void
initable_iface_init (GInitableIface *initable_iface);
+
+static void prepare_for_sleep_cb (MetaBackend *backend,
+ gboolean suspending);
+
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaBackend, meta_backend, G_TYPE_OBJECT,
G_ADD_PRIVATE (MetaBackend)
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
@@ -177,8 +184,6 @@ meta_backend_finalize (GObject *object)
g_clear_object (&priv->remote_access_controller);
#endif
- if (priv->sleep_signal_id)
- g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
if (priv->upower_watch_id)
g_bus_unwatch_name (priv->upower_watch_id);
g_cancellable_cancel (priv->cancellable);
@@ -764,13 +769,8 @@ meta_backend_create_renderer (MetaBackend *backend,
}
static void
-prepare_for_sleep_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
+prepare_for_sleep_cb (MetaBackend *backend,
+ gboolean suspending)
{
gboolean suspending;
@@ -780,12 +780,31 @@ prepare_for_sleep_cb (GDBusConnection *connection,
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
}
+static Login1Manager *
+get_logind_proxy (GCancellable *cancellable,
+ GError **error)
+{
+ Login1Manager *proxy;
+
+ proxy =
+ login1_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ cancellable, error);
+ if (!proxy)
+ g_prefix_error (error, "Could not get logind proxy: ");
+
+ return proxy;
+}
+
static void
system_bus_gotten_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
MetaBackendPrivate *priv;
+ g_autoptr (GError) error = NULL;
GDBusConnection *bus;
bus = g_bus_get_finish (res, NULL);
@@ -794,17 +813,16 @@ system_bus_gotten_cb (GObject *object,
priv = meta_backend_get_instance_private (user_data);
priv->system_bus = bus;
- priv->sleep_signal_id =
- g_dbus_connection_signal_subscribe (priv->system_bus,
- "org.freedesktop.login1",
- "org.freedesktop.login1.Manager",
- "PrepareForSleep",
- "/org/freedesktop/login1",
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- prepare_for_sleep_cb,
- NULL,
- NULL);
+ priv->logind_proxy = get_logind_proxy (priv->cancellable, &error);
+
+ if (!priv->logind_proxy)
+ g_warning ("Failed to get logind proxy: %s", error->message);
+
+ g_signal_connect_object (priv->logind_proxy,
+ "prepare-for-sleep",
+ G_CALLBACK (prepare_for_sleep_cb),
+ user_data,
+ G_CONNECT_SWAPPED);
}
static gboolean
diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml
index 765475132..1ecfd976f 100644
--- a/src/org.freedesktop.login1.xml
+++ b/src/org.freedesktop.login1.xml
@@ -43,4 +43,17 @@
<arg name="vt" type="u"/>
</method>
</interface>
+
+ <interface name="org.freedesktop.login1.Manager">
+ <method name="Inhibit">
+ <arg name="what" type="s" direction="in"/>
+ <arg name="who" type="s" direction="in"/>
+ <arg name="why" type="s" direction="in"/>
+ <arg name="mode" type="s" direction="in"/>
+ <arg name="fd" type="h" direction="out"/>
+ </method>
+ <signal name="PrepareForSleep">
+ <arg name="active" type="b"/>
+ </signal>
+ </interface>
</node>
--
2.21.0

View File

@ -1,181 +0,0 @@
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
This commit adds "suspending" and "resuming" signals
to MetaBackend.
It's preliminary work needed for tracking when to purge
and recreate all textures (needed by nvidia).
---
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..f59b899b7 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -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,
+ SUSPENDING,
+ RESUMING,
N_SIGNALS
};
@@ -745,6 +749,20 @@ meta_backend_class_init (MetaBackendClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ signals[SUSPENDING] =
+ g_signal_new ("suspending",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+ signals[RESUMING] =
+ g_signal_new ("resuming",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
@@ -768,15 +786,66 @@ meta_backend_create_renderer (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
}
+static void
+inhibit_sleep (MetaBackend *backend)
+{
+ 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;
+
+ if (!login1_manager_call_inhibit_sync (priv->logind_proxy,
+ "sleep",
+ "Display Server",
+ "Prepare for suspend",
+ "delay",
+ NULL,
+ &fd_variant,
+ &fd_list,
+ priv->cancellable,
+ &error))
+ {
+ g_warning ("Failed to inhibit sleep: %s", error->message);
+ return;
+ }
+
+ 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
+uninhibit_sleep (MetaBackend *backend)
+{
+ MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+ close (priv->inhibit_sleep_fd);
+ priv->inhibit_sleep_fd = -1;
+}
+
static void
prepare_for_sleep_cb (MetaBackend *backend,
gboolean suspending)
{
- gboolean suspending;
-
- g_variant_get (parameters, "(b)", &suspending);
- if (suspending)
+ if (suspending) {
+ g_signal_emit (backend, signals[SUSPENDING], 0);
+ uninhibit_sleep (backend);
return;
+ }
+
+ inhibit_sleep (backend);
+ g_signal_emit (backend, signals[RESUMING], 0);
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
}
@@ -803,6 +872,7 @@ system_bus_gotten_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
+ MetaBackend *backend = META_BACKEND (user_data);
MetaBackendPrivate *priv;
g_autoptr (GError) error = NULL;
GDBusConnection *bus;
@@ -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);
+ priv->inhibit_sleep_fd = -1;
if (!priv->logind_proxy)
- g_warning ("Failed to get logind proxy: %s", error->message);
-
- g_signal_connect_object (priv->logind_proxy,
- "prepare-for-sleep",
- G_CALLBACK (prepare_for_sleep_cb),
- user_data,
- G_CONNECT_SWAPPED);
+ {
+ g_warning ("Failed to get logind proxy: %s", error->message);
+ }
+ else
+ {
+ inhibit_sleep (backend);
+ g_signal_connect_object (priv->logind_proxy,
+ "prepare-for-sleep",
+ G_CALLBACK (prepare_for_sleep_cb),
+ user_data,
+ G_CONNECT_SWAPPED);
+ }
}
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

@ -1,118 +0,0 @@
From a4a703c75e208badf78c81558994a249797dbb0a Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Sat, 12 Jan 2019 12:38:01 -0500
Subject: [PATCH 4/9] wayland: force X clients to redraw on resume
On nvidia, the textures backing Xwayland client window contents get
corrupted on suspend. Xwayland currently doesn't handle this situation
itself.
For now, in order to work around this issue, send an empty output
change event to Xwayland. This will cause it to force Expose events
to get sent to all clients and get them to redraw.
---
.../native/meta-monitor-manager-kms.c | 7 +++
src/wayland/meta-wayland-outputs.c | 47 +++++++++++++++++++
src/wayland/meta-wayland-outputs.h | 1 +
3 files changed, 55 insertions(+)
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 9a0364441..7bcceee97 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -60,6 +60,7 @@
#include "clutter/clutter.h"
#include "meta/main.h"
#include "meta/meta-x11-errors.h"
+#include "wayland/meta-wayland-outputs.h"
#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
@@ -505,9 +506,15 @@ void
meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
+ ClutterBackend *clutter_backend = clutter_get_default_backend ();
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
handle_hotplug_event (manager);
+
+ if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
+ meta_wayland_outputs_redraw (meta_wayland_compositor_get_default ());
}
static gboolean
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index 099e87ab9..bc69d699d 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -496,6 +496,53 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
return new_table;
}
+void
+meta_wayland_outputs_redraw (MetaWaylandCompositor *compositor)
+{
+ MetaMonitorManager *monitor_manager;
+ GList *logical_monitors, *l;
+
+ monitor_manager = meta_monitor_manager_get ();
+
+ logical_monitors =
+ meta_monitor_manager_get_logical_monitors (monitor_manager);
+
+ for (l = logical_monitors; l; l = l->next)
+ {
+ MetaLogicalMonitor *logical_monitor = l->data;
+ MetaWaylandOutput *wayland_output;
+ GList *iter;
+
+ if (logical_monitor->winsys_id == 0)
+ continue;
+
+ wayland_output =
+ g_hash_table_lookup (compositor->outputs,
+ GSIZE_TO_POINTER (logical_monitor->winsys_id));
+
+ if (wayland_output == NULL)
+ continue;
+
+ /* Just output a "changes done" event for one of the outputs, with no actual changes.
+ * xwayland takes this as a cue to send expose events to all X clients.
+ */
+ for (iter = wayland_output->resources; iter; iter = iter->next)
+ {
+ struct wl_resource *resource = iter->data;
+ if (wl_resource_get_version (resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
+ wl_output_send_done (resource);
+ }
+
+ for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next)
+ {
+ struct wl_resource *xdg_output = iter->data;
+ zxdg_output_v1_send_done (xdg_output);
+ }
+
+ break;
+ }
+}
+
static void
on_monitors_changed (MetaMonitorManager *monitors,
MetaWaylandCompositor *compositor)
diff --git a/src/wayland/meta-wayland-outputs.h b/src/wayland/meta-wayland-outputs.h
index ff15a81bd..d649e0fa1 100644
--- a/src/wayland/meta-wayland-outputs.h
+++ b/src/wayland/meta-wayland-outputs.h
@@ -49,5 +49,6 @@ struct _MetaWaylandOutput
};
void meta_wayland_outputs_init (MetaWaylandCompositor *compositor);
+void meta_wayland_outputs_redraw (MetaWaylandCompositor *compositor);
#endif /* META_WAYLAND_OUTPUTS_H */
--
2.21.0

View File

@ -1,40 +0,0 @@
From 122d7726e450712b8b2fc85db41e3c8ab7b6ad56 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 10:29:55 -0500
Subject: [PATCH 5/9] backends/native: emit gl-video-memory-purged when
becoming active
The proprietary NVIDIA driver garbles memory on suspend. In order
to work around that limitation, mutter needs to refresh all its
textures on resuem.
This commit lays the way toward doing that by emitting the
"gl-video-memory-purged" signal when the compositor becomes active
by logind (which happens on VT switch and on resume).
---
src/backends/native/meta-backend-native.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index c473681cb..f593197e7 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -653,8 +653,15 @@ void meta_backend_native_resume (MetaBackendNative *native)
meta_backend_get_monitor_manager (backend);
MetaMonitorManagerKms *monitor_manager_kms =
META_MONITOR_MANAGER_KMS (monitor_manager);
+ MetaDisplay *display = meta_get_display ();
+ ClutterBackend *clutter_backend = clutter_get_default_backend ();
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
MetaIdleMonitor *idle_monitor;
+ if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
+ g_signal_emit_by_name (display, "gl-video-memory-purged");
+
meta_monitor_manager_kms_resume (monitor_manager_kms);
clutter_evdev_reclaim_devices ();
--
2.21.0

View File

@ -1,35 +0,0 @@
From 762ffddfa6157fe50bfa394ecbe4ba707d15f368 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 10:29:55 -0500
Subject: [PATCH 6/9] backends/native: update glyph cache on resume
As mentioned in a previous commit, the proprietary NVIDIA
driver garbles memory on suspend. That behavior, means that
clutter's glyph cache (which is stored in GPU memory) gets
corrupted on suspend.
This commit ensures the glyph cache is blown away when
the logind session becomes active (on VT switch and resume).
---
src/backends/native/meta-backend-native.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index f593197e7..db9b63ac4 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -660,7 +660,10 @@ void meta_backend_native_resume (MetaBackendNative *native)
MetaIdleMonitor *idle_monitor;
if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
- g_signal_emit_by_name (display, "gl-video-memory-purged");
+ {
+ clutter_clear_glyph_cache ();
+ g_signal_emit_by_name (display, "gl-video-memory-purged");
+ }
meta_monitor_manager_kms_resume (monitor_manager_kms);
--
2.21.0

View File

@ -1,38 +0,0 @@
From 59ba24c09e5d2a3210ca3d259789f7ba5ae6266a Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 10:29:55 -0500
Subject: [PATCH 7/9] backends/native: update cursor on resume
As mentioned in a previous commit, the proprietary NVIDIA
driver garbles memory on suspend. That behavior, means that
the cursor gets corrupted on suspend.
This commit forces the cursor to redraw itself when the
logind session becomes active (on VT switch and resume).
---
src/backends/native/meta-backend-native.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index db9b63ac4..479e9326b 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -54,6 +54,7 @@
#include "backends/native/meta-renderer-native.h"
#include "backends/native/meta-stage-native.h"
#include "clutter/evdev/clutter-evdev.h"
+#include "core/display-private.h"
#include "core/meta-border.h"
#include "meta/main.h"
@@ -662,6 +663,7 @@ void meta_backend_native_resume (MetaBackendNative *native)
if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
{
clutter_clear_glyph_cache ();
+ meta_display_update_cursor (display);
g_signal_emit_by_name (display, "gl-video-memory-purged");
}
--
2.21.0

View File

@ -1,110 +0,0 @@
From c78a614b0d45a4bc8101a93c7138c9fb6102d13c Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 9 Jan 2019 16:57:05 -0500
Subject: [PATCH 8/9] background: purge all background textures on suspend
This commit makes sure all background textures get purged
on suspend, which is important for nvidia.
---
src/compositor/meta-background-image.c | 28 ++++++++++++++++++++++++++
src/compositor/meta-background.c | 17 +++++++++++++++-
src/meta/meta-background-image.h | 2 ++
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/src/compositor/meta-background-image.c b/src/compositor/meta-background-image.c
index 14d3baf57..98909cb53 100644
--- a/src/compositor/meta-background-image.c
+++ b/src/compositor/meta-background-image.c
@@ -283,6 +283,34 @@ meta_background_image_cache_purge (MetaBackgroundImageCache *cache,
image->in_cache = FALSE;
}
+/**
+ * meta_background_image_cache_unload_all:
+ * @cache: a #MetaBackgroundImageCache
+ *
+ * Remove all entries from the cache and unloads them; this would be used
+ * if textures in video memory have been invalidated.
+ */
+void
+meta_background_image_cache_unload_all (MetaBackgroundImageCache *cache)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache));
+
+ g_hash_table_iter_init (&iter, cache->images);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ MetaBackgroundImage *image = value;
+
+ g_clear_pointer (&image->texture, cogl_object_unref);
+ image->in_cache = FALSE;
+ image->loaded = FALSE;
+ }
+
+ g_hash_table_remove_all (cache->images);
+}
+
G_DEFINE_TYPE (MetaBackgroundImage, meta_background_image, G_TYPE_OBJECT);
static void
diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c
index c033395fe..abdfcc7df 100644
--- a/src/compositor/meta-background.c
+++ b/src/compositor/meta-background.c
@@ -303,6 +303,18 @@ meta_background_finalize (GObject *object)
G_OBJECT_CLASS (meta_background_parent_class)->finalize (object);
}
+static void
+free_textures (MetaBackground *self)
+{
+ free_color_texture (self);
+ free_wallpaper_texture (self);
+
+ set_file (self, &self->file1, &self->background_image1, NULL);
+ set_file (self, &self->file2, &self->background_image2, NULL);
+
+ mark_changed (self);
+}
+
static void
meta_background_constructed (GObject *object)
{
@@ -312,7 +324,7 @@ meta_background_constructed (GObject *object)
G_OBJECT_CLASS (meta_background_parent_class)->constructed (object);
g_signal_connect_object (self->display, "gl-video-memory-purged",
- G_CALLBACK (mark_changed), object, G_CONNECT_SWAPPED);
+ G_CALLBACK (free_textures), object, G_CONNECT_SWAPPED);
g_signal_connect_object (monitor_manager, "monitors-changed",
G_CALLBACK (on_monitors_changed), self,
@@ -950,8 +962,11 @@ meta_background_set_blend (MetaBackground *self,
void
meta_background_refresh_all (void)
{
+ MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
GSList *l;
+ meta_background_image_cache_unload_all (cache);
+
for (l = all_backgrounds; l; l = l->next)
mark_changed (l->data);
}
diff --git a/src/meta/meta-background-image.h b/src/meta/meta-background-image.h
index 137a6ff8e..87e40d251 100644
--- a/src/meta/meta-background-image.h
+++ b/src/meta/meta-background-image.h
@@ -66,4 +66,6 @@ META_EXPORT
void meta_background_image_cache_purge (MetaBackgroundImageCache *cache,
GFile *file);
+void meta_background_image_cache_unload_all (MetaBackgroundImageCache *cache);
+
#endif /* __META_BACKGROUND_IMAGE_H__ */
--
2.21.0

View File

@ -1,712 +0,0 @@
From d8cc418899276b45cb1a787493e0998e3b008fe5 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 10 Jan 2019 10:48:02 -0500
Subject: [PATCH 9/9] MetaShapedTexture: save and restore textures on suspend
The proprietary nvidia driver garbles GPU memory on suspend.
In order to workaround that limitation, this commit copies all
textures to host memory on suspend and restores them on resume.
One complication comes from external textures (such as those
given to us by Xwayland for X clients). We can't just restore
those textures, since they aren't writable.
This commit addresses that complication by keeping a local texture
around for those external textures, and using it instead for parts
of the window that haven't been redrawn since resume.
---
src/compositor/meta-shaped-texture.c | 487 +++++++++++++++++++++++++--
src/meta/meta-shaped-texture.h | 2 +
2 files changed, 468 insertions(+), 21 deletions(-)
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index d64e214e5..ea8daa03d 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -40,7 +40,9 @@
#include "compositor/meta-texture-tower.h"
#include "compositor/region-utils.h"
#include "core/boxes-private.h"
+#include <meta/meta-backend.h>
#include "meta/meta-shaped-texture.h"
+#include "meta-texture-rectangle.h"
/* MAX_MIPMAPPING_FPS needs to be as small as possible for the best GPU
* performance, but higher than the refresh rate of commonly slow updating
@@ -72,8 +74,12 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
+static void disable_backing_store (MetaShapedTexture *stex);
+
static void cullable_iface_init (MetaCullableInterface *iface);
+static gboolean meta_debug_show_backing_store = FALSE;
+
enum
{
SIZE_CHANGED,
@@ -83,6 +89,14 @@ enum
static guint signals[LAST_SIGNAL];
+typedef struct
+{
+ CoglTexture *texture;
+ CoglTexture *mask_texture;
+ cairo_surface_t *mask_surface;
+ cairo_region_t *region;
+} MetaTextureBackingStore;
+
struct _MetaShapedTexture
{
ClutterActor parent;
@@ -114,6 +128,16 @@ struct _MetaShapedTexture
int viewport_dst_width;
int viewport_dst_height;
+ /* textures get corrupted on suspend, so save them */
+ cairo_surface_t *saved_base_surface;
+ cairo_surface_t *saved_mask_surface;
+
+ /* We can't just restore external textures, so we need to track
+ * which parts of the external texture are freshly drawn from
+ * the client after corruption, and fill in the rest from our
+ * saved snapshot */
+ MetaTextureBackingStore *backing_store;
+
int tex_width, tex_height;
int fallback_width, fallback_height;
int dst_width, dst_height;
@@ -148,6 +172,9 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
+
+ if (g_getenv ("MUTTER_DEBUG_BACKING_STORE"))
+ meta_debug_show_backing_store = TRUE;
}
static void
@@ -159,6 +186,11 @@ invalidate_size (MetaShapedTexture *stex)
static void
meta_shaped_texture_init (MetaShapedTexture *stex)
{
+ MetaBackend *backend = meta_get_backend ();
+ ClutterBackend *clutter_backend = clutter_get_default_backend ();
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
+
stex->paint_tower = meta_texture_tower_new ();
stex->texture = NULL;
@@ -171,6 +203,12 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
"notify::scale-x",
G_CALLBACK (invalidate_size),
stex);
+
+ if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
+ {
+ g_signal_connect_object (backend, "suspending", G_CALLBACK (meta_shaped_texture_save), stex, G_CONNECT_SWAPPED);
+ g_signal_connect_object (backend, "resuming", G_CALLBACK (meta_shaped_texture_restore), stex, G_CONNECT_SWAPPED);
+ }
}
static void
@@ -311,24 +349,72 @@ meta_shaped_texture_dispose (GObject *object)
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
}
+static int
+get_layer_indices (MetaShapedTexture *stex,
+ int *main_layer_index,
+ int *backing_mask_layer_index,
+ int *backing_layer_index,
+ int *mask_layer_index)
+{
+ int next_layer_index = 0;
+
+ if (main_layer_index)
+ *main_layer_index = next_layer_index;
+
+ next_layer_index++;
+
+ if (stex->backing_store)
+ {
+ if (backing_mask_layer_index)
+ *backing_mask_layer_index = next_layer_index;
+ next_layer_index++;
+ if (backing_layer_index)
+ *backing_layer_index = next_layer_index;
+ next_layer_index++;
+ }
+ else
+ {
+ if (backing_mask_layer_index)
+ *backing_mask_layer_index = -1;
+ if (backing_layer_index)
+ *backing_layer_index = -1;
+ }
+
+ if (mask_layer_index)
+ *mask_layer_index = next_layer_index;
+
+ return next_layer_index;
+}
+
static CoglPipeline *
get_base_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
+ int main_layer_index;
+ int backing_layer_index;
+ int backing_mask_layer_index;
+ int i, number_of_layers;
if (stex->base_pipeline)
return stex->base_pipeline;
pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+
+ number_of_layers = get_layer_indices (stex,
+ &main_layer_index,
+ &backing_mask_layer_index,
+ &backing_layer_index,
+ NULL);
+
+ for (i = 0; i < number_of_layers; i++)
+ {
+ cogl_pipeline_set_layer_wrap_mode_s (pipeline, i,
+ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+ cogl_pipeline_set_layer_wrap_mode_t (pipeline, i,
+ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+ }
+
if (!stex->is_y_inverted)
{
CoglMatrix matrix;
@@ -336,7 +422,22 @@ get_base_pipeline (MetaShapedTexture *stex,
cogl_matrix_init_identity (&matrix);
cogl_matrix_scale (&matrix, 1, -1, 1);
cogl_matrix_translate (&matrix, 0, -1, 0);
- cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
+ cogl_pipeline_set_layer_matrix (pipeline, main_layer_index, &matrix);
+ }
+
+ if (stex->backing_store)
+ {
+ g_autofree char *backing_description = NULL;
+ cogl_pipeline_set_layer_combine (pipeline, backing_mask_layer_index,
+ "RGBA = REPLACE(PREVIOUS)",
+ NULL);
+ backing_description = g_strdup_printf ("RGBA = INTERPOLATE(PREVIOUS, TEXTURE_%d, TEXTURE_%d[A])",
+ backing_layer_index,
+ backing_mask_layer_index);
+ cogl_pipeline_set_layer_combine (pipeline,
+ backing_layer_index,
+ backing_description,
+ NULL);
}
if (stex->transform != META_MONITOR_TRANSFORM_NORMAL)
@@ -379,7 +480,7 @@ get_base_pipeline (MetaShapedTexture *stex,
}
if (stex->snippet)
- cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
+ cogl_pipeline_add_layer_snippet (pipeline, main_layer_index, stex->snippet);
stex->base_pipeline = pipeline;
@@ -398,12 +499,15 @@ get_masked_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
+ int mask_layer_index;
if (stex->masked_pipeline)
return stex->masked_pipeline;
+ get_layer_indices (stex, NULL, NULL, NULL, &mask_layer_index);
+
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 1,
+ cogl_pipeline_set_layer_combine (pipeline, mask_layer_index,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
@@ -517,6 +621,8 @@ set_cogl_texture (MetaShapedTexture *stex,
if (stex->texture)
cogl_object_unref (stex->texture);
+ g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
+
stex->texture = cogl_tex;
if (cogl_tex != NULL)
@@ -579,6 +685,10 @@ do_paint (MetaShapedTexture *stex,
CoglContext *ctx;
ClutterActorBox alloc;
CoglPipelineFilter filter;
+ int main_layer_index;
+ int backing_mask_layer_index;
+ int backing_layer_index;
+ int mask_layer_index;
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
ensure_size_valid (stex);
@@ -665,6 +775,12 @@ do_paint (MetaShapedTexture *stex,
}
}
+ get_layer_indices (stex,
+ &main_layer_index,
+ &backing_mask_layer_index,
+ &backing_layer_index,
+ &mask_layer_index);
+
/* First, paint the unblended parts, which are part of the opaque region. */
if (use_opaque_region)
{
@@ -686,8 +802,24 @@ do_paint (MetaShapedTexture *stex,
if (!cairo_region_is_empty (region))
{
opaque_pipeline = get_unblended_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
+ cogl_pipeline_set_layer_texture (opaque_pipeline, main_layer_index, paint_tex);
+ cogl_pipeline_set_layer_filters (opaque_pipeline, main_layer_index, filter, filter);
+
+ if (stex->backing_store)
+ {
+ cogl_pipeline_set_layer_texture (opaque_pipeline,
+ backing_mask_layer_index,
+ stex->backing_store->mask_texture);
+ cogl_pipeline_set_layer_filters (opaque_pipeline,
+ backing_mask_layer_index,
+ filter, filter);
+ cogl_pipeline_set_layer_texture (opaque_pipeline,
+ backing_layer_index,
+ stex->backing_store->texture);
+ cogl_pipeline_set_layer_filters (opaque_pipeline,
+ backing_layer_index,
+ filter, filter);
+ }
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
@@ -726,12 +858,28 @@ do_paint (MetaShapedTexture *stex,
else
{
blended_pipeline = get_masked_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
- cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
+ cogl_pipeline_set_layer_texture (blended_pipeline, mask_layer_index, stex->mask_texture);
+ cogl_pipeline_set_layer_filters (blended_pipeline, mask_layer_index, filter, filter);
}
- cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
+ cogl_pipeline_set_layer_texture (blended_pipeline, main_layer_index, paint_tex);
+ cogl_pipeline_set_layer_filters (blended_pipeline, main_layer_index, filter, filter);
+
+ if (stex->backing_store)
+ {
+ cogl_pipeline_set_layer_texture (blended_pipeline,
+ backing_mask_layer_index,
+ stex->backing_store->mask_texture);
+ cogl_pipeline_set_layer_filters (blended_pipeline,
+ backing_mask_layer_index,
+ filter, filter);
+ cogl_pipeline_set_layer_texture (blended_pipeline,
+ backing_layer_index,
+ stex->backing_store->texture);
+ cogl_pipeline_set_layer_filters (blended_pipeline,
+ backing_layer_index,
+ filter, filter);
+ }
CoglColor color;
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
@@ -925,6 +1073,7 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
g_clear_pointer (&stex->mask_texture, cogl_object_unref);
+ g_clear_pointer (&stex->saved_mask_surface, cairo_surface_destroy);
if (mask_texture != NULL)
{
@@ -946,6 +1095,65 @@ meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
return FALSE;
}
+static void
+meta_texture_backing_store_redraw_mask (MetaTextureBackingStore *backing_store)
+{
+ CoglError *error = NULL;
+
+ if (!cogl_texture_set_data (backing_store->mask_texture, COGL_PIXEL_FORMAT_A_8,
+ cairo_image_surface_get_stride (backing_store->mask_surface),
+ cairo_image_surface_get_data (backing_store->mask_surface), 0,
+ &error))
+ {
+
+ g_warning ("Failed to update backing mask texture");
+ g_clear_pointer (&error, cogl_error_free);
+ }
+}
+
+static gboolean
+meta_texture_backing_store_shrink (MetaTextureBackingStore *backing_store,
+ const cairo_rectangle_int_t *area)
+{
+ cairo_t *cr;
+
+ cairo_region_subtract_rectangle (backing_store->region, area);
+
+ /* If the client has finally redrawn the entire surface, we can
+ * ditch our snapshot
+ */
+ if (cairo_region_is_empty (backing_store->region))
+ return FALSE;
+
+ cr = cairo_create (backing_store->mask_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ gdk_cairo_region (cr, backing_store->region);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+
+ meta_texture_backing_store_redraw_mask (backing_store);
+
+ return TRUE;
+}
+
+static void
+shrink_backing_region (MetaShapedTexture *stex,
+ const cairo_rectangle_int_t *area)
+{
+ gboolean still_backing_texture;
+
+ if (!stex->backing_store)
+ return;
+
+ still_backing_texture =
+ meta_texture_backing_store_shrink (stex->backing_store, area);
+
+ if (!still_backing_texture)
+ disable_backing_store (stex);
+}
+
/**
* meta_shaped_texture_update_area:
* @stex: #MetaShapedTexture
@@ -1041,6 +1249,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
&clip);
}
+ shrink_backing_region (stex, &clip);
+
meta_texture_tower_update_area (stex->paint_tower,
clip.x,
clip.y,
@@ -1268,8 +1478,9 @@ should_get_via_offscreen (MetaShapedTexture *stex)
}
static cairo_surface_t *
-get_image_via_offscreen (MetaShapedTexture *stex,
- cairo_rectangle_int_t *clip)
+get_image_via_offscreen (MetaShapedTexture *stex,
+ cairo_rectangle_int_t *clip,
+ CoglTexture **texture)
{
ClutterBackend *clutter_backend = clutter_get_default_backend ();
CoglContext *cogl_context =
@@ -1340,9 +1551,29 @@ get_image_via_offscreen (MetaShapedTexture *stex,
clip->width, clip->height,
CLUTTER_CAIRO_FORMAT_ARGB32,
cairo_image_surface_get_data (surface));
+ cairo_surface_mark_dirty (surface);
+
+ if (texture)
+ {
+ *texture = cogl_object_ref (image_texture);
+
+ if (G_UNLIKELY (meta_debug_show_backing_store))
+ {
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.75);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+ }
+
+ cogl_texture_set_data (*texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (surface),
+ cairo_image_surface_get_data (surface), 0, NULL);
+ }
+
cogl_object_unref (fb);
- cairo_surface_mark_dirty (surface);
return surface;
}
@@ -1404,7 +1635,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
}
if (should_get_via_offscreen (stex))
- return get_image_via_offscreen (stex, transformed_clip);
+ return get_image_via_offscreen (stex, transformed_clip, NULL);
if (transformed_clip)
texture = cogl_texture_new_from_sub_texture (texture,
@@ -1465,6 +1696,220 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
return surface;
}
+static void
+meta_texture_backing_store_free (MetaTextureBackingStore *backing_store)
+{
+ g_clear_pointer (&backing_store->texture, cogl_object_unref);
+ g_clear_pointer (&backing_store->mask_texture, cogl_object_unref);
+ g_clear_pointer (&backing_store->mask_surface, cairo_surface_destroy);
+ g_clear_pointer (&backing_store->region, cairo_region_destroy);
+
+ g_slice_free (MetaTextureBackingStore, backing_store);
+}
+
+static MetaTextureBackingStore *
+meta_texture_backing_store_new (CoglTexture *texture)
+{
+ MetaTextureBackingStore *backing_store = NULL;
+ ClutterBackend *backend = clutter_get_default_backend ();
+ CoglContext *context = clutter_backend_get_cogl_context (backend);
+ CoglTexture *mask_texture = NULL;
+ guchar *mask_data;
+ int width, height, stride;
+ cairo_surface_t *surface;
+ cairo_region_t *region;
+ cairo_rectangle_int_t backing_rectangle;
+
+ width = cogl_texture_get_width (texture);
+ height = cogl_texture_get_height (texture);
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, width);
+
+ /* we start off by only letting the backing texture through, and none of the real texture */
+ backing_rectangle.x = 0;
+ backing_rectangle.y = 0;
+ backing_rectangle.width = width;
+ backing_rectangle.height = height;
+
+ region = cairo_region_create_rectangle (&backing_rectangle);
+
+ /* initialize mask to transparent, so the entire backing store shows through
+ * up front
+ */
+ mask_data = g_malloc0 (stride * height);
+ surface = cairo_image_surface_create_for_data (mask_data,
+ CAIRO_FORMAT_A8,
+ width,
+ height,
+ stride);
+
+ if (meta_texture_rectangle_check (texture))
+ {
+ mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (context,
+ width,
+ height));
+ cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A);
+ cogl_texture_set_region (mask_texture,
+ 0, 0,
+ 0, 0,
+ width, height,
+ width, height,
+ COGL_PIXEL_FORMAT_A_8,
+ stride, mask_data);
+ }
+ else
+ {
+ CoglError *error = NULL;
+
+ mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (context, width, height,
+ COGL_PIXEL_FORMAT_A_8,
+ stride, mask_data, &error));
+
+ if (error)
+ {
+ g_warning ("Failed to allocate mask texture: %s", error->message);
+ cogl_error_free (error);
+ }
+ }
+
+ if (mask_texture)
+ {
+ backing_store = g_slice_new0 (MetaTextureBackingStore);
+ backing_store->texture = cogl_object_ref (texture);
+ backing_store->mask_texture = mask_texture;
+ backing_store->mask_surface = surface;
+ backing_store->region = region;
+ }
+
+ return backing_store;
+}
+
+static void
+enable_backing_store (MetaShapedTexture *stex,
+ CoglTexture *texture)
+{
+ g_clear_pointer (&stex->backing_store, meta_texture_backing_store_free);
+
+ stex->backing_store = meta_texture_backing_store_new (texture);
+
+ meta_shaped_texture_reset_pipelines (stex);
+}
+
+static void
+disable_backing_store (MetaShapedTexture *stex)
+{
+ g_clear_pointer (&stex->backing_store, meta_texture_backing_store_free);
+
+ meta_shaped_texture_reset_pipelines (stex);
+}
+
+void
+meta_shaped_texture_save (MetaShapedTexture *stex)
+{
+
+ CoglTexture *texture, *mask_texture;
+ cairo_surface_t *surface;
+
+ g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
+
+ texture = COGL_TEXTURE (stex->texture);
+
+ if (texture == NULL)
+ return;
+
+ g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
+ g_clear_pointer (&stex->saved_mask_surface, cairo_surface_destroy);
+ g_clear_pointer (&stex->backing_store, meta_texture_backing_store_free);
+
+ if (should_get_via_offscreen (stex))
+ {
+ CoglTexture *backing_texture;
+
+ meta_shaped_texture_reset_pipelines (stex);
+
+ surface = get_image_via_offscreen (stex, NULL, &backing_texture);
+
+ enable_backing_store (stex, backing_texture);
+ cogl_object_unref (backing_texture);
+ }
+ else
+ {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cogl_texture_get_width (texture),
+ cogl_texture_get_height (texture));
+
+ cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (surface),
+ cairo_image_surface_get_data (surface));
+ }
+
+ stex->saved_base_surface = surface;
+
+ mask_texture = stex->mask_texture;
+ if (mask_texture != NULL)
+ {
+ cairo_surface_t *mask_surface;
+
+ mask_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cogl_texture_get_width (mask_texture),
+ cogl_texture_get_height (mask_texture));
+
+ cogl_texture_get_data (mask_texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (mask_surface),
+ cairo_image_surface_get_data (mask_surface));
+
+ cairo_surface_mark_dirty (mask_surface);
+
+ stex->saved_mask_surface = mask_surface;
+ }
+}
+
+void
+meta_shaped_texture_restore (MetaShapedTexture *stex)
+{
+ CoglTexture *texture;
+ CoglError *error = NULL;
+
+ texture = meta_shaped_texture_get_texture (stex);
+
+ if (texture == NULL)
+ return;
+
+ if (stex->mask_texture)
+ {
+ if (!cogl_texture_set_data (stex->mask_texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (stex->saved_mask_surface),
+ cairo_image_surface_get_data (stex->saved_mask_surface), 0,
+ &error))
+ {
+ g_warning ("Failed to restore mask texture");
+ g_clear_pointer (&error, cogl_error_free);
+ }
+ g_clear_pointer (&stex->saved_mask_surface, cairo_surface_destroy);
+ }
+
+ /* if the main texture doesn't support direct writes, then
+ * write to the local backing texture instead, and blend old
+ * versus new at paint time.
+ */
+ if (stex->backing_store)
+ {
+ meta_texture_backing_store_redraw_mask (stex->backing_store);
+ texture = stex->backing_store->texture;
+ }
+
+ if (!cogl_texture_set_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (stex->saved_base_surface),
+ cairo_image_surface_get_data (stex->saved_base_surface), 0,
+ &error))
+ {
+ g_warning ("Failed to restore texture");
+ g_clear_pointer (&error, cogl_error_free);
+ }
+ g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
+
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
+}
+
void
meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
int fallback_width,
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index c36b8547f..22b4fbd53 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -66,6 +66,8 @@ META_EXPORT
cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_rectangle_int_t *clip);
+void meta_shaped_texture_save (MetaShapedTexture *self);
+void meta_shaped_texture_restore (MetaShapedTexture *self);
G_END_DECLS
#endif /* __META_SHAPED_TEXTURE_H__ */
--
2.21.0

View File

@ -8,7 +8,7 @@
Name: mutter Name: mutter
Version: 3.32.2 Version: 3.32.2
Release: 34%{?dist} Release: 35%{?dist}
Summary: Window and compositing manager based on Clutter Summary: Window and compositing manager based on Clutter
License: GPLv2+ License: GPLv2+
@ -28,17 +28,6 @@ Patch3: covscan-fixes.patch
Patch4: 0001-enum-types-Use-basename-in-header-comment.patch Patch4: 0001-enum-types-Use-basename-in-header-comment.patch
Patch5: 0001-workspace-manager-Expose-layout-properties.patch Patch5: 0001-workspace-manager-Expose-layout-properties.patch
# Fix corruption on suspend and resume with nvidia (rhbz#1663440)
Patch10001: 0001-cogl-add-new-UNSTABLE_TEXTURES-feature.patch
Patch10002: 0002-backend-switch-to-using-generated-logind-proxy.patch
Patch10003: 0003-backend-add-signals-for-reporting-suspend-and-resume.patch
Patch10004: 0004-wayland-force-X-clients-to-redraw-on-resume.patch
Patch10005: 0005-backends-native-emit-gl-video-memory-purged-when-bec.patch
Patch10006: 0006-backends-native-update-glyph-cache-on-resume.patch
Patch10007: 0007-backends-native-update-cursor-on-resume.patch
Patch10008: 0008-background-purge-all-background-textures-on-suspend.patch
Patch10009: 0009-MetaShapedTexture-save-and-restore-textures-on-suspe.patch
# RHEL 7 downstream patches # RHEL 7 downstream patches
Patch100: deal-more-gracefully-with-oversized-windows.patch Patch100: deal-more-gracefully-with-oversized-windows.patch
# Work-around for Xvnc resizing (rhbz#1265511) # Work-around for Xvnc resizing (rhbz#1265511)
@ -263,6 +252,10 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop
%{_datadir}/mutter-%{mutter_api_version}/tests %{_datadir}/mutter-%{mutter_api_version}/tests
%changelog %changelog
* Mon Mar 23 2020 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-35
- Drop EGLStream robustness patches
Resolves: #1821198
* Thu Mar 05 2020 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-34 * Thu Mar 05 2020 Jonas Ådahl <jadahl@redhat.com> - 3.32.2-34
- gnome-shell core dump after connection to docking station - gnome-shell core dump after connection to docking station
Resolves: #1809079 Resolves: #1809079