Skip to content

Commit

Permalink
spice-display: support ANGLE backend
Browse files Browse the repository at this point in the history
Add support for creating a pbuffer surface and setup from SPICE.
  • Loading branch information
osy committed Aug 2, 2021
1 parent 1adb9ff commit dc386f9
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/ui/egl-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#ifdef CONFIG_GBM
#include <gbm.h>
#endif
#ifdef CONFIG_ANGLE
#include <EGL/eglext_angle.h>
#endif
#include "ui/console.h"
#include "ui/shader.h"

Expand Down Expand Up @@ -49,6 +52,9 @@ void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
#endif

EGLSurface qemu_egl_init_surface(EGLContext ectx, EGLNativeWindowType win);
EGLSurface qemu_egl_init_buffer_surface(EGLContext ectx, EGLenum buftype,
EGLClientBuffer buffer, const EGLint *attrib_list);
bool qemu_egl_destroy_surface(EGLSurface surface);

int qemu_egl_init_dpy_cocoa(DisplayGLMode mode);
int qemu_egl_init_dpy_surfaceless(DisplayGLMode mode);
Expand All @@ -60,6 +66,12 @@ int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy, DisplayGLMode mode);

#endif

#if defined(CONFIG_ANGLE)

int qemu_egl_init_dpy_angle(DisplayGLMode mode);

#endif

EGLContext qemu_egl_init_ctx(void);
bool qemu_egl_has_dmabuf(void);

Expand Down
6 changes: 6 additions & 0 deletions include/ui/spice-display.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ struct SimpleSpiceDisplay {
#if defined(CONFIG_GBM)
QemuDmaBuf *guest_dmabuf;
bool guest_dmabuf_refresh;
#endif
#if defined(CONFIG_ANGLE)
EGLSurface esurface;
egl_fb iosurface_fb;
DisplayGLTextureBorrower backing_borrow;
uint32_t backing_id;
#endif
bool render_cursor;

Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,7 @@ config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
config_host_data.set('CONFIG_ANGLE', cc.has_header('EGL/eglext_angle.h'))

# has_function
config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
Expand Down
48 changes: 48 additions & 0 deletions ui/egl-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,38 @@ EGLSurface qemu_egl_init_surface(EGLContext ectx, EGLNativeWindowType win)
return esurface;
}

EGLSurface qemu_egl_init_buffer_surface(EGLContext ectx,
EGLenum buftype,
EGLClientBuffer buffer,
const EGLint *attrib_list)
{
EGLSurface esurface;
EGLBoolean b;

esurface = eglCreatePbufferFromClientBuffer(qemu_egl_display,
buftype,
buffer,
qemu_egl_config,
attrib_list);
if (esurface == EGL_NO_SURFACE) {
error_report("egl: eglCreatePbufferFromClientBuffer failed");
return NULL;
}

b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
if (b == EGL_FALSE) {
error_report("egl: eglMakeCurrent failed");
return NULL;
}

return esurface;
}

bool qemu_egl_destroy_surface(EGLSurface surface)
{
return eglDestroySurface(qemu_egl_display, surface);
}

/* ---------------------------------------------------------------------- */

static int qemu_egl_init_dpy(EGLDisplay dpy, DisplayGLMode mode)
Expand Down Expand Up @@ -493,6 +525,22 @@ int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy, DisplayGLMode mode)

#endif

#if defined(CONFIG_ANGLE)

int qemu_egl_init_dpy_angle(DisplayGLMode mode)
{
int result;

result = qemu_egl_init_dpy_platform(NULL, EGL_PLATFORM_ANGLE_ANGLE, mode);
if (!result) {
result = qemu_egl_config_dpy();
}

return result;
}

#endif

bool qemu_egl_has_dmabuf(void)
{
if (qemu_egl_display == EGL_NO_DISPLAY) {
Expand Down
20 changes: 20 additions & 0 deletions ui/spice-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ static int spice_have_target_host;

static QemuThread me;

#ifdef CONFIG_ANGLE
extern EGLContext spice_gl_ctx;
#endif

struct SpiceTimer {
QEMUTimer *timer;
};
Expand Down Expand Up @@ -845,11 +849,27 @@ static void qemu_spice_init(void)
"incompatible with -spice port/tls-port");
exit(1);
}
#if defined(CONFIG_GBM)
if (egl_rendernode_init(qemu_opt_get(opts, "rendernode"),
DISPLAYGL_MODE_ON) != 0) {
error_report("Failed to initialize EGL render node for SPICE GL");
exit(1);
}
#elif defined(CONFIG_ANGLE)
if (qemu_egl_init_dpy_angle(DISPLAYGL_MODE_ES)) {
error_report("SPICE GL failed to initialize ANGLE display");
exit(1);
}

spice_gl_ctx = qemu_egl_init_ctx();
if (!spice_gl_ctx) {
error_report("egl: egl_init_ctx failed");
exit(1);
}
#else
error_report("No backend to support SPICE GL");
exit(1);
#endif
display_opengl = 1;
spice_opengl = 1;
}
Expand Down
16 changes: 16 additions & 0 deletions ui/spice-display.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@

bool spice_opengl;

#ifdef CONFIG_ANGLE
EGLContext spice_gl_ctx;
#endif

int qemu_spice_rect_is_empty(const QXLRect* r)
{
return r->top == r->bottom || r->left == r->right;
Expand Down Expand Up @@ -920,6 +924,9 @@ static QEMUGLContext qemu_spice_gl_create_context(void *dg,
#if defined(CONFIG_GBM)
eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
qemu_egl_rn_ctx);
#elif defined(CONFIG_ANGLE)
eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
spice_gl_ctx);
#endif
return qemu_egl_create_context(dg, params);
}
Expand All @@ -933,6 +940,10 @@ static void qemu_spice_gl_scanout_disable(void *dg)
qemu_spice_gl_monitor_config(ssd, 0, 0, 0, 0);
ssd->have_surface = false;
ssd->have_scanout = false;
#if defined(CONFIG_ANGLE)
ssd->backing_borrow = NULL;
ssd->backing_id = -1;
#endif
}

static void qemu_spice_gl_scanout_texture(void *dg,
Expand Down Expand Up @@ -1160,6 +1171,11 @@ static void qemu_spice_display_init_one(QemuConsole *con)
ssd->gls = qemu_gl_init_shader();
ssd->have_surface = false;
ssd->have_scanout = false;
#if defined(CONFIG_ANGLE)
ssd->esurface = EGL_NO_SURFACE;
ssd->backing_borrow = NULL;
ssd->backing_id = -1;
#endif
console_set_displayglcontext(con, ssd);
register_displayglops(&display_gl_ops);
}
Expand Down

0 comments on commit dc386f9

Please sign in to comment.