From nobody Mon Feb 9 00:38:49 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1531917174593794.3494482903807; Wed, 18 Jul 2018 05:32:54 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2776A81DE6; Wed, 18 Jul 2018 12:32:52 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D20DA60C4E; Wed, 18 Jul 2018 12:32:51 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 7A18C14B09; Wed, 18 Jul 2018 12:32:51 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w6ICVsCT005342 for ; Wed, 18 Jul 2018 08:31:54 -0400 Received: by smtp.corp.redhat.com (Postfix) id 683B72027047; Wed, 18 Jul 2018 12:31:54 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id BFE662026D69; Wed, 18 Jul 2018 12:31:53 +0000 (UTC) From: Erik Skultety To: libvir-list@redhat.com Date: Wed, 18 Jul 2018 14:31:40 +0200 Message-Id: <320803fccf120df4136ba6d6d95a058ab2911c95.1531916860.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v4 04/10] qemu: Introduce a new graphics display type 'headless' X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 18 Jul 2018 12:32:53 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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=3Dsocket/none) Signed-off-by: Erik Skultety Reviewed-by: J=EF=BF=BDn Tomko --- 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 | 14 ++++- src/qemu/qemu_domain.c | 60 ++++++++++++++++++= +++- 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, 488 insertions(+), 5 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-headl= ess.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 d08ede9ab5..091888c879 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6321,7 +6321,8 @@ qemu-kvm -net nic,model=3D? /dev/null

The graphics element has a mandatory type attribute which takes the value sdl, vnc, - spice, rdp or desktop: + spice, rdp, desktop or + egl-headless:

sdl
@@ -6380,6 +6381,11 @@ qemu-kvm -net nic,model=3D? /dev/null auto-allocation and autoport having no effect d= ue to security reasons) Since 1.0.6.

+

+ Although VNC doesn't support OpenGL natively, it can be pair= ed + with graphics type egl-headless (see below) whi= ch + will instruct QEMU to open and use drm nodes for OpenGL rend= ering. +

spice Since 0.8.6<= /dt>
@@ -6485,6 +6491,12 @@ qemu-kvm -net nic,model=3D? /dev/null You can enable or disable OpenGL support explicitly with the gl element, by setting the enable property. (QEMU only, since 1.3.3). + Note that this only works locally, since this requires usage= of + UNIX sockets, i.e. using listen types 'socket' = or + 'none'. For accelerated OpenGL with remote support, consider + pairing this element with type egl-headless + (see below). However, this will deliver weaker performance + compared to native Spice OpenGL support.

By default, QEMU will pick the first available GPU DRM rende= r node. @@ -6520,6 +6532,25 @@ qemu-kvm -net nic,model=3D? /dev/null fullscreen.

+
egl-headlessSince 4.6.0
+
+

+ 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 th= is + display type doesn't provide any window or graphical console= like + the other types, for practical reasons it should be paired w= ith + either vnc or spice graphics types. + This display type is only supported by QEMU domains + (needs QEMU 2.10 or newer) and = doesn't + accept any attributes. +

+
+<graphics type=3D'spice' autoport=3D'yes'/>
+<graphics type=3D'egl-headless'/>
+            
+
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index f24a56392a..157726752c 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3366,6 +3366,9 @@ + + egl-headless + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7396616eda..89c6556026 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -615,7 +615,8 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TY= PE_LAST, "vnc", "rdp", "desktop", - "spice") + "spice", + "egl-headless") =20 VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAS= T, "none", @@ -1426,6 +1427,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr= def) virDomainGraphicsAuthDefClear(&def->data.spice.auth); break; =20 + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } @@ -14162,6 +14164,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; } @@ -26394,6 +26397,7 @@ virDomainGraphicsDefFormat(virBufferPtr buf, virDomainGraphicsAuthDefFormatAttr(buf, &def->data.spice.auth, fla= gs); break; =20 + 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 0f10e242fd..26f75b15d0 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, =20 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 c628ac3985..7c44045d61 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8216,6 +8216,7 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfig= Ptr cfg, return -1; } =20 + static int qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, virCommandPtr cmd, @@ -8245,6 +8246,11 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr = cfg, qemuCaps, graphics) < 0) return -1; =20 + break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: + virCommandAddArg(cmd, "-display"); + virCommandAddArg(cmd, "egl-headless"); + break; case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: @@ -10072,6 +10078,7 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr drive= r, int sdl =3D 0; int vnc =3D 0; int spice =3D 0; + int egl_headless =3D 0; =20 if (!virQEMUDriverIsPrivileged(driver)) { /* If we have no cgroups then we can have no tunings that @@ -10113,6 +10120,9 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr drive= r, 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: @@ -10120,10 +10130,10 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr dri= ver, } } =20 - 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; } =20 diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ed76495309..ce252b47eb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5528,6 +5528,60 @@ qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm, } =20 =20 +static int +qemuDomainDeviceDefValidateGraphics(const virDomainGraphicsDef *graphics, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + bool have_egl_headless =3D false; + size_t i; + + for (i =3D 0; i < def->ngraphics; i++) { + graphics =3D def->graphics[i]; + + if (graphics->type =3D=3D VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS) { + have_egl_headless =3D 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) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_EGL_HEADLESS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("egl-headless display is not supported with t= his " + "QEMU binary")); + return -1; + } + + if (graphics->type !=3D VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS && + graphics->type !=3D VIR_DOMAIN_GRAPHICS_TYPE_VNC && + graphics->type !=3D VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("graphics type 'egl-headless' is only support= ed " + "with one of: 'vnc', 'spice' graphics types")= ); + return -1; + } + + /* '-spice gl=3Don' and '-display egl-headless' are mutually + * exclusive + */ + if (graphics->type =3D=3D VIR_DOMAIN_GRAPHICS_TYPE_SPICE && + graphics->data.spice.gl =3D=3D VIR_TRISTATE_BOOL_YES) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("multiple OpenGL displays are not supported " + "by QEMU")); + return -1; + } + } + + return 0; +} + + static int qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def, @@ -5595,11 +5649,15 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDe= f *dev, ret =3D qemuDomainDeviceDefValidateTPM(dev->data.tpm, def); break; =20 + case VIR_DOMAIN_DEVICE_GRAPHICS: + ret =3D qemuDomainDeviceDefValidateGraphics(dev->data.graphics, de= f, + qemuCaps); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: - case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_HUB: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 847dab2edc..cc25c8ef54 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18104,6 +18104,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, no= t %s"), virDomainGraphicsTypeToString(vm->def->graphics[idx= ]->type)); @@ -18172,6 +18173,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, no= t %s"), virDomainGraphicsTypeToString(vm->def->graphics[idx= ]->type)); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 2b6633a998..978dd8af72 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3702,6 +3702,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 c903a8e5c8..a4b1f97df5 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4467,6 +4467,7 @@ qemuProcessGraphicsReservePorts(virDomainGraphicsDefP= tr 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; } @@ -4505,6 +4506,7 @@ qemuProcessGraphicsAllocatePorts(virQEMUDriverPtr dri= ver, 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; } @@ -4657,6 +4659,7 @@ qemuProcessGraphicsSetupListen(virQEMUDriverPtr drive= r, 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; } @@ -4944,6 +4947,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, virDomainXMLOp= tionPtr 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/domaincapsschemada= ta/full.xml index d3faf38da0..154c4a6fe9 100644 --- a/tests/domaincapsschemadata/full.xml +++ b/tests/domaincapsschemadata/full.xml @@ -59,6 +59,7 @@ rdp desktop spice + egl-headless