--- Here's some additional documentation on multiple monitors. I have a few open questions about the driver memory stuff. multiple-monitors.rst | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 multiple-monitors.rst diff --git a/multiple-monitors.rst b/multiple-monitors.rst new file mode 100644 index 0000000..5967999 --- /dev/null +++ b/multiple-monitors.rst @@ -0,0 +1,201 @@ +Spice with multiple monitors +=============================================================================== +:slug: multiple-monitors + +The SPICE protocol supports guests with more than one monitor. Windows guests +and Linux guests behave somewhat differently, so they need to be configured in +slightly different ways. + +Guest requirements +++++++++++++++++++ +Both Windows and Linux guests should be configured with a QXL video device and +a spice vdagent to take full advantage of the multiple monitor functionality. +While these are not absolutely required, they are highly recommended. + +Without a spice vdagent running in the guest, it may be possible to enable or +disable displays from within the guest (and the spice client will adapt to +those changes), but it will not be possible to enable or disable displays from +the client. + +Without a QXL driver in the guest, it may be possible to resize a display, but +it will not be possible to resize it to an arbitrary resolution. Each display +will only support a fixed set of resolutions. + +Guest QXL Configuration ++++++++++++++++++++++++ +One major difference between Linux and Windows QXL devices is that the Linux +QXL driver supports multiple displays (up to 4) with a single video device, +whereas the Windows QXL driver only supports a single display for each video +device. So to enable 4 monitors, a Linux guest would need only a single QXL +device, while a Windows guest would need to be configured with 4 separate QXL +devices. It is possible to limit the number of displays that a single linux +driver supports by setting the `qxl-vga.max_outputs` property in qemu. If you +are using libvirt to configure your guest, you may need to ensure that the +`heads` parameter for the video device is set properly. + +QXL Driver Video Memory +----------------------- +If you want to use multiple displays on your guest, you need to make sure that +the device has enough video memory to support the number and size of screens +you intend to use. There are several QXL parameters that you can use to control +the amount of memory allocated to the QXL devices. These parameters are: + +* `ram_size` / `ram_size_mb` +* `vram_size` / `vram_size_mb` +* `vram64_size_mb` +* `vgamem_mb` + +The QXL driver device has two memory bars. `ram_size`/`ram_size_mb` controls the +size of the first memory bar, and `vram_size`/`vram_size_mb`/`vram64_size_mb` +controls the size of the second memory bar. `vgamem_mb` is located within the +first memory bar, which means that `ram_size_mb` is constrained to be a least 2 +times as large as `vgamem_mb`. + +These memory bars are used in different ways by different QXL drivers. In the +Windows QXL driver and non-KMS Linux drivers (e.g. RHEL 6), `vgamem_mb` +determines the size of the primary surface, and therefore determines the +maximum resolution of the device. For devices that support +multiple displays with a single device (i.e. Linux drivers), this primary +surface must be large enough to contain all displays. This bar is also used for +dynamic meory such as cursors, commands, and images. The second bar is used for +offscreen memory. + +In KMS-based Linux drivers, all surfaces (including the primary surface) are +allocated in the second memory bar and the first memory bar is used for dynamic +memory such as cursors, commands, images, and monitor configs. Therefore, +devices that support multiple displays will need larger values for `vram_size` +/ `vram_size_mb`. + +XXX: what is `vram64_size_mb` used for? Does the non-KMS driver actually use +the second bar? + +Spice Protocol +++++++++++++++ +Additional displays are enabled and disabled via the spice protocol using agent +data messages on the Main channel. When the client wants to adjust the display +of the guest (either adjusting the resolution of displays, enabling a new +display, or disabling an existing display), it constructs a new +VD_AGENT_MONITORS_CONFIG message that specifies the dimensions of all of the +monitors that should be enabled. This message is then sent to the server. The +server receives this message and attempts to adjust the display to match the +new configuration. If a display that is currently enabled is not listed in this +message (or if it is explicitly set to a height or width of 0), that display +will be disabled. + +After the displays are reconfigured, the server sends a MONITORS_CONFIG message +on the DisplayChannel associated with the display that was changed. When the +client receives this message it should update its displays to match the current +state of the guest. + +As mentioned above, the Linux QXL device supports multiple displays in a single +device, whereas the Windows QXL device requires a separate device for each +display. This has implications at the protocol level as well. A Linux guest +will have a single DisplayChannel which manages up to 4 displays on the same +channel. A Windows guest will have multiple DisplayChannels, one for each +device and each managing a single display. + +Implementation +++++++++++++++ +Since so many different components are involved, the implementation can vary +significantly between different guest operating systems or even between +different versions of the components. Several of these differences have already +been discussed above, but there are others to be aware of as well. + +Server +------ +When the server receives a new monitors config message from the client, the +server checks whether the qxl device implementation provides a monitors config +callback function. If it does, that callback is executed. If that callback is +not provided, the monitors config is instead send via a char device to the +spice vdagent running within the guest. These different approaches will be +discussed in more detail below. As the guest display configuration changes, the +QXL device will be updated and the server will send new monitors config +messages to the client. Note that guests can change display configurations in +different manners and the change is not necessarily done atomically. So when a +client requests a display configuration change, the change may happen in +several steps (e.g. enable an additional display and then move that display to +the proper location and then resize that display to the appropriate +resolution). These different steps may each result in a monitors config message +being sent from the server to the client. So you cannot rely on a single +monitors config request from a client generating a single monitors config reply +from the server. + +Guest +----- +Software components within the guest are responsible for doing the display +reconfiguration. The implementation can vary based on the guest. + +vdagent implementation +********************** +Older versions of the QXL driver do not provide the callback mentioned above +and instead handle all monitor configuration changes via the spice-vdagent +executable running within the guest. The configuration is sent from the host to +the guest via the vdagent char device. The spice-vdagent executable then uses +platform APIs (e.g. xrandr on linux) to attempt to configure the displays to +match the requested configuration. + +Device implementation +********************* +Newer versions of the QXL implementation (for example, RHEL7 and newer) provide +an implementation of the monitors config callback function mentioned above. In +broad terms, this callback function updates some internal ROM data within the +virtual device and then triggers an interrupt within the guest. The guest +driver handles this interrupt and generates a hotplug event. This hotplug event +is then handled by the userspace software in the same way a normal physical +hotplug event would be handled. This has the advantage of consolidating all of +the monitor reconfiguration functionality within a single component (in GNOME3, +that component is the window manager) instead of both the vdagent and the +desktop environment responsible display configuration in different situations. +In the past this duplication has caused minor issues where the desktop +environment attempted to apply a saved display configuration that conflicted +with the vdagent. + +Client +------ +The spice-gtk library is the main library used for implementing spice clients. +Although spice-gtk provides the means to support multiple monitors, not all +clients implement that feature. The most full-featured client at the moment is +virt-viewer, so that is the client that we will address here. + +When a client connects to the spice server, it will receive a monitors config +message from the display channel indicating the current display state of the +guest. The client receives this message and opens a window for each monitor and +sets the window to the appropriate size. + +When a client window is resized, the client sends a monitors config message to +the server to adjust the guest display resolution to match the size of the +client window. The client has a timeout to avoid sending excessive and repeated +monitor configs while the user is resizing window. + +When a client window is closed, the client sends a monitors config message to +the server to disable the closed display. And when a new window is opened, the +client sends a monitors config message to the server to enable an additional +display. When the guest configuration is updated, the server will send a new +monitors config message back to the client. + +When virt-viewer constructs a new monitors config message to send to the +server, it places one display at (0,0) and arranges additional monitors +linearly in a horizontal row without gaps. It uses the locations of the client +windows to determine how to order the displays. This helps with predictability +because the guest displays will be arranged in roughly the same order as the +client windows. + +Fullscreen mode +*************** +One exception to this linear arrangement is in fullscreen mode. In fullscreen +mode, virt-viewer attempts to enable a single guest display for each physical +client monitor and set the resolution of the guest displays to be equal to the +resolution of the client monitors. It also arranges the guest displays in the +same arrangement as the client monitors. For example, if the client has +four monitors arranged in a 2x2 grid, the guest displays will also be +configured to a 2x2 grid instead of a horizontal array of 4 monitors. + +One additional feature of fullscreen mode is the ability to use a configuration +file to fine-tune this behavior. If you have multiple client monitors, but you +want to run virt-viewer in fullscreen mode on only a subset of those monitors, +you can do so with the `monitor-mapping` configuration option to specify which +monitors to use. This option is an array of mappings between guest displays and +client monitors. For example, if you have 3 monitors and want to run +virt-viewer in fullscreen mode on the last two, you can use +`monitor-mapping=1:2;2:3`. That will place guest display 1 on client monitor 2, +and guest display 2 on client monitor 3. -- 2.9.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel