Since 2.10 QEMU supports a new display type egl-headless which uses the
drm nodes for OpenGL rendering copying back the rendered bits back to
QEMU into a dma-buf which can be accessed by standard "display" apps
like VNC or SPICE. Although this display type can be used on its own,
for any practical use case it makes sense to pair it with either VNC or
SPICE display. The clear benefit of this display is that VNC gains
OpenGL support, which it natively doesn't have, and SPICE gains remote
OpenGL support (native OpenGL support only works locally through a UNIX
socket, i.e. listen type=socket/none)
Signed-off-by: Erik Skultety <eskultet(a)redhat.com>
---
docs/formatdomain.html.in | 33 ++++++++++++-
docs/schemas/domaincommon.rng | 3 ++
src/conf/domain_conf.c | 6 ++-
src/conf/domain_conf.h | 1 +
src/libxl/libxl_conf.c | 1 +
src/qemu/qemu_command.c | 35 +++++++++++++-
src/qemu/qemu_domain.c | 54 ++++++++++++++++++++++
src/qemu/qemu_driver.c | 2 +
src/qemu/qemu_hotplug.c | 1 +
src/qemu/qemu_process.c | 4 ++
src/vmx/vmx.c | 1 +
tests/domaincapsschemadata/full.xml | 1 +
tests/qemuxml2argvdata/graphics-egl-headless.args | 26 +++++++++++
tests/qemuxml2argvdata/graphics-egl-headless.xml | 31 +++++++++++++
.../qemuxml2argvdata/graphics-sdl-egl-headless.xml | 35 ++++++++++++++
.../graphics-spice-egl-headless.args | 31 +++++++++++++
.../graphics-spice-egl-headless.xml | 36 +++++++++++++++
.../graphics-spice-invalid-egl-headless.xml | 37 +++++++++++++++
.../graphics-vnc-egl-headless.args | 28 +++++++++++
.../qemuxml2argvdata/graphics-vnc-egl-headless.xml | 37 +++++++++++++++
tests/qemuxml2argvtest.c | 17 +++++++
.../graphics-spice-egl-headless.xml | 44 ++++++++++++++++++
.../graphics-vnc-egl-headless.xml | 42 +++++++++++++++++
tests/qemuxml2xmltest.c | 2 +
24 files changed, 504 insertions(+), 4 deletions(-)
create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.args
create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.xml
create mode 100644 tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml
create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.args
create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.xml
create mode 100644 tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml
create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.args
create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml
create mode 100644 tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml
create mode 100644 tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a3afe137bf..9dd22554ad 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -6299,7 +6299,8 @@ qemu-kvm -net nic,model=? /dev/null
<p>
The <code>graphics</code> element has a mandatory
<code>type</code>
attribute which takes the value <code>sdl</code>,
<code>vnc</code>,
- <code>spice</code>, <code>rdp</code> or
<code>desktop</code>:
+ <code>spice</code>, <code>rdp</code>,
<code>desktop</code> or
+ <code>egl-headless</code>:
</p>
<dl>
<dt><code>sdl</code></dt>
@@ -6358,6 +6359,11 @@ qemu-kvm -net nic,model=? /dev/null
auto-allocation and <code>autoport</code> having no effect due
to
security reasons) <span class="since">Since
1.0.6</span>.
</p>
+ <p>
+ Although VNC doesn't support OpenGL natively, it can be paired
+ with graphics type <code>egl-headless</code> (see below) which
+ will instruct QEMU to open and use drm nodes for OpenGL rendering.
+ </p>
</dd>
<dt><code>spice</code> <span
class="since">Since 0.8.6</span></dt>
<dd>
@@ -6463,6 +6469,12 @@ qemu-kvm -net nic,model=? /dev/null
You can enable or disable OpenGL support explicitly with
the <code>gl</code> element, by setting the
<code>enable</code>
property. (QEMU only, <span class="since">since
1.3.3</span>).
+ Note that this only works locally, since this requires usage of
+ UNIX sockets, i.e. using <code>listen</code> types
'socket' or
+ 'none'. For accelerated OpenGL with remote support, consider
+ pairing this element with type <code>egl-headless</code>
+ (see below). However, this will deliver weaker performance
+ compared to native Spice OpenGL support.
</p>
<p>
By default, QEMU will pick the first available GPU DRM render node.
@@ -6498,6 +6510,25 @@ qemu-kvm -net nic,model=? /dev/null
<code>fullscreen</code>.
</p>
</dd>
+ <dt><code>egl-headless</code><span
class="since">Since 4.6.0</span></dt>
+ <dd>
+ <p>
+ This display type provides support for an OpenGL accelerated
+ display accessible both locally and remotely (for comparison,
+ Spice's native OpenGL support only works locally using UNIX
+ sockets at the moment, but has better performance). Since this
+ display type doesn't provide any window or graphical console like
+ the other types, for practical reasons it should be paired with
+ either <code>vnc</code> or <code>spice</code>
graphics types.
+ This display type is only supported by QEMU domains
+ (needs QEMU <span class="since">2.10</span> or newer)
and doesn't
+ accept any attributes.
+ </p>
+ <pre>
+<graphics type='spice' autoport='yes'/>
+<graphics type='egl-headless'/>
+ </pre>
+ </dd>
</dl>
</dd>
</dl>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index bd687ce9d3..8f7d273d9f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3366,6 +3366,9 @@
</attribute>
</optional>
</group>
+ <attribute name="type">
+ <value>egl-headless</value>
+ </attribute>
</choice>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7c9d04c924..27f55d8868 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -615,7 +615,8 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST,
"vnc",
"rdp",
"desktop",
- "spice")
+ "spice",
+ "egl-headless")
VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST,
"none",
@@ -1426,6 +1427,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
virDomainGraphicsAuthDefClear(&def->data.spice.auth);
break;
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
@@ -14135,6 +14137,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node,
if (virDomainGraphicsDefParseXMLSpice(def, node, ctxt, flags) < 0)
goto error;
break;
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
@@ -26366,6 +26369,7 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
virDomainGraphicsAuthDefFormatAttr(buf, &def->data.spice.auth, flags);
break;
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 41d27482fb..66bfc94545 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1473,6 +1473,7 @@ typedef enum {
VIR_DOMAIN_GRAPHICS_TYPE_RDP,
VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP,
VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS,
VIR_DOMAIN_GRAPHICS_TYPE_LAST
} virDomainGraphicsType;
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 452a77f3b8..cda4eb9d31 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1441,6 +1441,7 @@ libxlMakeVfb(virPortAllocatorRangePtr graphicsports,
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index cea31e6a24..8026efbe87 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8184,6 +8184,27 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
return -1;
}
+
+static int
+qemuBuildGraphicsHeadlessCommandLine(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED,
+ virCommandPtr cmd,
+ virQEMUCapsPtr qemuCaps,
+ virDomainGraphicsDefPtr def ATTRIBUTE_UNUSED)
+{
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_EGL_HEADLESS)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("egl-headless display is not supported with this "
+ "QEMU binary"));
+ return -1;
+ }
+
+ virCommandAddArg(cmd, "-display");
+ virCommandAddArg(cmd, "egl-headless");
+
+ return 0;
+}
+
+
static int
qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
virCommandPtr cmd,
@@ -8213,6 +8234,12 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
qemuCaps, graphics) < 0)
return -1;
+ break;
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
+ if (qemuBuildGraphicsHeadlessCommandLine(cfg, cmd,
+ qemuCaps, graphics) < 0)
+ return -1;
+
break;
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
@@ -10040,6 +10067,7 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
int sdl = 0;
int vnc = 0;
int spice = 0;
+ int egl_headless = 0;
if (!virQEMUDriverIsPrivileged(driver)) {
/* If we have no cgroups then we can have no tunings that
@@ -10081,6 +10109,9 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
++spice;
break;
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
+ ++egl_headless;
+ break;
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
@@ -10088,10 +10119,10 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
}
}
- if (sdl > 1 || vnc > 1 || spice > 1) {
+ if (sdl > 1 || vnc > 1 || spice > 1 || egl_headless > 1) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("only 1 graphics device of each type "
- "(sdl, vnc, spice) is supported"));
+ "(sdl, vnc, spice, headless) is supported"));
return -1;
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b10bbc40a4..f488050bf8 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3695,6 +3695,57 @@ qemuDomainDefPostParseBasic(virDomainDefPtr def,
}
+static int
+qemuDomainDefGraphicsPostParse(virDomainDefPtr def)
+{
+ virDomainGraphicsDefPtr graphics = NULL;
+ bool have_egl_headless = false;
+ size_t i;
+
+ /* are we running with egl-headless? */
+ for (i = 0; i < def->ngraphics; i++) {
+ graphics = def->graphics[i];
+
+ if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS) {
+ have_egl_headless = true;
+ break;
+ }
+ }
+
+ /* Only VNC and SPICE can be paired with egl-headless, the other types
+ * either don't make sense to pair with egl-headless or aren't even
+ * supported by QEMU.
+ */
+ if (have_egl_headless) {
+ for (i = 0; i < def->ngraphics; i++) {
+ graphics = def->graphics[i];
+
+ if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS &&
+ graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+ graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("graphics type 'egl-headless' is only
supported "
+ "with one of: 'vnc', 'spice'
graphics types"));
+ return -1;
+ }
+
+ /* '-spice gl=on' and '-display egl-headless' are mutually
+ * exclusive
+ */
+ if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
+ graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("multiple OpenGL displays are not supported "
+ "by QEMU"));
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
static int
qemuDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps ATTRIBUTE_UNUSED,
@@ -3754,6 +3805,9 @@ qemuDomainDefPostParse(virDomainDefPtr def,
if (qemuDomainDefTsegPostParse(def, qemuCaps) < 0)
goto cleanup;
+ if (qemuDomainDefGraphicsPostParse(def) < 0)
+ goto cleanup;
+
ret = 0;
cleanup:
virObjectUnref(cfg);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9a35e04a85..3bf8acc077 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18087,6 +18087,7 @@ qemuDomainOpenGraphics(virDomainPtr dom,
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Can only open VNC or SPICE graphics backends, not
%s"),
virDomainGraphicsTypeToString(vm->def->graphics[idx]->type));
@@ -18155,6 +18156,7 @@ qemuDomainOpenGraphicsFD(virDomainPtr dom,
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Can only open VNC or SPICE graphics backends, not
%s"),
virDomainGraphicsTypeToString(vm->def->graphics[idx]->type));
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 23f6d1daba..5749c2d1b9 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3691,6 +3691,7 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unable to change config on '%s' graphics
type"), type);
break;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 40d35cbe6b..4b68023114 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4353,6 +4353,7 @@ qemuProcessGraphicsReservePorts(virDomainGraphicsDefPtr graphics,
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
@@ -4391,6 +4392,7 @@ qemuProcessGraphicsAllocatePorts(virQEMUDriverPtr driver,
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
@@ -4543,6 +4545,7 @@ qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver,
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
@@ -4830,6 +4833,7 @@ qemuProcessStartValidateGraphics(virDomainObjPtr vm)
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
break;
}
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index fe24b060d7..937bf0c96b 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -3282,6 +3282,7 @@ virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt,
virDomainDe
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
+ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported graphics type '%s'"),
virDomainGraphicsTypeToString(def->graphics[i]->type));
diff --git a/tests/domaincapsschemadata/full.xml b/tests/domaincapsschemadata/full.xml
index d3faf38da0..154c4a6fe9 100644
--- a/tests/domaincapsschemadata/full.xml
+++ b/tests/domaincapsschemadata/full.xml
@@ -59,6 +59,7 @@
<value>rdp</value>
<value>desktop</value>
<value>spice</value>
+ <value>egl-headless</value>
</enum>
</graphics>
<video supported='yes'>
diff --git a/tests/qemuxml2argvdata/graphics-egl-headless.args
b/tests/qemuxml2argvdata/graphics-egl-headless.args
new file mode 100644
index 0000000000..fdf540ddfc
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-egl-headless.args
@@ -0,0 +1,26 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot c \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-display egl-headless \
+-vga cirrus
diff --git a/tests/qemuxml2argvdata/graphics-egl-headless.xml
b/tests/qemuxml2argvdata/graphics-egl-headless.xml
new file mode 100644
index 0000000000..7b001cd2eb
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-egl-headless.xml
@@ -0,0 +1,31 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='egl-headless'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml
b/tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml
new file mode 100644
index 0000000000..955dfeb3c2
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml
@@ -0,0 +1,35 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='sdl' display=':0.1'
xauth='/root/.Xauthority'/>
+ <graphics type='egl-headless'/>
+ <video>
+ <model type='vga' vram='16384' heads='1'/>
+ </video>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/graphics-spice-egl-headless.args
b/tests/qemuxml2argvdata/graphics-spice-egl-headless.args
new file mode 100644
index 0000000000..4886ee05f6
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-spice-egl-headless.args
@@ -0,0 +1,31 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=spice \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot c \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-spice port=5903,addr=127.0.0.1 \
+-display egl-headless \
+-vga qxl \
+-global qxl-vga.ram_size=67108864 \
+-global qxl-vga.vram_size=33554432 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/graphics-spice-egl-headless.xml
b/tests/qemuxml2argvdata/graphics-spice-egl-headless.xml
new file mode 100644
index 0000000000..fafae13a0f
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-spice-egl-headless.xml
@@ -0,0 +1,36 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='spice' port='5903' autoport='no'
listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1'/>
+ </graphics>
+ <graphics type='egl-headless'/>
+ <video>
+ <model type='qxl' ram='65536' vram='32768'
vgamem='8192' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml
b/tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml
new file mode 100644
index 0000000000..25ae61cef6
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml
@@ -0,0 +1,37 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='spice'>
+ <listen type='none'/>
+ <gl enable='yes'/>
+ </graphics>
+ <graphics type='egl-headless'/>
+ <video>
+ <model type='qxl' ram='65536' vram='32768'
vgamem='8192' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/graphics-vnc-egl-headless.args
b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.args
new file mode 100644
index 0000000000..2d2b3cf0fb
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.args
@@ -0,0 +1,28 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot c \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-vnc '[2001:1:2:3:4:5:1234:1234]:3' \
+-display egl-headless \
+-vga cirrus
diff --git a/tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml
b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml
new file mode 100644
index 0000000000..570cf2e50f
--- /dev/null
+++ b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml
@@ -0,0 +1,37 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='vnc' port='5903' autoport='no'
listen='2001:1:2:3:4:5:1234:1234'>
+ <listen type='address' address='2001:1:2:3:4:5:1234:1234'/>
+ </graphics>
+ <graphics type='egl-headless'/>
+ <video>
+ <model type='cirrus' vram='16384' heads='1'/>
+ </video>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 3be5af03aa..26f40d3144 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1167,6 +1167,10 @@ mymain(void)
DO_TEST_PARSE_ERROR("disk-scsi-incompatible-address",
QEMU_CAPS_VIRTIO_SCSI);
+ DO_TEST("graphics-egl-headless",
+ QEMU_CAPS_EGL_HEADLESS,
+ QEMU_CAPS_DEVICE_CIRRUS_VGA);
+
DO_TEST("graphics-vnc", QEMU_CAPS_VNC, QEMU_CAPS_DEVICE_CIRRUS_VGA);
DO_TEST("graphics-vnc-socket", QEMU_CAPS_VNC,
QEMU_CAPS_DEVICE_CIRRUS_VGA);
DO_TEST("graphics-vnc-websocket", QEMU_CAPS_VNC, QEMU_CAPS_VNC_WEBSOCKET,
@@ -1198,9 +1202,14 @@ mymain(void)
driver.config->vncSASL = driver.config->vncTLSx509verify =
driver.config->vncTLS = 0;
VIR_FREE(driver.config->vncSASLdir);
VIR_FREE(driver.config->vncTLSx509certdir);
+ DO_TEST("graphics-vnc-egl-headless",
+ QEMU_CAPS_VNC,
+ QEMU_CAPS_EGL_HEADLESS,
+ QEMU_CAPS_DEVICE_CIRRUS_VGA);
DO_TEST("graphics-sdl",
QEMU_CAPS_DEVICE_VGA);
+ DO_TEST_PARSE_ERROR("graphics-sdl-egl-headless", NONE);
DO_TEST("graphics-sdl-fullscreen",
QEMU_CAPS_DEVICE_CIRRUS_VGA);
DO_TEST("graphics-spice",
@@ -1255,6 +1264,14 @@ mymain(void)
QEMU_CAPS_SPICE_UNIX,
QEMU_CAPS_DEVICE_CIRRUS_VGA);
driver.config->spiceAutoUnixSocket = false;
+ DO_TEST("graphics-spice-egl-headless",
+ QEMU_CAPS_SPICE,
+ QEMU_CAPS_EGL_HEADLESS,
+ QEMU_CAPS_DEVICE_QXL);
+ DO_TEST_PARSE_ERROR("graphics-spice-invalid-egl-headless",
+ QEMU_CAPS_SPICE,
+ QEMU_CAPS_EGL_HEADLESS,
+ QEMU_CAPS_DEVICE_QXL);
DO_TEST("input-usbmouse", NONE);
DO_TEST("input-usbtablet", NONE);
diff --git a/tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml
b/tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml
new file mode 100644
index 0000000000..6d96264914
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml
@@ -0,0 +1,44 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='spice' port='5903' autoport='no'
listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1'/>
+ </graphics>
+ <graphics type='egl-headless'/>
+ <video>
+ <model type='qxl' ram='65536' vram='32768'
vgamem='8192' heads='1' primary='yes'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml
b/tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml
new file mode 100644
index 0000000000..4155c10397
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml
@@ -0,0 +1,42 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='vnc' port='5903' autoport='no'
listen='2001:1:2:3:4:5:1234:1234'>
+ <listen type='address' address='2001:1:2:3:4:5:1234:1234'/>
+ </graphics>
+ <graphics type='egl-headless'/>
+ <video>
+ <model type='cirrus' vram='16384' heads='1'
primary='yes'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </video>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index bbb995656e..fa57221d62 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -417,6 +417,7 @@ mymain(void)
cfg->vncAutoUnixSocket = false;
DO_TEST("graphics-vnc-socket", NONE);
DO_TEST("graphics-vnc-auto-socket", NONE);
+ DO_TEST("graphics-vnc-egl-headless", NONE);
DO_TEST("graphics-sdl", NONE);
DO_TEST("graphics-sdl-fullscreen", NONE);
@@ -428,6 +429,7 @@ mymain(void)
cfg->spiceAutoUnixSocket = true;
DO_TEST("graphics-spice-auto-socket-cfg", NONE);
cfg->spiceAutoUnixSocket = false;
+ DO_TEST("graphics-spice-egl-headless", NONE);
DO_TEST("input-usbmouse", NONE);
DO_TEST("input-usbtablet", NONE);
--
2.14.4