kathenas / rpms / mutter

Forked from rpms/mutter 5 years ago
Clone

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

776610
From d20f20c9d4c52b7a96d5c879df5fe322a0ca356c Mon Sep 17 00:00:00 2001
776610
From: Ray Strode <rstrode@redhat.com>
776610
Date: Sat, 12 Jan 2019 12:38:01 -0500
776610
Subject: [PATCH 4/9] wayland: force X clients to redraw on resume
776610
776610
On nvidia, the textures backing Xwayland client window contents get
776610
corrupted on suspend.  Xwayland currently doesn't handle this situation
776610
itself.
776610
776610
For now, in order to work around this issue, send an empty output
776610
change event to Xwayland.  This will cause it to force Expose events
776610
to get sent to all clients and get them to redraw.
776610
---
776610
 .../native/meta-monitor-manager-kms.c         |  7 +++
776610
 src/wayland/meta-wayland-outputs.c            | 47 +++++++++++++++++++
776610
 src/wayland/meta-wayland-outputs.h            |  1 +
776610
 3 files changed, 55 insertions(+)
776610
776610
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
776610
index 438069110..f9a9e1c6d 100644
776610
--- a/src/backends/native/meta-monitor-manager-kms.c
776610
+++ b/src/backends/native/meta-monitor-manager-kms.c
776610
@@ -7,60 +7,61 @@
776610
  * modify it under the terms of the GNU General Public License as
776610
  * published by the Free Software Foundation; either version 2 of the
776610
  * License, or (at your option) any later version.
776610
  *
776610
  * This program is distributed in the hope that it will be useful, but
776610
  * WITHOUT ANY WARRANTY; without even the implied warranty of
776610
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
776610
  * General Public License for more details.
776610
  *
776610
  * You should have received a copy of the GNU General Public License
776610
  * along with this program; if not, write to the Free Software
776610
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
776610
  * 02111-1307, USA.
776610
  *
776610
  * Author: Giovanni Campagna <gcampagn@redhat.com>
776610
  */
776610
 
776610
 #include "config.h"
776610
 
776610
 #include "meta-monitor-manager-kms.h"
776610
 #include "meta-monitor-config-manager.h"
776610
 #include "meta-backend-native.h"
776610
 #include "meta-crtc.h"
776610
 #include "meta-launcher.h"
776610
 #include "meta-output.h"
776610
 #include "meta-backend-private.h"
776610
 #include "meta-renderer-native.h"
776610
 #include "meta-crtc-kms.h"
776610
 #include "meta-gpu-kms.h"
776610
 #include "meta-output-kms.h"
776610
+#include "wayland/meta-wayland-outputs.h"
776610
 
776610
 #include <string.h>
776610
 #include <stdlib.h>
776610
 #include <clutter/clutter.h>
776610
 
776610
 #include <drm.h>
776610
 #include <errno.h>
776610
 #include <sys/ioctl.h>
776610
 #include <sys/mman.h>
776610
 #include <unistd.h>
776610
 
776610
 #include <meta/main.h>
776610
 #include <meta/errors.h>
776610
 
776610
 #include <gudev/gudev.h>
776610
 
776610
 #define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
776610
 
776610
 typedef struct
776610
 {
776610
   GSource source;
776610
 
776610
   gpointer fd_tag;
776610
   MetaMonitorManagerKms *manager_kms;
776610
 } MetaKmsSource;
776610
 
776610
 struct _MetaMonitorManagerKms
776610
 {
776610
   MetaMonitorManager parent_instance;
776610
 
776610
@@ -388,63 +389,69 @@ on_uevent (GUdevClient *client,
776610
   handle_hotplug_event (manager);
776610
 }
776610
 
776610
 static void
776610
 meta_monitor_manager_kms_connect_uevent_handler (MetaMonitorManagerKms *manager_kms)
776610
 {
776610
   manager_kms->uevent_handler_id = g_signal_connect (manager_kms->udev,
776610
                                                      "uevent",
776610
                                                      G_CALLBACK (on_uevent),
776610
                                                      manager_kms);
776610
 }
776610
 
776610
 static void
776610
 meta_monitor_manager_kms_disconnect_uevent_handler (MetaMonitorManagerKms *manager_kms)
776610
 {
776610
   g_signal_handler_disconnect (manager_kms->udev,
776610
                                manager_kms->uevent_handler_id);
776610
   manager_kms->uevent_handler_id = 0;
776610
 }
776610
 
776610
 void
776610
 meta_monitor_manager_kms_pause (MetaMonitorManagerKms *manager_kms)
776610
 {
776610
   meta_monitor_manager_kms_disconnect_uevent_handler (manager_kms);
776610
 }
776610
 
776610
 void
776610
 meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms)
776610
 {
776610
   MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
776610
+  ClutterBackend *clutter_backend = clutter_get_default_backend ();
776610
+  CoglContext *cogl_context =
776610
+    clutter_backend_get_cogl_context (clutter_backend);
776610
 
776610
   meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
776610
   handle_hotplug_event (manager);
776610
+
776610
+  if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
776610
+    meta_wayland_outputs_redraw (meta_wayland_compositor_get_default ());
776610
 }
776610
 
776610
 static gboolean
776610
 meta_monitor_manager_kms_is_transform_handled (MetaMonitorManager  *manager,
776610
                                                MetaCrtc            *crtc,
776610
                                                MetaMonitorTransform transform)
776610
 {
776610
   return meta_crtc_kms_is_transform_handled (crtc, transform);
776610
 }
776610
 
776610
 static float
776610
 meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manager,
776610
                                                        MetaMonitor        *monitor,
776610
                                                        MetaMonitorMode    *monitor_mode)
776610
 {
776610
   return meta_monitor_calculate_mode_scale (monitor, monitor_mode);
776610
 }
776610
 
776610
 static float *
776610
 meta_monitor_manager_kms_calculate_supported_scales (MetaMonitorManager          *manager,
776610
                                                      MetaLogicalMonitorLayoutMode layout_mode,
776610
                                                      MetaMonitor                 *monitor,
776610
                                                      MetaMonitorMode             *monitor_mode,
776610
                                                      int                         *n_supported_scales)
776610
 {
776610
   MetaMonitorScalesConstraint constraints =
776610
     META_MONITOR_SCALES_CONSTRAINT_NONE;
776610
 
776610
   switch (layout_mode)
776610
     {
776610
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
776610
index 1f99a163d..450f5e484 100644
776610
--- a/src/wayland/meta-wayland-outputs.c
776610
+++ b/src/wayland/meta-wayland-outputs.c
776610
@@ -425,60 +425,107 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
776610
 
776610
       if (logical_monitor->winsys_id == 0)
776610
         continue;
776610
 
776610
       wayland_output =
776610
         g_hash_table_lookup (compositor->outputs,
776610
                              GSIZE_TO_POINTER (logical_monitor->winsys_id));
776610
 
776610
       if (wayland_output)
776610
         {
776610
           g_hash_table_steal (compositor->outputs,
776610
                               GSIZE_TO_POINTER (logical_monitor->winsys_id));
776610
         }
776610
       else
776610
         {
776610
           wayland_output = meta_wayland_output_new (compositor, logical_monitor);
776610
         }
776610
 
776610
       wayland_output_update_for_output (wayland_output, logical_monitor);
776610
       g_hash_table_insert (new_table,
776610
                            GSIZE_TO_POINTER (logical_monitor->winsys_id),
776610
                            wayland_output);
776610
     }
776610
 
776610
   g_hash_table_foreach (compositor->outputs, make_output_inert, NULL);
776610
   g_timeout_add_seconds (10, delayed_destroy_outputs, compositor->outputs);
776610
 
776610
   return new_table;
776610
 }
776610
 
776610
+void
776610
+meta_wayland_outputs_redraw (MetaWaylandCompositor *compositor)
776610
+{
776610
+  MetaMonitorManager *monitor_manager;
776610
+  GList *logical_monitors, *l;
776610
+
776610
+  monitor_manager = meta_monitor_manager_get ();
776610
+
776610
+  logical_monitors =
776610
+    meta_monitor_manager_get_logical_monitors (monitor_manager);
776610
+
776610
+  for (l = logical_monitors; l; l = l->next)
776610
+    {
776610
+      MetaLogicalMonitor *logical_monitor = l->data;
776610
+      MetaWaylandOutput *wayland_output;
776610
+      GList *iter;
776610
+
776610
+      if (logical_monitor->winsys_id == 0)
776610
+        continue;
776610
+
776610
+      wayland_output =
776610
+        g_hash_table_lookup (compositor->outputs,
776610
+                             GSIZE_TO_POINTER (logical_monitor->winsys_id));
776610
+
776610
+      if (wayland_output == NULL)
776610
+        continue;
776610
+
776610
+      /* Just output a "changes done" event for one of the outputs, with no actual changes.
776610
+       * xwayland takes this as a cue to send expose events to all X clients.
776610
+       */
776610
+      for (iter = wayland_output->resources; iter; iter = iter->next)
776610
+        {
776610
+          struct wl_resource *resource = iter->data;
776610
+          if (wl_resource_get_version (resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
776610
+            wl_output_send_done (resource);
776610
+        }
776610
+
776610
+      for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next)
776610
+        {
776610
+          struct wl_resource *xdg_output = iter->data;
776610
+          zxdg_output_v1_send_done (xdg_output);
776610
+        }
776610
+
776610
+      break;
776610
+    }
776610
+}
776610
+
776610
 static void
776610
 on_monitors_changed (MetaMonitorManager    *monitors,
776610
                      MetaWaylandCompositor *compositor)
776610
 {
776610
   compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors);
776610
 }
776610
 
776610
 static void
776610
 meta_wayland_output_init (MetaWaylandOutput *wayland_output)
776610
 {
776610
 }
776610
 
776610
 static void
776610
 meta_wayland_output_finalize (GObject *object)
776610
 {
776610
   MetaWaylandOutput *wayland_output = META_WAYLAND_OUTPUT (object);
776610
   GList *l;
776610
 
776610
   wl_global_destroy (wayland_output->global);
776610
 
776610
   /* Make sure the wl_output destructor doesn't try to access MetaWaylandOutput
776610
    * after we have freed it.
776610
    */
776610
   make_output_resources_inert (wayland_output);
776610
 
776610
   G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object);
776610
 }
776610
 
776610
 static void
776610
 meta_wayland_output_class_init (MetaWaylandOutputClass *klass)
776610
diff --git a/src/wayland/meta-wayland-outputs.h b/src/wayland/meta-wayland-outputs.h
776610
index e6b60d5fa..d8c648174 100644
776610
--- a/src/wayland/meta-wayland-outputs.h
776610
+++ b/src/wayland/meta-wayland-outputs.h
776610
@@ -20,32 +20,33 @@
776610
  *
776610
  * Written by:
776610
  *     Jasper St. Pierre <jstpierre@mecheye.net>
776610
  */
776610
 
776610
 #ifndef META_WAYLAND_OUTPUTS_H
776610
 #define META_WAYLAND_OUTPUTS_H
776610
 
776610
 #include "backends/meta-monitor-manager-private.h"
776610
 #include "meta-wayland-private.h"
776610
 
776610
 #define META_TYPE_WAYLAND_OUTPUT (meta_wayland_output_get_type ())
776610
 G_DECLARE_FINAL_TYPE (MetaWaylandOutput, meta_wayland_output,
776610
                       META, WAYLAND_OUTPUT, GObject)
776610
 
776610
 struct _MetaWaylandOutput
776610
 {
776610
   GObject                   parent;
776610
 
776610
   struct wl_global         *global;
776610
   MetaLogicalMonitor       *logical_monitor;
776610
   guint                     mode_flags;
776610
   float                     refresh_rate;
776610
   gint                      scale;
776610
 
776610
   GList                    *resources;
776610
   GList                    *xdg_output_resources;
776610
 };
776610
 
776610
 void meta_wayland_outputs_init (MetaWaylandCompositor *compositor);
776610
+void meta_wayland_outputs_redraw (MetaWaylandCompositor *compositor);
776610
 
776610
 #endif /* META_WAYLAND_OUTPUTS_H */
776610
-- 
776610
2.18.1
776610