Spice 主窗口表面的创建应该由虚拟机的QXL驱动发起,经由QEMU将相关参数传递给spice server(主要由负责显示的red_worker.c完成),最后spice server将SPICE_SURFACE_FLAGS_PRIMARY 消息发给spice client完成。上图中省略了QXL driver与 spice client相关部分的过程,用文字来说明。
文件 | 方法 | 描述 |
QEMU Qxl.c | ioport_write | 接受CPU QXL部分的模拟指令,当指令是QXL_IO_CREATE_PRIMARY 的时候调用qxl_create_guest_primary()进行处理 |
| qxl_create_guest_primary() | 第一个参数是PCIQXLDevice,里面包含了primary surface的信息,负责将其转换成surface数据结构的形式,然后调用qemu_spice_create_primary_surface继续(同步的话是调用(qxl_create_guest_primary_complete),下面都以异步来说明 |
QEMU Spice-display.c | qemu_spice_create_primary_surface() | 调用RedWorker的create_primary_surface方法,但是由于这是个回调函数,实际调用的是Red_dispatcher.c的qxl_worker_create_primary_surface 方法 |
LibSpice Red_dispatcher.c | qxl_worker_create_primary_surface() | 简单调用 red_dispatcher_create_primary_surface() |
| red_dispatcher_create_primary_surface() | 根据同步异步设置,调用相应的方法,这里默认是同步,调用red_dispatcher_create_primary_surface_sync |
| red_dispatcher_create_primary_surface_sync() | Dispatcher与Red_worker之间是通过双向的socketpair发消息通信的,因此这里Dispatcher发了一个RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE消息给Red_worker |
LibSpice Red_worker.c | handle_dev_create_primary_surface()
| Red_worker收到创建Primary surface的消息后开始在handle_dev_create_primary_surface()进行处理,简单转给dev_create_primary_surface() |
| dev_create_primary_surface() | 主要做了三件事情: 1. 调用red_create_surface()创建primary surface(通过调用PIXMAN的API完成)并发送SPICE_SURFACE_FLAGS_PRIMARY消息给spice client,由spice client的Display_channel.cpp处理完成; 2. 调用red_worker_push_monitors_config 发送监视器的配置给spice client; 3. 调用red_channel_pipes_add_type 发送PIPE_ITEM_TYPE_CURSOR_INIT消息给spice client,spice client调用Cursor_channel.cpp的handle_init进行光标的初始化处理。
|