import mutter-3.32.2-35.el8_2
This commit is contained in:
parent
24a5739380
commit
dc2087df87
@ -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>
|
||||
Date: Thu, 8 May 2014 18:44:15 -0400
|
||||
Subject: [PATCH] Add support for quad-buffer stereo
|
||||
@ -265,10 +265,10 @@ 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..9a00ccd6d 100644
|
||||
index d64e214e5..e77a32109 100644
|
||||
--- a/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;
|
||||
|
||||
MetaTextureTower *paint_tower;
|
||||
@ -279,15 +279,15 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
CoglTexture *mask_texture;
|
||||
CoglSnippet *snippet;
|
||||
|
||||
@@ -192,6 +194,7 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
|
||||
clutter_backend_get_cogl_context (clutter_backend);
|
||||
|
||||
@@ -160,6 +162,7 @@ static void
|
||||
meta_shaped_texture_init (MetaShapedTexture *stex)
|
||||
{
|
||||
stex->paint_tower = meta_texture_tower_new ();
|
||||
+ stex->paint_tower_right = NULL; /* demand create */
|
||||
|
||||
stex->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);
|
||||
stex->paint_tower = NULL;
|
||||
|
||||
@ -297,7 +297,7 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
g_clear_pointer (&stex->texture, cogl_object_unref);
|
||||
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
|
||||
@ -309,21 +309,19 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
{
|
||||
int width, height;
|
||||
|
||||
@@ -620,10 +627,13 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
@@ -516,8 +523,11 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
|
||||
if (stex->texture)
|
||||
cogl_object_unref (stex->texture);
|
||||
+ if (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_right = cogl_tex_right;
|
||||
|
||||
if (cogl_tex != NULL)
|
||||
{
|
||||
@@ -637,6 +647,9 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
@@ -531,6 +541,9 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
height = 0;
|
||||
}
|
||||
|
||||
@ -333,7 +331,7 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
if (stex->tex_width != width ||
|
||||
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
|
||||
* damage. */
|
||||
|
||||
@ -358,7 +356,7 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
}
|
||||
|
||||
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);
|
||||
CoglTexture *paint_tex;
|
||||
@ -368,7 +366,7 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
|
||||
if (!stex->texture)
|
||||
return;
|
||||
@@ -989,7 +1019,32 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
@@ -841,7 +871,32 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
return;
|
||||
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
@ -402,7 +400,7 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
}
|
||||
|
||||
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;
|
||||
base_texture = create_mipmaps ? stex->texture : NULL;
|
||||
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.width,
|
||||
clip.height);
|
||||
@ -428,7 +426,7 @@ index ea8daa03d..9a00ccd6d 100644
|
||||
|
||||
stex->prev_invalidation = stex->last_invalidation;
|
||||
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);
|
||||
g_clear_pointer (&snippet, cogl_object_unref);
|
||||
--
|
||||
2.23.0
|
||||
2.25.1
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
Name: mutter
|
||||
Version: 3.32.2
|
||||
Release: 34%{?dist}
|
||||
Release: 35%{?dist}
|
||||
Summary: Window and compositing manager based on Clutter
|
||||
|
||||
License: GPLv2+
|
||||
@ -28,17 +28,6 @@ Patch3: covscan-fixes.patch
|
||||
Patch4: 0001-enum-types-Use-basename-in-header-comment.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
|
||||
Patch100: deal-more-gracefully-with-oversized-windows.patch
|
||||
# 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
|
||||
|
||||
%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
|
||||
- gnome-shell core dump after connection to docking station
|
||||
Resolves: #1809079
|
||||
|
Loading…
Reference in New Issue
Block a user