Daniel van Vugt has proposed merging
~vanvugt/ubuntu/+source/mutter:fix-1809407-eoan into
~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/master.
Commit message:
Fix wallpaper corruption on resume from suspend on Nvidia
https://bugs.launchpad.net/bugs/1809407
Requested reviews:
Ubuntu Desktop (ubuntu-desktop)
Related bugs:
Bug #1809407 in mutter (Ubuntu): "[nvidia] Corrupted wallpaper after resuming
from suspend"
https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1809407
For more details, see:
https://code.launchpad.net/~vanvugt/ubuntu/+source/mutter/+git/mutter/+merge/368536
--
Your team Ubuntu Desktop is requested to review the proposed merge of
~vanvugt/ubuntu/+source/mutter:fix-1809407-eoan into
~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/master.
diff --git a/debian/changelog b/debian/changelog
index dd565d9..2c7c657 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+mutter (3.32.2-1ubuntu2) eoan; urgency=medium
+
+ * Add fix-lp1809407-3.32.patch to fix background wallpaper corruption on
+ Nvidia when resuming from suspend (LP: #1809407)
+
+ -- Daniel van Vugt <[email protected]> Fri, 07 Jun 2019 18:01:23 +0800
+
mutter (3.32.2-1ubuntu1) eoan; urgency=medium
* Merge with debian. Remaining changes:
diff --git a/debian/patches/fix-lp1809407-3.32.patch b/debian/patches/fix-lp1809407-3.32.patch
new file mode 100644
index 0000000..ef3177b
--- /dev/null
+++ b/debian/patches/fix-lp1809407-3.32.patch
@@ -0,0 +1,234 @@
+Description: Refresh desktop wallpaper upon resume from suspend
+ The Nvidia driver loses/corrupts its texture memory upon resuming from
+ suspend. This is a *feature* that is officially documented in OpenGL
+ extension "NV_robustness_video_memory_purge". To accomodate this we need
+ to refresh textures kept long-term in GPU memory, most noticeably the
+ desktop wallpaper and clutter canvases like the rounded panel corners
+ (if enabled).
+Author: Daniel van Vugt <[email protected]>
+Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/600
+Bug: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1084
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1809407
+Forwarded: yes
+Last-Update: 2019-06-07
+
+diff --git a/clutter/clutter/clutter-canvas.c b/clutter/clutter/clutter-canvas.c
+index b0f1f080c..e7b8de87e 100644
+--- a/clutter/clutter/clutter-canvas.c
++++ b/clutter/clutter/clutter-canvas.c
+@@ -76,6 +76,8 @@ struct _ClutterCanvasPrivate
+ gboolean dirty;
+
+ CoglBitmap *buffer;
++
++ ClutterStage *stage;
+ };
+
+ enum
+@@ -129,6 +131,14 @@ clutter_cairo_context_draw_marshaller (GClosure *closure,
+ cairo_restore (cr);
+ }
+
++static void
++clutter_canvas_dispose (GObject *gobject)
++{
++ ClutterCanvasPrivate *priv = CLUTTER_CANVAS (gobject)->priv;
++
++ g_clear_object (&priv->stage);
++}
++
+ static void
+ clutter_canvas_finalize (GObject *gobject)
+ {
+@@ -312,6 +322,7 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
+
+ gobject_class->set_property = clutter_canvas_set_property;
+ gobject_class->get_property = clutter_canvas_get_property;
++ gobject_class->dispose = clutter_canvas_dispose;
+ gobject_class->finalize = clutter_canvas_finalize;
+
+ g_object_class_install_properties (gobject_class, LAST_PROP, obj_props);
+@@ -327,6 +338,12 @@ clutter_canvas_init (ClutterCanvas *self)
+ self->priv->scale_factor = 1.0f;
+ }
+
++static void
++clutter_canvas_video_memory_purged (ClutterCanvas *self)
++{
++ clutter_content_invalidate (CLUTTER_CONTENT (self));
++}
++
+ static void
+ clutter_canvas_paint_content (ClutterContent *content,
+ ClutterActor *actor,
+@@ -335,6 +352,7 @@ clutter_canvas_paint_content (ClutterContent *content,
+ ClutterCanvas *self = CLUTTER_CANVAS (content);
+ ClutterCanvasPrivate *priv = self->priv;
+ ClutterPaintNode *node;
++ ClutterActor *stage;
+
+ if (priv->buffer == NULL)
+ return;
+@@ -356,6 +374,17 @@ clutter_canvas_paint_content (ClutterContent *content,
+ clutter_paint_node_unref (node);
+
+ priv->dirty = FALSE;
++
++ stage = clutter_actor_get_stage (actor);
++ if (stage != (ClutterActor *) priv->stage)
++ {
++ g_set_object (&priv->stage, CLUTTER_STAGE (stage));
++
++ g_signal_connect_object (stage, "gl-video-memory-purged",
++ G_CALLBACK (clutter_canvas_video_memory_purged),
++ self,
++ G_CONNECT_SWAPPED);
++ }
+ }
+
+ static void
+diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
+index 1eea5b305..a83d27b65 100644
+--- a/clutter/clutter/clutter-stage.c
++++ b/clutter/clutter/clutter-stage.c
+@@ -192,6 +192,7 @@ enum
+ DELETE_EVENT,
+ AFTER_PAINT,
+ PRESENTED,
++ GL_VIDEO_MEMORY_PURGED,
+
+ LAST_SIGNAL
+ };
+@@ -2268,6 +2269,22 @@ clutter_stage_class_init (ClutterStageClass *klass)
+ G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_POINTER);
+
++ /**
++ * ClutterStage::gl-video-memory-purged: (skip)
++ * @stage: the stage that received the event
++ *
++ * Signals that the underlying GL driver has had its texture memory purged
++ * so anything presently held in texture memory is now invalidated, and
++ * likely corrupt. It needs redrawing.
++ */
++ stage_signals[GL_VIDEO_MEMORY_PURGED] =
++ g_signal_new (I_("gl-video-memory-purged"),
++ G_TYPE_FROM_CLASS (gobject_class),
++ G_SIGNAL_RUN_LAST,
++ 0,
++ NULL, NULL, NULL,
++ G_TYPE_NONE, 0);
++
+ klass->fullscreen = clutter_stage_real_fullscreen;
+ klass->activate = clutter_stage_real_activate;
+ klass->deactivate = clutter_stage_real_deactivate;
+diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
+index 2a2c8fb3b..efcc0a882 100644
+--- a/src/compositor/compositor.c
++++ b/src/compositor/compositor.c
+@@ -1266,6 +1266,7 @@ meta_post_paint_func (gpointer data)
+
+ case COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET:
+ g_signal_emit_by_name (compositor->display, "gl-video-memory-purged");
++ g_signal_emit_by_name (compositor->stage , "gl-video-memory-purged");
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (compositor->stage));
+ break;
+
+diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c
+index c033395fe..387ce5dd3 100644
+--- a/src/compositor/meta-background.c
++++ b/src/compositor/meta-background.c
+@@ -252,12 +252,11 @@ static void
+ set_file (MetaBackground *self,
+ GFile **filep,
+ MetaBackgroundImage **imagep,
+- GFile *file)
++ GFile *file,
++ gboolean force_reload)
+ {
+- if (!file_equal0 (*filep, file))
++ if (force_reload || !file_equal0 (*filep, file))
+ {
+- g_clear_object (filep);
+-
+ if (*imagep)
+ {
+ g_signal_handlers_disconnect_by_func (*imagep,
+@@ -267,11 +266,12 @@ set_file (MetaBackground *self,
+ *imagep = NULL;
+ }
+
++ g_set_object (filep, file);
++
+ if (file)
+ {
+ MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
+
+- *filep = g_object_ref (file);
+ *imagep = meta_background_image_cache_load (cache, file);
+ g_signal_connect (*imagep, "loaded",
+ G_CALLBACK (on_background_loaded), self);
+@@ -279,6 +279,32 @@ set_file (MetaBackground *self,
+ }
+ }
+
++static void
++on_gl_video_memory_purged (MetaBackground *self)
++{
++ MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
++
++ /* The GPU memory that just got invalidated is the texture inside
++ * self->background_image1,2 and/or its mipmaps. However, to save memory the
++ * original pixbuf isn't kept in RAM so we can't do a simple re-upload. The
++ * only copy of the image was the one in texture memory that got invalidated.
++ * So we need to do a full reload from disk.
++ */
++ if (self->file1)
++ {
++ meta_background_image_cache_purge (cache, self->file1);
++ set_file (self, &self->file1, &self->background_image1, self->file1, TRUE);
++ }
++
++ if (self->file2)
++ {
++ meta_background_image_cache_purge (cache, self->file2);
++ set_file (self, &self->file2, &self->background_image2, self->file2, TRUE);
++ }
++
++ mark_changed (self);
++}
++
+ static void
+ meta_background_dispose (GObject *object)
+ {
+@@ -287,8 +313,8 @@ meta_background_dispose (GObject *object)
+ 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);
++ set_file (self, &self->file1, &self->background_image1, NULL, FALSE);
++ set_file (self, &self->file2, &self->background_image2, NULL, FALSE);
+
+ set_display (self, NULL);
+
+@@ -312,7 +338,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 (on_gl_video_memory_purged), object, G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (monitor_manager, "monitors-changed",
+ G_CALLBACK (on_monitors_changed), self,
+@@ -937,8 +963,8 @@ meta_background_set_blend (MetaBackground *self,
+ g_return_if_fail (META_IS_BACKGROUND (self));
+ g_return_if_fail (blend_factor >= 0.0 && blend_factor <= 1.0);
+
+- set_file (self, &self->file1, &self->background_image1, file1);
+- set_file (self, &self->file2, &self->background_image2, file2);
++ set_file (self, &self->file1, &self->background_image1, file1, FALSE);
++ set_file (self, &self->file2, &self->background_image2, file2, FALSE);
+
+ self->blend_factor = blend_factor;
+ self->style = style;
diff --git a/debian/patches/series b/debian/patches/series
index 5e2b370..cd3cd05 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,4 @@ theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch
meson-add-back-default_driver-option.patch
debian/synaptics-support.patch
x11-Add-support-for-fractional-scaling-using-Randr.patch
+fix-lp1809407-3.32.patch
--
ubuntu-desktop mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-desktop