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 <daniel.van.v...@canonical.com>  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 <daniel.van.v...@canonical.com>
+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
ubuntu-desktop@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-desktop

Reply via email to