[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RfC PATCH 09/11] qxl: local rendering for sdl/vnc
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [RfC PATCH 09/11] qxl: local rendering for sdl/vnc |
Date: |
Wed, 14 Apr 2010 11:55:20 +0200 |
Not fully functional yet. Known issues:
- if the guest creates a "top down" primary surface (windows does)
the vns/sdl display will be upside down.
- mouse pointer isn't rendered.
---
hw/qxl.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index ed7e975..d69ad17 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -61,6 +61,12 @@ typedef struct PCIQXLDevice {
enum qxl_mode mode;
int generation;
+ DisplaySurface *surface_native;
+ SpiceRect surface_rect;
+ uint32_t surface_id;
+ int surface_render;
+ int surface_commands;
+
/* thread signaling */
pthread_t main;
int pipe[2];
@@ -325,6 +331,7 @@ static int interface_get_command(QXLInstance *sin, struct
QXLCommandExt *ext)
if (notify) {
qxl_send_events(qxl, QXL_INTERRUPT_DISPLAY);
}
+ qxl->surface_commands++;
return true;
case QXL_MODE_UNDEFINED:
default:
@@ -433,6 +440,7 @@ static int interface_get_cursor_command(QXLInstance *sin,
struct QXLCommandExt *
if (notify) {
qxl_send_events(qxl, QXL_INTERRUPT_CURSOR);
}
+ qxl->surface_commands++;
return true;
} else {
return false;
@@ -454,6 +462,13 @@ static void interface_get_update_area(QXLInstance *sin,
const struct SpiceRect *
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
+ if (qxl->surface_render) {
+ qxl->surface_render = 0;
+ *rect = &qxl->surface_rect;
+ *surface_id = &qxl->surface_id;
+ return;
+ }
+
*rect = &qxl->ram->update_area;
*surface_id = &qxl->ram->update_surface;
}
@@ -711,6 +726,7 @@ static void qxl_del_memslot(PCIQXLDevice *d, uint32_t
slot_id)
static void qxl_create_guest_primary(PCIQXLDevice *d)
{
QXLDevSurfaceCreate surface;
+ void *ptr;
assert(d->mode != QXL_MODE_NATIVE);
qxl_exit_vga_mode(d);
@@ -732,6 +748,30 @@ static void qxl_create_guest_primary(PCIQXLDevice *d)
d->mode = QXL_MODE_NATIVE;
d->ssd.worker->create_primary_surface(d->ssd.worker, 0, &surface);
+
+ fprintf(stderr, "%s: width %d height %d depth %d stride %d\n",
__FUNCTION__,
+ surface.width, surface.height, surface.depth, surface.stride);
+
+ if (surface.stride < 0) {
+ /* FIXME: will display upside down */
+ surface.stride = -surface.stride;
+ }
+
+ if (d->surface_native) {
+ qemu_free(d->surface_native);
+ d->surface_native = NULL;
+ }
+
+ ptr = qemu_get_ram_ptr(d->vga.vram_offset);
+ d->surface_native =
+ qemu_create_displaysurface_from(surface.width, surface.height,
+ surface.depth, surface.stride, ptr);
+
+ d->surface_id = 0;
+ d->surface_rect.top = 0;
+ d->surface_rect.bottom = surface.height;
+ d->surface_rect.left = 0;
+ d->surface_rect.right = surface.width;
}
static void qxl_destroy_primary(PCIQXLDevice *d)
@@ -826,10 +866,16 @@ static uint32_t ioport_read(void *opaque, uint32_t addr)
static void qxl_map(PCIDevice *pci, int region_num,
pcibus_t addr, pcibus_t size, int type)
{
+ static const char *names[] = {
+ [ QXL_IO_RANGE_INDEX ] = "ioports",
+ [ QXL_RAM_RANGE_INDEX ] = "devram",
+ [ QXL_ROM_RANGE_INDEX ] = "rom",
+ [ QXL_VRAM_RANGE_INDEX ] = "vram",
+ };
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci);
- dprintf(1, "%s: bar %d addr 0x%lx size 0x%lx\n", __FUNCTION__,
- region_num, addr, size);
+ dprintf(1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__,
+ region_num, names[region_num], addr, size);
switch (region_num) {
case QXL_IO_RANGE_INDEX:
@@ -901,6 +947,67 @@ static void init_pipe_signaling(PCIQXLDevice *d)
qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
}
+/* graphics console */
+
+static void qxl_hw_update(void *opaque)
+{
+ PCIQXLDevice *qxl = opaque;
+ VGACommonState *vga = &qxl->vga;
+
+ if (qxl->mode == QXL_MODE_VGA) {
+ vga->update(vga);
+ return;
+ }
+
+ if (qxl->surface_native) {
+ qemu_free_displaysurface(vga->ds);
+ vga->ds->surface = qxl->surface_native;
+ qxl->surface_native = NULL;
+ dpy_resize(vga->ds);
+ }
+
+ if (qxl->surface_commands) {
+ qxl->surface_commands = 0;
+ qxl->surface_render = 1;
+ qxl->ssd.worker->update_area(qxl->ssd.worker);
+
+ /* FIXME: want more specific dirty region here */
+ dpy_update(vga->ds, 0, 0, ds_get_width(vga->ds),
ds_get_height(vga->ds));
+ }
+}
+
+static void qxl_hw_invalidate(void *opaque)
+{
+ PCIQXLDevice *qxl = opaque;
+ VGACommonState *vga = &qxl->vga;
+
+ vga->invalidate(vga);
+}
+
+static void qxl_hw_screen_dump(void *opaque, const char *filename)
+{
+ PCIQXLDevice *qxl = opaque;
+ VGACommonState *vga = &qxl->vga;
+
+ if (qxl->mode == QXL_MODE_VGA) {
+ vga->screen_dump(vga, filename);
+ return;
+ }
+}
+
+static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
+{
+ PCIQXLDevice *qxl = opaque;
+ VGACommonState *vga = &qxl->vga;
+
+ if (qxl->mode == QXL_MODE_VGA) {
+ vga->text_update(vga, chardata);
+ return;
+ }
+}
+
+/* display change listener */
+
static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
{
if (qxl0->mode == QXL_MODE_VGA) {
@@ -950,13 +1057,19 @@ static int qxl_init(PCIDevice *dev)
register_ioport_write(0x3ba, 1, 1, qxl_vga_ioport_write, vga);
register_ioport_write(0x3da, 1, 1, qxl_vga_ioport_write, vga);
- qxl0 = qxl;
+#if 0
vga->ds = graphic_console_init(vga->update, vga->invalidate,
vga->screen_dump, vga->text_update,
vga);
+#else
+ vga->ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
+ qxl_hw_screen_dump, qxl_hw_text_update,
qxl);
+#endif
qxl->ssd.ds = vga->ds;
qxl->ssd.bufsize = (16 * 1024 * 1024);
qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize);
pthread_mutex_init(&qxl->ssd.lock, NULL);
+
+ qxl0 = qxl;
register_displaychangelistener(vga->ds, &display_listener);
if (qxl->pci.romfile == NULL)
@@ -1021,7 +1134,7 @@ static PCIDeviceInfo qxl_info = {
.init = qxl_init,
.config_write = qxl_write_config,
.qdev.props = (Property[]) {
- DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 32 * 1024
* 1024),
+ DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024
* 1024),
DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 *
1024),
DEFINE_PROP_END_OF_LIST(),
}
--
1.6.6.1
[Qemu-devel] [RfC PATCH 09/11] qxl: local rendering for sdl/vnc,
Gerd Hoffmann <=
[Qemu-devel] [RfC PATCH 08/11] spice: add qxl device, Gerd Hoffmann, 2010/04/14
- Re: [Qemu-devel] [RfC PATCH 08/11] spice: add qxl device, Blue Swirl, 2010/04/14
- [Qemu-devel] Re: [RfC PATCH 08/11] spice: add qxl device, Gerd Hoffmann, 2010/04/16
- [Qemu-devel] Re: [RfC PATCH 08/11] spice: add qxl device, Paolo Bonzini, 2010/04/16
- Re: [Qemu-devel] Re: [RfC PATCH 08/11] spice: add qxl device, Gerd Hoffmann, 2010/04/16
- [Qemu-devel] Re: [RfC PATCH 08/11] spice: add qxl device, Richard Henderson, 2010/04/16
Re: [Qemu-devel] [RfC PATCH 08/11] spice: add qxl device, Alexander Graf, 2010/04/14