qxl显卡与spice模块笔记
1、qxl虚拟显卡设备创建QemuConsole,并保存在全局变量consoles链表中。
static void qxl_realize_primary(PCIDevice *dev, Error **errp)
{PCIQXLDevice *qxl = PCI_QXL(dev);VGACommonState *vga = &qxl->vga;Error *local_err = NULL;qxl_init_ramsize(qxl);vga->vbe_size = qxl->vgamem_size;vga->vram_size_mb = qxl->vga.vram_size / MiB;vga_common_init(vga, OBJECT(dev), &local_err);if (local_err) {error_propagate(errp, local_err);return;}vga_init(vga, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), false);portio_list_init(&qxl->vga_port_list, OBJECT(dev), qxl_vga_portio_list, vga, "vga");portio_list_set_flush_coalesced(&qxl->vga_port_list);portio_list_add(&qxl->vga_port_list, pci_address_space_io(dev), 0x3b0);qxl->have_vga = true;vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
...
2、spice参数模块获取QemuConsole调用qemu_spice_add_display_interface,添加QXL接口到libspice。
static void qemu_spice_display_init_one(QemuConsole *con)
{SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);qemu_spice_display_init_common(ssd);ssd->dcl.ops = &display_listener_ops;
#ifdef HAVE_SPICE_GLif (spice_opengl) {ssd->dcl.ops = &display_listener_gl_ops;ssd->dgc.ops = &gl_ctx_ops;ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,qemu_spice_gl_block_timer, ssd);ssd->gls = qemu_gl_init_shader();ssd->have_surface = false;ssd->have_scanout = false;}
#endifssd->dcl.con = con;ssd->qxl.base.sif = &dpy_interface.base;qemu_spice_add_display_interface(&ssd->qxl, con);#if SPICE_SERVER_VERSION >= 0x000e02 /* release 0.14.2 */Error *err = NULL;char device_address[256] = "";if (qemu_console_fill_device_address(con, device_address, 256, &err)) {spice_qxl_set_device_info(&ssd->qxl, device_address, qemu_console_get_head(con), 1);} else {error_report_err(err);}
#endifqemu_spice_create_host_memslot(ssd);if (spice_opengl) {qemu_console_set_display_gl_ctx(con, &ssd->dgc);}register_displaychangelistener(&ssd->dcl);
}
总结:在 SPICE 场景中,QXL 驱动生成图形数据,QemuConsole 提供接口,SPICE 传输到客户端。