Add a couple of backported QXL/Spice bugfixes
- Add spice volume control patches
This commit is contained in:
parent
c7f7fc0b56
commit
56753ff081
@ -0,0 +1,36 @@
|
|||||||
|
From 4c245e5ecbc7d5c30c8e8bb4bfcd18c79fafddfe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hans de Goede <hdegoede@redhat.com>
|
||||||
|
Date: Tue, 3 Apr 2012 14:04:31 +0200
|
||||||
|
Subject: [PATCH 147/181] usb-ehci: Ensure frindex writes leave a valid
|
||||||
|
frindex value
|
||||||
|
|
||||||
|
frindex is a 14 bits counter, so bits 31-14 should always be 0, and
|
||||||
|
after the commit titled "usb-ehci: frindex always is a 14 bits counter"
|
||||||
|
we rely on frindex always being a multiple of 8. I've not seen this in
|
||||||
|
practice, but theoretically a guest can write a value >= 0x4000 or a value
|
||||||
|
which is not a multiple of 8 value to frindex, this patch ensures that
|
||||||
|
things will still work when that happens.
|
||||||
|
|
||||||
|
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||||
|
---
|
||||||
|
hw/usb-ehci.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
|
||||||
|
index ff69587..16e6053 100644
|
||||||
|
--- a/hw/usb-ehci.c
|
||||||
|
+++ b/hw/usb-ehci.c
|
||||||
|
@@ -1081,6 +1081,10 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
|
||||||
|
val &= USBINTR_MASK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case FRINDEX:
|
||||||
|
+ val &= 0x00003ff8; /* frindex is 14bits and always a multiple of 8 */
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case CONFIGFLAG:
|
||||||
|
val &= 0x1;
|
||||||
|
if (val) {
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
From 8858b6d0dac346d9f841cfa84f57cb03bffdf050 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Armbruster <armbru@redhat.com>
|
||||||
|
Date: Fri, 4 Nov 2011 10:34:24 +0100
|
||||||
|
Subject: [PATCH 401/434] qxl: Slot sanity check in qxl_phys2virt() is off by
|
||||||
|
one, fix
|
||||||
|
|
||||||
|
Spotted by Coverity.
|
||||||
|
|
||||||
|
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 41500e9..e0f9d4a 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1020,7 +1020,7 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
|
||||||
|
case MEMSLOT_GROUP_HOST:
|
||||||
|
return (void*)offset;
|
||||||
|
case MEMSLOT_GROUP_GUEST:
|
||||||
|
- PANIC_ON(slot > NUM_MEMSLOTS);
|
||||||
|
+ PANIC_ON(slot >= NUM_MEMSLOTS);
|
||||||
|
PANIC_ON(!qxl->guest_slots[slot].active);
|
||||||
|
PANIC_ON(offset < qxl->guest_slots[slot].delta);
|
||||||
|
offset -= qxl->guest_slots[slot].delta;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From f87b93c3944652f90e2c0010da6ee8c182382369 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Wed, 15 Feb 2012 09:15:37 +0100
|
||||||
|
Subject: [PATCH 402/434] input: send kbd+mouse events only to running guests.
|
||||||
|
|
||||||
|
Trying to interact with a stopped guest will queue up the events,
|
||||||
|
then send them all at once when the guest continues running, with
|
||||||
|
a high chance to have them cause unwanted actions.
|
||||||
|
|
||||||
|
Avoid that by only injecting the input events only when the guest
|
||||||
|
is in running state.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
||||||
|
---
|
||||||
|
input.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/input.c b/input.c
|
||||||
|
index 9ade63f..b48408d 100644
|
||||||
|
--- a/input.c
|
||||||
|
+++ b/input.c
|
||||||
|
@@ -130,6 +130,9 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
|
||||||
|
|
||||||
|
void kbd_put_keycode(int keycode)
|
||||||
|
{
|
||||||
|
+ if (!runstate_is_running()) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
if (qemu_put_kbd_event) {
|
||||||
|
qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
|
||||||
|
}
|
||||||
|
@@ -151,6 +154,9 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
|
||||||
|
void *mouse_event_opaque;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
+ if (!runstate_is_running()) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
if (QTAILQ_EMPTY(&mouse_handlers)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
45
0403-qxl-fix-warnings-on-32bit.patch
Normal file
45
0403-qxl-fix-warnings-on-32bit.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
From 3b36dd31d54b24e02493fdd86269ba5286086c98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Wed, 8 Feb 2012 15:58:35 +0100
|
||||||
|
Subject: [PATCH 403/434] qxl: fix warnings on 32bit
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index e0f9d4a..4fd5e4e 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -628,7 +628,7 @@ static void interface_release_resource(QXLInstance *sin,
|
||||||
|
|
||||||
|
if (ext.group_id == MEMSLOT_GROUP_HOST) {
|
||||||
|
/* host group -> vga mode update request */
|
||||||
|
- qemu_spice_destroy_update(&qxl->ssd, (void*)ext.info->id);
|
||||||
|
+ qemu_spice_destroy_update(&qxl->ssd, (void *)(intptr_t)ext.info->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -751,7 +751,8 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
|
||||||
|
qxl->current_async = QXL_UNDEFINED_IO;
|
||||||
|
qemu_mutex_unlock(&qxl->async_lock);
|
||||||
|
|
||||||
|
- dprint(qxl, 2, "async_complete: %d (%ld) done\n", current_async, cookie);
|
||||||
|
+ dprint(qxl, 2, "async_complete: %d (%" PRId64 ") done\n",
|
||||||
|
+ current_async, cookie);
|
||||||
|
switch (current_async) {
|
||||||
|
case QXL_IO_CREATE_PRIMARY_ASYNC:
|
||||||
|
qxl_create_guest_primary_complete(qxl);
|
||||||
|
@@ -1018,7 +1019,7 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
|
||||||
|
|
||||||
|
switch (group_id) {
|
||||||
|
case MEMSLOT_GROUP_HOST:
|
||||||
|
- return (void*)offset;
|
||||||
|
+ return (void *)(intptr_t)offset;
|
||||||
|
case MEMSLOT_GROUP_GUEST:
|
||||||
|
PANIC_ON(slot >= NUM_MEMSLOTS);
|
||||||
|
PANIC_ON(!qxl->guest_slots[slot].active);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
56
0404-qxl-don-t-render-stuff-when-the-vm-is-stopped.patch
Normal file
56
0404-qxl-don-t-render-stuff-when-the-vm-is-stopped.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
From 29fdb0f3a401e5590e465a0cc37d82383f3d5f07 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Wed, 15 Feb 2012 14:04:44 +0100
|
||||||
|
Subject: [PATCH 404/434] qxl: don't render stuff when the vm is stopped.
|
||||||
|
|
||||||
|
This patch fixes the local qxl renderer to not kick spice-server
|
||||||
|
in case the vm is stopped. First it is largely pointless because
|
||||||
|
we ask spice-server to process all not-yet processed commands when
|
||||||
|
the vm is stopped, so there isn't much do do anyway. Second we
|
||||||
|
avoid triggering an assert in spice-server.
|
||||||
|
|
||||||
|
The patch makes sure we still honor redraw requests, even if we don't
|
||||||
|
ask spice-server for updates. This is needed to handle displaysurface
|
||||||
|
changes with a stopped vm correctly.
|
||||||
|
|
||||||
|
With this patch applied it is possible to take screen shots (via
|
||||||
|
screendump monitor command) from a qxl gpu even in case the guest
|
||||||
|
is stopped.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl-render.c | 12 +++++-------
|
||||||
|
1 file changed, 5 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
|
||||||
|
index 2c51ba9..a7891b2 100644
|
||||||
|
--- a/hw/qxl-render.c
|
||||||
|
+++ b/hw/qxl-render.c
|
||||||
|
@@ -121,19 +121,17 @@ void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
dpy_resize(vga->ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!qxl->guest_primary.commands) {
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
- qxl->guest_primary.commands = 0;
|
||||||
|
-
|
||||||
|
update.left = 0;
|
||||||
|
update.right = qxl->guest_primary.surface.width;
|
||||||
|
update.top = 0;
|
||||||
|
update.bottom = qxl->guest_primary.surface.height;
|
||||||
|
|
||||||
|
memset(dirty, 0, sizeof(dirty));
|
||||||
|
- qxl_spice_update_area(qxl, 0, &update,
|
||||||
|
- dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
|
||||||
|
+ if (runstate_is_running() && qxl->guest_primary.commands) {
|
||||||
|
+ qxl->guest_primary.commands = 0;
|
||||||
|
+ qxl_spice_update_area(qxl, 0, &update,
|
||||||
|
+ dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
|
||||||
|
+ }
|
||||||
|
if (redraw) {
|
||||||
|
memset(dirty, 0, sizeof(dirty));
|
||||||
|
dirty[0] = update;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,97 @@
|
|||||||
|
From 0386bf2be16745ce87f35ce65153ef4e11f93b22 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Date: Wed, 15 Feb 2012 11:22:15 +0200
|
||||||
|
Subject: [PATCH 405/434] qxl: set only off-screen surfaces dirty instead of
|
||||||
|
the whole vram
|
||||||
|
|
||||||
|
We used to assure the guest surfaces were saved before migration by
|
||||||
|
setting the whole vram dirty. This patch sets dirty only the areas
|
||||||
|
that are actually used in the vram.
|
||||||
|
|
||||||
|
Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++---------
|
||||||
|
1 file changed, 44 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 4fd5e4e..3d9b1b3 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1010,7 +1010,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
|
||||||
|
qxl_spice_destroy_surfaces(d, QXL_SYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* called from spice server thread context only */
|
||||||
|
+/* can be also called from spice server thread context */
|
||||||
|
void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
|
||||||
|
{
|
||||||
|
uint64_t phys = le64_to_cpu(pqxl);
|
||||||
|
@@ -1469,6 +1469,46 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
|
||||||
|
+{
|
||||||
|
+ intptr_t vram_start;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (qxl->mode != QXL_MODE_NATIVE) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* dirty the primary surface */
|
||||||
|
+ qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
|
||||||
|
+ qxl->shadow_rom.surface0_area_size);
|
||||||
|
+
|
||||||
|
+ vram_start = (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
|
||||||
|
+
|
||||||
|
+ /* dirty the off-screen surfaces */
|
||||||
|
+ for (i = 0; i < NUM_SURFACES; i++) {
|
||||||
|
+ QXLSurfaceCmd *cmd;
|
||||||
|
+ intptr_t surface_offset;
|
||||||
|
+ int surface_size;
|
||||||
|
+
|
||||||
|
+ if (qxl->guest_surfaces.cmds[i] == 0) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
|
||||||
|
+ MEMSLOT_GROUP_GUEST);
|
||||||
|
+ assert(cmd->type == QXL_SURFACE_CMD_CREATE);
|
||||||
|
+ surface_offset = (intptr_t)qxl_phys2virt(qxl,
|
||||||
|
+ cmd->u.surface_create.data,
|
||||||
|
+ MEMSLOT_GROUP_GUEST);
|
||||||
|
+ surface_offset -= vram_start;
|
||||||
|
+ surface_size = cmd->u.surface_create.height *
|
||||||
|
+ abs(cmd->u.surface_create.stride);
|
||||||
|
+ dprint(qxl, 3, "%s: dirty surface %d, offset %d, size %d\n", __func__,
|
||||||
|
+ i, (int)surface_offset, surface_size);
|
||||||
|
+ qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void qxl_vm_change_state_handler(void *opaque, int running,
|
||||||
|
RunState state)
|
||||||
|
{
|
||||||
|
@@ -1482,14 +1522,9 @@ static void qxl_vm_change_state_handler(void *opaque, int running,
|
||||||
|
* called
|
||||||
|
*/
|
||||||
|
qxl_update_irq(qxl);
|
||||||
|
- } else if (qxl->mode == QXL_MODE_NATIVE) {
|
||||||
|
- /* dirty all vram (which holds surfaces) and devram (primary surface)
|
||||||
|
- * to make sure they are saved */
|
||||||
|
- /* FIXME #1: should go out during "live" stage */
|
||||||
|
- /* FIXME #2: we only need to save the areas which are actually used */
|
||||||
|
- qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
|
||||||
|
- qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
|
||||||
|
- qxl->shadow_rom.surface0_area_size);
|
||||||
|
+ } else {
|
||||||
|
+ /* make sure surfaces are saved before migration */
|
||||||
|
+ qxl_dirty_surfaces(qxl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
From ba922e5e6a5687f13def623e36bfb834ece2defc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Date: Wed, 15 Feb 2012 11:22:16 +0200
|
||||||
|
Subject: [PATCH 406/434] qxl: make sure primary surface is saved on migration
|
||||||
|
also in compat mode
|
||||||
|
|
||||||
|
RHBZ #790083
|
||||||
|
|
||||||
|
Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 3d9b1b3..b910337 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1474,7 +1474,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
|
||||||
|
intptr_t vram_start;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- if (qxl->mode != QXL_MODE_NATIVE) {
|
||||||
|
+ if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
139
0407-Add-SPICE-support-to-add_client-monitor-command.patch
Normal file
139
0407-Add-SPICE-support-to-add_client-monitor-command.patch
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
From 9ada192cfea65a92a765c6a2f6b56a08f1b865df Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||||
|
Date: Mon, 13 Feb 2012 13:43:08 +0000
|
||||||
|
Subject: [PATCH 407/434] Add SPICE support to add_client monitor command
|
||||||
|
|
||||||
|
With the acceptance of some new APIs to libspice-server.so it
|
||||||
|
is possible to add support for SPICE to the 'add_client'
|
||||||
|
monitor command, bringing parity with VNC. Since SPICE can
|
||||||
|
use TLS or plain connections, the command also gains a new
|
||||||
|
'tls' parameter to specify whether TLS should be attempted
|
||||||
|
on the injected client sockets.
|
||||||
|
|
||||||
|
This new feature is only enabled if building against a
|
||||||
|
libspice-server >= 0.10.1
|
||||||
|
|
||||||
|
* qmp-commands.hx: Add 'tls' parameter & missing doc for
|
||||||
|
'skipauth' parameter
|
||||||
|
* monitor.c: Wire up SPICE for 'add_client' command
|
||||||
|
* ui/qemu-spice.h, ui/spice-core.c: Add qemu_spice_display_add_client
|
||||||
|
API to wire up from monitor
|
||||||
|
|
||||||
|
[1] http://cgit.freedesktop.org/spice/spice/commit/server/spice.h?id=d55b68b6b44f2499278fa860fb47ff22f5011faa
|
||||||
|
http://cgit.freedesktop.org/spice/spice/commit/server/spice.h?id=bd07dde530d9504e1cfe7ed5837fc00c26f36716
|
||||||
|
|
||||||
|
Changes in v3:
|
||||||
|
- Added 'optional' flag to new parameters documented
|
||||||
|
- Added no-op impl of qemu_spice_display_add_client when
|
||||||
|
SPICE is disabled during build
|
||||||
|
|
||||||
|
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
monitor.c | 9 +++++++--
|
||||||
|
qmp-commands.hx | 6 ++++--
|
||||||
|
ui/qemu-spice.h | 7 +++++++
|
||||||
|
ui/spice-core.c | 13 +++++++++++++
|
||||||
|
4 files changed, 31 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/monitor.c b/monitor.c
|
||||||
|
index a82fda3..3c23aa4 100644
|
||||||
|
--- a/monitor.c
|
||||||
|
+++ b/monitor.c
|
||||||
|
@@ -998,13 +998,18 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d
|
||||||
|
CharDriverState *s;
|
||||||
|
|
||||||
|
if (strcmp(protocol, "spice") == 0) {
|
||||||
|
+ int fd = monitor_get_fd(mon, fdname);
|
||||||
|
+ int skipauth = qdict_get_try_bool(qdict, "skipauth", 0);
|
||||||
|
+ int tls = qdict_get_try_bool(qdict, "tls", 0);
|
||||||
|
if (!using_spice) {
|
||||||
|
/* correct one? spice isn't a device ,,, */
|
||||||
|
qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- qerror_report(QERR_ADD_CLIENT_FAILED);
|
||||||
|
- return -1;
|
||||||
|
+ if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) {
|
||||||
|
+ close(fd);
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
} else if (strcmp(protocol, "vnc") == 0) {
|
||||||
|
int fd = monitor_get_fd(mon, fdname);
|
||||||
|
diff --git a/qmp-commands.hx b/qmp-commands.hx
|
||||||
|
index 97975a5..122b10d 100644
|
||||||
|
--- a/qmp-commands.hx
|
||||||
|
+++ b/qmp-commands.hx
|
||||||
|
@@ -909,8 +909,8 @@ EQMP
|
||||||
|
|
||||||
|
{
|
||||||
|
.name = "add_client",
|
||||||
|
- .args_type = "protocol:s,fdname:s,skipauth:b?",
|
||||||
|
- .params = "protocol fdname skipauth",
|
||||||
|
+ .args_type = "protocol:s,fdname:s,skipauth:b?,tls:b?",
|
||||||
|
+ .params = "protocol fdname skipauth tls",
|
||||||
|
.help = "add a graphics client",
|
||||||
|
.user_print = monitor_user_noop,
|
||||||
|
.mhandler.cmd_new = add_graphics_client,
|
||||||
|
@@ -926,6 +926,8 @@ Arguments:
|
||||||
|
|
||||||
|
- "protocol": protocol name (json-string)
|
||||||
|
- "fdname": file descriptor name (json-string)
|
||||||
|
+- "skipauth": whether to skip authentication (json-bool, optional)
|
||||||
|
+- "tls": whether to perform TLS (json-bool, optional)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
|
||||||
|
index c35b29c..680206a 100644
|
||||||
|
--- a/ui/qemu-spice.h
|
||||||
|
+++ b/ui/qemu-spice.h
|
||||||
|
@@ -33,6 +33,7 @@ void qemu_spice_init(void);
|
||||||
|
void qemu_spice_input_init(void);
|
||||||
|
void qemu_spice_audio_init(void);
|
||||||
|
void qemu_spice_display_init(DisplayState *ds);
|
||||||
|
+int qemu_spice_display_add_client(int csock, int skipauth, int tls);
|
||||||
|
int qemu_spice_add_interface(SpiceBaseInstance *sin);
|
||||||
|
int qemu_spice_set_passwd(const char *passwd,
|
||||||
|
bool fail_if_connected, bool disconnect_if_connected);
|
||||||
|
@@ -68,6 +69,12 @@ static inline int qemu_spice_migrate_info(const char *h, int p, int t,
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline int qemu_spice_display_add_client(int csock, int skipauth,
|
||||||
|
+ int tls)
|
||||||
|
+{
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#endif /* CONFIG_SPICE */
|
||||||
|
|
||||||
|
#endif /* QEMU_SPICE_H */
|
||||||
|
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||||
|
index 5639c6f..d98863e 100644
|
||||||
|
--- a/ui/spice-core.c
|
||||||
|
+++ b/ui/spice-core.c
|
||||||
|
@@ -747,6 +747,19 @@ int qemu_spice_set_pw_expire(time_t expires)
|
||||||
|
return qemu_spice_set_ticket(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int qemu_spice_display_add_client(int csock, int skipauth, int tls)
|
||||||
|
+{
|
||||||
|
+#if SPICE_SERVER_VERSION >= 0x000a01
|
||||||
|
+ if (tls) {
|
||||||
|
+ return spice_server_add_ssl_client(spice_server, csock, skipauth);
|
||||||
|
+ } else {
|
||||||
|
+ return spice_server_add_client(spice_server, csock, skipauth);
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
+ return -1;
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void spice_register_config(void)
|
||||||
|
{
|
||||||
|
qemu_add_opts(&qemu_spice_opts);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,83 @@
|
|||||||
|
From 6594551ebe427cae4298b038be02ddc9c335219f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Date: Wed, 8 Feb 2012 15:40:15 +0200
|
||||||
|
Subject: [PATCH 408/434] spice: support ipv6 channel address in monitor
|
||||||
|
events and in spice info
|
||||||
|
|
||||||
|
RHBZ #788444
|
||||||
|
|
||||||
|
CC: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
|
||||||
|
Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
ui/spice-core.c | 37 ++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 32 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||||
|
index d98863e..27216e9 100644
|
||||||
|
--- a/ui/spice-core.c
|
||||||
|
+++ b/ui/spice-core.c
|
||||||
|
@@ -220,10 +220,23 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
|
||||||
|
}
|
||||||
|
|
||||||
|
client = qdict_new();
|
||||||
|
- add_addr_info(client, &info->paddr, info->plen);
|
||||||
|
-
|
||||||
|
server = qdict_new();
|
||||||
|
- add_addr_info(server, &info->laddr, info->llen);
|
||||||
|
+
|
||||||
|
+#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
|
||||||
|
+ if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
|
||||||
|
+ add_addr_info(client, (struct sockaddr *)&info->paddr_ext,
|
||||||
|
+ info->plen_ext);
|
||||||
|
+ add_addr_info(server, (struct sockaddr *)&info->laddr_ext,
|
||||||
|
+ info->llen_ext);
|
||||||
|
+ } else {
|
||||||
|
+ fprintf(stderr, "spice: %s, extended address is expected\n",
|
||||||
|
+ __func__);
|
||||||
|
+#endif
|
||||||
|
+ add_addr_info(client, &info->paddr, info->plen);
|
||||||
|
+ add_addr_info(server, &info->laddr, info->llen);
|
||||||
|
+#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (event == SPICE_CHANNEL_EVENT_INITIALIZED) {
|
||||||
|
qdict_put(server, "auth", qstring_from_str(auth));
|
||||||
|
@@ -376,16 +389,30 @@ static SpiceChannelList *qmp_query_spice_channels(void)
|
||||||
|
QTAILQ_FOREACH(item, &channel_list, link) {
|
||||||
|
SpiceChannelList *chan;
|
||||||
|
char host[NI_MAXHOST], port[NI_MAXSERV];
|
||||||
|
+ struct sockaddr *paddr;
|
||||||
|
+ socklen_t plen;
|
||||||
|
|
||||||
|
chan = g_malloc0(sizeof(*chan));
|
||||||
|
chan->value = g_malloc0(sizeof(*chan->value));
|
||||||
|
|
||||||
|
- getnameinfo(&item->info->paddr, item->info->plen,
|
||||||
|
+#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
|
||||||
|
+ if (item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
|
||||||
|
+ paddr = (struct sockaddr *)&item->info->paddr_ext;
|
||||||
|
+ plen = item->info->plen_ext;
|
||||||
|
+ } else {
|
||||||
|
+#endif
|
||||||
|
+ paddr = &item->info->paddr;
|
||||||
|
+ plen = item->info->plen;
|
||||||
|
+#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ getnameinfo(paddr, plen,
|
||||||
|
host, sizeof(host), port, sizeof(port),
|
||||||
|
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||||
|
chan->value->host = g_strdup(host);
|
||||||
|
chan->value->port = g_strdup(port);
|
||||||
|
- chan->value->family = g_strdup(inet_strfamily(item->info->paddr.sa_family));
|
||||||
|
+ chan->value->family = g_strdup(inet_strfamily(paddr->sa_family));
|
||||||
|
|
||||||
|
chan->value->connection_id = item->info->connection_id;
|
||||||
|
chan->value->channel_type = item->info->type;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
30
0409-qxl-drop-vram-bar-minimum-size.patch
Normal file
30
0409-qxl-drop-vram-bar-minimum-size.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From f7656005900f3c07450303afa66151b6a1bb9599 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 17 Feb 2012 14:40:01 +0100
|
||||||
|
Subject: [PATCH 409/434] qxl: drop vram bar minimum size
|
||||||
|
|
||||||
|
There is no reason to require a minimum size of 16 MB for the vram.
|
||||||
|
Lower the limit to 4096 (one page). Make it disapper completely would
|
||||||
|
break guests.
|
||||||
|
---
|
||||||
|
hw/qxl.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index b910337..d71c94d 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1595,8 +1595,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
|
||||||
|
init_qxl_rom(qxl);
|
||||||
|
init_qxl_ram(qxl);
|
||||||
|
|
||||||
|
- if (qxl->vram_size < 16 * 1024 * 1024) {
|
||||||
|
- qxl->vram_size = 16 * 1024 * 1024;
|
||||||
|
+ if (qxl->vram_size < 4096) {
|
||||||
|
+ qxl->vram_size = 4096;
|
||||||
|
}
|
||||||
|
if (qxl->revision == 1) {
|
||||||
|
qxl->vram_size = 4096;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
97
0410-qxl-move-ram-size-init-to-new-function.patch
Normal file
97
0410-qxl-move-ram-size-init-to-new-function.patch
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
From 619c68418809149d56025e5b4e7a9828eef90ea8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 17 Feb 2012 15:02:40 +0100
|
||||||
|
Subject: [PATCH 410/434] qxl: move ram size init to new function
|
||||||
|
|
||||||
|
Factor memory bar sizing bits out to a separate function.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
|
||||||
|
hw/qxl.c
|
||||||
|
---
|
||||||
|
hw/qxl.c | 41 ++++++++++++++++++++++-------------------
|
||||||
|
1 file changed, 22 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index d71c94d..df8efbc 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1557,6 +1557,25 @@ static DisplayChangeListener display_listener = {
|
||||||
|
.dpy_refresh = display_refresh,
|
||||||
|
};
|
||||||
|
|
||||||
|
+static void qxl_init_ramsize(PCIQXLDevice *qxl, uint32_t ram_min_mb)
|
||||||
|
+{
|
||||||
|
+ /* vga ram (bar 0) */
|
||||||
|
+ if (qxl->vga.vram_size < ram_min_mb * 1024 * 1024) {
|
||||||
|
+ qxl->vga.vram_size = ram_min_mb * 1024 * 1024;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* vram (surfaces, bar 1) */
|
||||||
|
+ if (qxl->vram_size < 4096) {
|
||||||
|
+ qxl->vram_size = 4096;
|
||||||
|
+ }
|
||||||
|
+ if (qxl->revision == 1) {
|
||||||
|
+ qxl->vram_size = 4096;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ qxl->vga.vram_size = msb_mask(qxl->vga.vram_size * 2 - 1);
|
||||||
|
+ qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int qxl_init_common(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
uint8_t* config = qxl->pci.config;
|
||||||
|
@@ -1595,13 +1614,6 @@ static int qxl_init_common(PCIQXLDevice *qxl)
|
||||||
|
init_qxl_rom(qxl);
|
||||||
|
init_qxl_ram(qxl);
|
||||||
|
|
||||||
|
- if (qxl->vram_size < 4096) {
|
||||||
|
- qxl->vram_size = 4096;
|
||||||
|
- }
|
||||||
|
- if (qxl->revision == 1) {
|
||||||
|
- qxl->vram_size = 4096;
|
||||||
|
- }
|
||||||
|
- qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
|
||||||
|
memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram",
|
||||||
|
qxl->vram_size);
|
||||||
|
|
||||||
|
@@ -1644,15 +1656,11 @@ static int qxl_init_primary(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
|
||||||
|
VGACommonState *vga = &qxl->vga;
|
||||||
|
- ram_addr_t ram_size = msb_mask(qxl->vga.vram_size * 2 - 1);
|
||||||
|
PortioList *qxl_vga_port_list = g_new(PortioList, 1);
|
||||||
|
|
||||||
|
qxl->id = 0;
|
||||||
|
-
|
||||||
|
- if (ram_size < 32 * 1024 * 1024) {
|
||||||
|
- ram_size = 32 * 1024 * 1024;
|
||||||
|
- }
|
||||||
|
- vga_common_init(vga, ram_size);
|
||||||
|
+ qxl_init_ramsize(qxl, 32);
|
||||||
|
+ vga_common_init(vga, qxl->vga.vram_size);
|
||||||
|
vga_init(vga, pci_address_space(dev), pci_address_space_io(dev), false);
|
||||||
|
portio_list_init(qxl_vga_port_list, qxl_vga_portio_list, vga, "vga");
|
||||||
|
portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
|
||||||
|
@@ -1671,14 +1679,9 @@ static int qxl_init_secondary(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
static int device_id = 1;
|
||||||
|
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
|
||||||
|
- ram_addr_t ram_size = msb_mask(qxl->vga.vram_size * 2 - 1);
|
||||||
|
|
||||||
|
qxl->id = device_id++;
|
||||||
|
-
|
||||||
|
- if (ram_size < 16 * 1024 * 1024) {
|
||||||
|
- ram_size = 16 * 1024 * 1024;
|
||||||
|
- }
|
||||||
|
- qxl->vga.vram_size = ram_size;
|
||||||
|
+ qxl_init_ramsize(qxl, 16);
|
||||||
|
memory_region_init_ram(&qxl->vga.vram, &qxl->pci.qdev, "qxl.vgavram",
|
||||||
|
qxl->vga.vram_size);
|
||||||
|
qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
63
0411-qxl-add-user-friendly-bar-size-properties.patch
Normal file
63
0411-qxl-add-user-friendly-bar-size-properties.patch
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
From eff66c7db18e9a3ef0b6ce5deb9a49b61090d809 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 17 Feb 2012 15:03:24 +0100
|
||||||
|
Subject: [PATCH 411/434] qxl: add user-friendly bar size properties
|
||||||
|
|
||||||
|
Add two properties to specify bar sizes in megabytes instead of bytes,
|
||||||
|
which is alot more user-friendly.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 8 ++++++++
|
||||||
|
hw/qxl.h | 4 ++++
|
||||||
|
2 files changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index df8efbc..c8839c3 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1560,11 +1560,17 @@ static DisplayChangeListener display_listener = {
|
||||||
|
static void qxl_init_ramsize(PCIQXLDevice *qxl, uint32_t ram_min_mb)
|
||||||
|
{
|
||||||
|
/* vga ram (bar 0) */
|
||||||
|
+ if (qxl->ram_size_mb != -1) {
|
||||||
|
+ qxl->vga.vram_size = qxl->ram_size_mb * 1024 * 1024;
|
||||||
|
+ }
|
||||||
|
if (qxl->vga.vram_size < ram_min_mb * 1024 * 1024) {
|
||||||
|
qxl->vga.vram_size = ram_min_mb * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vram (surfaces, bar 1) */
|
||||||
|
+ if (qxl->vram_size_mb != -1) {
|
||||||
|
+ qxl->vram_size = qxl->vram_size_mb * 1024 * 1024;
|
||||||
|
+ }
|
||||||
|
if (qxl->vram_size < 4096) {
|
||||||
|
qxl->vram_size = 4096;
|
||||||
|
}
|
||||||
|
@@ -1863,6 +1869,8 @@ static Property qxl_properties[] = {
|
||||||
|
DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
|
||||||
|
DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
|
||||||
|
DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
|
||||||
|
+ DEFINE_PROP_UINT32("ram_size_mb", PCIQXLDevice, ram_size_mb, -1),
|
||||||
|
+ DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram_size_mb, -1),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.h b/hw/qxl.h
|
||||||
|
index 766aa6d..d062991 100644
|
||||||
|
--- a/hw/qxl.h
|
||||||
|
+++ b/hw/qxl.h
|
||||||
|
@@ -89,6 +89,10 @@ typedef struct PCIQXLDevice {
|
||||||
|
|
||||||
|
/* io bar */
|
||||||
|
MemoryRegion io_bar;
|
||||||
|
+
|
||||||
|
+ /* user-friendly properties (in megabytes) */
|
||||||
|
+ uint32_t ram_size_mb;
|
||||||
|
+ uint32_t vram_size_mb;
|
||||||
|
} PCIQXLDevice;
|
||||||
|
|
||||||
|
#define PANIC_ON(x) if ((x)) { \
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
93
0412-qxl-fix-spice-sdl-no-cursor-regression.patch
Normal file
93
0412-qxl-fix-spice-sdl-no-cursor-regression.patch
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
From 1cae61c4d4fe994e5158d63d5f4fe9b52a7b8211 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 23:19:25 +0200
|
||||||
|
Subject: [PATCH 412/434] qxl: fix spice+sdl no cursor regression
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
regression introduced by 075360945860ad9bdd491921954b383bf762b0e5,
|
||||||
|
|
||||||
|
v2: lock around qemu_spice_cursor_refresh_unlocked
|
||||||
|
|
||||||
|
Reported-by: Fabiano Fidêncio <fabiano@fidencio.org>
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 4 ++++
|
||||||
|
ui/spice-display.c | 23 ++++++++++++++---------
|
||||||
|
ui/spice-display.h | 1 +
|
||||||
|
3 files changed, 19 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index c8839c3..17f2576 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1548,6 +1548,10 @@ static void display_refresh(struct DisplayState *ds)
|
||||||
|
{
|
||||||
|
if (qxl0->mode == QXL_MODE_VGA) {
|
||||||
|
qemu_spice_display_refresh(&qxl0->ssd);
|
||||||
|
+ } else {
|
||||||
|
+ qemu_mutex_lock(&qxl0->ssd.lock);
|
||||||
|
+ qemu_spice_cursor_refresh_unlocked(&qxl0->ssd);
|
||||||
|
+ qemu_mutex_unlock(&qxl0->ssd.lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/ui/spice-display.c b/ui/spice-display.c
|
||||||
|
index 6c302a3..c6e61d8 100644
|
||||||
|
--- a/ui/spice-display.c
|
||||||
|
+++ b/ui/spice-display.c
|
||||||
|
@@ -317,16 +317,8 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
|
||||||
|
ssd->notify++;
|
||||||
|
}
|
||||||
|
|
||||||
|
-void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
|
||||||
|
+void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
|
||||||
|
{
|
||||||
|
- dprint(3, "%s:\n", __FUNCTION__);
|
||||||
|
- vga_hw_update();
|
||||||
|
-
|
||||||
|
- qemu_mutex_lock(&ssd->lock);
|
||||||
|
- if (ssd->update == NULL) {
|
||||||
|
- ssd->update = qemu_spice_create_update(ssd);
|
||||||
|
- ssd->notify++;
|
||||||
|
- }
|
||||||
|
if (ssd->cursor) {
|
||||||
|
ssd->ds->cursor_define(ssd->cursor);
|
||||||
|
cursor_put(ssd->cursor);
|
||||||
|
@@ -337,6 +329,19 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
|
||||||
|
ssd->mouse_x = -1;
|
||||||
|
ssd->mouse_y = -1;
|
||||||
|
}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
|
||||||
|
+{
|
||||||
|
+ dprint(3, "%s:\n", __func__);
|
||||||
|
+ vga_hw_update();
|
||||||
|
+
|
||||||
|
+ qemu_mutex_lock(&ssd->lock);
|
||||||
|
+ if (ssd->update == NULL) {
|
||||||
|
+ ssd->update = qemu_spice_create_update(ssd);
|
||||||
|
+ ssd->notify++;
|
||||||
|
+ }
|
||||||
|
+ qemu_spice_cursor_refresh_unlocked(ssd);
|
||||||
|
qemu_mutex_unlock(&ssd->lock);
|
||||||
|
|
||||||
|
if (ssd->notify) {
|
||||||
|
diff --git a/ui/spice-display.h b/ui/spice-display.h
|
||||||
|
index 5e52df9..a23bfc8 100644
|
||||||
|
--- a/ui/spice-display.h
|
||||||
|
+++ b/ui/spice-display.h
|
||||||
|
@@ -97,6 +97,7 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
|
||||||
|
int x, int y, int w, int h);
|
||||||
|
void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
|
||||||
|
void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
|
||||||
|
+void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd);
|
||||||
|
|
||||||
|
void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
|
||||||
|
qxl_async_io async);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
29
0413-sdl-remove-NULL-check-g_malloc0-can-t-fail.patch
Normal file
29
0413-sdl-remove-NULL-check-g_malloc0-can-t-fail.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From 4888e60d646b0f8cdfe4180bacc90857d3d2a5dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 23:19:26 +0200
|
||||||
|
Subject: [PATCH 413/434] sdl: remove NULL check, g_malloc0 can't fail
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
ui/sdl.c | 4 ----
|
||||||
|
1 file changed, 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/sdl.c b/ui/sdl.c
|
||||||
|
index 8cafc44..6844c83 100644
|
||||||
|
--- a/ui/sdl.c
|
||||||
|
+++ b/ui/sdl.c
|
||||||
|
@@ -167,10 +167,6 @@ static PixelFormat sdl_to_qemu_pixelformat(SDL_PixelFormat *sdl_pf)
|
||||||
|
static DisplaySurface* sdl_create_displaysurface(int width, int height)
|
||||||
|
{
|
||||||
|
DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
|
||||||
|
- if (surface == NULL) {
|
||||||
|
- fprintf(stderr, "sdl_create_displaysurface: malloc failed\n");
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
|
||||||
|
surface->width = width;
|
||||||
|
surface->height = height;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
34
0414-qxl-drop-qxl_spice_update_area_async-definition.patch
Normal file
34
0414-qxl-drop-qxl_spice_update_area_async-definition.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From 813c46edf4f3f69347353749755e040bc5fbd597 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 23:19:27 +0200
|
||||||
|
Subject: [PATCH 414/434] qxl: drop qxl_spice_update_area_async definition
|
||||||
|
|
||||||
|
It was never used. Introduced in
|
||||||
|
5ff4e36c804157bd84af43c139f8cd3a59722db9
|
||||||
|
qxl: async io support using new spice api
|
||||||
|
|
||||||
|
But not used even then.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.h | 6 ------
|
||||||
|
1 file changed, 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.h b/hw/qxl.h
|
||||||
|
index d062991..a615eca 100644
|
||||||
|
--- a/hw/qxl.h
|
||||||
|
+++ b/hw/qxl.h
|
||||||
|
@@ -138,9 +138,3 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
|
||||||
|
void qxl_render_resize(PCIQXLDevice *qxl);
|
||||||
|
void qxl_render_update(PCIQXLDevice *qxl);
|
||||||
|
void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
-void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
|
||||||
|
- struct QXLRect *area,
|
||||||
|
- uint32_t clear_dirty_region,
|
||||||
|
- int is_vga);
|
||||||
|
-#endif
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
358
0415-qxl-require-spice-0.8.2.patch
Normal file
358
0415-qxl-require-spice-0.8.2.patch
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
From e07eeb01819b40b839cc12b2eb658f48f13a5ff0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 23:19:28 +0200
|
||||||
|
Subject: [PATCH 415/434] qxl: require spice >= 0.8.2
|
||||||
|
|
||||||
|
drop all ifdefs on SPICE_INTERFACE_QXL_MINOR >= 1 as a result,
|
||||||
|
any check for SPICE_SERVER_VERSION that is now always satisfied,
|
||||||
|
and SPICE_INTERFACE_CORE_MINOR >= 3 tests, because
|
||||||
|
0.8.2 has SPICE_INTERFACE_QXL_MINOR == 1 and
|
||||||
|
SPICE_INTERFACE_CORE_MINOR == 3.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
configure | 2 +-
|
||||||
|
hw/qxl.c | 40 ----------------------------------------
|
||||||
|
hw/qxl.h | 4 ----
|
||||||
|
ui/spice-core.c | 17 -----------------
|
||||||
|
ui/spice-display.c | 12 ------------
|
||||||
|
5 files changed, 1 insertion(+), 74 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index a4848a4..b03172c 100755
|
||||||
|
--- a/configure
|
||||||
|
+++ b/configure
|
||||||
|
@@ -2501,7 +2501,7 @@ int main(void) { spice_server_new(); return 0; }
|
||||||
|
EOF
|
||||||
|
spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
|
||||||
|
spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
|
||||||
|
- if $pkg_config --atleast-version=0.6.0 spice-server >/dev/null 2>&1 && \
|
||||||
|
+ if $pkg_config --atleast-version=0.8.2 spice-server >/dev/null 2>&1 && \
|
||||||
|
compile_prog "$spice_cflags" "$spice_libs" ; then
|
||||||
|
spice="yes"
|
||||||
|
libs_softmmu="$libs_softmmu $spice_libs"
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 17f2576..0be9859 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -125,9 +125,7 @@ static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
|
||||||
|
|
||||||
|
void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
|
||||||
|
{
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
|
||||||
|
-#endif
|
||||||
|
if (qxl->guestdebug) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, msg);
|
||||||
|
@@ -149,12 +147,8 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
|
||||||
|
qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
|
||||||
|
dirty_rects, num_dirty_rects, clear_dirty_region);
|
||||||
|
} else {
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
|
||||||
|
clear_dirty_region, 0);
|
||||||
|
-#else
|
||||||
|
- abort();
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -171,24 +165,18 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async) {
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR < 1
|
||||||
|
- abort();
|
||||||
|
-#else
|
||||||
|
spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id,
|
||||||
|
(uint64_t)id);
|
||||||
|
-#endif
|
||||||
|
} else {
|
||||||
|
qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
|
||||||
|
qxl_spice_destroy_surface_wait_complete(qxl, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, 0);
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
|
||||||
|
uint32_t count)
|
||||||
|
@@ -217,11 +205,7 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
|
||||||
|
static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async) {
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR < 1
|
||||||
|
- abort();
|
||||||
|
-#else
|
||||||
|
spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0);
|
||||||
|
-#endif
|
||||||
|
} else {
|
||||||
|
qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
|
||||||
|
qxl_spice_destroy_surfaces_complete(qxl);
|
||||||
|
@@ -493,7 +477,6 @@ static const char *io_port_to_string(uint32_t io_port)
|
||||||
|
[QXL_IO_DESTROY_PRIMARY] = "QXL_IO_DESTROY_PRIMARY",
|
||||||
|
[QXL_IO_DESTROY_SURFACE_WAIT] = "QXL_IO_DESTROY_SURFACE_WAIT",
|
||||||
|
[QXL_IO_DESTROY_ALL_SURFACES] = "QXL_IO_DESTROY_ALL_SURFACES",
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
[QXL_IO_UPDATE_AREA_ASYNC] = "QXL_IO_UPDATE_AREA_ASYNC",
|
||||||
|
[QXL_IO_MEMSLOT_ADD_ASYNC] = "QXL_IO_MEMSLOT_ADD_ASYNC",
|
||||||
|
[QXL_IO_CREATE_PRIMARY_ASYNC] = "QXL_IO_CREATE_PRIMARY_ASYNC",
|
||||||
|
@@ -503,7 +486,6 @@ static const char *io_port_to_string(uint32_t io_port)
|
||||||
|
= "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",
|
||||||
|
[QXL_IO_FLUSH_SURFACES_ASYNC] = "QXL_IO_FLUSH_SURFACES_ASYNC",
|
||||||
|
[QXL_IO_FLUSH_RELEASE] = "QXL_IO_FLUSH_RELEASE",
|
||||||
|
-#endif
|
||||||
|
};
|
||||||
|
return io_port_to_string[io_port];
|
||||||
|
}
|
||||||
|
@@ -738,8 +720,6 @@ static int interface_flush_resources(QXLInstance *sin)
|
||||||
|
|
||||||
|
static void qxl_create_guest_primary_complete(PCIQXLDevice *d);
|
||||||
|
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
-
|
||||||
|
/* called from spice server thread context only */
|
||||||
|
static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
|
||||||
|
{
|
||||||
|
@@ -767,8 +747,6 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
|
||||||
|
qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
static const QXLInterface qxl_interface = {
|
||||||
|
.base.type = SPICE_INTERFACE_QXL,
|
||||||
|
.base.description = "qxl gpu",
|
||||||
|
@@ -788,9 +766,7 @@ static const QXLInterface qxl_interface = {
|
||||||
|
.req_cursor_notification = interface_req_cursor_notification,
|
||||||
|
.notify_update = interface_notify_update,
|
||||||
|
.flush_resources = interface_flush_resources,
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
.async_complete = interface_async_complete,
|
||||||
|
-#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void qxl_enter_vga_mode(PCIQXLDevice *d)
|
||||||
|
@@ -1140,9 +1116,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
|
||||||
|
PCIQXLDevice *d = opaque;
|
||||||
|
uint32_t io_port = addr;
|
||||||
|
qxl_async_io async = QXL_SYNC;
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
uint32_t orig_io_port = io_port;
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
switch (io_port) {
|
||||||
|
case QXL_IO_RESET:
|
||||||
|
@@ -1152,10 +1126,8 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
|
||||||
|
case QXL_IO_CREATE_PRIMARY:
|
||||||
|
case QXL_IO_UPDATE_IRQ:
|
||||||
|
case QXL_IO_LOG:
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
case QXL_IO_MEMSLOT_ADD_ASYNC:
|
||||||
|
case QXL_IO_CREATE_PRIMARY_ASYNC:
|
||||||
|
-#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (d->mode != QXL_MODE_VGA) {
|
||||||
|
@@ -1163,17 +1135,14 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
|
||||||
|
}
|
||||||
|
dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
|
||||||
|
__func__, io_port, io_port_to_string(io_port));
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
/* be nice to buggy guest drivers */
|
||||||
|
if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
|
||||||
|
io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
|
||||||
|
qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
/* we change the io_port to avoid ifdeffery in the main switch */
|
||||||
|
orig_io_port = io_port;
|
||||||
|
switch (io_port) {
|
||||||
|
@@ -1212,7 +1181,6 @@ async_common:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
switch (io_port) {
|
||||||
|
case QXL_IO_UPDATE_AREA:
|
||||||
|
@@ -1304,7 +1272,6 @@ async_common:
|
||||||
|
}
|
||||||
|
qxl_spice_destroy_surface_wait(d, val, async);
|
||||||
|
break;
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
case QXL_IO_FLUSH_RELEASE: {
|
||||||
|
QXLReleaseRing *ring = &d->ram->release_ring;
|
||||||
|
if (ring->prod - ring->cons + 1 == ring->num_items) {
|
||||||
|
@@ -1325,7 +1292,6 @@ async_common:
|
||||||
|
d->num_free_res);
|
||||||
|
qxl_spice_flush_surfaces_async(d);
|
||||||
|
break;
|
||||||
|
-#endif
|
||||||
|
case QXL_IO_DESTROY_ALL_SURFACES:
|
||||||
|
d->mode = QXL_MODE_UNDEFINED;
|
||||||
|
qxl_spice_destroy_surfaces(d, async);
|
||||||
|
@@ -1336,16 +1302,12 @@ async_common:
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
cancel_async:
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
if (async) {
|
||||||
|
qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
|
||||||
|
qemu_mutex_lock(&d->async_lock);
|
||||||
|
d->current_async = QXL_UNDEFINED_IO;
|
||||||
|
qemu_mutex_unlock(&d->async_lock);
|
||||||
|
}
|
||||||
|
-#else
|
||||||
|
- return;
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
|
||||||
|
@@ -1607,9 +1569,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
|
||||||
|
case 2: /* spice 0.6 -- qxl-2 */
|
||||||
|
pci_device_rev = QXL_REVISION_STABLE_V06;
|
||||||
|
break;
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
case 3: /* qxl-3 */
|
||||||
|
-#endif
|
||||||
|
default:
|
||||||
|
pci_device_rev = QXL_DEFAULT_REVISION;
|
||||||
|
break;
|
||||||
|
diff --git a/hw/qxl.h b/hw/qxl.h
|
||||||
|
index a615eca..9288e46 100644
|
||||||
|
--- a/hw/qxl.h
|
||||||
|
+++ b/hw/qxl.h
|
||||||
|
@@ -108,11 +108,7 @@ typedef struct PCIQXLDevice {
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
|
||||||
|
-#else
|
||||||
|
-#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V06
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
/* qxl.c */
|
||||||
|
void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
|
||||||
|
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||||
|
index 27216e9..2c815f1 100644
|
||||||
|
--- a/ui/spice-core.c
|
||||||
|
+++ b/ui/spice-core.c
|
||||||
|
@@ -139,8 +139,6 @@ static void watch_remove(SpiceWatch *watch)
|
||||||
|
g_free(watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if SPICE_INTERFACE_CORE_MINOR >= 3
|
||||||
|
-
|
||||||
|
typedef struct ChannelList ChannelList;
|
||||||
|
struct ChannelList {
|
||||||
|
SpiceChannelEventInfo *info;
|
||||||
|
@@ -257,15 +255,6 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-#else /* SPICE_INTERFACE_CORE_MINOR >= 3 */
|
||||||
|
-
|
||||||
|
-static QList *channel_list_get(void)
|
||||||
|
-{
|
||||||
|
- return NULL;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#endif /* SPICE_INTERFACE_CORE_MINOR >= 3 */
|
||||||
|
-
|
||||||
|
static SpiceCoreInterface core_interface = {
|
||||||
|
.base.type = SPICE_INTERFACE_CORE,
|
||||||
|
.base.description = "qemu core services",
|
||||||
|
@@ -281,9 +270,7 @@ static SpiceCoreInterface core_interface = {
|
||||||
|
.watch_update_mask = watch_update_mask,
|
||||||
|
.watch_remove = watch_remove,
|
||||||
|
|
||||||
|
-#if SPICE_INTERFACE_CORE_MINOR >= 3
|
||||||
|
.channel_event = channel_event,
|
||||||
|
-#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef SPICE_INTERFACE_MIGRATION
|
||||||
|
@@ -490,7 +477,6 @@ static void migration_state_notifier(Notifier *notifier, void *data)
|
||||||
|
spice_server_migrate_start(spice_server);
|
||||||
|
#endif
|
||||||
|
} else if (migration_has_finished(s)) {
|
||||||
|
-#if SPICE_SERVER_VERSION >= 0x000701 /* 0.7.1 */
|
||||||
|
#ifndef SPICE_INTERFACE_MIGRATION
|
||||||
|
spice_server_migrate_switch(spice_server);
|
||||||
|
#else
|
||||||
|
@@ -498,7 +484,6 @@ static void migration_state_notifier(Notifier *notifier, void *data)
|
||||||
|
} else if (migration_has_failed(s)) {
|
||||||
|
spice_server_migrate_end(spice_server, false);
|
||||||
|
#endif
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -659,11 +644,9 @@ void qemu_spice_init(void)
|
||||||
|
spice_server_set_noauth(spice_server);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if SPICE_SERVER_VERSION >= 0x000801
|
||||||
|
if (qemu_opt_get_bool(opts, "disable-copy-paste", 0)) {
|
||||||
|
spice_server_set_agent_copypaste(spice_server, false);
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
compression = SPICE_IMAGE_COMPRESS_AUTO_GLZ;
|
||||||
|
str = qemu_opt_get(opts, "image-compression");
|
||||||
|
diff --git a/ui/spice-display.c b/ui/spice-display.c
|
||||||
|
index c6e61d8..ad76bae 100644
|
||||||
|
--- a/ui/spice-display.c
|
||||||
|
+++ b/ui/spice-display.c
|
||||||
|
@@ -64,11 +64,7 @@ void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
spice_qxl_add_memslot_async(&ssd->qxl, memslot, 0);
|
||||||
|
-#else
|
||||||
|
- abort();
|
||||||
|
-#endif
|
||||||
|
} else {
|
||||||
|
ssd->worker->add_memslot(ssd->worker, memslot);
|
||||||
|
}
|
||||||
|
@@ -84,11 +80,7 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, 0);
|
||||||
|
-#else
|
||||||
|
- abort();
|
||||||
|
-#endif
|
||||||
|
} else {
|
||||||
|
ssd->worker->create_primary_surface(ssd->worker, id, surface);
|
||||||
|
}
|
||||||
|
@@ -99,11 +91,7 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
|
||||||
|
uint32_t id, qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
-#if SPICE_INTERFACE_QXL_MINOR >= 1
|
||||||
|
spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, 0);
|
||||||
|
-#else
|
||||||
|
- abort();
|
||||||
|
-#endif
|
||||||
|
} else {
|
||||||
|
ssd->worker->destroy_primary_surface(ssd->worker, id);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
145
0416-qxl-remove-flipped.patch
Normal file
145
0416-qxl-remove-flipped.patch
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
From f9344933bcc1425cf1e8142dc2f8321522dc00af Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 23:19:29 +0200
|
||||||
|
Subject: [PATCH 416/434] qxl: remove flipped
|
||||||
|
|
||||||
|
Tested on linux and windows guests. For negative stride, qxl_flip copies
|
||||||
|
directly to vga->ds->surface->data, for positive it's reallocated to
|
||||||
|
share qxl->guest_primary.data
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl-render.c | 66 +++++++++++++++++++++++++------------------------------
|
||||||
|
hw/qxl.h | 2 +-
|
||||||
|
2 files changed, 31 insertions(+), 37 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
|
||||||
|
index a7891b2..5811d74 100644
|
||||||
|
--- a/hw/qxl-render.c
|
||||||
|
+++ b/hw/qxl-render.c
|
||||||
|
@@ -23,10 +23,21 @@
|
||||||
|
|
||||||
|
static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
|
||||||
|
{
|
||||||
|
- uint8_t *src = qxl->guest_primary.data;
|
||||||
|
- uint8_t *dst = qxl->guest_primary.flipped;
|
||||||
|
+ uint8_t *src;
|
||||||
|
+ uint8_t *dst = qxl->vga.ds->surface->data;
|
||||||
|
int len, i;
|
||||||
|
|
||||||
|
+ if (qxl->guest_primary.qxl_stride > 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (!qxl->guest_primary.data) {
|
||||||
|
+ dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__);
|
||||||
|
+ qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||||
|
+ }
|
||||||
|
+ dprint(qxl, 1, "%s: stride %d, [%d, %d, %d, %d]\n", __func__,
|
||||||
|
+ qxl->guest_primary.qxl_stride,
|
||||||
|
+ rect->left, rect->right, rect->top, rect->bottom);
|
||||||
|
+ src = qxl->guest_primary.data;
|
||||||
|
src += (qxl->guest_primary.surface.height - rect->top - 1) *
|
||||||
|
qxl->guest_primary.abs_stride;
|
||||||
|
dst += rect->top * qxl->guest_primary.abs_stride;
|
||||||
|
@@ -75,52 +86,38 @@ void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
VGACommonState *vga = &qxl->vga;
|
||||||
|
QXLRect dirty[32], update;
|
||||||
|
- void *ptr;
|
||||||
|
int i, redraw = 0;
|
||||||
|
-
|
||||||
|
- if (!is_buffer_shared(vga->ds->surface)) {
|
||||||
|
- dprint(qxl, 1, "%s: restoring shared displaysurface\n", __func__);
|
||||||
|
- qxl->guest_primary.resized++;
|
||||||
|
- qxl->guest_primary.commands++;
|
||||||
|
- redraw = 1;
|
||||||
|
- }
|
||||||
|
+ DisplaySurface *surface = vga->ds->surface;
|
||||||
|
|
||||||
|
if (qxl->guest_primary.resized) {
|
||||||
|
qxl->guest_primary.resized = 0;
|
||||||
|
|
||||||
|
- if (qxl->guest_primary.flipped) {
|
||||||
|
- g_free(qxl->guest_primary.flipped);
|
||||||
|
- qxl->guest_primary.flipped = NULL;
|
||||||
|
- }
|
||||||
|
- qemu_free_displaysurface(vga->ds);
|
||||||
|
-
|
||||||
|
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||||
|
- if (qxl->guest_primary.qxl_stride < 0) {
|
||||||
|
- /* spice surface is upside down -> need extra buffer to flip */
|
||||||
|
- qxl->guest_primary.flipped =
|
||||||
|
- g_malloc(qxl->guest_primary.surface.width *
|
||||||
|
- qxl->guest_primary.abs_stride);
|
||||||
|
- ptr = qxl->guest_primary.flipped;
|
||||||
|
- } else {
|
||||||
|
- ptr = qxl->guest_primary.data;
|
||||||
|
- }
|
||||||
|
- dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
|
||||||
|
+ dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height,
|
||||||
|
qxl->guest_primary.qxl_stride,
|
||||||
|
qxl->guest_primary.bytes_pp,
|
||||||
|
- qxl->guest_primary.bits_pp,
|
||||||
|
- qxl->guest_primary.flipped ? "yes" : "no");
|
||||||
|
- vga->ds->surface =
|
||||||
|
+ qxl->guest_primary.bits_pp);
|
||||||
|
+ }
|
||||||
|
+ if (surface->width != qxl->guest_primary.surface.width ||
|
||||||
|
+ surface->height != qxl->guest_primary.surface.height) {
|
||||||
|
+ dprint(qxl, 1, "%s: resizing displaysurface to guest_primary\n",
|
||||||
|
+ __func__);
|
||||||
|
+ if (qxl->guest_primary.qxl_stride > 0) {
|
||||||
|
+ qemu_free_displaysurface(vga->ds);
|
||||||
|
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height,
|
||||||
|
qxl->guest_primary.bits_pp,
|
||||||
|
qxl->guest_primary.abs_stride,
|
||||||
|
- ptr);
|
||||||
|
- dpy_resize(vga->ds);
|
||||||
|
+ qxl->guest_primary.data);
|
||||||
|
+ } else {
|
||||||
|
+ qemu_resize_displaysurface(vga->ds,
|
||||||
|
+ qxl->guest_primary.surface.width,
|
||||||
|
+ qxl->guest_primary.surface.height);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
-
|
||||||
|
update.left = 0;
|
||||||
|
update.right = qxl->guest_primary.surface.width;
|
||||||
|
update.top = 0;
|
||||||
|
@@ -136,14 +133,11 @@ void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
memset(dirty, 0, sizeof(dirty));
|
||||||
|
dirty[0] = update;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
for (i = 0; i < ARRAY_SIZE(dirty); i++) {
|
||||||
|
if (qemu_spice_rect_is_empty(dirty+i)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- if (qxl->guest_primary.flipped) {
|
||||||
|
- qxl_flip(qxl, dirty+i);
|
||||||
|
- }
|
||||||
|
+ qxl_flip(qxl, dirty+i);
|
||||||
|
dpy_update(vga->ds,
|
||||||
|
dirty[i].left, dirty[i].top,
|
||||||
|
dirty[i].right - dirty[i].left,
|
||||||
|
diff --git a/hw/qxl.h b/hw/qxl.h
|
||||||
|
index 9288e46..53a3ace 100644
|
||||||
|
--- a/hw/qxl.h
|
||||||
|
+++ b/hw/qxl.h
|
||||||
|
@@ -52,7 +52,7 @@ typedef struct PCIQXLDevice {
|
||||||
|
uint32_t abs_stride;
|
||||||
|
uint32_t bits_pp;
|
||||||
|
uint32_t bytes_pp;
|
||||||
|
- uint8_t *data, *flipped;
|
||||||
|
+ uint8_t *data;
|
||||||
|
} guest_primary;
|
||||||
|
|
||||||
|
struct surfaces {
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
264
0417-qxl-introduce-QXLCookie.patch
Normal file
264
0417-qxl-introduce-QXLCookie.patch
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
From bbe362cd6a386d98a94ac791f1263671bd79b754 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 23:19:30 +0200
|
||||||
|
Subject: [PATCH 417/434] qxl: introduce QXLCookie
|
||||||
|
|
||||||
|
Will be used in the next patch.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl-render.c | 2 +-
|
||||||
|
hw/qxl.c | 61 ++++++++++++++++++++++++++++++++++++++++------------
|
||||||
|
hw/qxl.h | 2 +-
|
||||||
|
ui/spice-display.c | 22 ++++++++++++++++---
|
||||||
|
ui/spice-display.h | 14 ++++++++++++
|
||||||
|
5 files changed, 82 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
|
||||||
|
index 5811d74..4c22166 100644
|
||||||
|
--- a/hw/qxl-render.c
|
||||||
|
+++ b/hw/qxl-render.c
|
||||||
|
@@ -127,7 +127,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
if (runstate_is_running() && qxl->guest_primary.commands) {
|
||||||
|
qxl->guest_primary.commands = 0;
|
||||||
|
qxl_spice_update_area(qxl, 0, &update,
|
||||||
|
- dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
|
||||||
|
+ dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC, NULL);
|
||||||
|
}
|
||||||
|
if (redraw) {
|
||||||
|
memset(dirty, 0, sizeof(dirty));
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 0be9859..e6e65d9 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -141,14 +141,15 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
|
||||||
|
struct QXLRect *area, struct QXLRect *dirty_rects,
|
||||||
|
uint32_t num_dirty_rects,
|
||||||
|
uint32_t clear_dirty_region,
|
||||||
|
- qxl_async_io async)
|
||||||
|
+ qxl_async_io async, struct QXLCookie *cookie)
|
||||||
|
{
|
||||||
|
if (async == QXL_SYNC) {
|
||||||
|
qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
|
||||||
|
dirty_rects, num_dirty_rects, clear_dirty_region);
|
||||||
|
} else {
|
||||||
|
+ assert(cookie != NULL);
|
||||||
|
spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
|
||||||
|
- clear_dirty_region, 0);
|
||||||
|
+ clear_dirty_region, (uint64_t)cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -164,9 +165,13 @@ static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
|
||||||
|
static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
+ QXLCookie *cookie;
|
||||||
|
+
|
||||||
|
if (async) {
|
||||||
|
- spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id,
|
||||||
|
- (uint64_t)id);
|
||||||
|
+ cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_DESTROY_SURFACE_ASYNC);
|
||||||
|
+ cookie->u.surface_id = id;
|
||||||
|
+ spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uint64_t)cookie);
|
||||||
|
} else {
|
||||||
|
qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
|
||||||
|
qxl_spice_destroy_surface_wait_complete(qxl, id);
|
||||||
|
@@ -175,7 +180,9 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
|
||||||
|
|
||||||
|
static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
- spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, 0);
|
||||||
|
+ spice_qxl_flush_surfaces_async(&qxl->ssd.qxl,
|
||||||
|
+ (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_FLUSH_SURFACES_ASYNC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
|
||||||
|
@@ -205,7 +212,9 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
|
||||||
|
static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async) {
|
||||||
|
- spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0);
|
||||||
|
+ spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl,
|
||||||
|
+ (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
|
||||||
|
} else {
|
||||||
|
qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
|
||||||
|
qxl_spice_destroy_surfaces_complete(qxl);
|
||||||
|
@@ -721,9 +730,8 @@ static int interface_flush_resources(QXLInstance *sin)
|
||||||
|
static void qxl_create_guest_primary_complete(PCIQXLDevice *d);
|
||||||
|
|
||||||
|
/* called from spice server thread context only */
|
||||||
|
-static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
|
||||||
|
+static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
|
||||||
|
{
|
||||||
|
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
uint32_t current_async;
|
||||||
|
|
||||||
|
qemu_mutex_lock(&qxl->async_lock);
|
||||||
|
@@ -731,8 +739,16 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
|
||||||
|
qxl->current_async = QXL_UNDEFINED_IO;
|
||||||
|
qemu_mutex_unlock(&qxl->async_lock);
|
||||||
|
|
||||||
|
- dprint(qxl, 2, "async_complete: %d (%" PRId64 ") done\n",
|
||||||
|
- current_async, cookie);
|
||||||
|
+ dprint(qxl, 2, "async_complete: %d (%p) done\n", current_async, cookie);
|
||||||
|
+ if (!cookie) {
|
||||||
|
+ fprintf(stderr, "qxl: %s: error, cookie is NULL\n", __func__);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (cookie && current_async != cookie->io) {
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "qxl: %s: error: current_async = %d != %ld = cookie->io\n",
|
||||||
|
+ __func__, current_async, cookie->io);
|
||||||
|
+ }
|
||||||
|
switch (current_async) {
|
||||||
|
case QXL_IO_CREATE_PRIMARY_ASYNC:
|
||||||
|
qxl_create_guest_primary_complete(qxl);
|
||||||
|
@@ -741,12 +757,29 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
|
||||||
|
qxl_spice_destroy_surfaces_complete(qxl);
|
||||||
|
break;
|
||||||
|
case QXL_IO_DESTROY_SURFACE_ASYNC:
|
||||||
|
- qxl_spice_destroy_surface_wait_complete(qxl, (uint32_t)cookie);
|
||||||
|
+ qxl_spice_destroy_surface_wait_complete(qxl, cookie->u.surface_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* called from spice server thread context only */
|
||||||
|
+static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
|
||||||
|
+{
|
||||||
|
+ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
+ QXLCookie *cookie = (QXLCookie *)cookie_token;
|
||||||
|
+
|
||||||
|
+ switch (cookie->type) {
|
||||||
|
+ case QXL_COOKIE_TYPE_IO:
|
||||||
|
+ interface_async_complete_io(qxl, cookie);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ fprintf(stderr, "qxl: %s: unexpected cookie type %d\n",
|
||||||
|
+ __func__, cookie->type);
|
||||||
|
+ }
|
||||||
|
+ g_free(cookie);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const QXLInterface qxl_interface = {
|
||||||
|
.base.type = SPICE_INTERFACE_QXL,
|
||||||
|
.base.description = "qxl gpu",
|
||||||
|
@@ -1057,9 +1090,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
|
||||||
|
if (d->mode == QXL_MODE_UNDEFINED) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
dprint(d, 1, "%s\n", __FUNCTION__);
|
||||||
|
-
|
||||||
|
d->mode = QXL_MODE_UNDEFINED;
|
||||||
|
qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
|
||||||
|
qxl_spice_reset_cursor(d);
|
||||||
|
@@ -1187,7 +1218,9 @@ async_common:
|
||||||
|
{
|
||||||
|
QXLRect update = d->ram->update_area;
|
||||||
|
qxl_spice_update_area(d, d->ram->update_surface,
|
||||||
|
- &update, NULL, 0, 0, async);
|
||||||
|
+ &update, NULL, 0, 0, async,
|
||||||
|
+ qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_UPDATE_AREA_ASYNC));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QXL_IO_NOTIFY_CMD:
|
||||||
|
diff --git a/hw/qxl.h b/hw/qxl.h
|
||||||
|
index 53a3ace..1443925 100644
|
||||||
|
--- a/hw/qxl.h
|
||||||
|
+++ b/hw/qxl.h
|
||||||
|
@@ -118,7 +118,7 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
|
||||||
|
struct QXLRect *area, struct QXLRect *dirty_rects,
|
||||||
|
uint32_t num_dirty_rects,
|
||||||
|
uint32_t clear_dirty_region,
|
||||||
|
- qxl_async_io async);
|
||||||
|
+ qxl_async_io async, QXLCookie *cookie);
|
||||||
|
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
|
||||||
|
uint32_t count);
|
||||||
|
void qxl_spice_oom(PCIQXLDevice *qxl);
|
||||||
|
diff --git a/ui/spice-display.c b/ui/spice-display.c
|
||||||
|
index ad76bae..ab266ae 100644
|
||||||
|
--- a/ui/spice-display.c
|
||||||
|
+++ b/ui/spice-display.c
|
||||||
|
@@ -60,11 +60,23 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
|
||||||
|
dest->right = MAX(dest->right, r->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
+QXLCookie *qxl_cookie_new(int type, uint64_t io)
|
||||||
|
+{
|
||||||
|
+ QXLCookie *cookie;
|
||||||
|
+
|
||||||
|
+ cookie = g_malloc0(sizeof(*cookie));
|
||||||
|
+ cookie->type = type;
|
||||||
|
+ cookie->io = io;
|
||||||
|
+ return cookie;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
- spice_qxl_add_memslot_async(&ssd->qxl, memslot, 0);
|
||||||
|
+ spice_qxl_add_memslot_async(&ssd->qxl, memslot,
|
||||||
|
+ (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_MEMSLOT_ADD_ASYNC));
|
||||||
|
} else {
|
||||||
|
ssd->worker->add_memslot(ssd->worker, memslot);
|
||||||
|
}
|
||||||
|
@@ -80,7 +92,9 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
- spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, 0);
|
||||||
|
+ spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface,
|
||||||
|
+ (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_CREATE_PRIMARY_ASYNC));
|
||||||
|
} else {
|
||||||
|
ssd->worker->create_primary_surface(ssd->worker, id, surface);
|
||||||
|
}
|
||||||
|
@@ -91,7 +105,9 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
|
||||||
|
uint32_t id, qxl_async_io async)
|
||||||
|
{
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
- spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, 0);
|
||||||
|
+ spice_qxl_destroy_primary_surface_async(&ssd->qxl, id,
|
||||||
|
+ (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_DESTROY_PRIMARY_ASYNC));
|
||||||
|
} else {
|
||||||
|
ssd->worker->destroy_primary_surface(ssd->worker, id);
|
||||||
|
}
|
||||||
|
diff --git a/ui/spice-display.h b/ui/spice-display.h
|
||||||
|
index a23bfc8..8a010cb 100644
|
||||||
|
--- a/ui/spice-display.h
|
||||||
|
+++ b/ui/spice-display.h
|
||||||
|
@@ -48,6 +48,20 @@ typedef enum qxl_async_io {
|
||||||
|
QXL_ASYNC,
|
||||||
|
} qxl_async_io;
|
||||||
|
|
||||||
|
+enum {
|
||||||
|
+ QXL_COOKIE_TYPE_IO,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct QXLCookie {
|
||||||
|
+ int type;
|
||||||
|
+ uint64_t io;
|
||||||
|
+ union {
|
||||||
|
+ uint32_t surface_id;
|
||||||
|
+ } u;
|
||||||
|
+} QXLCookie;
|
||||||
|
+
|
||||||
|
+QXLCookie *qxl_cookie_new(int type, uint64_t io);
|
||||||
|
+
|
||||||
|
typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
|
||||||
|
typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
360
0418-qxl-make-qxl_render_update-async.patch
Normal file
360
0418-qxl-make-qxl_render_update-async.patch
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
From c26805e29312fee136008a57c70a2f5f140ba706 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 23:19:31 +0200
|
||||||
|
Subject: [PATCH 418/434] qxl: make qxl_render_update async
|
||||||
|
|
||||||
|
RHBZ# 747011
|
||||||
|
|
||||||
|
Removes the last user of QXL_SYNC when using update drivers that use the
|
||||||
|
_ASYNC io ports.
|
||||||
|
|
||||||
|
The last user is qxl_render_update, it is called both by qxl_hw_update
|
||||||
|
which is the vga_hw_update_ptr passed to graphic_console_init, and by
|
||||||
|
qxl_hw_screen_dump.
|
||||||
|
|
||||||
|
At the same time the QXLRect area being passed to the red_worker thread
|
||||||
|
is passed as a copy, as part of the QXLCookie.
|
||||||
|
|
||||||
|
The implementation uses interface_update_area_complete with a bh to make
|
||||||
|
sure dpy_update and qxl_flip are called from the io thread, otherwise
|
||||||
|
the vga->ds->surface.data can change under our feet.
|
||||||
|
|
||||||
|
With this patch sdl+spice works fine. But spice by itself doesn't
|
||||||
|
produce the expected screendumps unless repeated a few times, due to
|
||||||
|
ppm_save being called before update_area (rendering done in spice server
|
||||||
|
thread) having a chance to complete. Fixed by next patch, but see commit
|
||||||
|
message for problem introduced by it.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl-render.c | 96 +++++++++++++++++++++++++++++++++++++---------------
|
||||||
|
hw/qxl.c | 69 ++++++++++++++++++++++++++++++++++---
|
||||||
|
hw/qxl.h | 10 ++++++
|
||||||
|
ui/spice-display.h | 6 ++++
|
||||||
|
4 files changed, 150 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
|
||||||
|
index 4c22166..4857838 100644
|
||||||
|
--- a/hw/qxl-render.c
|
||||||
|
+++ b/hw/qxl-render.c
|
||||||
|
@@ -82,17 +82,25 @@ void qxl_render_resize(PCIQXLDevice *qxl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
+static void qxl_set_rect_to_surface(PCIQXLDevice *qxl, QXLRect *area)
|
||||||
|
+{
|
||||||
|
+ area->left = 0;
|
||||||
|
+ area->right = qxl->guest_primary.surface.width;
|
||||||
|
+ area->top = 0;
|
||||||
|
+ area->bottom = qxl->guest_primary.surface.height;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
VGACommonState *vga = &qxl->vga;
|
||||||
|
- QXLRect dirty[32], update;
|
||||||
|
- int i, redraw = 0;
|
||||||
|
+ int i;
|
||||||
|
DisplaySurface *surface = vga->ds->surface;
|
||||||
|
|
||||||
|
if (qxl->guest_primary.resized) {
|
||||||
|
qxl->guest_primary.resized = 0;
|
||||||
|
-
|
||||||
|
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||||
|
+ qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
|
||||||
|
+ qxl->num_dirty_rects = 1;
|
||||||
|
dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
qxl->guest_primary.surface.width,
|
||||||
|
@@ -103,9 +111,9 @@ void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
}
|
||||||
|
if (surface->width != qxl->guest_primary.surface.width ||
|
||||||
|
surface->height != qxl->guest_primary.surface.height) {
|
||||||
|
- dprint(qxl, 1, "%s: resizing displaysurface to guest_primary\n",
|
||||||
|
- __func__);
|
||||||
|
if (qxl->guest_primary.qxl_stride > 0) {
|
||||||
|
+ dprint(qxl, 1, "%s: using guest_primary for displaysurface\n",
|
||||||
|
+ __func__);
|
||||||
|
qemu_free_displaysurface(vga->ds);
|
||||||
|
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height,
|
||||||
|
@@ -113,36 +121,70 @@ void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
qxl->guest_primary.abs_stride,
|
||||||
|
qxl->guest_primary.data);
|
||||||
|
} else {
|
||||||
|
+ dprint(qxl, 1, "%s: resizing displaysurface to guest_primary\n",
|
||||||
|
+ __func__);
|
||||||
|
qemu_resize_displaysurface(vga->ds,
|
||||||
|
qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- update.left = 0;
|
||||||
|
- update.right = qxl->guest_primary.surface.width;
|
||||||
|
- update.top = 0;
|
||||||
|
- update.bottom = qxl->guest_primary.surface.height;
|
||||||
|
-
|
||||||
|
- memset(dirty, 0, sizeof(dirty));
|
||||||
|
- if (runstate_is_running() && qxl->guest_primary.commands) {
|
||||||
|
- qxl->guest_primary.commands = 0;
|
||||||
|
- qxl_spice_update_area(qxl, 0, &update,
|
||||||
|
- dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC, NULL);
|
||||||
|
- }
|
||||||
|
- if (redraw) {
|
||||||
|
- memset(dirty, 0, sizeof(dirty));
|
||||||
|
- dirty[0] = update;
|
||||||
|
- }
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(dirty); i++) {
|
||||||
|
- if (qemu_spice_rect_is_empty(dirty+i)) {
|
||||||
|
+ for (i = 0; i < qxl->num_dirty_rects; i++) {
|
||||||
|
+ if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- qxl_flip(qxl, dirty+i);
|
||||||
|
+ qxl_flip(qxl, qxl->dirty+i);
|
||||||
|
dpy_update(vga->ds,
|
||||||
|
- dirty[i].left, dirty[i].top,
|
||||||
|
- dirty[i].right - dirty[i].left,
|
||||||
|
- dirty[i].bottom - dirty[i].top);
|
||||||
|
+ qxl->dirty[i].left, qxl->dirty[i].top,
|
||||||
|
+ qxl->dirty[i].right - qxl->dirty[i].left,
|
||||||
|
+ qxl->dirty[i].bottom - qxl->dirty[i].top);
|
||||||
|
+ }
|
||||||
|
+ qxl->num_dirty_rects = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * use ssd.lock to protect render_update_cookie_num.
|
||||||
|
+ * qxl_render_update is called by io thread or vcpu thread, and the completion
|
||||||
|
+ * callbacks are called by spice_server thread, defering to bh called from the
|
||||||
|
+ * io thread.
|
||||||
|
+ */
|
||||||
|
+void qxl_render_update(PCIQXLDevice *qxl)
|
||||||
|
+{
|
||||||
|
+ QXLCookie *cookie;
|
||||||
|
+
|
||||||
|
+ qemu_mutex_lock(&qxl->ssd.lock);
|
||||||
|
+
|
||||||
|
+ if (!runstate_is_running() || !qxl->guest_primary.commands) {
|
||||||
|
+ qxl_render_update_area_unlocked(qxl);
|
||||||
|
+ qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ qxl->guest_primary.commands = 0;
|
||||||
|
+ qxl->render_update_cookie_num++;
|
||||||
|
+ qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
+ cookie = qxl_cookie_new(QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
|
||||||
|
+ 0);
|
||||||
|
+ qxl_set_rect_to_surface(qxl, &cookie->u.render.area);
|
||||||
|
+ qxl_spice_update_area(qxl, 0, &cookie->u.render.area, NULL,
|
||||||
|
+ 0, 1 /* clear_dirty_region */, QXL_ASYNC, cookie);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void qxl_render_update_area_bh(void *opaque)
|
||||||
|
+{
|
||||||
|
+ PCIQXLDevice *qxl = opaque;
|
||||||
|
+
|
||||||
|
+ qemu_mutex_lock(&qxl->ssd.lock);
|
||||||
|
+ qxl_render_update_area_unlocked(qxl);
|
||||||
|
+ qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
|
||||||
|
+{
|
||||||
|
+ qemu_mutex_lock(&qxl->ssd.lock);
|
||||||
|
+ qemu_bh_schedule(qxl->update_area_bh);
|
||||||
|
+ qxl->render_update_cookie_num--;
|
||||||
|
+ qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
+ g_free(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index e6e65d9..73be115 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -750,6 +750,11 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
|
||||||
|
__func__, current_async, cookie->io);
|
||||||
|
}
|
||||||
|
switch (current_async) {
|
||||||
|
+ case QXL_IO_MEMSLOT_ADD_ASYNC:
|
||||||
|
+ case QXL_IO_DESTROY_PRIMARY_ASYNC:
|
||||||
|
+ case QXL_IO_UPDATE_AREA_ASYNC:
|
||||||
|
+ case QXL_IO_FLUSH_SURFACES_ASYNC:
|
||||||
|
+ break;
|
||||||
|
case QXL_IO_CREATE_PRIMARY_ASYNC:
|
||||||
|
qxl_create_guest_primary_complete(qxl);
|
||||||
|
break;
|
||||||
|
@@ -759,11 +764,54 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
|
||||||
|
case QXL_IO_DESTROY_SURFACE_ASYNC:
|
||||||
|
qxl_spice_destroy_surface_wait_complete(qxl, cookie->u.surface_id);
|
||||||
|
break;
|
||||||
|
+ default:
|
||||||
|
+ fprintf(stderr, "qxl: %s: unexpected current_async %d\n", __func__,
|
||||||
|
+ current_async);
|
||||||
|
}
|
||||||
|
qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called from spice server thread context only */
|
||||||
|
+static void interface_update_area_complete(QXLInstance *sin,
|
||||||
|
+ uint32_t surface_id,
|
||||||
|
+ QXLRect *dirty, uint32_t num_updated_rects)
|
||||||
|
+{
|
||||||
|
+ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
+ int i;
|
||||||
|
+ int qxl_i;
|
||||||
|
+
|
||||||
|
+ qemu_mutex_lock(&qxl->ssd.lock);
|
||||||
|
+ if (surface_id != 0 || !qxl->render_update_cookie_num) {
|
||||||
|
+ qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (qxl->num_dirty_rects + num_updated_rects > QXL_NUM_DIRTY_RECTS) {
|
||||||
|
+ /*
|
||||||
|
+ * overflow - treat this as a full update. Not expected to be common.
|
||||||
|
+ */
|
||||||
|
+ dprint(qxl, 1, "%s: overflow of dirty rects\n", __func__);
|
||||||
|
+ qxl->guest_primary.resized = 1;
|
||||||
|
+ }
|
||||||
|
+ if (qxl->guest_primary.resized) {
|
||||||
|
+ /*
|
||||||
|
+ * Don't bother copying or scheduling the bh since we will flip
|
||||||
|
+ * the whole area anyway on completion of the update_area async call
|
||||||
|
+ */
|
||||||
|
+ qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ qxl_i = qxl->num_dirty_rects;
|
||||||
|
+ for (i = 0; i < num_updated_rects; i++) {
|
||||||
|
+ qxl->dirty[qxl_i++] = dirty[i];
|
||||||
|
+ }
|
||||||
|
+ qxl->num_dirty_rects += num_updated_rects;
|
||||||
|
+ dprint(qxl, 1, "%s: scheduling update_area_bh, #dirty %d\n",
|
||||||
|
+ __func__, qxl->num_dirty_rects);
|
||||||
|
+ qemu_bh_schedule(qxl->update_area_bh);
|
||||||
|
+ qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* called from spice server thread context only */
|
||||||
|
static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
@@ -772,12 +820,16 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
|
||||||
|
switch (cookie->type) {
|
||||||
|
case QXL_COOKIE_TYPE_IO:
|
||||||
|
interface_async_complete_io(qxl, cookie);
|
||||||
|
+ g_free(cookie);
|
||||||
|
+ break;
|
||||||
|
+ case QXL_COOKIE_TYPE_RENDER_UPDATE_AREA:
|
||||||
|
+ qxl_render_update_area_done(qxl, cookie);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "qxl: %s: unexpected cookie type %d\n",
|
||||||
|
__func__, cookie->type);
|
||||||
|
+ g_free(cookie);
|
||||||
|
}
|
||||||
|
- g_free(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QXLInterface qxl_interface = {
|
||||||
|
@@ -800,6 +852,7 @@ static const QXLInterface qxl_interface = {
|
||||||
|
.notify_update = interface_notify_update,
|
||||||
|
.flush_resources = interface_flush_resources,
|
||||||
|
.async_complete = interface_async_complete,
|
||||||
|
+ .update_area_complete = interface_update_area_complete,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void qxl_enter_vga_mode(PCIQXLDevice *d)
|
||||||
|
@@ -1216,11 +1269,17 @@ async_common:
|
||||||
|
switch (io_port) {
|
||||||
|
case QXL_IO_UPDATE_AREA:
|
||||||
|
{
|
||||||
|
+ QXLCookie *cookie = NULL;
|
||||||
|
QXLRect update = d->ram->update_area;
|
||||||
|
+
|
||||||
|
+ if (async == QXL_ASYNC) {
|
||||||
|
+ cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_UPDATE_AREA_ASYNC);
|
||||||
|
+ cookie->u.area = update;
|
||||||
|
+ }
|
||||||
|
qxl_spice_update_area(d, d->ram->update_surface,
|
||||||
|
- &update, NULL, 0, 0, async,
|
||||||
|
- qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
- QXL_IO_UPDATE_AREA_ASYNC));
|
||||||
|
+ cookie ? &cookie->u.area : &update,
|
||||||
|
+ NULL, 0, 0, async, cookie);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QXL_IO_NOTIFY_CMD:
|
||||||
|
@@ -1652,6 +1711,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
|
||||||
|
init_pipe_signaling(qxl);
|
||||||
|
qxl_reset_state(qxl);
|
||||||
|
|
||||||
|
+ qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.h b/hw/qxl.h
|
||||||
|
index 1443925..86e415b 100644
|
||||||
|
--- a/hw/qxl.h
|
||||||
|
+++ b/hw/qxl.h
|
||||||
|
@@ -18,6 +18,8 @@ enum qxl_mode {
|
||||||
|
|
||||||
|
#define QXL_UNDEFINED_IO UINT32_MAX
|
||||||
|
|
||||||
|
+#define QXL_NUM_DIRTY_RECTS 64
|
||||||
|
+
|
||||||
|
typedef struct PCIQXLDevice {
|
||||||
|
PCIDevice pci;
|
||||||
|
SimpleSpiceDisplay ssd;
|
||||||
|
@@ -93,6 +95,12 @@ typedef struct PCIQXLDevice {
|
||||||
|
/* user-friendly properties (in megabytes) */
|
||||||
|
uint32_t ram_size_mb;
|
||||||
|
uint32_t vram_size_mb;
|
||||||
|
+
|
||||||
|
+ /* qxl_render_update state */
|
||||||
|
+ int render_update_cookie_num;
|
||||||
|
+ int num_dirty_rects;
|
||||||
|
+ QXLRect dirty[QXL_NUM_DIRTY_RECTS];
|
||||||
|
+ QEMUBH *update_area_bh;
|
||||||
|
} PCIQXLDevice;
|
||||||
|
|
||||||
|
#define PANIC_ON(x) if ((x)) { \
|
||||||
|
@@ -134,3 +142,5 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
|
||||||
|
void qxl_render_resize(PCIQXLDevice *qxl);
|
||||||
|
void qxl_render_update(PCIQXLDevice *qxl);
|
||||||
|
void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
|
||||||
|
+void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);
|
||||||
|
+void qxl_render_update_area_bh(void *opaque);
|
||||||
|
diff --git a/ui/spice-display.h b/ui/spice-display.h
|
||||||
|
index 8a010cb..12e50b6 100644
|
||||||
|
--- a/ui/spice-display.h
|
||||||
|
+++ b/ui/spice-display.h
|
||||||
|
@@ -50,6 +50,7 @@ typedef enum qxl_async_io {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct QXLCookie {
|
||||||
|
@@ -57,6 +58,11 @@ typedef struct QXLCookie {
|
||||||
|
uint64_t io;
|
||||||
|
union {
|
||||||
|
uint32_t surface_id;
|
||||||
|
+ QXLRect area;
|
||||||
|
+ struct {
|
||||||
|
+ QXLRect area;
|
||||||
|
+ int redraw;
|
||||||
|
+ } render;
|
||||||
|
} u;
|
||||||
|
} QXLCookie;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
102
0419-spice-use-error_report-to-report-errors.patch
Normal file
102
0419-spice-use-error_report-to-report-errors.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
From 2b973a5ea22635211cbde2e559cc6e6355ca8205 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe Fergeau <cfergeau@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 18:13:12 +0100
|
||||||
|
Subject: [PATCH 419/434] spice: use error_report to report errors
|
||||||
|
|
||||||
|
Error message reporting during spice startup wasn't consistent, it was done
|
||||||
|
with fprintf(stderr, "") but sometimes the message didn't have a trailing
|
||||||
|
\n. Using error_report make the intent of the message clearer and deal
|
||||||
|
with the final \n for us.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
ui/spice-core.c | 22 +++++++++++-----------
|
||||||
|
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||||
|
index 2c815f1..8503f03 100644
|
||||||
|
--- a/ui/spice-core.c
|
||||||
|
+++ b/ui/spice-core.c
|
||||||
|
@@ -227,8 +227,8 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
|
||||||
|
add_addr_info(server, (struct sockaddr *)&info->laddr_ext,
|
||||||
|
info->llen_ext);
|
||||||
|
} else {
|
||||||
|
- fprintf(stderr, "spice: %s, extended address is expected\n",
|
||||||
|
- __func__);
|
||||||
|
+ error_report("spice: %s, extended address is expected",
|
||||||
|
+ __func__);
|
||||||
|
#endif
|
||||||
|
add_addr_info(client, &info->paddr, info->plen);
|
||||||
|
add_addr_info(server, &info->laddr, info->llen);
|
||||||
|
@@ -333,7 +333,7 @@ static int parse_name(const char *string, const char *optname,
|
||||||
|
if (value != -1) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
- fprintf(stderr, "spice: invalid %s: %s\n", optname, string);
|
||||||
|
+ error_report("spice: invalid %s: %s", optname, string);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -525,7 +525,7 @@ static int add_channel(const char *name, const char *value, void *opaque)
|
||||||
|
rc = spice_server_set_channel_security(spice_server, value, security);
|
||||||
|
}
|
||||||
|
if (rc != 0) {
|
||||||
|
- fprintf(stderr, "spice: failed to set channel security for %s\n", value);
|
||||||
|
+ error_report("spice: failed to set channel security for %s", value);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
@@ -553,15 +553,15 @@ void qemu_spice_init(void)
|
||||||
|
port = qemu_opt_get_number(opts, "port", 0);
|
||||||
|
tls_port = qemu_opt_get_number(opts, "tls-port", 0);
|
||||||
|
if (!port && !tls_port) {
|
||||||
|
- fprintf(stderr, "neither port nor tls-port specified for spice.");
|
||||||
|
+ error_report("neither port nor tls-port specified for spice");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (port < 0 || port > 65535) {
|
||||||
|
- fprintf(stderr, "spice port is out of range");
|
||||||
|
+ error_report("spice port is out of range");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (tls_port < 0 || tls_port > 65535) {
|
||||||
|
- fprintf(stderr, "spice tls-port is out of range");
|
||||||
|
+ error_report("spice tls-port is out of range");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
password = qemu_opt_get(opts, "password");
|
||||||
|
@@ -631,11 +631,11 @@ void qemu_spice_init(void)
|
||||||
|
#if SPICE_SERVER_VERSION >= 0x000900 /* 0.9.0 */
|
||||||
|
if (spice_server_set_sasl_appname(spice_server, "qemu") == -1 ||
|
||||||
|
spice_server_set_sasl(spice_server, 1) == -1) {
|
||||||
|
- fprintf(stderr, "spice: failed to enable sasl\n");
|
||||||
|
+ error_report("spice: failed to enable sasl");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
- fprintf(stderr, "spice: sasl is not available (spice >= 0.9 required)\n");
|
||||||
|
+ error_report("spice: sasl is not available (spice >= 0.9 required)");
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@@ -683,7 +683,7 @@ void qemu_spice_init(void)
|
||||||
|
qemu_opt_foreach(opts, add_channel, NULL, 0);
|
||||||
|
|
||||||
|
if (0 != spice_server_init(spice_server, &core_interface)) {
|
||||||
|
- fprintf(stderr, "failed to initialize spice server");
|
||||||
|
+ error_report("failed to initialize spice server");
|
||||||
|
exit(1);
|
||||||
|
};
|
||||||
|
using_spice = 1;
|
||||||
|
@@ -708,7 +708,7 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
|
||||||
|
{
|
||||||
|
if (!spice_server) {
|
||||||
|
if (QTAILQ_FIRST(&qemu_spice_opts.head) != NULL) {
|
||||||
|
- fprintf(stderr, "Oops: spice configured but not active\n");
|
||||||
|
+ error_report("Oops: spice configured but not active");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From d01f59d652b8ac906ecd129afa338f56b2aaef90 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe Fergeau <cfergeau@redhat.com>
|
||||||
|
Date: Fri, 24 Feb 2012 18:28:32 +0100
|
||||||
|
Subject: [PATCH 420/434] Error out when tls-channel option is used without
|
||||||
|
TLS
|
||||||
|
|
||||||
|
It's currently possible to setup spice channels using TLS when
|
||||||
|
no TLS port has been specified (ie TLS is disabled). This cannot
|
||||||
|
work, so better to error out in such a situation.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
ui/spice-core.c | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||||
|
index 8503f03..98356b0 100644
|
||||||
|
--- a/ui/spice-core.c
|
||||||
|
+++ b/ui/spice-core.c
|
||||||
|
@@ -511,6 +511,12 @@ static int add_channel(const char *name, const char *value, void *opaque)
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (strcmp(name, "tls-channel") == 0) {
|
||||||
|
+ int *tls_port = opaque;
|
||||||
|
+ if (!*tls_port) {
|
||||||
|
+ error_report("spice: tried to setup tls-channel"
|
||||||
|
+ " without specifying a TLS port");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
security = SPICE_CHANNEL_SECURITY_SSL;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "plaintext-channel") == 0) {
|
||||||
|
@@ -680,7 +686,7 @@ void qemu_spice_init(void)
|
||||||
|
spice_server_set_playback_compression
|
||||||
|
(spice_server, qemu_opt_get_bool(opts, "playback-compression", 1));
|
||||||
|
|
||||||
|
- qemu_opt_foreach(opts, add_channel, NULL, 0);
|
||||||
|
+ qemu_opt_foreach(opts, add_channel, &tls_port, 0);
|
||||||
|
|
||||||
|
if (0 != spice_server_init(spice_server, &core_interface)) {
|
||||||
|
error_report("failed to initialize spice server");
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
From 7027fa0d3be22f48a51420a45aff13bec54fef1e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Mon, 27 Feb 2012 11:05:09 +0100
|
||||||
|
Subject: [PATCH 421/434] qxl: properly handle upright and non-shared surfaces
|
||||||
|
|
||||||
|
Although qxl creates a shared displaysurface when the qxl surface is
|
||||||
|
upright and doesn't need to be flipped there is no guarantee that the
|
||||||
|
surface doesn't become unshared for some reason. Rename qxl_flip to
|
||||||
|
qxl_blit and fix it to handle both flip and non-flip cases.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl-render.c | 20 +++++++++++++-------
|
||||||
|
1 file changed, 13 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
|
||||||
|
index 4857838..2e10e93 100644
|
||||||
|
--- a/hw/qxl-render.c
|
||||||
|
+++ b/hw/qxl-render.c
|
||||||
|
@@ -21,25 +21,31 @@
|
||||||
|
|
||||||
|
#include "qxl.h"
|
||||||
|
|
||||||
|
-static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
|
||||||
|
+static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
|
||||||
|
{
|
||||||
|
uint8_t *src;
|
||||||
|
uint8_t *dst = qxl->vga.ds->surface->data;
|
||||||
|
int len, i;
|
||||||
|
|
||||||
|
- if (qxl->guest_primary.qxl_stride > 0) {
|
||||||
|
+ if (is_buffer_shared(qxl->vga.ds->surface)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!qxl->guest_primary.data) {
|
||||||
|
dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__);
|
||||||
|
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||||
|
}
|
||||||
|
- dprint(qxl, 1, "%s: stride %d, [%d, %d, %d, %d]\n", __func__,
|
||||||
|
+ dprint(qxl, 2, "%s: stride %d, [%d, %d, %d, %d]\n", __func__,
|
||||||
|
qxl->guest_primary.qxl_stride,
|
||||||
|
rect->left, rect->right, rect->top, rect->bottom);
|
||||||
|
src = qxl->guest_primary.data;
|
||||||
|
- src += (qxl->guest_primary.surface.height - rect->top - 1) *
|
||||||
|
- qxl->guest_primary.abs_stride;
|
||||||
|
+ if (qxl->guest_primary.qxl_stride < 0) {
|
||||||
|
+ /* qxl surface is upside down, walk src scanlines
|
||||||
|
+ * in reverse order to flip it */
|
||||||
|
+ src += (qxl->guest_primary.surface.height - rect->top - 1) *
|
||||||
|
+ qxl->guest_primary.abs_stride;
|
||||||
|
+ } else {
|
||||||
|
+ src += rect->top * qxl->guest_primary.abs_stride;
|
||||||
|
+ }
|
||||||
|
dst += rect->top * qxl->guest_primary.abs_stride;
|
||||||
|
src += rect->left * qxl->guest_primary.bytes_pp;
|
||||||
|
dst += rect->left * qxl->guest_primary.bytes_pp;
|
||||||
|
@@ -48,7 +54,7 @@ static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
|
||||||
|
for (i = rect->top; i < rect->bottom; i++) {
|
||||||
|
memcpy(dst, src, len);
|
||||||
|
dst += qxl->guest_primary.abs_stride;
|
||||||
|
- src -= qxl->guest_primary.abs_stride;
|
||||||
|
+ src += qxl->guest_primary.qxl_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -132,7 +138,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||||
|
if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- qxl_flip(qxl, qxl->dirty+i);
|
||||||
|
+ qxl_blit(qxl, qxl->dirty+i);
|
||||||
|
dpy_update(vga->ds,
|
||||||
|
qxl->dirty[i].left, qxl->dirty[i].top,
|
||||||
|
qxl->dirty[i].right - qxl->dirty[i].left,
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
39
0422-spice-set-spice-uuid-and-name.patch
Normal file
39
0422-spice-set-spice-uuid-and-name.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 544cfc4a2c730aca346df7215a0dd83280f864d5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Mon, 5 Mar 2012 18:22:26 +0100
|
||||||
|
Subject: [PATCH 422/434] spice: set spice uuid and name
|
||||||
|
|
||||||
|
This allows a Spice client to identify a VM
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
ui/spice-core.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||||
|
index 98356b0..4ad0a67 100644
|
||||||
|
--- a/ui/spice-core.c
|
||||||
|
+++ b/ui/spice-core.c
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
#include <spice-experimental.h>
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
+#include "sysemu.h"
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
|
#include "qemu-spice.h"
|
||||||
|
@@ -688,6 +689,11 @@ void qemu_spice_init(void)
|
||||||
|
|
||||||
|
qemu_opt_foreach(opts, add_channel, &tls_port, 0);
|
||||||
|
|
||||||
|
+#if SPICE_SERVER_VERSION >= 0x000a02 /* 0.10.2 */
|
||||||
|
+ spice_server_set_name(spice_server, qemu_name);
|
||||||
|
+ spice_server_set_uuid(spice_server, qemu_uuid);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
if (0 != spice_server_init(spice_server, &core_interface)) {
|
||||||
|
error_report("failed to initialize spice server");
|
||||||
|
exit(1);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
35
0423-monitor-fix-client_migrate_info-error-handling.patch
Normal file
35
0423-monitor-fix-client_migrate_info-error-handling.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 63f3e6ee49e0a88bbd7915d81962c9046205c411 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Date: Sun, 18 Mar 2012 09:42:39 +0200
|
||||||
|
Subject: [PATCH 423/434] monitor: fix client_migrate_info error handling
|
||||||
|
|
||||||
|
Report QERR_MISSING_PARAMETER when port is missing. Otherwise
|
||||||
|
QERR_UNDEFINED_ERROR will occur.
|
||||||
|
|
||||||
|
rhbz #795652
|
||||||
|
|
||||||
|
Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
monitor.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/monitor.c b/monitor.c
|
||||||
|
index 3c23aa4..76739d7 100644
|
||||||
|
--- a/monitor.c
|
||||||
|
+++ b/monitor.c
|
||||||
|
@@ -1046,6 +1046,11 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict,
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (port == -1 && tls_port == -1) {
|
||||||
|
+ qerror_report(QERR_MISSING_PARAMETER, "port/tls-port");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ret = qemu_spice_migrate_info(hostname, port, tls_port, subject,
|
||||||
|
cb, opaque);
|
||||||
|
if (ret != 0) {
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
49
0424-qxl-init_pipe_signaling-exit-on-failure.patch
Normal file
49
0424-qxl-init_pipe_signaling-exit-on-failure.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
From d3e6c37f68e7e4573a47b0540f626a2add0d05e4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Sun, 18 Mar 2012 13:46:13 +0100
|
||||||
|
Subject: [PATCH 424/434] qxl: init_pipe_signaling: exit on failure
|
||||||
|
|
||||||
|
If pipe creation fails, exit, don't log and continue. Fix indentation at
|
||||||
|
the same time.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 21 +++++++++++----------
|
||||||
|
1 file changed, 11 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 73be115..9ad5807 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1453,16 +1453,17 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
|
||||||
|
|
||||||
|
static void init_pipe_signaling(PCIQXLDevice *d)
|
||||||
|
{
|
||||||
|
- if (pipe(d->pipe) < 0) {
|
||||||
|
- dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
- fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
|
||||||
|
- fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
|
||||||
|
- fcntl(d->pipe[0], F_SETOWN, getpid());
|
||||||
|
-
|
||||||
|
- qemu_thread_get_self(&d->main);
|
||||||
|
- qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
|
||||||
|
+ if (pipe(d->pipe) < 0) {
|
||||||
|
+ fprintf(stderr, "%s:%s: qxl pipe creation failed\n",
|
||||||
|
+ __FILE__, __func__);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
|
||||||
|
+ fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
|
||||||
|
+ fcntl(d->pipe[0], F_SETOWN, getpid());
|
||||||
|
+
|
||||||
|
+ qemu_thread_get_self(&d->main);
|
||||||
|
+ qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* graphics console */
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
753
0425-qxl-switch-qxl.c-to-trace-events.patch
Normal file
753
0425-qxl-switch-qxl.c-to-trace-events.patch
Normal file
@ -0,0 +1,753 @@
|
|||||||
|
From 29304ce6b6863b544f1ad8535a927dfc8864354c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Sun, 18 Mar 2012 13:46:14 +0100
|
||||||
|
Subject: [PATCH 425/434] qxl: switch qxl.c to trace-events
|
||||||
|
|
||||||
|
dprint is still used for qxl_init_common one time prints.
|
||||||
|
|
||||||
|
also switched parts of spice-display.c over, mainly all the callbacks to
|
||||||
|
spice server.
|
||||||
|
|
||||||
|
All qxl device trace events start with the qxl device id.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
|
||||||
|
trace-events
|
||||||
|
---
|
||||||
|
hw/qxl.c | 141 +++++++++++++++++++++++++---------------------------
|
||||||
|
trace-events | 59 ++++++++++++++++++++++
|
||||||
|
ui/spice-display.c | 14 +++++-
|
||||||
|
3 files changed, 140 insertions(+), 74 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 9ad5807..813873a 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include "qemu-queue.h"
|
||||||
|
#include "monitor.h"
|
||||||
|
#include "sysemu.h"
|
||||||
|
+#include "trace.h"
|
||||||
|
|
||||||
|
#include "qxl.h"
|
||||||
|
|
||||||
|
@@ -143,6 +144,10 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
|
||||||
|
uint32_t clear_dirty_region,
|
||||||
|
qxl_async_io async, struct QXLCookie *cookie)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_update_area(qxl->id, surface_id, area->left, area->right,
|
||||||
|
+ area->top, area->bottom);
|
||||||
|
+ trace_qxl_spice_update_area_rest(qxl->id, num_dirty_rects,
|
||||||
|
+ clear_dirty_region);
|
||||||
|
if (async == QXL_SYNC) {
|
||||||
|
qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
|
||||||
|
dirty_rects, num_dirty_rects, clear_dirty_region);
|
||||||
|
@@ -156,6 +161,7 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
|
||||||
|
static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_destroy_surface_wait_complete(qxl->id, id);
|
||||||
|
qemu_mutex_lock(&qxl->track_lock);
|
||||||
|
qxl->guest_surfaces.cmds[id] = 0;
|
||||||
|
qxl->guest_surfaces.count--;
|
||||||
|
@@ -167,6 +173,7 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
|
||||||
|
{
|
||||||
|
QXLCookie *cookie;
|
||||||
|
|
||||||
|
+ trace_qxl_spice_destroy_surface_wait(qxl->id, id, async);
|
||||||
|
if (async) {
|
||||||
|
cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
QXL_IO_DESTROY_SURFACE_ASYNC);
|
||||||
|
@@ -174,12 +181,13 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
|
||||||
|
spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uint64_t)cookie);
|
||||||
|
} else {
|
||||||
|
qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
|
||||||
|
- qxl_spice_destroy_surface_wait_complete(qxl, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_flush_surfaces_async(qxl->id, qxl->guest_surfaces.count,
|
||||||
|
+ qxl->num_free_res);
|
||||||
|
spice_qxl_flush_surfaces_async(&qxl->ssd.qxl,
|
||||||
|
(uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
QXL_IO_FLUSH_SURFACES_ASYNC));
|
||||||
|
@@ -188,21 +196,25 @@ static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
|
||||||
|
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
|
||||||
|
uint32_t count)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_loadvm_commands(qxl->id, ext, count);
|
||||||
|
qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qxl_spice_oom(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_oom(qxl->id);
|
||||||
|
qxl->ssd.worker->oom(qxl->ssd.worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_reset_memslots(qxl->id);
|
||||||
|
qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_destroy_surfaces_complete(qxl->id);
|
||||||
|
qemu_mutex_lock(&qxl->track_lock);
|
||||||
|
memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
|
||||||
|
qxl->guest_surfaces.count = 0;
|
||||||
|
@@ -211,6 +223,7 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
|
||||||
|
|
||||||
|
static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_destroy_surfaces(qxl->id, async);
|
||||||
|
if (async) {
|
||||||
|
spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl,
|
||||||
|
(uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
@@ -223,11 +236,13 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
|
||||||
|
|
||||||
|
void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_reset_image_cache(qxl->id);
|
||||||
|
qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
|
||||||
|
{
|
||||||
|
+ trace_qxl_spice_reset_cursor(qxl->id);
|
||||||
|
qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
|
||||||
|
qemu_mutex_lock(&qxl->track_lock);
|
||||||
|
qxl->guest_cursor = 0;
|
||||||
|
@@ -412,7 +427,7 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
|
||||||
|
- dprint(qxl, 1, "%s:\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_interface_attach_worker(qxl->id);
|
||||||
|
qxl->ssd.worker = qxl_worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -420,7 +435,7 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
|
||||||
|
- dprint(qxl, 1, "%s: %d\n", __FUNCTION__, level);
|
||||||
|
+ trace_qxl_interface_set_compression_level(qxl->id, level);
|
||||||
|
qxl->shadow_rom.compression_level = cpu_to_le32(level);
|
||||||
|
qxl->rom->compression_level = cpu_to_le32(level);
|
||||||
|
qxl_rom_set_dirty(qxl);
|
||||||
|
@@ -430,6 +445,7 @@ static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
|
||||||
|
+ trace_qxl_interface_set_mm_time(qxl->id, mm_time);
|
||||||
|
qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
|
||||||
|
qxl->rom->mm_clock = cpu_to_le32(mm_time);
|
||||||
|
qxl_rom_set_dirty(qxl);
|
||||||
|
@@ -439,7 +455,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
|
||||||
|
- dprint(qxl, 1, "%s:\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_interface_get_init_info(qxl->id);
|
||||||
|
info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
|
||||||
|
info->memslot_id_bits = MEMSLOT_SLOT_BITS;
|
||||||
|
info->num_memslots = NUM_MEMSLOTS;
|
||||||
|
@@ -508,9 +524,10 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
|
||||||
|
QXLCommand *cmd;
|
||||||
|
int notify, ret;
|
||||||
|
|
||||||
|
+ trace_qxl_ring_command_check(qxl->id, qxl_mode_to_string(qxl->mode));
|
||||||
|
+
|
||||||
|
switch (qxl->mode) {
|
||||||
|
case QXL_MODE_VGA:
|
||||||
|
- dprint(qxl, 2, "%s: vga\n", __FUNCTION__);
|
||||||
|
ret = false;
|
||||||
|
qemu_mutex_lock(&qxl->ssd.lock);
|
||||||
|
if (qxl->ssd.update != NULL) {
|
||||||
|
@@ -521,19 +538,18 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
|
||||||
|
}
|
||||||
|
qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
if (ret) {
|
||||||
|
- dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
|
||||||
|
+ trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
|
||||||
|
qxl_log_command(qxl, "vga", ext);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
case QXL_MODE_COMPAT:
|
||||||
|
case QXL_MODE_NATIVE:
|
||||||
|
case QXL_MODE_UNDEFINED:
|
||||||
|
- dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
|
||||||
|
ring = &qxl->ram->cmd_ring;
|
||||||
|
if (SPICE_RING_IS_EMPTY(ring)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
- dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
|
||||||
|
+ trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
|
||||||
|
SPICE_RING_CONS_ITEM(ring, cmd);
|
||||||
|
ext->cmd = *cmd;
|
||||||
|
ext->group_id = MEMSLOT_GROUP_GUEST;
|
||||||
|
@@ -558,6 +574,7 @@ static int interface_req_cmd_notification(QXLInstance *sin)
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
int wait = 1;
|
||||||
|
|
||||||
|
+ trace_qxl_ring_command_req_notification(qxl->id);
|
||||||
|
switch (qxl->mode) {
|
||||||
|
case QXL_MODE_COMPAT:
|
||||||
|
case QXL_MODE_NATIVE:
|
||||||
|
@@ -595,10 +612,11 @@ static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
|
||||||
|
}
|
||||||
|
|
||||||
|
SPICE_RING_PUSH(ring, notify);
|
||||||
|
- dprint(d, 2, "free: push %d items, notify %s, ring %d/%d [%d,%d]\n",
|
||||||
|
- d->num_free_res, notify ? "yes" : "no",
|
||||||
|
- ring->prod - ring->cons, ring->num_items,
|
||||||
|
- ring->prod, ring->cons);
|
||||||
|
+ trace_qxl_ring_res_push(d->id, qxl_mode_to_string(d->mode),
|
||||||
|
+ d->guest_surfaces.count, d->num_free_res,
|
||||||
|
+ d->last_release, notify ? "yes" : "no");
|
||||||
|
+ trace_qxl_ring_res_push_rest(d->id, ring->prod - ring->cons,
|
||||||
|
+ ring->num_items, ring->prod, ring->cons);
|
||||||
|
if (notify) {
|
||||||
|
qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
|
||||||
|
}
|
||||||
|
@@ -645,7 +663,7 @@ static void interface_release_resource(QXLInstance *sin,
|
||||||
|
}
|
||||||
|
qxl->last_release = ext.info;
|
||||||
|
qxl->num_free_res++;
|
||||||
|
- dprint(qxl, 3, "%4d\r", qxl->num_free_res);
|
||||||
|
+ trace_qxl_ring_res_put(qxl->id, qxl->num_free_res);
|
||||||
|
qxl_push_free_res(qxl, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -657,6 +675,8 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
|
||||||
|
QXLCommand *cmd;
|
||||||
|
int notify;
|
||||||
|
|
||||||
|
+ trace_qxl_ring_cursor_check(qxl->id, qxl_mode_to_string(qxl->mode));
|
||||||
|
+
|
||||||
|
switch (qxl->mode) {
|
||||||
|
case QXL_MODE_COMPAT:
|
||||||
|
case QXL_MODE_NATIVE:
|
||||||
|
@@ -680,6 +700,7 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
|
||||||
|
if (qxl->id == 0) {
|
||||||
|
qxl_render_cursor(qxl, ext);
|
||||||
|
}
|
||||||
|
+ trace_qxl_ring_cursor_get(qxl->id, qxl_mode_to_string(qxl->mode));
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
@@ -692,6 +713,7 @@ static int interface_req_cursor_notification(QXLInstance *sin)
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
int wait = 1;
|
||||||
|
|
||||||
|
+ trace_qxl_ring_cursor_req_notification(qxl->id);
|
||||||
|
switch (qxl->mode) {
|
||||||
|
case QXL_MODE_COMPAT:
|
||||||
|
case QXL_MODE_NATIVE:
|
||||||
|
@@ -719,7 +741,6 @@ static int interface_flush_resources(QXLInstance *sin)
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- dprint(qxl, 1, "free: guest flush (have %d)\n", qxl->num_free_res);
|
||||||
|
ret = qxl->num_free_res;
|
||||||
|
if (ret) {
|
||||||
|
qxl_push_free_res(qxl, 1);
|
||||||
|
@@ -739,7 +760,7 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
|
||||||
|
qxl->current_async = QXL_UNDEFINED_IO;
|
||||||
|
qemu_mutex_unlock(&qxl->async_lock);
|
||||||
|
|
||||||
|
- dprint(qxl, 2, "async_complete: %d (%p) done\n", current_async, cookie);
|
||||||
|
+ trace_qxl_interface_async_complete_io(qxl->id, current_async, cookie);
|
||||||
|
if (!cookie) {
|
||||||
|
fprintf(stderr, "qxl: %s: error, cookie is NULL\n", __func__);
|
||||||
|
return;
|
||||||
|
@@ -785,11 +806,15 @@ static void interface_update_area_complete(QXLInstance *sin,
|
||||||
|
qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+ trace_qxl_interface_update_area_complete(qxl->id, surface_id, dirty->left,
|
||||||
|
+ dirty->right, dirty->top, dirty->bottom);
|
||||||
|
+ trace_qxl_interface_update_area_complete_rest(qxl->id, num_updated_rects);
|
||||||
|
if (qxl->num_dirty_rects + num_updated_rects > QXL_NUM_DIRTY_RECTS) {
|
||||||
|
/*
|
||||||
|
* overflow - treat this as a full update. Not expected to be common.
|
||||||
|
*/
|
||||||
|
- dprint(qxl, 1, "%s: overflow of dirty rects\n", __func__);
|
||||||
|
+ trace_qxl_interface_update_area_complete_overflow(qxl->id,
|
||||||
|
+ QXL_NUM_DIRTY_RECTS);
|
||||||
|
qxl->guest_primary.resized = 1;
|
||||||
|
}
|
||||||
|
if (qxl->guest_primary.resized) {
|
||||||
|
@@ -805,8 +830,8 @@ static void interface_update_area_complete(QXLInstance *sin,
|
||||||
|
qxl->dirty[qxl_i++] = dirty[i];
|
||||||
|
}
|
||||||
|
qxl->num_dirty_rects += num_updated_rects;
|
||||||
|
- dprint(qxl, 1, "%s: scheduling update_area_bh, #dirty %d\n",
|
||||||
|
- __func__, qxl->num_dirty_rects);
|
||||||
|
+ trace_qxl_interface_update_area_complete_schedule_bh(qxl->id,
|
||||||
|
+ qxl->num_dirty_rects);
|
||||||
|
qemu_bh_schedule(qxl->update_area_bh);
|
||||||
|
qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
}
|
||||||
|
@@ -860,7 +885,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
|
||||||
|
if (d->mode == QXL_MODE_VGA) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "%s\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_enter_vga_mode(d->id);
|
||||||
|
qemu_spice_create_host_primary(&d->ssd);
|
||||||
|
d->mode = QXL_MODE_VGA;
|
||||||
|
memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
|
||||||
|
@@ -871,7 +896,7 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)
|
||||||
|
if (d->mode != QXL_MODE_VGA) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "%s\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_exit_vga_mode(d->id);
|
||||||
|
qxl_destroy_primary(d, QXL_SYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -908,7 +933,7 @@ static void qxl_reset_state(PCIQXLDevice *d)
|
||||||
|
|
||||||
|
static void qxl_soft_reset(PCIQXLDevice *d)
|
||||||
|
{
|
||||||
|
- dprint(d, 1, "%s:\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_soft_reset(d->id);
|
||||||
|
qxl_check_state(d);
|
||||||
|
|
||||||
|
if (d->id == 0) {
|
||||||
|
@@ -920,8 +945,7 @@ static void qxl_soft_reset(PCIQXLDevice *d)
|
||||||
|
|
||||||
|
static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
|
||||||
|
{
|
||||||
|
- dprint(d, 1, "%s: start%s\n", __FUNCTION__,
|
||||||
|
- loadvm ? " (loadvm)" : "");
|
||||||
|
+ trace_qxl_hard_reset(d->id, loadvm);
|
||||||
|
|
||||||
|
qxl_spice_reset_cursor(d);
|
||||||
|
qxl_spice_reset_image_cache(d);
|
||||||
|
@@ -936,13 +960,12 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
|
||||||
|
}
|
||||||
|
qemu_spice_create_host_memslot(&d->ssd);
|
||||||
|
qxl_soft_reset(d);
|
||||||
|
-
|
||||||
|
- dprint(d, 1, "%s: done\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qxl_reset_handler(DeviceState *dev)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *d = DO_UPCAST(PCIQXLDevice, pci.qdev, dev);
|
||||||
|
+
|
||||||
|
qxl_hard_reset(d, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -951,8 +974,8 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
VGACommonState *vga = opaque;
|
||||||
|
PCIQXLDevice *qxl = container_of(vga, PCIQXLDevice, vga);
|
||||||
|
|
||||||
|
+ trace_qxl_io_write_vga(qxl->id, qxl_mode_to_string(qxl->mode), addr, val);
|
||||||
|
if (qxl->mode != QXL_MODE_VGA) {
|
||||||
|
- dprint(qxl, 1, "%s\n", __FUNCTION__);
|
||||||
|
qxl_destroy_primary(qxl, QXL_SYNC);
|
||||||
|
qxl_soft_reset(qxl);
|
||||||
|
}
|
||||||
|
@@ -992,9 +1015,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
||||||
|
guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);
|
||||||
|
guest_end = le64_to_cpu(d->guest_slots[slot_id].slot.mem_end);
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s: slot %d: guest phys 0x%" PRIx64 " - 0x%" PRIx64 "\n",
|
||||||
|
- __FUNCTION__, slot_id,
|
||||||
|
- guest_start, guest_end);
|
||||||
|
+ trace_qxl_memslot_add_guest(d->id, slot_id, guest_start, guest_end);
|
||||||
|
|
||||||
|
PANIC_ON(slot_id >= NUM_MEMSLOTS);
|
||||||
|
PANIC_ON(guest_start > guest_end);
|
||||||
|
@@ -1040,10 +1061,6 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
||||||
|
memslot.generation = d->rom->slot_generation = 0;
|
||||||
|
qxl_rom_set_dirty(d);
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s: slot %d: host virt 0x%lx - 0x%lx\n",
|
||||||
|
- __FUNCTION__, memslot.slot_id,
|
||||||
|
- memslot.virt_start, memslot.virt_end);
|
||||||
|
-
|
||||||
|
qemu_spice_add_memslot(&d->ssd, &memslot, async);
|
||||||
|
d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
|
||||||
|
d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
|
||||||
|
@@ -1053,21 +1070,19 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
||||||
|
|
||||||
|
static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
|
||||||
|
{
|
||||||
|
- dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
|
||||||
|
qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
|
||||||
|
d->guest_slots[slot_id].active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qxl_reset_memslots(PCIQXLDevice *d)
|
||||||
|
{
|
||||||
|
- dprint(d, 1, "%s:\n", __FUNCTION__);
|
||||||
|
qxl_spice_reset_memslots(d);
|
||||||
|
memset(&d->guest_slots, 0, sizeof(d->guest_slots));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qxl_reset_surfaces(PCIQXLDevice *d)
|
||||||
|
{
|
||||||
|
- dprint(d, 1, "%s:\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_reset_surfaces(d->id);
|
||||||
|
d->mode = QXL_MODE_UNDEFINED;
|
||||||
|
qxl_spice_destroy_surfaces(d, QXL_SYNC);
|
||||||
|
}
|
||||||
|
@@ -1109,9 +1124,6 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
|
||||||
|
assert(qxl->mode != QXL_MODE_NATIVE);
|
||||||
|
qxl_exit_vga_mode(qxl);
|
||||||
|
|
||||||
|
- dprint(qxl, 1, "%s: %dx%d\n", __FUNCTION__,
|
||||||
|
- le32_to_cpu(sc->width), le32_to_cpu(sc->height));
|
||||||
|
-
|
||||||
|
surface.format = le32_to_cpu(sc->format);
|
||||||
|
surface.height = le32_to_cpu(sc->height);
|
||||||
|
surface.mem = le64_to_cpu(sc->mem);
|
||||||
|
@@ -1120,6 +1132,10 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
|
||||||
|
surface.width = le32_to_cpu(sc->width);
|
||||||
|
surface.type = le32_to_cpu(sc->type);
|
||||||
|
surface.flags = le32_to_cpu(sc->flags);
|
||||||
|
+ trace_qxl_create_guest_primary(qxl->id, sc->width, sc->height, sc->mem,
|
||||||
|
+ sc->format, sc->position);
|
||||||
|
+ trace_qxl_create_guest_primary_rest(qxl->id, sc->stride, sc->type,
|
||||||
|
+ sc->flags);
|
||||||
|
|
||||||
|
surface.mouse_mode = true;
|
||||||
|
surface.group_id = MEMSLOT_GROUP_GUEST;
|
||||||
|
@@ -1143,7 +1159,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
|
||||||
|
if (d->mode == QXL_MODE_UNDEFINED) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "%s\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_destroy_primary(d->id);
|
||||||
|
d->mode = QXL_MODE_UNDEFINED;
|
||||||
|
qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
|
||||||
|
qxl_spice_reset_cursor(d);
|
||||||
|
@@ -1170,8 +1186,8 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
|
||||||
|
.mem = devmem + d->shadow_rom.draw_area_offset,
|
||||||
|
};
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s: mode %d [ %d x %d @ %d bpp devmem 0x%" PRIx64 " ]\n",
|
||||||
|
- __func__, modenr, mode->x_res, mode->y_res, mode->bits, devmem);
|
||||||
|
+ trace_qxl_set_mode(d->id, modenr, mode->x_res, mode->y_res, mode->bits,
|
||||||
|
+ devmem);
|
||||||
|
if (!loadvm) {
|
||||||
|
qxl_hard_reset(d, 0);
|
||||||
|
}
|
||||||
|
@@ -1217,8 +1233,8 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
|
||||||
|
if (d->mode != QXL_MODE_VGA) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
|
||||||
|
- __func__, io_port, io_port_to_string(io_port));
|
||||||
|
+ trace_qxl_io_unexpected_vga_mode(d->id,
|
||||||
|
+ io_port, io_port_to_string(io_port));
|
||||||
|
/* be nice to buggy guest drivers */
|
||||||
|
if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
|
||||||
|
io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
|
||||||
|
@@ -1260,11 +1276,12 @@ async_common:
|
||||||
|
}
|
||||||
|
d->current_async = orig_io_port;
|
||||||
|
qemu_mutex_unlock(&d->async_lock);
|
||||||
|
- dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ trace_qxl_io_write(d->id, qxl_mode_to_string(d->mode), addr, val, size,
|
||||||
|
+ async);
|
||||||
|
|
||||||
|
switch (io_port) {
|
||||||
|
case QXL_IO_UPDATE_AREA:
|
||||||
|
@@ -1300,7 +1317,6 @@ async_common:
|
||||||
|
d->oom_running = 0;
|
||||||
|
break;
|
||||||
|
case QXL_IO_SET_MODE:
|
||||||
|
- dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
|
||||||
|
qxl_set_mode(d, val, 0);
|
||||||
|
break;
|
||||||
|
case QXL_IO_LOG:
|
||||||
|
@@ -1310,7 +1326,6 @@ async_common:
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QXL_IO_RESET:
|
||||||
|
- dprint(d, 1, "QXL_IO_RESET\n");
|
||||||
|
qxl_hard_reset(d, 0);
|
||||||
|
break;
|
||||||
|
case QXL_IO_MEMSLOT_ADD:
|
||||||
|
@@ -1338,7 +1353,6 @@ async_common:
|
||||||
|
async);
|
||||||
|
goto cancel_async;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);
|
||||||
|
d->guest_primary.surface = d->ram->create_surface;
|
||||||
|
qxl_create_guest_primary(d, 0, async);
|
||||||
|
break;
|
||||||
|
@@ -1348,11 +1362,9 @@ async_common:
|
||||||
|
async);
|
||||||
|
goto cancel_async;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
|
||||||
|
- qxl_mode_to_string(d->mode));
|
||||||
|
if (!qxl_destroy_primary(d, async)) {
|
||||||
|
- dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
|
||||||
|
- qxl_mode_to_string(d->mode));
|
||||||
|
+ trace_qxl_io_destroy_primary_ignored(d->id,
|
||||||
|
+ qxl_mode_to_string(d->mode));
|
||||||
|
goto cancel_async;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
@@ -1372,16 +1384,9 @@ async_common:
|
||||||
|
ring->prod, ring->cons);
|
||||||
|
}
|
||||||
|
qxl_push_free_res(d, 1 /* flush */);
|
||||||
|
- dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
|
||||||
|
- qxl_mode_to_string(d->mode), d->guest_surfaces.count,
|
||||||
|
- d->num_free_res, d->last_release);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QXL_IO_FLUSH_SURFACES_ASYNC:
|
||||||
|
- dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC"
|
||||||
|
- " (%"PRId64") (%s, s#=%d, res#=%d)\n",
|
||||||
|
- val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
|
||||||
|
- d->num_free_res);
|
||||||
|
qxl_spice_flush_surfaces_async(d);
|
||||||
|
break;
|
||||||
|
case QXL_IO_DESTROY_ALL_SURFACES:
|
||||||
|
@@ -1407,7 +1412,7 @@ static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
|
||||||
|
{
|
||||||
|
PCIQXLDevice *d = opaque;
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s: unexpected\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_io_read_unexpected(d->id);
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1558,8 +1563,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
|
||||||
|
surface_offset -= vram_start;
|
||||||
|
surface_size = cmd->u.surface_create.height *
|
||||||
|
abs(cmd->u.surface_create.stride);
|
||||||
|
- dprint(qxl, 3, "%s: dirty surface %d, offset %d, size %d\n", __func__,
|
||||||
|
- i, (int)surface_offset, surface_size);
|
||||||
|
+ trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
|
||||||
|
qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1759,7 +1763,7 @@ static void qxl_pre_save(void *opaque)
|
||||||
|
PCIQXLDevice* d = opaque;
|
||||||
|
uint8_t *ram_start = d->vga.vram_ptr;
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s:\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_pre_save(d->id);
|
||||||
|
if (d->last_release == NULL) {
|
||||||
|
d->last_release_offset = 0;
|
||||||
|
} else {
|
||||||
|
@@ -1772,10 +1776,9 @@ static int qxl_pre_load(void *opaque)
|
||||||
|
{
|
||||||
|
PCIQXLDevice* d = opaque;
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s: start\n", __FUNCTION__);
|
||||||
|
+ trace_qxl_pre_load(d->id);
|
||||||
|
qxl_hard_reset(d, 1);
|
||||||
|
qxl_exit_vga_mode(d);
|
||||||
|
- dprint(d, 1, "%s: done\n", __FUNCTION__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1787,7 +1790,6 @@ static void qxl_create_memslots(PCIQXLDevice *d)
|
||||||
|
if (!d->guest_slots[i].active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "%s: restoring guest slot %d\n", __func__, i);
|
||||||
|
qxl_add_memslot(d, i, 0, QXL_SYNC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1799,8 +1801,6 @@ static int qxl_post_load(void *opaque, int version)
|
||||||
|
QXLCommandExt *cmds;
|
||||||
|
int in, out, newmode;
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s: start\n", __FUNCTION__);
|
||||||
|
-
|
||||||
|
assert(d->last_release_offset < d->vga.vram_size);
|
||||||
|
if (d->last_release_offset == 0) {
|
||||||
|
d->last_release = NULL;
|
||||||
|
@@ -1810,8 +1810,7 @@ static int qxl_post_load(void *opaque, int version)
|
||||||
|
|
||||||
|
d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
|
||||||
|
|
||||||
|
- dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__,
|
||||||
|
- qxl_mode_to_string(d->mode));
|
||||||
|
+ trace_qxl_post_load(d->id, qxl_mode_to_string(d->mode));
|
||||||
|
newmode = d->mode;
|
||||||
|
d->mode = QXL_MODE_UNDEFINED;
|
||||||
|
|
||||||
|
@@ -1853,8 +1852,6 @@ static int qxl_post_load(void *opaque, int version)
|
||||||
|
qxl_set_mode(d, d->shadow_rom.mode, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- dprint(d, 1, "%s: done\n", __FUNCTION__);
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/trace-events b/trace-events
|
||||||
|
index 962caca..0bc290f 100644
|
||||||
|
--- a/trace-events
|
||||||
|
+++ b/trace-events
|
||||||
|
@@ -631,3 +631,62 @@ win_helper_no_switch_pstate(uint32_t new_pstate_regs) "change_pstate: regs new=%
|
||||||
|
win_helper_wrpil(uint32_t psrpil, uint32_t new_pil) "old=%x new=%x"
|
||||||
|
win_helper_done(uint32_t tl) "tl=%d"
|
||||||
|
win_helper_retry(uint32_t tl) "tl=%d"
|
||||||
|
+
|
||||||
|
+# hw/qxl.c
|
||||||
|
+disable qxl_interface_set_mm_time(int qid, uint32_t mm_time) "%d %d"
|
||||||
|
+disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
|
||||||
|
+qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position) "%d %dx%d mem=%lx %d,%d"
|
||||||
|
+qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags) "%d %d,%d,%d"
|
||||||
|
+qxl_destroy_primary(int qid) "%d"
|
||||||
|
+qxl_enter_vga_mode(int qid) "%d"
|
||||||
|
+qxl_exit_vga_mode(int qid) "%d"
|
||||||
|
+qxl_hard_reset(int qid, int64_t loadvm) "%d loadvm=%"PRId64""
|
||||||
|
+qxl_interface_async_complete_io(int qid, uint32_t current_async, void *cookie) "%d current=%d cookie=%p"
|
||||||
|
+qxl_interface_attach_worker(int qid) "%d"
|
||||||
|
+qxl_interface_get_init_info(int qid) "%d"
|
||||||
|
+qxl_interface_set_compression_level(int qid, int64_t level) "%d %"PRId64
|
||||||
|
+qxl_interface_update_area_complete(int qid, uint32_t surface_id, uint32_t dirty_left, uint32_t dirty_right, uint32_t dirty_top, uint32_t dirty_bottom) "%d surface=%d [%d,%d,%d,%d]"
|
||||||
|
+qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d #=%d"
|
||||||
|
+qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
|
||||||
|
+qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
|
||||||
|
+qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
|
||||||
|
+qxl_io_read_unexpected(int qid) "%d"
|
||||||
|
+qxl_io_unexpected_vga_mode(int qid, uint32_t io_port, const char *desc) "%d 0x%x (%s)"
|
||||||
|
+qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d"
|
||||||
|
+qxl_memslot_add_guest(int qid, uint32_t slot_id, uint64_t guest_start, uint64_t guest_end) "%d %u: guest phys 0x%"PRIx64 " - 0x%" PRIx64
|
||||||
|
+qxl_post_load(int qid, const char *mode) "%d %s"
|
||||||
|
+qxl_pre_load(int qid) "%d"
|
||||||
|
+qxl_pre_save(int qid) "%d"
|
||||||
|
+qxl_reset_surfaces(int qid) "%d"
|
||||||
|
+qxl_ring_command_check(int qid, const char *mode) "%d %s"
|
||||||
|
+qxl_ring_command_get(int qid, const char *mode) "%d %s"
|
||||||
|
+qxl_ring_command_req_notification(int qid) "%d"
|
||||||
|
+qxl_ring_cursor_check(int qid, const char *mode) "%d %s"
|
||||||
|
+qxl_ring_cursor_get(int qid, const char *mode) "%d %s"
|
||||||
|
+qxl_ring_cursor_req_notification(int qid) "%d"
|
||||||
|
+qxl_ring_res_push(int qid, const char *mode, uint32_t surface_count, uint32_t free_res, void *last_release, const char *notify) "%d %s s#=%d res#=%d last=%p notify=%s"
|
||||||
|
+qxl_ring_res_push_rest(int qid, uint32_t ring_has, uint32_t ring_size, uint32_t prod, uint32_t cons) "%d ring %d/%d [%d,%d]"
|
||||||
|
+qxl_ring_res_put(int qid, uint32_t free_res) "%d #res=%d"
|
||||||
|
+qxl_set_mode(int qid, int modenr, uint32_t x_res, uint32_t y_res, uint32_t bits, uint64_t devmem) "%d mode=%d [ x=%d y=%d @ bpp=%d devmem=0x%" PRIx64 " ]"
|
||||||
|
+qxl_soft_reset(int qid) "%d"
|
||||||
|
+qemu_spice_add_memslot(int qid, uint32_t slot_id, unsigned long virt_start, unsigned long virt_end, int async) "%d %u: host virt 0x%lx - 0x%lx async=%d"
|
||||||
|
+qemu_spice_del_memslot(int qid, uint32_t gid, uint32_t slot_id) "%d gid=%u sid=%u"
|
||||||
|
+qemu_spice_create_primary_surface(int qid, uint32_t sid, void *surface, int async) "%d sid=%u surface=%p async=%d"
|
||||||
|
+qemu_spice_destroy_primary_surface(int qid, uint32_t sid, int async) "%d sid=%u async=%d"
|
||||||
|
+qemu_spice_wakeup(uint32_t qid) "%d"
|
||||||
|
+qemu_spice_start(uint32_t qid) "%d"
|
||||||
|
+qemu_spice_stop(uint32_t qid) "%d"
|
||||||
|
+qemu_spice_create_update(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "lr %d -> %d, tb -> %d -> %d"
|
||||||
|
+qxl_spice_destroy_surfaces_complete(int qid) "%d"
|
||||||
|
+qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
|
||||||
|
+qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id) "%d sid=%d"
|
||||||
|
+qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async) "%d sid=%d async=%d"
|
||||||
|
+qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res) "%d s#=%d, res#=%d"
|
||||||
|
+qxl_spice_loadvm_commands(int qid, void *ext, uint32_t count) "%d ext=%p count=%d"
|
||||||
|
+qxl_spice_oom(int qid) "%d"
|
||||||
|
+qxl_spice_reset_cursor(int qid) "%d"
|
||||||
|
+qxl_spice_reset_image_cache(int qid) "%d"
|
||||||
|
+qxl_spice_reset_memslots(int qid) "%d"
|
||||||
|
+qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
|
||||||
|
+qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
|
||||||
|
+qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
|
||||||
|
diff --git a/ui/spice-display.c b/ui/spice-display.c
|
||||||
|
index ab266ae..28d6d4a 100644
|
||||||
|
--- a/ui/spice-display.c
|
||||||
|
+++ b/ui/spice-display.c
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
#include "monitor.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "sysemu.h"
|
||||||
|
+#include "trace.h"
|
||||||
|
|
||||||
|
#include "spice-display.h"
|
||||||
|
|
||||||
|
@@ -73,6 +74,10 @@ QXLCookie *qxl_cookie_new(int type, uint64_t io)
|
||||||
|
void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
+ trace_qemu_spice_add_memslot(ssd->qxl.id, memslot->slot_id,
|
||||||
|
+ memslot->virt_start, memslot->virt_end,
|
||||||
|
+ async);
|
||||||
|
+
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
spice_qxl_add_memslot_async(&ssd->qxl, memslot,
|
||||||
|
(uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
@@ -84,6 +89,7 @@ void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
|
||||||
|
|
||||||
|
void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
|
||||||
|
{
|
||||||
|
+ trace_qemu_spice_del_memslot(ssd->qxl.id, gid, sid);
|
||||||
|
ssd->worker->del_memslot(ssd->worker, gid, sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -91,6 +97,7 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
|
||||||
|
QXLDevSurfaceCreate *surface,
|
||||||
|
qxl_async_io async)
|
||||||
|
{
|
||||||
|
+ trace_qemu_spice_create_primary_surface(ssd->qxl.id, id, surface, async);
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface,
|
||||||
|
(uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
@@ -100,10 +107,10 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
|
||||||
|
uint32_t id, qxl_async_io async)
|
||||||
|
{
|
||||||
|
+ trace_qemu_spice_destroy_primary_surface(ssd->qxl.id, id, async);
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
spice_qxl_destroy_primary_surface_async(&ssd->qxl, id,
|
||||||
|
(uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
@@ -115,16 +122,19 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
|
||||||
|
|
||||||
|
void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
|
||||||
|
{
|
||||||
|
+ trace_qemu_spice_wakeup(ssd->qxl.id);
|
||||||
|
ssd->worker->wakeup(ssd->worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qemu_spice_start(SimpleSpiceDisplay *ssd)
|
||||||
|
{
|
||||||
|
+ trace_qemu_spice_start(ssd->qxl.id);
|
||||||
|
ssd->worker->start(ssd->worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qemu_spice_stop(SimpleSpiceDisplay *ssd)
|
||||||
|
{
|
||||||
|
+ trace_qemu_spice_stop(ssd->qxl.id);
|
||||||
|
ssd->worker->stop(ssd->worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -142,7 +152,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
- dprint(2, "%s: lr %d -> %d, tb -> %d -> %d\n", __FUNCTION__,
|
||||||
|
+ trace_qemu_spice_create_update(
|
||||||
|
ssd->dirty.left, ssd->dirty.right,
|
||||||
|
ssd->dirty.top, ssd->dirty.bottom);
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
95
0426-qxl-qxl_render.c-add-trace-events.patch
Normal file
95
0426-qxl-qxl_render.c-add-trace-events.patch
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
From 6b3e0d7afd011b8d40207fe45f6518937df1d99e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Sun, 18 Mar 2012 13:46:15 +0100
|
||||||
|
Subject: [PATCH 426/434] qxl/qxl_render.c: add trace events
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
|
||||||
|
Cherry-pick: Added missing include "trace.h"
|
||||||
|
---
|
||||||
|
hw/qxl-render.c | 14 +++++---------
|
||||||
|
trace-events | 7 +++++++
|
||||||
|
2 files changed, 12 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
|
||||||
|
index 2e10e93..835dc5e 100644
|
||||||
|
--- a/hw/qxl-render.c
|
||||||
|
+++ b/hw/qxl-render.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qxl.h"
|
||||||
|
+#include "trace.h"
|
||||||
|
|
||||||
|
static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
|
||||||
|
{
|
||||||
|
@@ -31,11 +32,10 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!qxl->guest_primary.data) {
|
||||||
|
- dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__);
|
||||||
|
+ trace_qxl_render_blit_guest_primary_initialized();
|
||||||
|
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||||
|
}
|
||||||
|
- dprint(qxl, 2, "%s: stride %d, [%d, %d, %d, %d]\n", __func__,
|
||||||
|
- qxl->guest_primary.qxl_stride,
|
||||||
|
+ trace_qxl_render_blit(qxl->guest_primary.qxl_stride,
|
||||||
|
rect->left, rect->right, rect->top, rect->bottom);
|
||||||
|
src = qxl->guest_primary.data;
|
||||||
|
if (qxl->guest_primary.qxl_stride < 0) {
|
||||||
|
@@ -107,8 +107,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||||
|
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||||
|
qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
|
||||||
|
qxl->num_dirty_rects = 1;
|
||||||
|
- dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d\n",
|
||||||
|
- __FUNCTION__,
|
||||||
|
+ trace_qxl_render_guest_primary_resized(
|
||||||
|
qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height,
|
||||||
|
qxl->guest_primary.qxl_stride,
|
||||||
|
@@ -118,8 +117,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||||
|
if (surface->width != qxl->guest_primary.surface.width ||
|
||||||
|
surface->height != qxl->guest_primary.surface.height) {
|
||||||
|
if (qxl->guest_primary.qxl_stride > 0) {
|
||||||
|
- dprint(qxl, 1, "%s: using guest_primary for displaysurface\n",
|
||||||
|
- __func__);
|
||||||
|
qemu_free_displaysurface(vga->ds);
|
||||||
|
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height,
|
||||||
|
@@ -127,8 +124,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||||
|
qxl->guest_primary.abs_stride,
|
||||||
|
qxl->guest_primary.data);
|
||||||
|
} else {
|
||||||
|
- dprint(qxl, 1, "%s: resizing displaysurface to guest_primary\n",
|
||||||
|
- __func__);
|
||||||
|
qemu_resize_displaysurface(vga->ds,
|
||||||
|
qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height);
|
||||||
|
@@ -187,6 +182,7 @@ void qxl_render_update_area_bh(void *opaque)
|
||||||
|
void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
|
||||||
|
{
|
||||||
|
qemu_mutex_lock(&qxl->ssd.lock);
|
||||||
|
+ trace_qxl_render_update_area_done(cookie);
|
||||||
|
qemu_bh_schedule(qxl->update_area_bh);
|
||||||
|
qxl->render_update_cookie_num--;
|
||||||
|
qemu_mutex_unlock(&qxl->ssd.lock);
|
||||||
|
diff --git a/trace-events b/trace-events
|
||||||
|
index 0bc290f..6050d92 100644
|
||||||
|
--- a/trace-events
|
||||||
|
+++ b/trace-events
|
||||||
|
@@ -690,3 +690,10 @@ qxl_spice_reset_memslots(int qid) "%d"
|
||||||
|
qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
|
||||||
|
qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
|
||||||
|
qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
|
||||||
|
+qxl_vga_ioport_while_not_in_vga_mode(int qid) "%d (int qid, reset to VGA mode because of VGA io)"
|
||||||
|
+
|
||||||
|
+# hw/qxl-render.c
|
||||||
|
+qxl_render_blit_guest_primary_initialized(void) ""
|
||||||
|
+qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom) "stride=%d [%d, %d, %d, %d]"
|
||||||
|
+qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp) "%dx%d, stride %d, bpp %d, depth %d"
|
||||||
|
+qxl_render_update_area_done(void *cookie) "%p"
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
80
0427-hw-qxl.c-Fix-compilation-failures-on-32-bit-hosts.patch
Normal file
80
0427-hw-qxl.c-Fix-compilation-failures-on-32-bit-hosts.patch
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
From 1ca7f74b31de28e9170e404ce2b932e311e4d2d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 16 Mar 2012 13:50:04 +0000
|
||||||
|
Subject: [PATCH 427/434] hw/qxl.c: Fix compilation failures on 32 bit hosts
|
||||||
|
|
||||||
|
Fix compilation failures on 32 bit hosts (cast from pointer to
|
||||||
|
integer of different size; %ld expects 'long int' not uint64_t).
|
||||||
|
|
||||||
|
Reported-by: Steve Langasek <steve.langasek@canonical.com>
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 16 ++++++++--------
|
||||||
|
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 813873a..bcdf274 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -154,7 +154,7 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
|
||||||
|
} else {
|
||||||
|
assert(cookie != NULL);
|
||||||
|
spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
|
||||||
|
- clear_dirty_region, (uint64_t)cookie);
|
||||||
|
+ clear_dirty_region, (uintptr_t)cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -178,7 +178,7 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
|
||||||
|
cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
QXL_IO_DESTROY_SURFACE_ASYNC);
|
||||||
|
cookie->u.surface_id = id;
|
||||||
|
- spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uint64_t)cookie);
|
||||||
|
+ spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uintptr_t)cookie);
|
||||||
|
} else {
|
||||||
|
qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
|
||||||
|
}
|
||||||
|
@@ -189,8 +189,8 @@ static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
|
||||||
|
trace_qxl_spice_flush_surfaces_async(qxl->id, qxl->guest_surfaces.count,
|
||||||
|
qxl->num_free_res);
|
||||||
|
spice_qxl_flush_surfaces_async(&qxl->ssd.qxl,
|
||||||
|
- (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
- QXL_IO_FLUSH_SURFACES_ASYNC));
|
||||||
|
+ (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_FLUSH_SURFACES_ASYNC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
|
||||||
|
@@ -226,8 +226,8 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
|
||||||
|
trace_qxl_spice_destroy_surfaces(qxl->id, async);
|
||||||
|
if (async) {
|
||||||
|
spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl,
|
||||||
|
- (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
- QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
|
||||||
|
+ (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
|
||||||
|
} else {
|
||||||
|
qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
|
||||||
|
qxl_spice_destroy_surfaces_complete(qxl);
|
||||||
|
@@ -767,7 +767,7 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
|
||||||
|
}
|
||||||
|
if (cookie && current_async != cookie->io) {
|
||||||
|
fprintf(stderr,
|
||||||
|
- "qxl: %s: error: current_async = %d != %ld = cookie->io\n",
|
||||||
|
+ "qxl: %s: error: current_async = %d != %" PRId64 " = cookie->io\n",
|
||||||
|
__func__, current_async, cookie->io);
|
||||||
|
}
|
||||||
|
switch (current_async) {
|
||||||
|
@@ -840,7 +840,7 @@ static void interface_update_area_complete(QXLInstance *sin,
|
||||||
|
static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
|
||||||
|
{
|
||||||
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
|
- QXLCookie *cookie = (QXLCookie *)cookie_token;
|
||||||
|
+ QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
|
||||||
|
|
||||||
|
switch (cookie->type) {
|
||||||
|
case QXL_COOKIE_TYPE_IO:
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
67
0428-spice-fix-broken-initialization.patch
Normal file
67
0428-spice-fix-broken-initialization.patch
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
From 9f7bc0be9a5c353d076bb42b3bfdf77d8709063f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Wed, 14 Mar 2012 20:33:37 +0200
|
||||||
|
Subject: [PATCH 428/434] spice: fix broken initialization
|
||||||
|
|
||||||
|
Commit 1b71f7c14fab6f00c2680d4489fbee7baf796e4f moved MODULE_INIT_QOM to
|
||||||
|
way before MODULE_INIT_MACHINE, thereby breaking assumptions made in
|
||||||
|
spice-core.c which registered both a type initializer and a machine
|
||||||
|
intializer.
|
||||||
|
|
||||||
|
This fix removes the type registration, and replaces it with calling
|
||||||
|
qemu_spice_init in vl.c after command line parsing (second pass) is
|
||||||
|
done, and after timers are armed, required by spice server.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
|
||||||
|
ui/spice-core.c
|
||||||
|
---
|
||||||
|
ui/spice-core.c | 8 +-------
|
||||||
|
vl.c | 5 +++++
|
||||||
|
2 files changed, 6 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||||
|
index 4ad0a67..a468524 100644
|
||||||
|
--- a/ui/spice-core.c
|
||||||
|
+++ b/ui/spice-core.c
|
||||||
|
@@ -554,7 +554,7 @@ void qemu_spice_init(void)
|
||||||
|
|
||||||
|
qemu_thread_get_self(&me);
|
||||||
|
|
||||||
|
- if (!opts) {
|
||||||
|
+ if (!opts) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
port = qemu_opt_get_number(opts, "port", 0);
|
||||||
|
@@ -787,9 +787,3 @@ static void spice_register_config(void)
|
||||||
|
qemu_add_opts(&qemu_spice_opts);
|
||||||
|
}
|
||||||
|
machine_init(spice_register_config);
|
||||||
|
-
|
||||||
|
-static void spice_initialize(void)
|
||||||
|
-{
|
||||||
|
- qemu_spice_init();
|
||||||
|
-}
|
||||||
|
-device_init(spice_initialize);
|
||||||
|
diff --git a/vl.c b/vl.c
|
||||||
|
index fdefa86..d33eb03 100644
|
||||||
|
--- a/vl.c
|
||||||
|
+++ b/vl.c
|
||||||
|
@@ -3271,6 +3271,11 @@ int main(int argc, char **argv, char **envp)
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_SPICE
|
||||||
|
+ /* spice needs the timers to be initialized by this point */
|
||||||
|
+ qemu_spice_init();
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
if (icount_option && (kvm_enabled() || xen_enabled())) {
|
||||||
|
fprintf(stderr, "-icount is not allowed with kvm or xen\n");
|
||||||
|
exit(1);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,56 @@
|
|||||||
|
From 2b4d2ccd83280b22d2fea0801e11af5a944a135d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Wed, 7 Mar 2012 13:36:48 +0000
|
||||||
|
Subject: [PATCH 429/434] ui/spice-display.c: Fix compilation warnings on 32
|
||||||
|
bit hosts
|
||||||
|
|
||||||
|
Fix compilation failures ("cast from pointer to integer of
|
||||||
|
different size [-Werror=pointer-to-int-cast]") by using
|
||||||
|
uintptr_t instead.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
ui/spice-display.c | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-display.c b/ui/spice-display.c
|
||||||
|
index 28d6d4a..6d7563f 100644
|
||||||
|
--- a/ui/spice-display.c
|
||||||
|
+++ b/ui/spice-display.c
|
||||||
|
@@ -80,8 +80,8 @@ void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
|
||||||
|
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
spice_qxl_add_memslot_async(&ssd->qxl, memslot,
|
||||||
|
- (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
- QXL_IO_MEMSLOT_ADD_ASYNC));
|
||||||
|
+ (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_MEMSLOT_ADD_ASYNC));
|
||||||
|
} else {
|
||||||
|
ssd->worker->add_memslot(ssd->worker, memslot);
|
||||||
|
}
|
||||||
|
@@ -100,8 +100,8 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
|
||||||
|
trace_qemu_spice_create_primary_surface(ssd->qxl.id, id, surface, async);
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface,
|
||||||
|
- (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
- QXL_IO_CREATE_PRIMARY_ASYNC));
|
||||||
|
+ (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_CREATE_PRIMARY_ASYNC));
|
||||||
|
} else {
|
||||||
|
ssd->worker->create_primary_surface(ssd->worker, id, surface);
|
||||||
|
}
|
||||||
|
@@ -113,8 +113,8 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
|
||||||
|
trace_qemu_spice_destroy_primary_surface(ssd->qxl.id, id, async);
|
||||||
|
if (async != QXL_SYNC) {
|
||||||
|
spice_qxl_destroy_primary_surface_async(&ssd->qxl, id,
|
||||||
|
- (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
- QXL_IO_DESTROY_PRIMARY_ASYNC));
|
||||||
|
+ (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
|
||||||
|
+ QXL_IO_DESTROY_PRIMARY_ASYNC));
|
||||||
|
} else {
|
||||||
|
ssd->worker->destroy_primary_surface(ssd->worker, id);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
From 626eb7b96445815945600895a411ee14c10b9056 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Wed, 21 Mar 2012 18:17:18 +0200
|
||||||
|
Subject: [PATCH 430/434] ui/spice-display: use uintptr_t when casting qxl
|
||||||
|
physical addresses
|
||||||
|
|
||||||
|
The current intptr_t casts are a problem when the address's highest
|
||||||
|
bit is 1, and it is cast to a intptr_t and then to uint64_t, such
|
||||||
|
as at:
|
||||||
|
surface.mem = (intptr_t)ssd->buf;
|
||||||
|
|
||||||
|
This causes the sign bit to be extended which causes a wrong address to
|
||||||
|
be passed on to spice, which then complains when it gets the wrong
|
||||||
|
slot_id number, since the slot_id is taken from the higher bits.
|
||||||
|
|
||||||
|
The assertion happens early - during the first primary surface creation.
|
||||||
|
|
||||||
|
This fixes running "-vga qxl -spice" with 32 bit compiled
|
||||||
|
qemu-system-i386.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
ui/spice-display.c | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-display.c b/ui/spice-display.c
|
||||||
|
index 6d7563f..cb8a7ad 100644
|
||||||
|
--- a/ui/spice-display.c
|
||||||
|
+++ b/ui/spice-display.c
|
||||||
|
@@ -168,7 +168,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
|
||||||
|
drawable->bbox = ssd->dirty;
|
||||||
|
drawable->clip.type = SPICE_CLIP_TYPE_NONE;
|
||||||
|
drawable->effect = QXL_EFFECT_OPAQUE;
|
||||||
|
- drawable->release_info.id = (intptr_t)update;
|
||||||
|
+ drawable->release_info.id = (uintptr_t)update;
|
||||||
|
drawable->type = QXL_DRAW_COPY;
|
||||||
|
drawable->surfaces_dest[0] = -1;
|
||||||
|
drawable->surfaces_dest[1] = -1;
|
||||||
|
@@ -179,7 +179,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
|
||||||
|
+ time_space.tv_nsec / 1000 / 1000;
|
||||||
|
|
||||||
|
drawable->u.copy.rop_descriptor = SPICE_ROPD_OP_PUT;
|
||||||
|
- drawable->u.copy.src_bitmap = (intptr_t)image;
|
||||||
|
+ drawable->u.copy.src_bitmap = (uintptr_t)image;
|
||||||
|
drawable->u.copy.src_area.right = bw;
|
||||||
|
drawable->u.copy.src_area.bottom = bh;
|
||||||
|
|
||||||
|
@@ -189,7 +189,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
|
||||||
|
image->bitmap.stride = bw * 4;
|
||||||
|
image->descriptor.width = image->bitmap.x = bw;
|
||||||
|
image->descriptor.height = image->bitmap.y = bh;
|
||||||
|
- image->bitmap.data = (intptr_t)(update->bitmap);
|
||||||
|
+ image->bitmap.data = (uintptr_t)(update->bitmap);
|
||||||
|
image->bitmap.palette = 0;
|
||||||
|
image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
|
||||||
|
|
||||||
|
@@ -210,7 +210,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->type = QXL_CMD_DRAW;
|
||||||
|
- cmd->data = (intptr_t)drawable;
|
||||||
|
+ cmd->data = (uintptr_t)drawable;
|
||||||
|
|
||||||
|
memset(&ssd->dirty, 0, sizeof(ssd->dirty));
|
||||||
|
return update;
|
||||||
|
@@ -254,7 +254,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
|
||||||
|
surface.mouse_mode = true;
|
||||||
|
surface.flags = 0;
|
||||||
|
surface.type = 0;
|
||||||
|
- surface.mem = (intptr_t)ssd->buf;
|
||||||
|
+ surface.mem = (uintptr_t)ssd->buf;
|
||||||
|
surface.group_id = MEMSLOT_GROUP_HOST;
|
||||||
|
|
||||||
|
qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
185
0431-qxl-add-optinal-64bit-vram-bar.patch
Normal file
185
0431-qxl-add-optinal-64bit-vram-bar.patch
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
From f1e729a041efbd2d562e8202407e927745210bbd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 14 Oct 2011 18:05:48 +0200
|
||||||
|
Subject: [PATCH 431/434] qxl: add optinal 64bit vram bar
|
||||||
|
|
||||||
|
This patch adds an 64bit pci bar for vram. It is turned off by default.
|
||||||
|
It can be enabled by setting the size of the 64bit bar to be larger than
|
||||||
|
the 32bit bar. Both 32bit and 64bit bar refer to the same memory. Only
|
||||||
|
the first part of the memory is available via 32bit bar.
|
||||||
|
|
||||||
|
The intention is to allow large vram sizes for 64bit guests, by allowing
|
||||||
|
the vram bar being mapped above 4G, so we don't have to squeeze it into
|
||||||
|
the pci I/O window below 4G.
|
||||||
|
|
||||||
|
With vram_size_mb=16 and vram64_size_mb=256 it looks like this:
|
||||||
|
|
||||||
|
00:02.0 VGA compatible controller: Red Hat, Inc. Device 0100 (rev 02) (prog-if 00 [VGA controller])
|
||||||
|
Subsystem: Red Hat, Inc Device 1100
|
||||||
|
Physical Slot: 2
|
||||||
|
Flags: fast devsel, IRQ 10
|
||||||
|
Memory at f8000000 (32-bit, non-prefetchable) [size=64M]
|
||||||
|
Memory at fc000000 (32-bit, non-prefetchable) [size=16M]
|
||||||
|
Memory at fd020000 (32-bit, non-prefetchable) [size=8K]
|
||||||
|
I/O ports at c5a0 [size=32]
|
||||||
|
Memory at ffe0000000 (64-bit, prefetchable) [size=256M]
|
||||||
|
Expansion ROM at fd000000 [disabled] [size=64K]
|
||||||
|
|
||||||
|
[ mapping above 4G needs patched seabios:
|
||||||
|
http://www.kraxel.org/cgit/seabios/commit/?h=pci64 ]
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
|
||||||
|
hw/qxl.c
|
||||||
|
---
|
||||||
|
hw/qxl.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
|
||||||
|
hw/qxl.h | 7 +++++++
|
||||||
|
2 files changed, 51 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index bcdf274..18f3759 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1002,6 +1002,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
||||||
|
static const int regions[] = {
|
||||||
|
QXL_RAM_RANGE_INDEX,
|
||||||
|
QXL_VRAM_RANGE_INDEX,
|
||||||
|
+ QXL_VRAM64_RANGE_INDEX,
|
||||||
|
};
|
||||||
|
uint64_t guest_start;
|
||||||
|
uint64_t guest_end;
|
||||||
|
@@ -1046,6 +1047,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
||||||
|
virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
|
||||||
|
break;
|
||||||
|
case QXL_VRAM_RANGE_INDEX:
|
||||||
|
+ case 4 /* vram 64bit */:
|
||||||
|
virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
@@ -1630,18 +1632,28 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl, uint32_t ram_min_mb)
|
||||||
|
qxl->vga.vram_size = ram_min_mb * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* vram (surfaces, bar 1) */
|
||||||
|
+ /* vram32 (surfaces, 32bit, bar 1) */
|
||||||
|
+ if (qxl->vram32_size_mb != -1) {
|
||||||
|
+ qxl->vram32_size = qxl->vram32_size_mb * 1024 * 1024;
|
||||||
|
+ }
|
||||||
|
+ if (qxl->vram32_size < 4096) {
|
||||||
|
+ qxl->vram32_size = 4096;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* vram (surfaces, 64bit, bar 4+5) */
|
||||||
|
if (qxl->vram_size_mb != -1) {
|
||||||
|
qxl->vram_size = qxl->vram_size_mb * 1024 * 1024;
|
||||||
|
}
|
||||||
|
- if (qxl->vram_size < 4096) {
|
||||||
|
- qxl->vram_size = 4096;
|
||||||
|
+ if (qxl->vram_size < qxl->vram32_size) {
|
||||||
|
+ qxl->vram_size = qxl->vram32_size;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
if (qxl->revision == 1) {
|
||||||
|
+ qxl->vram32_size = 4096;
|
||||||
|
qxl->vram_size = 4096;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
qxl->vga.vram_size = msb_mask(qxl->vga.vram_size * 2 - 1);
|
||||||
|
+ qxl->vram32_size = msb_mask(qxl->vram32_size * 2 - 1);
|
||||||
|
qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1683,6 +1695,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
|
||||||
|
|
||||||
|
memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram",
|
||||||
|
qxl->vram_size);
|
||||||
|
+ memory_region_init_alias(&qxl->vram32_bar, "qxl.vram32", &qxl->vram_bar,
|
||||||
|
+ 0, qxl->vram32_size);
|
||||||
|
|
||||||
|
io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
|
||||||
|
if (qxl->revision == 1) {
|
||||||
|
@@ -1706,7 +1720,29 @@ static int qxl_init_common(PCIQXLDevice *qxl)
|
||||||
|
PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
|
||||||
|
|
||||||
|
pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX,
|
||||||
|
- PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
|
||||||
|
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram32_bar);
|
||||||
|
+
|
||||||
|
+ if (qxl->vram32_size < qxl->vram_size) {
|
||||||
|
+ /*
|
||||||
|
+ * Make the 64bit vram bar show up only in case it is
|
||||||
|
+ * configured to be larger than the 32bit vram bar.
|
||||||
|
+ */
|
||||||
|
+ pci_register_bar(&qxl->pci, QXL_VRAM64_RANGE_INDEX,
|
||||||
|
+ PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||||
|
+ PCI_BASE_ADDRESS_MEM_TYPE_64 |
|
||||||
|
+ PCI_BASE_ADDRESS_MEM_PREFETCH,
|
||||||
|
+ &qxl->vram_bar);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* print pci bar details */
|
||||||
|
+ dprint(qxl, 1, "ram/%s: %d MB [region 0]\n",
|
||||||
|
+ qxl->id == 0 ? "pri" : "sec",
|
||||||
|
+ qxl->vga.vram_size / (1024*1024));
|
||||||
|
+ dprint(qxl, 1, "vram/32: %d MB [region 1]\n",
|
||||||
|
+ qxl->vram32_size / (1024*1024));
|
||||||
|
+ dprint(qxl, 1, "vram/64: %d MB %s\n",
|
||||||
|
+ qxl->vram_size / (1024*1024),
|
||||||
|
+ qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]");
|
||||||
|
|
||||||
|
qxl->ssd.qxl.base.sif = &qxl_interface.base;
|
||||||
|
qxl->ssd.qxl.id = qxl->id;
|
||||||
|
@@ -1918,7 +1954,7 @@ static VMStateDescription qxl_vmstate = {
|
||||||
|
static Property qxl_properties[] = {
|
||||||
|
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
|
||||||
|
64 * 1024 * 1024),
|
||||||
|
- DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
|
||||||
|
+ DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram32_size,
|
||||||
|
64 * 1024 * 1024),
|
||||||
|
DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
|
||||||
|
QXL_DEFAULT_REVISION),
|
||||||
|
@@ -1926,7 +1962,8 @@ static Property qxl_properties[] = {
|
||||||
|
DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
|
||||||
|
DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
|
||||||
|
DEFINE_PROP_UINT32("ram_size_mb", PCIQXLDevice, ram_size_mb, -1),
|
||||||
|
- DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram_size_mb, -1),
|
||||||
|
+ DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, 0),
|
||||||
|
+ DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, 0),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.h b/hw/qxl.h
|
||||||
|
index 86e415b..11a0db3 100644
|
||||||
|
--- a/hw/qxl.h
|
||||||
|
+++ b/hw/qxl.h
|
||||||
|
@@ -16,6 +16,10 @@ enum qxl_mode {
|
||||||
|
QXL_MODE_NATIVE,
|
||||||
|
};
|
||||||
|
|
||||||
|
+#ifndef QXL_VRAM64_RANGE_INDEX
|
||||||
|
+#define QXL_VRAM64_RANGE_INDEX 4
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define QXL_UNDEFINED_IO UINT32_MAX
|
||||||
|
|
||||||
|
#define QXL_NUM_DIRTY_RECTS 64
|
||||||
|
@@ -88,6 +92,8 @@ typedef struct PCIQXLDevice {
|
||||||
|
/* vram pci bar */
|
||||||
|
uint32_t vram_size;
|
||||||
|
MemoryRegion vram_bar;
|
||||||
|
+ uint32_t vram32_size;
|
||||||
|
+ MemoryRegion vram32_bar;
|
||||||
|
|
||||||
|
/* io bar */
|
||||||
|
MemoryRegion io_bar;
|
||||||
|
@@ -95,6 +101,7 @@ typedef struct PCIQXLDevice {
|
||||||
|
/* user-friendly properties (in megabytes) */
|
||||||
|
uint32_t ram_size_mb;
|
||||||
|
uint32_t vram_size_mb;
|
||||||
|
+ uint32_t vram32_size_mb;
|
||||||
|
|
||||||
|
/* qxl_render_update state */
|
||||||
|
int render_update_cookie_num;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
35
0432-qxl-set-default-values-of-vram-_size_mb-to-1.patch
Normal file
35
0432-qxl-set-default-values-of-vram-_size_mb-to-1.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From c18b8163ec4ebec3a7f99865038fa1ad36b2add2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Thu, 29 Mar 2012 22:24:38 +0200
|
||||||
|
Subject: [PATCH 432/434] qxl: set default values of vram*_size_mb to -1
|
||||||
|
|
||||||
|
The addition of those values caused a regression where not specifying
|
||||||
|
any value for the vram bar size would result in a 4096 _byte_ surface
|
||||||
|
area. This is ok for the windows driver but causes the X driver to be
|
||||||
|
unusable. Also, it's a regression. This patch returns the default
|
||||||
|
behavior of having a 64 megabyte vram BAR.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 18f3759..2135fde 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1962,8 +1962,8 @@ static Property qxl_properties[] = {
|
||||||
|
DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
|
||||||
|
DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
|
||||||
|
DEFINE_PROP_UINT32("ram_size_mb", PCIQXLDevice, ram_size_mb, -1),
|
||||||
|
- DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, 0),
|
||||||
|
- DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, 0),
|
||||||
|
+ DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, -1),
|
||||||
|
+ DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
From 68fc3d666b28d14c5023c1f2115cd3a51389f838 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Wed, 18 Apr 2012 12:24:28 +0300
|
||||||
|
Subject: [PATCH 433/434] qxl-render: fix broken vnc+spice since commit
|
||||||
|
f934493
|
||||||
|
|
||||||
|
Notify any listeners such as vnc that the displaysurface has been
|
||||||
|
changed, otherwise they will segfault when first accessing the freed old
|
||||||
|
displaysurface data.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl-render.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
|
||||||
|
index 835dc5e..180b8f9 100644
|
||||||
|
--- a/hw/qxl-render.c
|
||||||
|
+++ b/hw/qxl-render.c
|
||||||
|
@@ -127,6 +127,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||||
|
qemu_resize_displaysurface(vga->ds,
|
||||||
|
qxl->guest_primary.surface.width,
|
||||||
|
qxl->guest_primary.surface.height);
|
||||||
|
+ dpy_resize(vga->ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < qxl->num_dirty_rects; i++) {
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
36
0434-qxl-don-t-assert-on-guest-create_guest_primary.patch
Normal file
36
0434-qxl-don-t-assert-on-guest-create_guest_primary.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From f9f547a6646d72204d88a79960191a0285774c23 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alon Levy <alevy@redhat.com>
|
||||||
|
Date: Wed, 18 Apr 2012 14:00:06 +0300
|
||||||
|
Subject: [PATCH 434/434] qxl: don't assert on guest create_guest_primary
|
||||||
|
|
||||||
|
initiate the implicit destroy ourselves.
|
||||||
|
|
||||||
|
Signed-off-by: Alon Levy <alevy@redhat.com>
|
||||||
|
---
|
||||||
|
hw/qxl.c | 10 +++++++++-
|
||||||
|
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/hw/qxl.c b/hw/qxl.c
|
||||||
|
index 2135fde..29c8873 100644
|
||||||
|
--- a/hw/qxl.c
|
||||||
|
+++ b/hw/qxl.c
|
||||||
|
@@ -1123,7 +1123,15 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
|
||||||
|
QXLDevSurfaceCreate surface;
|
||||||
|
QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
|
||||||
|
|
||||||
|
- assert(qxl->mode != QXL_MODE_NATIVE);
|
||||||
|
+ if (qxl->mode == QXL_MODE_NATIVE) {
|
||||||
|
+ /*
|
||||||
|
+ * allow a create without a destroy. This could be used
|
||||||
|
+ * later for an atomic "change primary" but right now just
|
||||||
|
+ * destroy the primary for the guest. Note that this uses
|
||||||
|
+ * the ability to have multiple concurrent async commands.
|
||||||
|
+ */
|
||||||
|
+ qxl_destroy_primary(qxl, async);
|
||||||
|
+ }
|
||||||
|
qxl_exit_vga_mode(qxl);
|
||||||
|
|
||||||
|
surface.format = le32_to_cpu(sc->format);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
68
0501-audio-add-VOICE_VOLUME-ctl.patch
Normal file
68
0501-audio-add-VOICE_VOLUME-ctl.patch
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
From be81272bafb948278e5e5739ef975cd7bbf0ee0c Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:35 +0200
|
||||||
|
Subject: [PATCH 501/509] audio: add VOICE_VOLUME ctl
|
||||||
|
|
||||||
|
Add a new PCM control operation to update the stream volume on the
|
||||||
|
audio backend. The argument given is a SWVoiceOut/SWVoiceIn.
|
||||||
|
|
||||||
|
v4:
|
||||||
|
- verified other backends didn't fail/assert on this new control
|
||||||
|
they randomly return 0 or -1, but we ignore return value.
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
audio/audio.c | 12 ++++++++++++
|
||||||
|
audio/audio_int.h | 1 +
|
||||||
|
2 files changed, 13 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/audio/audio.c b/audio/audio.c
|
||||||
|
index 50d0d71..2ae9b2f 100644
|
||||||
|
--- a/audio/audio.c
|
||||||
|
+++ b/audio/audio.c
|
||||||
|
@@ -2050,17 +2050,29 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
|
||||||
|
void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
|
||||||
|
{
|
||||||
|
if (sw) {
|
||||||
|
+ HWVoiceOut *hw = sw->hw;
|
||||||
|
+
|
||||||
|
sw->vol.mute = mute;
|
||||||
|
sw->vol.l = nominal_volume.l * lvol / 255;
|
||||||
|
sw->vol.r = nominal_volume.r * rvol / 255;
|
||||||
|
+
|
||||||
|
+ if (hw->pcm_ops->ctl_out) {
|
||||||
|
+ hw->pcm_ops->ctl_out (hw, VOICE_VOLUME, sw);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
|
||||||
|
{
|
||||||
|
if (sw) {
|
||||||
|
+ HWVoiceIn *hw = sw->hw;
|
||||||
|
+
|
||||||
|
sw->vol.mute = mute;
|
||||||
|
sw->vol.l = nominal_volume.l * lvol / 255;
|
||||||
|
sw->vol.r = nominal_volume.r * rvol / 255;
|
||||||
|
+
|
||||||
|
+ if (hw->pcm_ops->ctl_in) {
|
||||||
|
+ hw->pcm_ops->ctl_in (hw, VOICE_VOLUME, sw);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/audio/audio_int.h b/audio/audio_int.h
|
||||||
|
index 2003f8b..117f95e 100644
|
||||||
|
--- a/audio/audio_int.h
|
||||||
|
+++ b/audio/audio_int.h
|
||||||
|
@@ -231,6 +231,7 @@ void audio_run (const char *msg);
|
||||||
|
|
||||||
|
#define VOICE_ENABLE 1
|
||||||
|
#define VOICE_DISABLE 2
|
||||||
|
+#define VOICE_VOLUME 3
|
||||||
|
|
||||||
|
static inline int audio_ring_dist (int dst, int src, int len)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,99 @@
|
|||||||
|
From eaa3b2d4cc2ac17b2aaf0d6387d3991b9d08c56e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:36 +0200
|
||||||
|
Subject: [PATCH 502/509] audio: don't apply volume effect if backend has
|
||||||
|
VOICE_VOLUME_CAP
|
||||||
|
|
||||||
|
If the audio backend is capable of volume control, don't apply
|
||||||
|
software volume (mixeng_volume ()), but instead, rely on backend
|
||||||
|
volume control. This will allow guest to have full range volume
|
||||||
|
control.
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
audio/audio.c | 9 +++++++--
|
||||||
|
audio/audio_int.h | 5 +++++
|
||||||
|
audio/audio_template.h | 2 ++
|
||||||
|
3 files changed, 14 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/audio/audio.c b/audio/audio.c
|
||||||
|
index 2ae9b2f..0fe95a7 100644
|
||||||
|
--- a/audio/audio.c
|
||||||
|
+++ b/audio/audio.c
|
||||||
|
@@ -954,7 +954,9 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
|
||||||
|
total += isamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
- mixeng_volume (sw->buf, ret, &sw->vol);
|
||||||
|
+ if (!(hw->ctl_caps & VOICE_VOLUME_CAP)) {
|
||||||
|
+ mixeng_volume (sw->buf, ret, &sw->vol);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
sw->clip (buf, sw->buf, ret);
|
||||||
|
sw->total_hw_samples_acquired += total;
|
||||||
|
@@ -1038,7 +1040,10 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
|
||||||
|
swlim = audio_MIN (swlim, samples);
|
||||||
|
if (swlim) {
|
||||||
|
sw->conv (sw->buf, buf, swlim);
|
||||||
|
- mixeng_volume (sw->buf, swlim, &sw->vol);
|
||||||
|
+
|
||||||
|
+ if (!(sw->hw->ctl_caps & VOICE_VOLUME_CAP)) {
|
||||||
|
+ mixeng_volume (sw->buf, swlim, &sw->vol);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
while (swlim) {
|
||||||
|
diff --git a/audio/audio_int.h b/audio/audio_int.h
|
||||||
|
index 117f95e..b9b0676 100644
|
||||||
|
--- a/audio/audio_int.h
|
||||||
|
+++ b/audio/audio_int.h
|
||||||
|
@@ -82,6 +82,7 @@ typedef struct HWVoiceOut {
|
||||||
|
int samples;
|
||||||
|
QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
|
||||||
|
QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
|
||||||
|
+ int ctl_caps;
|
||||||
|
struct audio_pcm_ops *pcm_ops;
|
||||||
|
QLIST_ENTRY (HWVoiceOut) entries;
|
||||||
|
} HWVoiceOut;
|
||||||
|
@@ -101,6 +102,7 @@ typedef struct HWVoiceIn {
|
||||||
|
|
||||||
|
int samples;
|
||||||
|
QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
|
||||||
|
+ int ctl_caps;
|
||||||
|
struct audio_pcm_ops *pcm_ops;
|
||||||
|
QLIST_ENTRY (HWVoiceIn) entries;
|
||||||
|
} HWVoiceIn;
|
||||||
|
@@ -150,6 +152,7 @@ struct audio_driver {
|
||||||
|
int max_voices_in;
|
||||||
|
int voice_size_out;
|
||||||
|
int voice_size_in;
|
||||||
|
+ int ctl_caps;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct audio_pcm_ops {
|
||||||
|
@@ -233,6 +236,8 @@ void audio_run (const char *msg);
|
||||||
|
#define VOICE_DISABLE 2
|
||||||
|
#define VOICE_VOLUME 3
|
||||||
|
|
||||||
|
+#define VOICE_VOLUME_CAP (1 << VOICE_VOLUME)
|
||||||
|
+
|
||||||
|
static inline int audio_ring_dist (int dst, int src, int len)
|
||||||
|
{
|
||||||
|
return (dst >= src) ? (dst - src) : (len - src + dst);
|
||||||
|
diff --git a/audio/audio_template.h b/audio/audio_template.h
|
||||||
|
index e62a713..519432a 100644
|
||||||
|
--- a/audio/audio_template.h
|
||||||
|
+++ b/audio/audio_template.h
|
||||||
|
@@ -263,6 +263,8 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
|
||||||
|
}
|
||||||
|
|
||||||
|
hw->pcm_ops = drv->pcm_ops;
|
||||||
|
+ hw->ctl_caps = drv->ctl_caps;
|
||||||
|
+
|
||||||
|
QLIST_INIT (&hw->sw_head);
|
||||||
|
#ifdef DAC
|
||||||
|
QLIST_INIT (&hw->cap_head);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
170
0503-hw-ac97-remove-USE_MIXER-code.patch
Normal file
170
0503-hw-ac97-remove-USE_MIXER-code.patch
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
From e27e5ceeee3d8cb55ba0749446b49ccc6ec5b96d Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:37 +0200
|
||||||
|
Subject: [PATCH 503/509] hw/ac97: remove USE_MIXER code
|
||||||
|
|
||||||
|
That code doesn't compile. The interesting bits for volume control are
|
||||||
|
going to be rewritten in the following patch.
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
hw/ac97.c | 121 -------------------------------------------------------------
|
||||||
|
1 file changed, 121 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/ac97.c b/hw/ac97.c
|
||||||
|
index 0dbba3b..cd893c3 100644
|
||||||
|
--- a/hw/ac97.c
|
||||||
|
+++ b/hw/ac97.c
|
||||||
|
@@ -434,99 +434,6 @@ static void reset_voices (AC97LinkState *s, uint8_t active[LAST_INDEX])
|
||||||
|
AUD_set_active_in (s->voice_mc, active[MC_INDEX]);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef USE_MIXER
|
||||||
|
-static void set_volume (AC97LinkState *s, int index,
|
||||||
|
- audmixerctl_t mt, uint32_t val)
|
||||||
|
-{
|
||||||
|
- int mute = (val >> MUTE_SHIFT) & 1;
|
||||||
|
- uint8_t rvol = VOL_MASK - (val & VOL_MASK);
|
||||||
|
- uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK);
|
||||||
|
- rvol = 255 * rvol / VOL_MASK;
|
||||||
|
- lvol = 255 * lvol / VOL_MASK;
|
||||||
|
-
|
||||||
|
-#ifdef SOFT_VOLUME
|
||||||
|
- if (index == AC97_Master_Volume_Mute) {
|
||||||
|
- AUD_set_volume_out (s->voice_po, mute, lvol, rvol);
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- AUD_set_volume (mt, &mute, &lvol, &rvol);
|
||||||
|
- }
|
||||||
|
-#else
|
||||||
|
- AUD_set_volume (mt, &mute, &lvol, &rvol);
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- rvol = VOL_MASK - ((VOL_MASK * rvol) / 255);
|
||||||
|
- lvol = VOL_MASK - ((VOL_MASK * lvol) / 255);
|
||||||
|
- mixer_store (s, index, val);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static audrecsource_t ac97_to_aud_record_source (uint8_t i)
|
||||||
|
-{
|
||||||
|
- switch (i) {
|
||||||
|
- case REC_MIC:
|
||||||
|
- return AUD_REC_MIC;
|
||||||
|
-
|
||||||
|
- case REC_CD:
|
||||||
|
- return AUD_REC_CD;
|
||||||
|
-
|
||||||
|
- case REC_VIDEO:
|
||||||
|
- return AUD_REC_VIDEO;
|
||||||
|
-
|
||||||
|
- case REC_AUX:
|
||||||
|
- return AUD_REC_AUX;
|
||||||
|
-
|
||||||
|
- case REC_LINE_IN:
|
||||||
|
- return AUD_REC_LINE_IN;
|
||||||
|
-
|
||||||
|
- case REC_PHONE:
|
||||||
|
- return AUD_REC_PHONE;
|
||||||
|
-
|
||||||
|
- default:
|
||||||
|
- dolog ("Unknown record source %d, using MIC\n", i);
|
||||||
|
- return AUD_REC_MIC;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static uint8_t aud_to_ac97_record_source (audrecsource_t rs)
|
||||||
|
-{
|
||||||
|
- switch (rs) {
|
||||||
|
- case AUD_REC_MIC:
|
||||||
|
- return REC_MIC;
|
||||||
|
-
|
||||||
|
- case AUD_REC_CD:
|
||||||
|
- return REC_CD;
|
||||||
|
-
|
||||||
|
- case AUD_REC_VIDEO:
|
||||||
|
- return REC_VIDEO;
|
||||||
|
-
|
||||||
|
- case AUD_REC_AUX:
|
||||||
|
- return REC_AUX;
|
||||||
|
-
|
||||||
|
- case AUD_REC_LINE_IN:
|
||||||
|
- return REC_LINE_IN;
|
||||||
|
-
|
||||||
|
- case AUD_REC_PHONE:
|
||||||
|
- return REC_PHONE;
|
||||||
|
-
|
||||||
|
- default:
|
||||||
|
- dolog ("Unknown audio recording source %d using MIC\n", rs);
|
||||||
|
- return REC_MIC;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void record_select (AC97LinkState *s, uint32_t val)
|
||||||
|
-{
|
||||||
|
- uint8_t rs = val & REC_MASK;
|
||||||
|
- uint8_t ls = (val >> 8) & REC_MASK;
|
||||||
|
- audrecsource_t ars = ac97_to_aud_record_source (rs);
|
||||||
|
- audrecsource_t als = ac97_to_aud_record_source (ls);
|
||||||
|
- AUD_set_record_source (&als, &ars);
|
||||||
|
- rs = aud_to_ac97_record_source (ars);
|
||||||
|
- ls = aud_to_ac97_record_source (als);
|
||||||
|
- mixer_store (s, AC97_Record_Select, rs | (ls << 8));
|
||||||
|
-}
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
static void mixer_reset (AC97LinkState *s)
|
||||||
|
{
|
||||||
|
uint8_t active[LAST_INDEX];
|
||||||
|
@@ -561,12 +468,6 @@ static void mixer_reset (AC97LinkState *s)
|
||||||
|
mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80);
|
||||||
|
mixer_store (s, AC97_MIC_ADC_Rate , 0xbb80);
|
||||||
|
|
||||||
|
-#ifdef USE_MIXER
|
||||||
|
- record_select (s, 0);
|
||||||
|
- set_volume (s, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME , 0x8000);
|
||||||
|
- set_volume (s, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM , 0x8808);
|
||||||
|
- set_volume (s, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808);
|
||||||
|
-#endif
|
||||||
|
reset_voices (s, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -625,20 +526,6 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
val |= mixer_load (s, index) & 0xf;
|
||||||
|
mixer_store (s, index, val);
|
||||||
|
break;
|
||||||
|
-#ifdef USE_MIXER
|
||||||
|
- case AC97_Master_Volume_Mute:
|
||||||
|
- set_volume (s, index, AUD_MIXER_VOLUME, val);
|
||||||
|
- break;
|
||||||
|
- case AC97_PCM_Out_Volume_Mute:
|
||||||
|
- set_volume (s, index, AUD_MIXER_PCM, val);
|
||||||
|
- break;
|
||||||
|
- case AC97_Line_In_Volume_Mute:
|
||||||
|
- set_volume (s, index, AUD_MIXER_LINE_IN, val);
|
||||||
|
- break;
|
||||||
|
- case AC97_Record_Select:
|
||||||
|
- record_select (s, val);
|
||||||
|
- break;
|
||||||
|
-#endif
|
||||||
|
case AC97_Vendor_ID1:
|
||||||
|
case AC97_Vendor_ID2:
|
||||||
|
dolog ("Attempt to write vendor ID to %#x\n", val);
|
||||||
|
@@ -1191,14 +1078,6 @@ static int ac97_post_load (void *opaque, int version_id)
|
||||||
|
uint8_t active[LAST_INDEX];
|
||||||
|
AC97LinkState *s = opaque;
|
||||||
|
|
||||||
|
-#ifdef USE_MIXER
|
||||||
|
- record_select (s, mixer_load (s, AC97_Record_Select));
|
||||||
|
-#define V_(a, b) set_volume (s, a, b, mixer_load (s, a))
|
||||||
|
- V_ (AC97_Master_Volume_Mute, AUD_MIXER_VOLUME);
|
||||||
|
- V_ (AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM);
|
||||||
|
- V_ (AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN);
|
||||||
|
-#undef V_
|
||||||
|
-#endif
|
||||||
|
active[PI_INDEX] = !!(s->bm_regs[PI_INDEX].cr & CR_RPBM);
|
||||||
|
active[PO_INDEX] = !!(s->bm_regs[PO_INDEX].cr & CR_RPBM);
|
||||||
|
active[MC_INDEX] = !!(s->bm_regs[MC_INDEX].cr & CR_RPBM);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
28
0504-hw-ac97-the-volume-mask-is-not-only-0x1f.patch
Normal file
28
0504-hw-ac97-the-volume-mask-is-not-only-0x1f.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From c0bcb346459445db2895fb56c78ab71e592c0c90 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:38 +0200
|
||||||
|
Subject: [PATCH 504/509] hw/ac97: the volume mask is not only 0x1f
|
||||||
|
|
||||||
|
It's a case by case (see Table 66. AC ?97 Baseline Audio Register Map)
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
hw/ac97.c | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/hw/ac97.c b/hw/ac97.c
|
||||||
|
index cd893c3..aa1babf 100644
|
||||||
|
--- a/hw/ac97.c
|
||||||
|
+++ b/hw/ac97.c
|
||||||
|
@@ -115,7 +115,6 @@ enum {
|
||||||
|
#define EACS_VRA 1
|
||||||
|
#define EACS_VRM 8
|
||||||
|
|
||||||
|
-#define VOL_MASK 0x1f
|
||||||
|
#define MUTE_SHIFT 15
|
||||||
|
|
||||||
|
#define REC_MASK 7
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
134
0505-hw-ac97-add-support-for-volume-control.patch
Normal file
134
0505-hw-ac97-add-support-for-volume-control.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
From 41d13bd2047a3a3ae8f451ff4aaf0585231ba1c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:39 +0200
|
||||||
|
Subject: [PATCH 505/509] hw/ac97: add support for volume control
|
||||||
|
|
||||||
|
Combine output volume with Master and PCM registers values.
|
||||||
|
Use default values in mixer_reset ().
|
||||||
|
Set volume on post-load to update backend values.
|
||||||
|
|
||||||
|
v4,v5:
|
||||||
|
- fix some code style
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
hw/ac97.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 81 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/hw/ac97.c b/hw/ac97.c
|
||||||
|
index aa1babf..dd4917b 100644
|
||||||
|
--- a/hw/ac97.c
|
||||||
|
+++ b/hw/ac97.c
|
||||||
|
@@ -433,6 +433,65 @@ static void reset_voices (AC97LinkState *s, uint8_t active[LAST_INDEX])
|
||||||
|
AUD_set_active_in (s->voice_mc, active[MC_INDEX]);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void get_volume (uint16_t vol, uint16_t mask, int inverse,
|
||||||
|
+ int *mute, uint8_t *lvol, uint8_t *rvol)
|
||||||
|
+{
|
||||||
|
+ *mute = (vol >> MUTE_SHIFT) & 1;
|
||||||
|
+ *rvol = (255 * (vol & mask)) / mask;
|
||||||
|
+ *lvol = (255 * ((vol >> 8) & mask)) / mask;
|
||||||
|
+
|
||||||
|
+ if (inverse) {
|
||||||
|
+ *rvol = 255 - *rvol;
|
||||||
|
+ *lvol = 255 - *lvol;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void update_combined_volume_out (AC97LinkState *s)
|
||||||
|
+{
|
||||||
|
+ uint8_t lvol, rvol, plvol, prvol;
|
||||||
|
+ int mute, pmute;
|
||||||
|
+
|
||||||
|
+ get_volume (mixer_load (s, AC97_Master_Volume_Mute), 0x3f, 1,
|
||||||
|
+ &mute, &lvol, &rvol);
|
||||||
|
+ /* FIXME: should be 1f according to spec */
|
||||||
|
+ get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x3f, 1,
|
||||||
|
+ &pmute, &plvol, &prvol);
|
||||||
|
+
|
||||||
|
+ mute = mute | pmute;
|
||||||
|
+ lvol = (lvol * plvol) / 255;
|
||||||
|
+ rvol = (rvol * prvol) / 255;
|
||||||
|
+
|
||||||
|
+ AUD_set_volume_out (s->voice_po, mute, lvol, rvol);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void update_volume_in (AC97LinkState *s)
|
||||||
|
+{
|
||||||
|
+ uint8_t lvol, rvol;
|
||||||
|
+ int mute;
|
||||||
|
+
|
||||||
|
+ get_volume (mixer_load (s, AC97_Record_Gain_Mute), 0x0f, 0,
|
||||||
|
+ &mute, &lvol, &rvol);
|
||||||
|
+
|
||||||
|
+ AUD_set_volume_in (s->voice_pi, mute, lvol, rvol);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void set_volume (AC97LinkState *s, int index, uint32_t val)
|
||||||
|
+{
|
||||||
|
+ mixer_store (s, index, val);
|
||||||
|
+ if (index == AC97_Master_Volume_Mute || index == AC97_PCM_Out_Volume_Mute) {
|
||||||
|
+ update_combined_volume_out (s);
|
||||||
|
+ } else if (index == AC97_Record_Gain_Mute) {
|
||||||
|
+ update_volume_in (s);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void record_select (AC97LinkState *s, uint32_t val)
|
||||||
|
+{
|
||||||
|
+ uint8_t rs = val & REC_MASK;
|
||||||
|
+ uint8_t ls = (val >> 8) & REC_MASK;
|
||||||
|
+ mixer_store (s, AC97_Record_Select, rs | (ls << 8));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void mixer_reset (AC97LinkState *s)
|
||||||
|
{
|
||||||
|
uint8_t active[LAST_INDEX];
|
||||||
|
@@ -467,6 +526,11 @@ static void mixer_reset (AC97LinkState *s)
|
||||||
|
mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80);
|
||||||
|
mixer_store (s, AC97_MIC_ADC_Rate , 0xbb80);
|
||||||
|
|
||||||
|
+ record_select (s, 0);
|
||||||
|
+ set_volume (s, AC97_Master_Volume_Mute, 0x8000);
|
||||||
|
+ set_volume (s, AC97_PCM_Out_Volume_Mute, 0x8808);
|
||||||
|
+ set_volume (s, AC97_Line_In_Volume_Mute, 0x8808);
|
||||||
|
+
|
||||||
|
reset_voices (s, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -525,6 +589,15 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
val |= mixer_load (s, index) & 0xf;
|
||||||
|
mixer_store (s, index, val);
|
||||||
|
break;
|
||||||
|
+ case AC97_PCM_Out_Volume_Mute:
|
||||||
|
+ case AC97_Master_Volume_Mute:
|
||||||
|
+ case AC97_Record_Gain_Mute:
|
||||||
|
+ case AC97_Line_In_Volume_Mute:
|
||||||
|
+ set_volume (s, index, val);
|
||||||
|
+ break;
|
||||||
|
+ case AC97_Record_Select:
|
||||||
|
+ record_select (s, val);
|
||||||
|
+ break;
|
||||||
|
case AC97_Vendor_ID1:
|
||||||
|
case AC97_Vendor_ID2:
|
||||||
|
dolog ("Attempt to write vendor ID to %#x\n", val);
|
||||||
|
@@ -1077,6 +1150,14 @@ static int ac97_post_load (void *opaque, int version_id)
|
||||||
|
uint8_t active[LAST_INDEX];
|
||||||
|
AC97LinkState *s = opaque;
|
||||||
|
|
||||||
|
+ record_select (s, mixer_load (s, AC97_Record_Select));
|
||||||
|
+ set_volume (s, AC97_Master_Volume_Mute,
|
||||||
|
+ mixer_load (s, AC97_Master_Volume_Mute));
|
||||||
|
+ set_volume (s, AC97_PCM_Out_Volume_Mute,
|
||||||
|
+ mixer_load (s, AC97_PCM_Out_Volume_Mute));
|
||||||
|
+ set_volume (s, AC97_Line_In_Volume_Mute,
|
||||||
|
+ mixer_load (s, AC97_Line_In_Volume_Mute));
|
||||||
|
+
|
||||||
|
active[PI_INDEX] = !!(s->bm_regs[PI_INDEX].cr & CR_RPBM);
|
||||||
|
active[PO_INDEX] = !!(s->bm_regs[PO_INDEX].cr & CR_RPBM);
|
||||||
|
active[MC_INDEX] = !!(s->bm_regs[MC_INDEX].cr & CR_RPBM);
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
84
0506-audio-spice-add-support-for-volume-control.patch
Normal file
84
0506-audio-spice-add-support-for-volume-control.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
From a9f796f670f3c34c3b5874026b61bbe4d782be2e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:40 +0200
|
||||||
|
Subject: [PATCH 506/509] audio/spice: add support for volume control
|
||||||
|
|
||||||
|
Use Spice server volume control API when available.
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
audio/spiceaudio.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 41 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
|
||||||
|
index f972110..6f15591 100644
|
||||||
|
--- a/audio/spiceaudio.c
|
||||||
|
+++ b/audio/spiceaudio.c
|
||||||
|
@@ -202,7 +202,26 @@ static int line_out_ctl (HWVoiceOut *hw, int cmd, ...)
|
||||||
|
}
|
||||||
|
spice_server_playback_stop (&out->sin);
|
||||||
|
break;
|
||||||
|
+ case VOICE_VOLUME:
|
||||||
|
+ {
|
||||||
|
+#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2))
|
||||||
|
+ SWVoiceOut *sw;
|
||||||
|
+ va_list ap;
|
||||||
|
+ uint16_t vol[2];
|
||||||
|
+
|
||||||
|
+ va_start (ap, cmd);
|
||||||
|
+ sw = va_arg (ap, SWVoiceOut *);
|
||||||
|
+ va_end (ap);
|
||||||
|
+
|
||||||
|
+ vol[0] = sw->vol.l / ((1ULL << 16) + 1);
|
||||||
|
+ vol[1] = sw->vol.r / ((1ULL << 16) + 1);
|
||||||
|
+ spice_server_playback_set_volume (&out->sin, 2, vol);
|
||||||
|
+ spice_server_playback_set_mute (&out->sin, sw->vol.mute);
|
||||||
|
+#endif
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -304,7 +323,26 @@ static int line_in_ctl (HWVoiceIn *hw, int cmd, ...)
|
||||||
|
in->active = 0;
|
||||||
|
spice_server_record_stop (&in->sin);
|
||||||
|
break;
|
||||||
|
+ case VOICE_VOLUME:
|
||||||
|
+ {
|
||||||
|
+#if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2))
|
||||||
|
+ SWVoiceIn *sw;
|
||||||
|
+ va_list ap;
|
||||||
|
+ uint16_t vol[2];
|
||||||
|
+
|
||||||
|
+ va_start (ap, cmd);
|
||||||
|
+ sw = va_arg (ap, SWVoiceIn *);
|
||||||
|
+ va_end (ap);
|
||||||
|
+
|
||||||
|
+ vol[0] = sw->vol.l / ((1ULL << 16) + 1);
|
||||||
|
+ vol[1] = sw->vol.r / ((1ULL << 16) + 1);
|
||||||
|
+ spice_server_record_set_volume (&in->sin, 2, vol);
|
||||||
|
+ spice_server_record_set_mute (&in->sin, sw->vol.mute);
|
||||||
|
+#endif
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -337,6 +375,9 @@ struct audio_driver spice_audio_driver = {
|
||||||
|
.max_voices_in = 1,
|
||||||
|
.voice_size_out = sizeof (SpiceVoiceOut),
|
||||||
|
.voice_size_in = sizeof (SpiceVoiceIn),
|
||||||
|
+#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2))
|
||||||
|
+ .ctl_caps = VOICE_VOLUME_CAP
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void qemu_spice_audio_init (void)
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
573
0507-Do-not-use-pa_simple-PulseAudio-API.patch
Normal file
573
0507-Do-not-use-pa_simple-PulseAudio-API.patch
Normal file
@ -0,0 +1,573 @@
|
|||||||
|
From 5c8ce128ec78d17a8a0f49115dc07726a3d3f0c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:41 +0200
|
||||||
|
Subject: [PATCH 507/509] Do not use pa_simple PulseAudio API
|
||||||
|
|
||||||
|
Unfortunately, pa_simple is a limited API which doesn't let us
|
||||||
|
retrieve the associated pa_stream. It is needed to control the volume
|
||||||
|
of the stream.
|
||||||
|
|
||||||
|
In v4:
|
||||||
|
- add missing braces
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
audio/paaudio.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 339 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/audio/paaudio.c b/audio/paaudio.c
|
||||||
|
index d1f3912..6f50c1c 100644
|
||||||
|
--- a/audio/paaudio.c
|
||||||
|
+++ b/audio/paaudio.c
|
||||||
|
@@ -2,8 +2,7 @@
|
||||||
|
#include "qemu-common.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
|
-#include <pulse/simple.h>
|
||||||
|
-#include <pulse/error.h>
|
||||||
|
+#include <pulse/pulseaudio.h>
|
||||||
|
|
||||||
|
#define AUDIO_CAP "pulseaudio"
|
||||||
|
#include "audio_int.h"
|
||||||
|
@@ -15,7 +14,7 @@ typedef struct {
|
||||||
|
int live;
|
||||||
|
int decr;
|
||||||
|
int rpos;
|
||||||
|
- pa_simple *s;
|
||||||
|
+ pa_stream *stream;
|
||||||
|
void *pcm_buf;
|
||||||
|
struct audio_pt pt;
|
||||||
|
} PAVoiceOut;
|
||||||
|
@@ -26,17 +25,23 @@ typedef struct {
|
||||||
|
int dead;
|
||||||
|
int incr;
|
||||||
|
int wpos;
|
||||||
|
- pa_simple *s;
|
||||||
|
+ pa_stream *stream;
|
||||||
|
void *pcm_buf;
|
||||||
|
struct audio_pt pt;
|
||||||
|
+ const void *read_data;
|
||||||
|
+ size_t read_index, read_length;
|
||||||
|
} PAVoiceIn;
|
||||||
|
|
||||||
|
-static struct {
|
||||||
|
+typedef struct {
|
||||||
|
int samples;
|
||||||
|
char *server;
|
||||||
|
char *sink;
|
||||||
|
char *source;
|
||||||
|
-} conf = {
|
||||||
|
+ pa_threaded_mainloop *mainloop;
|
||||||
|
+ pa_context *context;
|
||||||
|
+} paaudio;
|
||||||
|
+
|
||||||
|
+static paaudio glob_paaudio = {
|
||||||
|
.samples = 4096,
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -51,6 +56,126 @@ static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
|
||||||
|
AUD_log (AUDIO_CAP, "Reason: %s\n", pa_strerror (err));
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define CHECK_SUCCESS_GOTO(c, rerror, expression, label) \
|
||||||
|
+ do { \
|
||||||
|
+ if (!(expression)) { \
|
||||||
|
+ if (rerror) { \
|
||||||
|
+ *(rerror) = pa_context_errno ((c)->context); \
|
||||||
|
+ } \
|
||||||
|
+ goto label; \
|
||||||
|
+ } \
|
||||||
|
+ } while (0);
|
||||||
|
+
|
||||||
|
+#define CHECK_DEAD_GOTO(c, stream, rerror, label) \
|
||||||
|
+ do { \
|
||||||
|
+ if (!(c)->context || !PA_CONTEXT_IS_GOOD (pa_context_get_state((c)->context)) || \
|
||||||
|
+ !(stream) || !PA_STREAM_IS_GOOD (pa_stream_get_state ((stream)))) { \
|
||||||
|
+ if (((c)->context && pa_context_get_state ((c)->context) == PA_CONTEXT_FAILED) || \
|
||||||
|
+ ((stream) && pa_stream_get_state ((stream)) == PA_STREAM_FAILED)) { \
|
||||||
|
+ if (rerror) { \
|
||||||
|
+ *(rerror) = pa_context_errno ((c)->context); \
|
||||||
|
+ } \
|
||||||
|
+ } else { \
|
||||||
|
+ if (rerror) { \
|
||||||
|
+ *(rerror) = PA_ERR_BADSTATE; \
|
||||||
|
+ } \
|
||||||
|
+ } \
|
||||||
|
+ goto label; \
|
||||||
|
+ } \
|
||||||
|
+ } while (0);
|
||||||
|
+
|
||||||
|
+static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror)
|
||||||
|
+{
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_lock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
|
||||||
|
+
|
||||||
|
+ while (length > 0) {
|
||||||
|
+ size_t l;
|
||||||
|
+
|
||||||
|
+ while (!p->read_data) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = pa_stream_peek (p->stream, &p->read_data, &p->read_length);
|
||||||
|
+ CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
|
||||||
|
+
|
||||||
|
+ if (!p->read_data) {
|
||||||
|
+ pa_threaded_mainloop_wait (g->mainloop);
|
||||||
|
+ CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
|
||||||
|
+ } else {
|
||||||
|
+ p->read_index = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ l = p->read_length < length ? p->read_length : length;
|
||||||
|
+ memcpy (data, (const uint8_t *) p->read_data+p->read_index, l);
|
||||||
|
+
|
||||||
|
+ data = (uint8_t *) data + l;
|
||||||
|
+ length -= l;
|
||||||
|
+
|
||||||
|
+ p->read_index += l;
|
||||||
|
+ p->read_length -= l;
|
||||||
|
+
|
||||||
|
+ if (!p->read_length) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = pa_stream_drop (p->stream);
|
||||||
|
+ p->read_data = NULL;
|
||||||
|
+ p->read_length = 0;
|
||||||
|
+ p->read_index = 0;
|
||||||
|
+
|
||||||
|
+ CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+unlock_and_fail:
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, int *rerror)
|
||||||
|
+{
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_lock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
|
||||||
|
+
|
||||||
|
+ while (length > 0) {
|
||||||
|
+ size_t l;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ while (!(l = pa_stream_writable_size (p->stream))) {
|
||||||
|
+ pa_threaded_mainloop_wait (g->mainloop);
|
||||||
|
+ CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ CHECK_SUCCESS_GOTO (g, rerror, l != (size_t) -1, unlock_and_fail);
|
||||||
|
+
|
||||||
|
+ if (l > length) {
|
||||||
|
+ l = length;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = pa_stream_write (p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
|
||||||
|
+ CHECK_SUCCESS_GOTO (g, rerror, r >= 0, unlock_and_fail);
|
||||||
|
+
|
||||||
|
+ data = (const uint8_t *) data + l;
|
||||||
|
+ length -= l;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+unlock_and_fail:
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void *qpa_thread_out (void *arg)
|
||||||
|
{
|
||||||
|
PAVoiceOut *pa = arg;
|
||||||
|
@@ -77,7 +202,7 @@ static void *qpa_thread_out (void *arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- decr = to_mix = audio_MIN (pa->live, conf.samples >> 2);
|
||||||
|
+ decr = to_mix = audio_MIN (pa->live, glob_paaudio.samples >> 2);
|
||||||
|
rpos = pa->rpos;
|
||||||
|
|
||||||
|
if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
|
||||||
|
@@ -91,8 +216,8 @@ static void *qpa_thread_out (void *arg)
|
||||||
|
|
||||||
|
hw->clip (pa->pcm_buf, src, chunk);
|
||||||
|
|
||||||
|
- if (pa_simple_write (pa->s, pa->pcm_buf,
|
||||||
|
- chunk << hw->info.shift, &error) < 0) {
|
||||||
|
+ if (qpa_simple_write (pa, pa->pcm_buf,
|
||||||
|
+ chunk << hw->info.shift, &error) < 0) {
|
||||||
|
qpa_logerr (error, "pa_simple_write failed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -169,7 +294,7 @@ static void *qpa_thread_in (void *arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- incr = to_grab = audio_MIN (pa->dead, conf.samples >> 2);
|
||||||
|
+ incr = to_grab = audio_MIN (pa->dead, glob_paaudio.samples >> 2);
|
||||||
|
wpos = pa->wpos;
|
||||||
|
|
||||||
|
if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
|
||||||
|
@@ -181,8 +306,8 @@ static void *qpa_thread_in (void *arg)
|
||||||
|
int chunk = audio_MIN (to_grab, hw->samples - wpos);
|
||||||
|
void *buf = advance (pa->pcm_buf, wpos);
|
||||||
|
|
||||||
|
- if (pa_simple_read (pa->s, buf,
|
||||||
|
- chunk << hw->info.shift, &error) < 0) {
|
||||||
|
+ if (qpa_simple_read (pa, buf,
|
||||||
|
+ chunk << hw->info.shift, &error) < 0) {
|
||||||
|
qpa_logerr (error, "pa_simple_read failed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -283,6 +408,109 @@ static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int *endianness)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void context_state_cb (pa_context *c, void *userdata)
|
||||||
|
+{
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ switch (pa_context_get_state(c)) {
|
||||||
|
+ case PA_CONTEXT_READY:
|
||||||
|
+ case PA_CONTEXT_TERMINATED:
|
||||||
|
+ case PA_CONTEXT_FAILED:
|
||||||
|
+ pa_threaded_mainloop_signal (g->mainloop, 0);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case PA_CONTEXT_UNCONNECTED:
|
||||||
|
+ case PA_CONTEXT_CONNECTING:
|
||||||
|
+ case PA_CONTEXT_AUTHORIZING:
|
||||||
|
+ case PA_CONTEXT_SETTING_NAME:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void stream_state_cb (pa_stream *s, void * userdata)
|
||||||
|
+{
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ switch (pa_stream_get_state (s)) {
|
||||||
|
+
|
||||||
|
+ case PA_STREAM_READY:
|
||||||
|
+ case PA_STREAM_FAILED:
|
||||||
|
+ case PA_STREAM_TERMINATED:
|
||||||
|
+ pa_threaded_mainloop_signal (g->mainloop, 0);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case PA_STREAM_UNCONNECTED:
|
||||||
|
+ case PA_STREAM_CREATING:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void stream_request_cb (pa_stream *s, size_t length, void *userdata)
|
||||||
|
+{
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_signal (g->mainloop, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static pa_stream *qpa_simple_new (
|
||||||
|
+ const char *server,
|
||||||
|
+ const char *name,
|
||||||
|
+ pa_stream_direction_t dir,
|
||||||
|
+ const char *dev,
|
||||||
|
+ const char *stream_name,
|
||||||
|
+ const pa_sample_spec *ss,
|
||||||
|
+ const pa_channel_map *map,
|
||||||
|
+ const pa_buffer_attr *attr,
|
||||||
|
+ int *rerror)
|
||||||
|
+{
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+ int r;
|
||||||
|
+ pa_stream *stream;
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_lock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ stream = pa_stream_new (g->context, name, ss, map);
|
||||||
|
+ if (!stream) {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_stream_set_state_callback (stream, stream_state_cb, g);
|
||||||
|
+ pa_stream_set_read_callback (stream, stream_request_cb, g);
|
||||||
|
+ pa_stream_set_write_callback (stream, stream_request_cb, g);
|
||||||
|
+
|
||||||
|
+ if (dir == PA_STREAM_PLAYBACK) {
|
||||||
|
+ r = pa_stream_connect_playback (stream, dev, attr,
|
||||||
|
+ PA_STREAM_INTERPOLATE_TIMING
|
||||||
|
+ |PA_STREAM_ADJUST_LATENCY
|
||||||
|
+ |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
|
||||||
|
+ } else {
|
||||||
|
+ r = pa_stream_connect_record (stream, dev, attr,
|
||||||
|
+ PA_STREAM_INTERPOLATE_TIMING
|
||||||
|
+ |PA_STREAM_ADJUST_LATENCY
|
||||||
|
+ |PA_STREAM_AUTO_TIMING_UPDATE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ return stream;
|
||||||
|
+
|
||||||
|
+fail:
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ if (stream) {
|
||||||
|
+ pa_stream_unref (stream);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ qpa_logerr (pa_context_errno (g->context),
|
||||||
|
+ "stream_new() failed\n");
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
@@ -306,24 +534,24 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
|
||||||
|
|
||||||
|
obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
|
||||||
|
|
||||||
|
- pa->s = pa_simple_new (
|
||||||
|
- conf.server,
|
||||||
|
+ pa->stream = qpa_simple_new (
|
||||||
|
+ glob_paaudio.server,
|
||||||
|
"qemu",
|
||||||
|
PA_STREAM_PLAYBACK,
|
||||||
|
- conf.sink,
|
||||||
|
+ glob_paaudio.sink,
|
||||||
|
"pcm.playback",
|
||||||
|
&ss,
|
||||||
|
NULL, /* channel map */
|
||||||
|
&ba, /* buffering attributes */
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
- if (!pa->s) {
|
||||||
|
+ if (!pa->stream) {
|
||||||
|
qpa_logerr (error, "pa_simple_new for playback failed\n");
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_pcm_init_info (&hw->info, &obt_as);
|
||||||
|
- hw->samples = conf.samples;
|
||||||
|
+ hw->samples = glob_paaudio.samples;
|
||||||
|
pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
|
||||||
|
pa->rpos = hw->rpos;
|
||||||
|
if (!pa->pcm_buf) {
|
||||||
|
@@ -342,8 +570,10 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
|
||||||
|
g_free (pa->pcm_buf);
|
||||||
|
pa->pcm_buf = NULL;
|
||||||
|
fail2:
|
||||||
|
- pa_simple_free (pa->s);
|
||||||
|
- pa->s = NULL;
|
||||||
|
+ if (pa->stream) {
|
||||||
|
+ pa_stream_unref (pa->stream);
|
||||||
|
+ pa->stream = NULL;
|
||||||
|
+ }
|
||||||
|
fail1:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@@ -361,24 +591,24 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as)
|
||||||
|
|
||||||
|
obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
|
||||||
|
|
||||||
|
- pa->s = pa_simple_new (
|
||||||
|
- conf.server,
|
||||||
|
+ pa->stream = qpa_simple_new (
|
||||||
|
+ glob_paaudio.server,
|
||||||
|
"qemu",
|
||||||
|
PA_STREAM_RECORD,
|
||||||
|
- conf.source,
|
||||||
|
+ glob_paaudio.source,
|
||||||
|
"pcm.capture",
|
||||||
|
&ss,
|
||||||
|
NULL, /* channel map */
|
||||||
|
NULL, /* buffering attributes */
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
- if (!pa->s) {
|
||||||
|
+ if (!pa->stream) {
|
||||||
|
qpa_logerr (error, "pa_simple_new for capture failed\n");
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_pcm_init_info (&hw->info, &obt_as);
|
||||||
|
- hw->samples = conf.samples;
|
||||||
|
+ hw->samples = glob_paaudio.samples;
|
||||||
|
pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
|
||||||
|
pa->wpos = hw->wpos;
|
||||||
|
if (!pa->pcm_buf) {
|
||||||
|
@@ -397,8 +627,10 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as)
|
||||||
|
g_free (pa->pcm_buf);
|
||||||
|
pa->pcm_buf = NULL;
|
||||||
|
fail2:
|
||||||
|
- pa_simple_free (pa->s);
|
||||||
|
- pa->s = NULL;
|
||||||
|
+ if (pa->stream) {
|
||||||
|
+ pa_stream_unref (pa->stream);
|
||||||
|
+ pa->stream = NULL;
|
||||||
|
+ }
|
||||||
|
fail1:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@@ -413,9 +645,9 @@ static void qpa_fini_out (HWVoiceOut *hw)
|
||||||
|
audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
|
||||||
|
audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
|
||||||
|
|
||||||
|
- if (pa->s) {
|
||||||
|
- pa_simple_free (pa->s);
|
||||||
|
- pa->s = NULL;
|
||||||
|
+ if (pa->stream) {
|
||||||
|
+ pa_stream_unref (pa->stream);
|
||||||
|
+ pa->stream = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_pt_fini (&pa->pt, AUDIO_FUNC);
|
||||||
|
@@ -433,9 +665,9 @@ static void qpa_fini_in (HWVoiceIn *hw)
|
||||||
|
audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
|
||||||
|
audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
|
||||||
|
|
||||||
|
- if (pa->s) {
|
||||||
|
- pa_simple_free (pa->s);
|
||||||
|
- pa->s = NULL;
|
||||||
|
+ if (pa->stream) {
|
||||||
|
+ pa_stream_unref (pa->stream);
|
||||||
|
+ pa->stream = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_pt_fini (&pa->pt, AUDIO_FUNC);
|
||||||
|
@@ -460,37 +692,106 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
|
||||||
|
/* common */
|
||||||
|
static void *qpa_audio_init (void)
|
||||||
|
{
|
||||||
|
- return &conf;
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ g->mainloop = pa_threaded_mainloop_new ();
|
||||||
|
+ if (!g->mainloop) {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop), glob_paaudio.server);
|
||||||
|
+ if (!g->context) {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_context_set_state_callback (g->context, context_state_cb, g);
|
||||||
|
+
|
||||||
|
+ if (pa_context_connect (g->context, glob_paaudio.server, 0, NULL) < 0) {
|
||||||
|
+ qpa_logerr (pa_context_errno (g->context),
|
||||||
|
+ "pa_context_connect() failed\n");
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_lock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ if (pa_threaded_mainloop_start (g->mainloop) < 0) {
|
||||||
|
+ goto unlock_and_fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (;;) {
|
||||||
|
+ pa_context_state_t state;
|
||||||
|
+
|
||||||
|
+ state = pa_context_get_state (g->context);
|
||||||
|
+
|
||||||
|
+ if (state == PA_CONTEXT_READY) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!PA_CONTEXT_IS_GOOD (state)) {
|
||||||
|
+ qpa_logerr (pa_context_errno (g->context),
|
||||||
|
+ "Wrong context state\n");
|
||||||
|
+ goto unlock_and_fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Wait until the context is ready */
|
||||||
|
+ pa_threaded_mainloop_wait (g->mainloop);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ return &glob_paaudio;
|
||||||
|
+
|
||||||
|
+unlock_and_fail:
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+fail:
|
||||||
|
+ AUD_log (AUDIO_CAP, "Failed to initialize PA context");
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qpa_audio_fini (void *opaque)
|
||||||
|
{
|
||||||
|
- (void) opaque;
|
||||||
|
+ paaudio *g = opaque;
|
||||||
|
+
|
||||||
|
+ if (g->mainloop) {
|
||||||
|
+ pa_threaded_mainloop_stop (g->mainloop);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (g->context) {
|
||||||
|
+ pa_context_disconnect (g->context);
|
||||||
|
+ pa_context_unref (g->context);
|
||||||
|
+ g->context = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (g->mainloop) {
|
||||||
|
+ pa_threaded_mainloop_free (g->mainloop);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g->mainloop = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct audio_option qpa_options[] = {
|
||||||
|
{
|
||||||
|
.name = "SAMPLES",
|
||||||
|
.tag = AUD_OPT_INT,
|
||||||
|
- .valp = &conf.samples,
|
||||||
|
+ .valp = &glob_paaudio.samples,
|
||||||
|
.descr = "buffer size in samples"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "SERVER",
|
||||||
|
.tag = AUD_OPT_STR,
|
||||||
|
- .valp = &conf.server,
|
||||||
|
+ .valp = &glob_paaudio.server,
|
||||||
|
.descr = "server address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "SINK",
|
||||||
|
.tag = AUD_OPT_STR,
|
||||||
|
- .valp = &conf.sink,
|
||||||
|
+ .valp = &glob_paaudio.sink,
|
||||||
|
.descr = "sink device name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "SOURCE",
|
||||||
|
.tag = AUD_OPT_STR,
|
||||||
|
- .valp = &conf.source,
|
||||||
|
+ .valp = &glob_paaudio.source,
|
||||||
|
.descr = "source device name"
|
||||||
|
},
|
||||||
|
{ /* End of list */ }
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
31
0508-configure-pa_simple-is-not-needed-anymore.patch
Normal file
31
0508-configure-pa_simple-is-not-needed-anymore.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From 1b4ee5ccd426102b9ea415a8ce563bf96d7aa1f4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:42 +0200
|
||||||
|
Subject: [PATCH 508/509] configure: pa_simple is not needed anymore
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
configure | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index b03172c..4559836 100755
|
||||||
|
--- a/configure
|
||||||
|
+++ b/configure
|
||||||
|
@@ -1791,9 +1791,9 @@ for drv in $audio_drv_list; do
|
||||||
|
;;
|
||||||
|
|
||||||
|
pa)
|
||||||
|
- audio_drv_probe $drv pulse/simple.h "-lpulse-simple -lpulse" \
|
||||||
|
- "pa_simple *s = 0; pa_simple_free(s); return 0;"
|
||||||
|
- libs_softmmu="-lpulse -lpulse-simple $libs_softmmu"
|
||||||
|
+ audio_drv_probe $drv pulse/mainloop.h "-lpulse" \
|
||||||
|
+ "pa_mainloop *m = 0; pa_mainloop_free (m); return 0;"
|
||||||
|
+ libs_softmmu="-lpulse $libs_softmmu"
|
||||||
|
audio_pt_int="yes"
|
||||||
|
;;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
134
0509-Allow-controlling-volume-with-PulseAudio-backend.patch
Normal file
134
0509-Allow-controlling-volume-with-PulseAudio-backend.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
From 4b09edbfdaad4536617bbb53ccadfe531156ed56 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
|
||||||
|
Date: Tue, 17 Apr 2012 14:32:43 +0200
|
||||||
|
Subject: [PATCH 509/509] Allow controlling volume with PulseAudio backend
|
||||||
|
|
||||||
|
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
|
||||||
|
Signed-off-by: malc <av1474@comtv.ru>
|
||||||
|
---
|
||||||
|
audio/paaudio.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 94 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/audio/paaudio.c b/audio/paaudio.c
|
||||||
|
index 6f50c1c..e6708d0 100644
|
||||||
|
--- a/audio/paaudio.c
|
||||||
|
+++ b/audio/paaudio.c
|
||||||
|
@@ -677,15 +677,103 @@ static void qpa_fini_in (HWVoiceIn *hw)
|
||||||
|
|
||||||
|
static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
||||||
|
{
|
||||||
|
- (void) hw;
|
||||||
|
- (void) cmd;
|
||||||
|
+ PAVoiceOut *pa = (PAVoiceOut *) hw;
|
||||||
|
+ pa_operation *op;
|
||||||
|
+ pa_cvolume v;
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ pa_cvolume_init (&v);
|
||||||
|
+
|
||||||
|
+ switch (cmd) {
|
||||||
|
+ case VOICE_VOLUME:
|
||||||
|
+ {
|
||||||
|
+ SWVoiceOut *sw;
|
||||||
|
+ va_list ap;
|
||||||
|
+
|
||||||
|
+ va_start (ap, cmd);
|
||||||
|
+ sw = va_arg (ap, SWVoiceOut *);
|
||||||
|
+ va_end (ap);
|
||||||
|
+
|
||||||
|
+ v.channels = 2;
|
||||||
|
+ v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX;
|
||||||
|
+ v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX;
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_lock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ op = pa_context_set_sink_input_volume (g->context,
|
||||||
|
+ pa_stream_get_index (pa->stream),
|
||||||
|
+ &v, NULL, NULL);
|
||||||
|
+ if (!op)
|
||||||
|
+ qpa_logerr (pa_context_errno (g->context),
|
||||||
|
+ "set_sink_input_volume() failed\n");
|
||||||
|
+ else
|
||||||
|
+ pa_operation_unref (op);
|
||||||
|
+
|
||||||
|
+ op = pa_context_set_sink_input_mute (g->context,
|
||||||
|
+ pa_stream_get_index (pa->stream),
|
||||||
|
+ sw->vol.mute, NULL, NULL);
|
||||||
|
+ if (!op) {
|
||||||
|
+ qpa_logerr (pa_context_errno (g->context),
|
||||||
|
+ "set_sink_input_mute() failed\n");
|
||||||
|
+ } else {
|
||||||
|
+ pa_operation_unref (op);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
|
||||||
|
{
|
||||||
|
- (void) hw;
|
||||||
|
- (void) cmd;
|
||||||
|
+ PAVoiceIn *pa = (PAVoiceIn *) hw;
|
||||||
|
+ pa_operation *op;
|
||||||
|
+ pa_cvolume v;
|
||||||
|
+ paaudio *g = &glob_paaudio;
|
||||||
|
+
|
||||||
|
+ pa_cvolume_init (&v);
|
||||||
|
+
|
||||||
|
+ switch (cmd) {
|
||||||
|
+ case VOICE_VOLUME:
|
||||||
|
+ {
|
||||||
|
+ SWVoiceIn *sw;
|
||||||
|
+ va_list ap;
|
||||||
|
+
|
||||||
|
+ va_start (ap, cmd);
|
||||||
|
+ sw = va_arg (ap, SWVoiceIn *);
|
||||||
|
+ va_end (ap);
|
||||||
|
+
|
||||||
|
+ v.channels = 2;
|
||||||
|
+ v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX;
|
||||||
|
+ v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX;
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_lock (g->mainloop);
|
||||||
|
+
|
||||||
|
+ /* FIXME: use the upcoming "set_source_output_{volume,mute}" */
|
||||||
|
+ op = pa_context_set_source_volume_by_index (g->context,
|
||||||
|
+ pa_stream_get_device_index (pa->stream),
|
||||||
|
+ &v, NULL, NULL);
|
||||||
|
+ if (!op) {
|
||||||
|
+ qpa_logerr (pa_context_errno (g->context),
|
||||||
|
+ "set_source_volume() failed\n");
|
||||||
|
+ } else {
|
||||||
|
+ pa_operation_unref(op);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ op = pa_context_set_source_mute_by_index (g->context,
|
||||||
|
+ pa_stream_get_index (pa->stream),
|
||||||
|
+ sw->vol.mute, NULL, NULL);
|
||||||
|
+ if (!op) {
|
||||||
|
+ qpa_logerr (pa_context_errno (g->context),
|
||||||
|
+ "set_source_mute() failed\n");
|
||||||
|
+ } else {
|
||||||
|
+ pa_operation_unref (op);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pa_threaded_mainloop_unlock (g->mainloop);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -822,5 +910,6 @@ struct audio_driver pa_audio_driver = {
|
||||||
|
.max_voices_out = INT_MAX,
|
||||||
|
.max_voices_in = INT_MAX,
|
||||||
|
.voice_size_out = sizeof (PAVoiceOut),
|
||||||
|
- .voice_size_in = sizeof (PAVoiceIn)
|
||||||
|
+ .voice_size_in = sizeof (PAVoiceIn),
|
||||||
|
+ .ctl_caps = VOICE_VOLUME_CAP
|
||||||
|
};
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
105
qemu.spec
105
qemu.spec
@ -38,7 +38,7 @@
|
|||||||
Summary: QEMU is a FAST! processor emulator
|
Summary: QEMU is a FAST! processor emulator
|
||||||
Name: qemu
|
Name: qemu
|
||||||
Version: 1.0
|
Version: 1.0
|
||||||
Release: 14%{?dist}
|
Release: 15%{?dist}
|
||||||
# Epoch because we pushed a qemu-1.0 package
|
# Epoch because we pushed a qemu-1.0 package
|
||||||
Epoch: 2
|
Epoch: 2
|
||||||
License: GPLv2+ and LGPLv2+ and BSD
|
License: GPLv2+ and LGPLv2+ and BSD
|
||||||
@ -104,7 +104,7 @@ Patch25: 0025-rbd-always-set-out-parameter-in-qemu_rbd_snap_list.patch
|
|||||||
Patch26: 0026-e1000-bounds-packet-size-against-buffer-size.patch
|
Patch26: 0026-e1000-bounds-packet-size-against-buffer-size.patch
|
||||||
Patch27: virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch
|
Patch27: virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch
|
||||||
|
|
||||||
# USB Redirect patches should go upstream soon!
|
# USB-redir patches all upstream for 1.1 except for the chardev flowcontrol set
|
||||||
Patch101: 0101-usb-redir-Clear-iso-irq-error-when-stopping-the-stre.patch
|
Patch101: 0101-usb-redir-Clear-iso-irq-error-when-stopping-the-stre.patch
|
||||||
Patch102: 0102-usb-redir-Dynamically-adjust-iso-buffering-size-base.patch
|
Patch102: 0102-usb-redir-Dynamically-adjust-iso-buffering-size-base.patch
|
||||||
Patch103: 0103-usb-redir-Pre-fill-our-isoc-input-buffer-before-send.patch
|
Patch103: 0103-usb-redir-Pre-fill-our-isoc-input-buffer-before-send.patch
|
||||||
@ -151,6 +151,7 @@ Patch143: 0143-usb-redir-Notify-our-peer-when-we-reject-a-device-du.patch
|
|||||||
Patch144: 0144-usb-redir-An-interface-count-of-0-is-a-valid-value.patch
|
Patch144: 0144-usb-redir-An-interface-count-of-0-is-a-valid-value.patch
|
||||||
Patch145: 0145-usb-redir-Reset-device-address-and-speed-on-disconne.patch
|
Patch145: 0145-usb-redir-Reset-device-address-and-speed-on-disconne.patch
|
||||||
Patch146: 0146-usb-redir-Not-finding-an-async-urb-id-is-not-an-erro.patch
|
Patch146: 0146-usb-redir-Not-finding-an-async-urb-id-is-not-an-erro.patch
|
||||||
|
Patch147: 0147-usb-ehci-Ensure-frindex-writes-leave-a-valid-frindex.patch
|
||||||
|
|
||||||
# General bug fixes
|
# General bug fixes
|
||||||
Patch201: Fix_save-restore_of_in-kernel_i8259.patch
|
Patch201: Fix_save-restore_of_in-kernel_i8259.patch
|
||||||
@ -160,6 +161,53 @@ Patch202: qemu-virtio-9p-noatime.patch
|
|||||||
Patch301: enable_architectural_PMU_cpuid_leaf.patch
|
Patch301: enable_architectural_PMU_cpuid_leaf.patch
|
||||||
Patch302: qemu_virtio-scsi_support.patch
|
Patch302: qemu_virtio-scsi_support.patch
|
||||||
|
|
||||||
|
# QXL fixes backports, all are upstream for 1.1
|
||||||
|
Patch401: 0401-qxl-Slot-sanity-check-in-qxl_phys2virt-is-off-by-one.patch
|
||||||
|
Patch402: 0402-input-send-kbd-mouse-events-only-to-running-guests.patch
|
||||||
|
Patch403: 0403-qxl-fix-warnings-on-32bit.patch
|
||||||
|
Patch404: 0404-qxl-don-t-render-stuff-when-the-vm-is-stopped.patch
|
||||||
|
Patch405: 0405-qxl-set-only-off-screen-surfaces-dirty-instead-of-th.patch
|
||||||
|
Patch406: 0406-qxl-make-sure-primary-surface-is-saved-on-migration-.patch
|
||||||
|
Patch407: 0407-Add-SPICE-support-to-add_client-monitor-command.patch
|
||||||
|
Patch408: 0408-spice-support-ipv6-channel-address-in-monitor-events.patch
|
||||||
|
Patch409: 0409-qxl-drop-vram-bar-minimum-size.patch
|
||||||
|
Patch410: 0410-qxl-move-ram-size-init-to-new-function.patch
|
||||||
|
Patch411: 0411-qxl-add-user-friendly-bar-size-properties.patch
|
||||||
|
Patch412: 0412-qxl-fix-spice-sdl-no-cursor-regression.patch
|
||||||
|
Patch413: 0413-sdl-remove-NULL-check-g_malloc0-can-t-fail.patch
|
||||||
|
Patch414: 0414-qxl-drop-qxl_spice_update_area_async-definition.patch
|
||||||
|
Patch415: 0415-qxl-require-spice-0.8.2.patch
|
||||||
|
Patch416: 0416-qxl-remove-flipped.patch
|
||||||
|
Patch417: 0417-qxl-introduce-QXLCookie.patch
|
||||||
|
Patch418: 0418-qxl-make-qxl_render_update-async.patch
|
||||||
|
Patch419: 0419-spice-use-error_report-to-report-errors.patch
|
||||||
|
Patch420: 0420-Error-out-when-tls-channel-option-is-used-without-TL.patch
|
||||||
|
Patch421: 0421-qxl-properly-handle-upright-and-non-shared-surfaces.patch
|
||||||
|
Patch422: 0422-spice-set-spice-uuid-and-name.patch
|
||||||
|
Patch423: 0423-monitor-fix-client_migrate_info-error-handling.patch
|
||||||
|
Patch424: 0424-qxl-init_pipe_signaling-exit-on-failure.patch
|
||||||
|
Patch425: 0425-qxl-switch-qxl.c-to-trace-events.patch
|
||||||
|
Patch426: 0426-qxl-qxl_render.c-add-trace-events.patch
|
||||||
|
Patch427: 0427-hw-qxl.c-Fix-compilation-failures-on-32-bit-hosts.patch
|
||||||
|
Patch428: 0428-spice-fix-broken-initialization.patch
|
||||||
|
Patch429: 0429-ui-spice-display.c-Fix-compilation-warnings-on-32-bi.patch
|
||||||
|
Patch430: 0430-ui-spice-display-use-uintptr_t-when-casting-qxl-phys.patch
|
||||||
|
Patch431: 0431-qxl-add-optinal-64bit-vram-bar.patch
|
||||||
|
Patch432: 0432-qxl-set-default-values-of-vram-_size_mb-to-1.patch
|
||||||
|
Patch433: 0433-qxl-render-fix-broken-vnc-spice-since-commit-f934493.patch
|
||||||
|
Patch434: 0434-qxl-don-t-assert-on-guest-create_guest_primary.patch
|
||||||
|
|
||||||
|
# Spice volume control backports, all are upstream for 1.1
|
||||||
|
Patch501: 0501-audio-add-VOICE_VOLUME-ctl.patch
|
||||||
|
Patch502: 0502-audio-don-t-apply-volume-effect-if-backend-has-VOICE.patch
|
||||||
|
Patch503: 0503-hw-ac97-remove-USE_MIXER-code.patch
|
||||||
|
Patch504: 0504-hw-ac97-the-volume-mask-is-not-only-0x1f.patch
|
||||||
|
Patch505: 0505-hw-ac97-add-support-for-volume-control.patch
|
||||||
|
Patch506: 0506-audio-spice-add-support-for-volume-control.patch
|
||||||
|
Patch507: 0507-Do-not-use-pa_simple-PulseAudio-API.patch
|
||||||
|
Patch508: 0508-configure-pa_simple-is-not-needed-anymore.patch
|
||||||
|
Patch509: 0509-Allow-controlling-volume-with-PulseAudio-backend.patch
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
|
BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
|
||||||
BuildRequires: libaio-devel
|
BuildRequires: libaio-devel
|
||||||
@ -478,6 +526,7 @@ such as kvm_stat.
|
|||||||
%patch144 -p1
|
%patch144 -p1
|
||||||
%patch145 -p1
|
%patch145 -p1
|
||||||
%patch146 -p1
|
%patch146 -p1
|
||||||
|
%patch147 -p1
|
||||||
|
|
||||||
%patch201 -p1
|
%patch201 -p1
|
||||||
%patch202 -p1
|
%patch202 -p1
|
||||||
@ -485,6 +534,52 @@ such as kvm_stat.
|
|||||||
%patch301 -p1
|
%patch301 -p1
|
||||||
%patch302 -p1
|
%patch302 -p1
|
||||||
|
|
||||||
|
%patch401 -p1
|
||||||
|
%patch402 -p1
|
||||||
|
%patch403 -p1
|
||||||
|
%patch404 -p1
|
||||||
|
%patch405 -p1
|
||||||
|
%patch406 -p1
|
||||||
|
%patch407 -p1
|
||||||
|
%patch408 -p1
|
||||||
|
%patch409 -p1
|
||||||
|
%patch410 -p1
|
||||||
|
%patch411 -p1
|
||||||
|
%patch412 -p1
|
||||||
|
%patch413 -p1
|
||||||
|
%patch414 -p1
|
||||||
|
%patch415 -p1
|
||||||
|
%patch416 -p1
|
||||||
|
%patch417 -p1
|
||||||
|
%patch418 -p1
|
||||||
|
%patch419 -p1
|
||||||
|
%patch420 -p1
|
||||||
|
%patch421 -p1
|
||||||
|
%patch422 -p1
|
||||||
|
%patch423 -p1
|
||||||
|
%patch424 -p1
|
||||||
|
%patch425 -p1
|
||||||
|
%patch426 -p1
|
||||||
|
%patch427 -p1
|
||||||
|
%patch428 -p1
|
||||||
|
%patch429 -p1
|
||||||
|
%patch430 -p1
|
||||||
|
%patch431 -p1
|
||||||
|
%patch432 -p1
|
||||||
|
%patch433 -p1
|
||||||
|
%patch434 -p1
|
||||||
|
|
||||||
|
%patch501 -p1
|
||||||
|
%patch502 -p1
|
||||||
|
%patch503 -p1
|
||||||
|
%patch504 -p1
|
||||||
|
%patch505 -p1
|
||||||
|
%patch506 -p1
|
||||||
|
%patch507 -p1
|
||||||
|
%patch508 -p1
|
||||||
|
%patch509 -p1
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# By default we build everything, but allow x86 to build a minimal version
|
# By default we build everything, but allow x86 to build a minimal version
|
||||||
# with only similar arch target support
|
# with only similar arch target support
|
||||||
@ -524,6 +619,7 @@ sed -i.debug 's/"-g $CFLAGS"/"$CFLAGS"/g' configure
|
|||||||
--extra-ldflags="$extraldflags -pie -Wl,-z,relro -Wl,-z,now" \
|
--extra-ldflags="$extraldflags -pie -Wl,-z,relro -Wl,-z,now" \
|
||||||
--extra-cflags="%{optflags} -fPIE -DPIE" \
|
--extra-cflags="%{optflags} -fPIE -DPIE" \
|
||||||
--enable-spice \
|
--enable-spice \
|
||||||
|
--enable-mixemu \
|
||||||
%if %{without rbd}
|
%if %{without rbd}
|
||||||
--disable-rbd \
|
--disable-rbd \
|
||||||
%endif
|
%endif
|
||||||
@ -561,6 +657,7 @@ make clean
|
|||||||
--disable-xen \
|
--disable-xen \
|
||||||
%ifarch %{ix86} x86_64
|
%ifarch %{ix86} x86_64
|
||||||
--enable-spice \
|
--enable-spice \
|
||||||
|
--enable-mixemu \
|
||||||
%endif
|
%endif
|
||||||
%if %{without rbd}
|
%if %{without rbd}
|
||||||
--disable-rbd \
|
--disable-rbd \
|
||||||
@ -912,6 +1009,10 @@ fi
|
|||||||
%{_mandir}/man1/qemu-img.1*
|
%{_mandir}/man1/qemu-img.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Apr 19 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.0-15
|
||||||
|
- Add a couple of backported QXL/Spice bugfixes
|
||||||
|
- Add spice volume control patches
|
||||||
|
|
||||||
* Fri Apr 6 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.0-12
|
* Fri Apr 6 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.0-12
|
||||||
- Add back PPC and SPARC user emulators
|
- Add back PPC and SPARC user emulators
|
||||||
- Update binfmt rules from upstream
|
- Update binfmt rules from upstream
|
||||||
|
Loading…
Reference in New Issue
Block a user