From: Alon Levy <alevy@redhat.com>
To: qemu-devel@nongnu.org, kraxel@redhat.com, elmarco@redhat.com
Subject: [Qemu-devel] [RFC 7/7] qxl: add allocator
Date: Sun, 19 Feb 2012 23:28:06 +0200 [thread overview]
Message-ID: <1329686886-6853-8-git-send-email-alevy@redhat.com> (raw)
In-Reply-To: <1329686886-6853-1-git-send-email-alevy@redhat.com>
Add an implementation of the DisplayAllocator callbacks for qxl. Uses
the QEMU_ALLOCATED_FLAG to ensure vga/vga_draw_graphic does the 24 to 32
bits per pixel line convertion. Since free/resize/create are defined in
qxl.c, it is easy to ensure consistent usage of the flag (it means
QXL_ALLOCATED basically).
With this patch and the previous two screendump works for vga and qxl
modes when using qxl and spice together. This might break sdl/vnc with
spice, untested since it isn't of known use.
Signed-off-by: Alon Levy <alevy@redhat.com>
---
hw/qxl-render.c | 34 +-----------------
hw/qxl.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++---
ui/spice-display.c | 1 +
ui/spice-display.h | 2 +
4 files changed, 101 insertions(+), 39 deletions(-)
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 7b120ab..8280b91 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -82,7 +82,6 @@ void qxl_render_update(PCIQXLDevice *qxl, const char *filename)
{
VGACommonState *vga = &qxl->vga;
QXLRect dirty[32];
- void *ptr;
int redraw = 0;
QXLRenderUpdateData *data;
QXLCookie *cookie;
@@ -96,38 +95,7 @@ void qxl_render_update(PCIQXLDevice *qxl, const char *filename)
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",
- __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 =
- 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);
+ qemu_resize_displaysurface(qxl->vga.ds, 0, 0);
}
if (!qxl->guest_primary.commands) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 6e25bd1..ec43c4e 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -138,6 +138,92 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
}
}
+static DisplaySurface *qxl_create_displaysurface(int width, int height)
+{
+ PCIQXLDevice *qxl = qxl0;
+ DisplaySurface *ret;
+ void *ptr;
+
+ dprint(qxl, 1, "%s: %d x %d (have %d, %d)\n", __func__,
+ width, height,
+ qxl->guest_primary.surface.width,
+ qxl->guest_primary.surface.height);
+ if (width != 0 && height != 0 &&
+ (qxl->mode == QXL_MODE_VGA || qxl->mode == QXL_MODE_UNDEFINED)) {
+ /* initial surface creation in vga mode, use give width and height */
+ qxl->guest_primary.surface.width = width;
+ qxl->guest_primary.surface.height = height;
+ qxl->guest_primary.qxl_stride = width * 4;
+ qxl->guest_primary.abs_stride = width * 4;
+ qxl->guest_primary.bytes_pp = 4;
+ qxl->guest_primary.bits_pp = 32;
+ qxl->guest_primary.flipped = 0;
+ qxl->guest_primary.data = qxl->ssd.buf;
+ } else {
+ if (qxl->guest_primary.flipped) {
+ g_free(qxl->guest_primary.flipped);
+ qxl->guest_primary.flipped = NULL;
+ }
+ 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",
+ __func__,
+ 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");
+ ret = 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);
+ /*
+ * set this flag to ensure vga_draw_graphic treats this as a non shared
+ * buffer, and so does the correct convertion to 32 bits that we always use.
+ */
+ ret->flags |= QEMU_ALLOCATED_FLAG;
+ return ret;
+}
+
+static void qxl_free_displaysurface(DisplaySurface *surface)
+{
+ g_free(surface);
+}
+
+static DisplaySurface *qxl_resize_displaysurface(DisplaySurface *surface,
+ int width, int height)
+{
+ if (surface != qxl0->vga.ds->surface) {
+ qxl_free_displaysurface(surface);
+ }
+ return qxl_create_displaysurface(width, height);
+}
+
+static struct DisplayAllocator qxl_displaysurface_allocator = {
+ qxl_create_displaysurface,
+ qxl_resize_displaysurface,
+ qxl_free_displaysurface
+};
+
+void qxl_set_allocator(DisplayState *ds)
+{
+ if (register_displayallocator(ds, &qxl_displaysurface_allocator) ==
+ &qxl_displaysurface_allocator) {
+ printf("qxl_set_allocator success\n");
+ dpy_resize(ds);
+ }
+}
void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
@@ -1493,9 +1579,18 @@ static void qxl_hw_invalidate(void *opaque)
static void qxl_hw_screen_dump(void *opaque, const char *filename)
{
PCIQXLDevice *qxl = opaque;
- VGACommonState *vga = &qxl->vga;
switch (qxl->mode) {
+ case QXL_MODE_VGA:
+ /*
+ * TODO: vga_hw_screen_dump needless does a number of ppm_save calls
+ * fix it instead of redoing it correctly here (needs testing which is
+ * why it isn't yet done)
+ */
+ qxl->vga.invalidate(&qxl->vga);
+ vga_hw_update();
+ ppm_save(filename, qxl->ssd.ds->surface);
+ break;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
/*
@@ -1508,9 +1603,6 @@ static void qxl_hw_screen_dump(void *opaque, const char *filename)
*/
qxl_render_update(qxl, filename);
break;
- case QXL_MODE_VGA:
- vga->screen_dump(vga, filename);
- break;
default:
break;
}
@@ -1682,9 +1774,8 @@ static int qxl_init_primary(PCIDevice *dev)
vga->ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
qxl_hw_screen_dump, qxl_hw_text_update, qxl);
- qemu_spice_display_init_common(&qxl->ssd, vga->ds);
-
qxl0 = qxl;
+ qemu_spice_display_init_common(&qxl->ssd, vga->ds);
register_displaychangelistener(vga->ds, &display_listener);
return qxl_init_common(qxl);
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 680e6f4..7fd18f4 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -295,6 +295,7 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
ssd->mouse_y = -1;
ssd->bufsize = (16 * 1024 * 1024);
ssd->buf = g_malloc(ssd->bufsize);
+ qxl_set_allocator(ds);
}
/* display listener callbacks */
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 8f286f8..9f24097 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -123,3 +123,5 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
void qemu_spice_start(SimpleSpiceDisplay *ssd);
void qemu_spice_stop(SimpleSpiceDisplay *ssd);
+
+void qxl_set_allocator(DisplayState *ds);
--
1.7.9
next prev parent reply other threads:[~2012-02-19 21:28 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-19 21:27 [Qemu-devel] [RFC 0/7] qxl: fix hangs caused by qxl_render_update Alon Levy
2012-02-19 21:28 ` [Qemu-devel] [RFC 1/7] sdl: remove NULL check, g_malloc0 can't fail Alon Levy
2012-02-19 21:28 ` [Qemu-devel] [RFC 2/7] qxl: drop qxl_spice_update_area_async definition Alon Levy
2012-02-19 21:28 ` [Qemu-devel] [RFC 3/7] qxl: introduce QXLCookie Alon Levy
2012-02-20 10:56 ` Gerd Hoffmann
2012-02-20 12:31 ` Alon Levy
2012-02-20 12:39 ` Gerd Hoffmann
2012-02-19 21:28 ` [Qemu-devel] [RFC 4/7] qxl: make qxl_render_update async Alon Levy
2012-02-20 11:10 ` Gerd Hoffmann
2012-02-20 12:32 ` Alon Levy
2012-02-20 12:45 ` Gerd Hoffmann
2012-02-19 21:28 ` [Qemu-devel] [RFC 5/7] qxl-render: call ppm_save on callback Alon Levy
2012-02-20 11:32 ` Gerd Hoffmann
2012-02-20 12:36 ` Alon Levy
2012-02-20 12:49 ` Gerd Hoffmann
2012-02-20 21:29 ` Eric Blake
2012-02-21 8:19 ` Alon Levy
2012-02-21 16:15 ` Eric Blake
2012-02-21 17:40 ` Alon Levy
2012-02-22 13:17 ` Luiz Capitulino
2012-02-22 13:22 ` Alon Levy
2012-02-22 13:49 ` Luiz Capitulino
2012-02-22 14:22 ` Gerd Hoffmann
2012-02-22 14:29 ` Alon Levy
2012-02-22 15:55 ` Luiz Capitulino
2012-02-22 16:35 ` Alon Levy
2012-02-22 19:27 ` Luiz Capitulino
2012-02-22 14:28 ` Alon Levy
2012-02-22 14:47 ` Gerd Hoffmann
2012-02-22 15:26 ` Alon Levy
2012-02-19 21:28 ` [Qemu-devel] [RFC 6/7] qxl: use spice_qxl_update_area_dirty_async Alon Levy
2012-02-19 21:28 ` Alon Levy [this message]
2012-02-20 11:41 ` [Qemu-devel] [RFC 7/7] qxl: add allocator Gerd Hoffmann
2012-02-20 12:38 ` Alon Levy
2012-02-20 13:18 ` Gerd Hoffmann
2012-02-20 17:36 ` Alon Levy
2012-02-21 7:57 ` Gerd Hoffmann
2012-02-21 8:26 ` Alon Levy
2012-02-21 9:20 ` Gerd Hoffmann
2012-02-21 9:59 ` Alon Levy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1329686886-6853-8-git-send-email-alevy@redhat.com \
--to=alevy@redhat.com \
--cc=elmarco@redhat.com \
--cc=kraxel@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).