Ver Fonte

spice-display: support ANGLE backend

Add support for creating a pbuffer surface and setup from SPICE.
osy há 4 anos atrás
pai
commit
dc386f9eb0
6 ficheiros alterados com 103 adições e 0 exclusões
  1. 12 0
      include/ui/egl-helpers.h
  2. 6 0
      include/ui/spice-display.h
  3. 1 0
      meson.build
  4. 48 0
      ui/egl-helpers.c
  5. 20 0
      ui/spice-core.c
  6. 16 0
      ui/spice-display.c

+ 12 - 0
include/ui/egl-helpers.h

@@ -6,6 +6,9 @@
 #ifdef CONFIG_GBM
 #ifdef CONFIG_GBM
 #include <gbm.h>
 #include <gbm.h>
 #endif
 #endif
+#ifdef CONFIG_ANGLE
+#include <EGL/eglext_angle.h>
+#endif
 #include "ui/console.h"
 #include "ui/console.h"
 #include "ui/shader.h"
 #include "ui/shader.h"
 
 
@@ -49,6 +52,9 @@ void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
 #endif
 #endif
 
 
 EGLSurface qemu_egl_init_surface(EGLContext ectx, EGLNativeWindowType win);
 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_cocoa(DisplayGLMode mode);
 int qemu_egl_init_dpy_surfaceless(DisplayGLMode mode);
 int qemu_egl_init_dpy_surfaceless(DisplayGLMode mode);
@@ -60,6 +66,12 @@ int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy, DisplayGLMode mode);
 
 
 #endif
 #endif
 
 
+#if defined(CONFIG_ANGLE)
+
+int qemu_egl_init_dpy_angle(DisplayGLMode mode);
+
+#endif
+
 EGLContext qemu_egl_init_ctx(void);
 EGLContext qemu_egl_init_ctx(void);
 bool qemu_egl_has_dmabuf(void);
 bool qemu_egl_has_dmabuf(void);
 
 

+ 6 - 0
include/ui/spice-display.h

@@ -129,6 +129,12 @@ struct SimpleSpiceDisplay {
 #if defined(CONFIG_GBM)
 #if defined(CONFIG_GBM)
     QemuDmaBuf *guest_dmabuf;
     QemuDmaBuf *guest_dmabuf;
     bool guest_dmabuf_refresh;
     bool guest_dmabuf_refresh;
+#endif
+#if defined(CONFIG_ANGLE)
+    EGLSurface esurface;
+    egl_fb iosurface_fb;
+    DisplayGLTextureBorrower backing_borrow;
+    uint32_t backing_id;
 #endif
 #endif
     bool render_cursor;
     bool render_cursor;
 
 

+ 1 - 0
meson.build

@@ -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_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_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('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
 # has_function
 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))

+ 48 - 0
ui/egl-helpers.c

@@ -313,6 +313,38 @@ EGLSurface qemu_egl_init_surface(EGLContext ectx, EGLNativeWindowType win)
     return esurface;
     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)
 static int qemu_egl_init_dpy(EGLDisplay dpy, DisplayGLMode mode)
@@ -493,6 +525,22 @@ int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy, DisplayGLMode mode)
 
 
 #endif
 #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)
 bool qemu_egl_has_dmabuf(void)
 {
 {
     if (qemu_egl_display == EGL_NO_DISPLAY) {
     if (qemu_egl_display == EGL_NO_DISPLAY) {

+ 20 - 0
ui/spice-core.c

@@ -52,6 +52,10 @@ static int spice_have_target_host;
 
 
 static QemuThread me;
 static QemuThread me;
 
 
+#ifdef CONFIG_ANGLE
+extern EGLContext spice_gl_ctx;
+#endif
+
 struct SpiceTimer {
 struct SpiceTimer {
     QEMUTimer *timer;
     QEMUTimer *timer;
 };
 };
@@ -845,11 +849,27 @@ static void qemu_spice_init(void)
                          "incompatible with -spice port/tls-port");
                          "incompatible with -spice port/tls-port");
             exit(1);
             exit(1);
         }
         }
+#if defined(CONFIG_GBM)
         if (egl_rendernode_init(qemu_opt_get(opts, "rendernode"),
         if (egl_rendernode_init(qemu_opt_get(opts, "rendernode"),
                                 DISPLAYGL_MODE_ON) != 0) {
                                 DISPLAYGL_MODE_ON) != 0) {
             error_report("Failed to initialize EGL render node for SPICE GL");
             error_report("Failed to initialize EGL render node for SPICE GL");
             exit(1);
             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;
         display_opengl = 1;
         spice_opengl = 1;
         spice_opengl = 1;
     }
     }

+ 16 - 0
ui/spice-display.c

@@ -29,6 +29,10 @@
 
 
 bool spice_opengl;
 bool spice_opengl;
 
 
+#ifdef CONFIG_ANGLE
+EGLContext spice_gl_ctx;
+#endif
+
 int qemu_spice_rect_is_empty(const QXLRect* r)
 int qemu_spice_rect_is_empty(const QXLRect* r)
 {
 {
     return r->top == r->bottom || r->left == r->right;
     return r->top == r->bottom || r->left == r->right;
@@ -920,6 +924,9 @@ static QEMUGLContext qemu_spice_gl_create_context(void *dg,
 #if defined(CONFIG_GBM)
 #if defined(CONFIG_GBM)
     eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
     eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                    qemu_egl_rn_ctx);
                    qemu_egl_rn_ctx);
+#elif defined(CONFIG_ANGLE)
+    eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                   spice_gl_ctx);
 #endif
 #endif
     return qemu_egl_create_context(dg, params);
     return qemu_egl_create_context(dg, params);
 }
 }
@@ -933,6 +940,10 @@ static void qemu_spice_gl_scanout_disable(void *dg)
     qemu_spice_gl_monitor_config(ssd, 0, 0, 0, 0);
     qemu_spice_gl_monitor_config(ssd, 0, 0, 0, 0);
     ssd->have_surface = false;
     ssd->have_surface = false;
     ssd->have_scanout = 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,
 static void qemu_spice_gl_scanout_texture(void *dg,
@@ -1160,6 +1171,11 @@ static void qemu_spice_display_init_one(QemuConsole *con)
         ssd->gls = qemu_gl_init_shader();
         ssd->gls = qemu_gl_init_shader();
         ssd->have_surface = false;
         ssd->have_surface = false;
         ssd->have_scanout = 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);
         console_set_displayglcontext(con, ssd);
         register_displayglops(&display_gl_ops);
         register_displayglops(&display_gl_ops);
     }
     }