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

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