|
|
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 |
|