Blame SOURCES/0004-wayland-force-X-clients-to-redraw-on-resume.patch

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