---
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
Maybe is worth documenting from which version(s) is possible this
limitation?
+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`
+
Maybe worth mentioning that these parameters are Qemu parameters?
Or maybe not as libvirt has similar configurations?
+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
typo, memory
+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?
+
The second bar can be configured very large but only using 64 bit.
So if you configure vram to 32mb and vram64 ro 128mb for instance
you will get a 32bit bar with 32mb and a 64bit bar with 128mb, the
first 32mb of the 64bit bar contains same data as the 32bit bar.
64bit drivers should map the 64bit bar and use it as second for
larger space.
+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.
+
It's clear to me. Not much sure if this is clear to people reading this
document. Who is the target of this document?
As a developer maybe confusing DisplayChannel as protocol or as spice-server
implementation but as the chapter is about protocol I assume is DisplayChannel
as protocol.
+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
Useful. So it does not try to reproduce a similar arrangement as
the client.
+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
Where's this file?
Can be configured in some way from RHV or put in the .vv files?
+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.
Frediano
_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel