|
|
9ae3a8 |
From de84e9659aa6b91bd1a7c4fb30fde859882b9201 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
|
|
9ae3a8 |
Date: Thu, 5 Jan 2017 23:58:10 +0100
|
|
|
9ae3a8 |
Subject: [PATCH 4/4] qxl: Only emit QXL_INTERRUPT_CLIENT_MONITORS_CONFIG on
|
|
|
9ae3a8 |
config changes
|
|
|
9ae3a8 |
MIME-Version: 1.0
|
|
|
9ae3a8 |
Content-Type: text/plain; charset=UTF-8
|
|
|
9ae3a8 |
Content-Transfer-Encoding: 8bit
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
9ae3a8 |
Message-id: <20170105235810.27189-1-marcandre.lureau@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 73185
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.4 qemu-kvm PATCH] qxl: Only emit QXL_INTERRUPT_CLIENT_MONITORS_CONFIG on config changes
|
|
|
9ae3a8 |
Bugzilla: 1342489
|
|
|
9ae3a8 |
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
From: Christophe Fergeau <cfergeau@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Currently if the client keeps sending the same monitor config to
|
|
|
9ae3a8 |
QEMU/spice-server, QEMU will always raise
|
|
|
9ae3a8 |
a QXL_INTERRUPT_CLIENT_MONITORS_CONFIG regardless of whether there was a
|
|
|
9ae3a8 |
change or not.
|
|
|
9ae3a8 |
Guest-side (with fedora 25), the kernel QXL KMS driver will also forward the
|
|
|
9ae3a8 |
event to user-space without checking if there were actual changes.
|
|
|
9ae3a8 |
Next in line are gnome-shell/mutter (on a default f25 install), which
|
|
|
9ae3a8 |
will try to reconfigure everything without checking if there is anything
|
|
|
9ae3a8 |
to do.
|
|
|
9ae3a8 |
Where this gets ugly is that when applying the resolution changes,
|
|
|
9ae3a8 |
gnome-shell/mutter will call drmModeRmFB, drmModeAddFB, and
|
|
|
9ae3a8 |
drmModeSetCrtc, which will cause the primary surface to be destroyed and
|
|
|
9ae3a8 |
recreated by the QXL KMS driver. This in turn will cause the client to
|
|
|
9ae3a8 |
resend a client monitors config message, which will cause QEMU to reemit
|
|
|
9ae3a8 |
an interrupt with an unchanged monitors configuration, ...
|
|
|
9ae3a8 |
This causes https://bugzilla.redhat.com/show_bug.cgi?id=1266484
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
This commit makes sure that we only emit
|
|
|
9ae3a8 |
QXL_INTERRUPT_CLIENT_MONITORS_CONFIG when there are actual configuration
|
|
|
9ae3a8 |
changes the guest should act on.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
|
|
|
9ae3a8 |
Message-id: 20161028144840.18326-1-cfergeau@redhat.com
|
|
|
9ae3a8 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
(cherry picked from commit 6c7565028c272c4c6f2a83c3a90b044eeaf2804a)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
hw/display/qxl.c | 37 ++++++++++++++++++++++++++++++++++++-
|
|
|
9ae3a8 |
1 file changed, 36 insertions(+), 1 deletion(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
|
|
9ae3a8 |
index f762439..c76c237 100644
|
|
|
9ae3a8 |
--- a/hw/display/qxl.c
|
|
|
9ae3a8 |
+++ b/hw/display/qxl.c
|
|
|
9ae3a8 |
@@ -989,6 +989,34 @@ static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
|
|
|
9ae3a8 |
return crc32(0xffffffff, p, len) ^ 0xffffffff;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+static bool qxl_rom_monitors_config_changed(QXLRom *rom,
|
|
|
9ae3a8 |
+ VDAgentMonitorsConfig *monitors_config,
|
|
|
9ae3a8 |
+ unsigned int max_outputs)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ int i;
|
|
|
9ae3a8 |
+ unsigned int monitors_count;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ monitors_count = MIN(monitors_config->num_of_monitors, max_outputs);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (rom->client_monitors_config.count != monitors_count) {
|
|
|
9ae3a8 |
+ return true;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
|
|
|
9ae3a8 |
+ VDAgentMonConfig *monitor = &monitors_config->monitors[i];
|
|
|
9ae3a8 |
+ QXLURect *rect = &rom->client_monitors_config.heads[i];
|
|
|
9ae3a8 |
+ /* monitor->depth ignored */
|
|
|
9ae3a8 |
+ if ((rect->left != monitor->x) ||
|
|
|
9ae3a8 |
+ (rect->top != monitor->y) ||
|
|
|
9ae3a8 |
+ (rect->right != monitor->x + monitor->width) ||
|
|
|
9ae3a8 |
+ (rect->bottom != monitor->y + monitor->height)) {
|
|
|
9ae3a8 |
+ return true;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ return false;
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/* called from main context only */
|
|
|
9ae3a8 |
static int interface_client_monitors_config(QXLInstance *sin,
|
|
|
9ae3a8 |
VDAgentMonitorsConfig *monitors_config)
|
|
|
9ae3a8 |
@@ -997,6 +1025,7 @@ static int interface_client_monitors_config(QXLInstance *sin,
|
|
|
9ae3a8 |
QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
|
|
|
9ae3a8 |
int i;
|
|
|
9ae3a8 |
unsigned max_outputs = ARRAY_SIZE(rom->client_monitors_config.heads);
|
|
|
9ae3a8 |
+ bool config_changed = false;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (qxl->revision < 4) {
|
|
|
9ae3a8 |
trace_qxl_client_monitors_config_unsupported_by_device(qxl->id,
|
|
|
9ae3a8 |
@@ -1027,6 +1056,10 @@ static int interface_client_monitors_config(QXLInstance *sin,
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ config_changed = qxl_rom_monitors_config_changed(rom,
|
|
|
9ae3a8 |
+ monitors_config,
|
|
|
9ae3a8 |
+ max_outputs);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
memset(&rom->client_monitors_config, 0,
|
|
|
9ae3a8 |
sizeof(rom->client_monitors_config));
|
|
|
9ae3a8 |
rom->client_monitors_config.count = monitors_config->num_of_monitors;
|
|
|
9ae3a8 |
@@ -1056,7 +1089,9 @@ static int interface_client_monitors_config(QXLInstance *sin,
|
|
|
9ae3a8 |
trace_qxl_interrupt_client_monitors_config(qxl->id,
|
|
|
9ae3a8 |
rom->client_monitors_config.count,
|
|
|
9ae3a8 |
rom->client_monitors_config.heads);
|
|
|
9ae3a8 |
- qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG);
|
|
|
9ae3a8 |
+ if (config_changed) {
|
|
|
9ae3a8 |
+ qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
return 1;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|