All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] spice/gl: render DisplaySurface via opengl
@ 2016-09-23  7:50 Gerd Hoffmann
  2016-09-23  7:50 ` [Qemu-devel] [PATCH 1/2] console: track gl_block state in QemuConsole Gerd Hoffmann
  2016-09-23  7:50 ` [Qemu-devel] [PATCH 2/2] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
  0 siblings, 2 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2016-09-23  7:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Have been sitting on these patches for quite a while.  There used to be
problems with this due to bugs in spice.  Finally found the time to
re-test this properly with the latest spice-server and spice-gtk
versions.  Everything is working fine now, so it is time to get this
finally merged.

cheers,
  Gerd

Gerd Hoffmann (2):
  console: track gl_block state in QemuConsole
  spice/gl: render DisplaySurface via opengl

 include/ui/console.h       |  1 +
 include/ui/spice-display.h |  5 ++-
 ui/console.c               | 15 ++++++--
 ui/spice-display.c         | 92 ++++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 100 insertions(+), 13 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 1/2] console: track gl_block state in QemuConsole
  2016-09-23  7:50 [Qemu-devel] [PATCH 0/2] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
@ 2016-09-23  7:50 ` Gerd Hoffmann
  2016-09-23  7:50 ` [Qemu-devel] [PATCH 2/2] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
  1 sibling, 0 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2016-09-23  7:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Keep track of gl_block state (added in bba19b8 console: block rendering
until client is done) in QemuConsole and allow to query it.  This way
we can avoid state inconsistencies in case different code paths make use
of this.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/ui/console.h |  1 +
 ui/console.c         | 15 +++++++++++----
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index d9c13d2..e2589e2 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -387,6 +387,7 @@ QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
 bool qemu_console_is_visible(QemuConsole *con);
 bool qemu_console_is_graphic(QemuConsole *con);
 bool qemu_console_is_fixedsize(QemuConsole *con);
+bool qemu_console_is_gl_blocked(QemuConsole *con);
 char *qemu_console_get_label(QemuConsole *con);
 int qemu_console_get_index(QemuConsole *con);
 uint32_t qemu_console_get_head(QemuConsole *con);
diff --git a/ui/console.c b/ui/console.c
index 3940762..f077eb8 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -123,6 +123,7 @@ struct QemuConsole {
     DisplaySurface *surface;
     int dcls;
     DisplayChangeListener *gl;
+    bool gl_block;
 
     /* Graphic console state.  */
     Object *device;
@@ -264,10 +265,10 @@ void graphic_hw_update(QemuConsole *con)
 
 void graphic_hw_gl_block(QemuConsole *con, bool block)
 {
-    if (!con) {
-        con = active_console;
-    }
-    if (con && con->hw_ops->gl_block) {
+    assert(con != NULL);
+
+    con->gl_block = block;
+    if (con->hw_ops->gl_block) {
         con->hw_ops->gl_block(con->hw, block);
     }
 }
@@ -1879,6 +1880,12 @@ bool qemu_console_is_fixedsize(QemuConsole *con)
     return con && (con->console_type != TEXT_CONSOLE);
 }
 
+bool qemu_console_is_gl_blocked(QemuConsole *con)
+{
+    assert(con != NULL);
+    return con->gl_block;
+}
+
 char *qemu_console_get_label(QemuConsole *con)
 {
     if (con->console_type == GRAPHIC_CONSOLE) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 2/2] spice/gl: render DisplaySurface via opengl
  2016-09-23  7:50 [Qemu-devel] [PATCH 0/2] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
  2016-09-23  7:50 ` [Qemu-devel] [PATCH 1/2] console: track gl_block state in QemuConsole Gerd Hoffmann
@ 2016-09-23  7:50 ` Gerd Hoffmann
  2016-09-23  9:26   ` Marc-André Lureau
  1 sibling, 1 reply; 4+ messages in thread
From: Gerd Hoffmann @ 2016-09-23  7:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

This switches over spice (in opengl mode) to render DisplaySurface
updates into a opengl texture, using the helper functions in
ui/console-gl.c.  With this patch applied spice (with gl=on) will
stop using qxl rendering ops, it will use dma-buf passing all the
time, i.e. for bios/bootloader (before virtio-gpu driver is loaded)
too.

This should improve performance even using spice (with gl=on) with
non-accelerated stdvga because we stop squeezing all display updates
through a unix/tcp socket and basically using a shared memory transport
instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/spice-display.h |  5 ++-
 ui/spice-display.c         | 92 ++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index 42e0fdf..184d4c3 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -119,7 +119,10 @@ struct SimpleSpiceDisplay {
     /* opengl rendering */
     QEMUBH *gl_unblock_bh;
     QEMUTimer *gl_unblock_timer;
-    int dmabuf_fd;
+    ConsoleGLState *gls;
+    int gl_updates;
+    bool have_scanout;
+    bool have_surface;
 #endif
 };
 
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 99132b6..5e6f78a 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -850,6 +850,74 @@ static void qemu_spice_gl_block_timer(void *opaque)
     fprintf(stderr, "WARNING: spice: no gl-draw-done within one second\n");
 }
 
+static void spice_gl_refresh(DisplayChangeListener *dcl)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    uint64_t cookie;
+
+    if (!ssd->ds || qemu_console_is_gl_blocked(ssd->dcl.con)) {
+        return;
+    }
+
+    graphic_hw_update(dcl->con);
+    if (ssd->gl_updates && ssd->have_surface) {
+        qemu_spice_gl_block(ssd, true);
+        cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
+        spice_qxl_gl_draw_async(&ssd->qxl, 0, 0,
+                                surface_width(ssd->ds),
+                                surface_height(ssd->ds),
+                                cookie);
+        ssd->gl_updates = 0;
+    }
+}
+
+static void spice_gl_update(DisplayChangeListener *dcl,
+                            int x, int y, int w, int h)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+
+    surface_gl_update_texture(ssd->gls, ssd->ds, x, y, w, h);
+    ssd->gl_updates++;
+}
+
+static void spice_gl_switch(DisplayChangeListener *dcl,
+                            struct DisplaySurface *new_surface)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    EGLint stride, fourcc;
+    int fd;
+
+    if (ssd->ds) {
+        surface_gl_destroy_texture(ssd->gls, ssd->ds);
+    }
+    ssd->ds = new_surface;
+    if (ssd->ds) {
+        surface_gl_create_texture(ssd->gls, ssd->ds);
+        fd = egl_get_fd_for_texture(ssd->ds->texture,
+                                    &stride, &fourcc);
+        if (fd < 0) {
+            surface_gl_destroy_texture(ssd->gls, ssd->ds);
+            return;
+        }
+
+        dprint(1, "%s: %dx%d (stride %d/%d, fourcc 0x%x)\n", __func__,
+               surface_width(ssd->ds), surface_height(ssd->ds),
+               surface_stride(ssd->ds), stride, fourcc);
+
+        /* note: spice server will close the fd */
+        spice_qxl_gl_scanout(&ssd->qxl, fd,
+                             surface_width(ssd->ds),
+                             surface_height(ssd->ds),
+                             stride, fourcc, false);
+        ssd->have_surface = true;
+        ssd->have_scanout = false;
+
+        qemu_spice_gl_monitor_config(ssd, 0, 0,
+                                     surface_width(ssd->ds),
+                                     surface_height(ssd->ds));
+    }
+}
+
 static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
                                                   QEMUGLParams *params)
 {
@@ -887,6 +955,8 @@ static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
     /* note: spice server will close the fd */
     spice_qxl_gl_scanout(&ssd->qxl, fd, backing_width, backing_height,
                          stride, fourcc, y_0_top);
+    ssd->have_surface = false;
+    ssd->have_scanout = (tex_id != 0);
 
     qemu_spice_gl_monitor_config(ssd, x, y, w, h);
 }
@@ -897,6 +967,10 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
     SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
     uint64_t cookie;
 
+    if (!ssd->have_scanout) {
+        return;
+    }
+
     dprint(2, "%s: %dx%d+%d+%d\n", __func__, w, h, x, y);
     qemu_spice_gl_block(ssd, true);
     cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
@@ -904,13 +978,13 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
 }
 
 static const DisplayChangeListenerOps display_listener_gl_ops = {
-    .dpy_name             = "spice-egl",
-    .dpy_gfx_update       = display_update,
-    .dpy_gfx_switch       = display_switch,
-    .dpy_gfx_check_format = qemu_pixman_check_format,
-    .dpy_refresh          = display_refresh,
-    .dpy_mouse_set        = display_mouse_set,
-    .dpy_cursor_define    = display_mouse_define,
+    .dpy_name                = "spice-egl",
+    .dpy_gfx_update          = spice_gl_update,
+    .dpy_gfx_switch          = spice_gl_switch,
+    .dpy_gfx_check_format    = console_gl_check_format,
+    .dpy_refresh             = spice_gl_refresh,
+    .dpy_mouse_set           = display_mouse_set,
+    .dpy_cursor_define       = display_mouse_define,
 
     .dpy_gl_ctx_create       = qemu_spice_gl_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
@@ -933,10 +1007,12 @@ static void qemu_spice_display_init_one(QemuConsole *con)
 #ifdef HAVE_SPICE_GL
     if (display_opengl) {
         ssd->dcl.ops = &display_listener_gl_ops;
-        ssd->dmabuf_fd = -1;
         ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
         ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
                                              qemu_spice_gl_block_timer, ssd);
+        ssd->gls = console_gl_init_context();
+        ssd->have_surface = false;
+        ssd->have_scanout = false;
     }
 #endif
     ssd->dcl.con = con;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] spice/gl: render DisplaySurface via opengl
  2016-09-23  7:50 ` [Qemu-devel] [PATCH 2/2] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
@ 2016-09-23  9:26   ` Marc-André Lureau
  0 siblings, 0 replies; 4+ messages in thread
From: Marc-André Lureau @ 2016-09-23  9:26 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

Hi

On Fri, Sep 23, 2016 at 1:09 PM Gerd Hoffmann <kraxel@redhat.com> wrote:

> This switches over spice (in opengl mode) to render DisplaySurface
> updates into a opengl texture, using the helper functions in
> ui/console-gl.c.  With this patch applied spice (with gl=on) will
> stop using qxl rendering ops, it will use dma-buf passing all the
> time, i.e. for bios/bootloader (before virtio-gpu driver is loaded)
> too.
>
> This should improve performance even using spice (with gl=on) with
> non-accelerated stdvga because we stop squeezing all display updates
> through a unix/tcp socket and basically using a shared memory transport
> instead.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>

I have been using it for a while too,

 Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

---
>  include/ui/spice-display.h |  5 ++-
>  ui/spice-display.c         | 92
> ++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 88 insertions(+), 9 deletions(-)
>
> diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
> index 42e0fdf..184d4c3 100644
> --- a/include/ui/spice-display.h
> +++ b/include/ui/spice-display.h
> @@ -119,7 +119,10 @@ struct SimpleSpiceDisplay {
>      /* opengl rendering */
>      QEMUBH *gl_unblock_bh;
>      QEMUTimer *gl_unblock_timer;
> -    int dmabuf_fd;
> +    ConsoleGLState *gls;
> +    int gl_updates;
> +    bool have_scanout;
> +    bool have_surface;
>  #endif
>  };
>
> diff --git a/ui/spice-display.c b/ui/spice-display.c
> index 99132b6..5e6f78a 100644
> --- a/ui/spice-display.c
> +++ b/ui/spice-display.c
> @@ -850,6 +850,74 @@ static void qemu_spice_gl_block_timer(void *opaque)
>      fprintf(stderr, "WARNING: spice: no gl-draw-done within one
> second\n");
>  }
>
> +static void spice_gl_refresh(DisplayChangeListener *dcl)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +    uint64_t cookie;
> +
> +    if (!ssd->ds || qemu_console_is_gl_blocked(ssd->dcl.con)) {
> +        return;
> +    }
> +
> +    graphic_hw_update(dcl->con);
> +    if (ssd->gl_updates && ssd->have_surface) {
> +        qemu_spice_gl_block(ssd, true);
> +        cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE,
> 0);
> +        spice_qxl_gl_draw_async(&ssd->qxl, 0, 0,
> +                                surface_width(ssd->ds),
> +                                surface_height(ssd->ds),
> +                                cookie);
> +        ssd->gl_updates = 0;
> +    }
> +}
> +
> +static void spice_gl_update(DisplayChangeListener *dcl,
> +                            int x, int y, int w, int h)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +
> +    surface_gl_update_texture(ssd->gls, ssd->ds, x, y, w, h);
> +    ssd->gl_updates++;
> +}
> +
> +static void spice_gl_switch(DisplayChangeListener *dcl,
> +                            struct DisplaySurface *new_surface)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +    EGLint stride, fourcc;
> +    int fd;
> +
> +    if (ssd->ds) {
> +        surface_gl_destroy_texture(ssd->gls, ssd->ds);
> +    }
> +    ssd->ds = new_surface;
> +    if (ssd->ds) {
> +        surface_gl_create_texture(ssd->gls, ssd->ds);
> +        fd = egl_get_fd_for_texture(ssd->ds->texture,
> +                                    &stride, &fourcc);
> +        if (fd < 0) {
> +            surface_gl_destroy_texture(ssd->gls, ssd->ds);
> +            return;
> +        }
> +
> +        dprint(1, "%s: %dx%d (stride %d/%d, fourcc 0x%x)\n", __func__,
> +               surface_width(ssd->ds), surface_height(ssd->ds),
> +               surface_stride(ssd->ds), stride, fourcc);
> +
> +        /* note: spice server will close the fd */
> +        spice_qxl_gl_scanout(&ssd->qxl, fd,
> +                             surface_width(ssd->ds),
> +                             surface_height(ssd->ds),
> +                             stride, fourcc, false);
> +        ssd->have_surface = true;
> +        ssd->have_scanout = false;
> +
> +        qemu_spice_gl_monitor_config(ssd, 0, 0,
> +                                     surface_width(ssd->ds),
> +                                     surface_height(ssd->ds));
> +    }
> +}
> +
>  static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener
> *dcl,
>                                                    QEMUGLParams *params)
>  {
> @@ -887,6 +955,8 @@ static void
> qemu_spice_gl_scanout(DisplayChangeListener *dcl,
>      /* note: spice server will close the fd */
>      spice_qxl_gl_scanout(&ssd->qxl, fd, backing_width, backing_height,
>                           stride, fourcc, y_0_top);
> +    ssd->have_surface = false;
> +    ssd->have_scanout = (tex_id != 0);
>
>      qemu_spice_gl_monitor_config(ssd, x, y, w, h);
>  }
> @@ -897,6 +967,10 @@ static void
> qemu_spice_gl_update(DisplayChangeListener *dcl,
>      SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
>      uint64_t cookie;
>
> +    if (!ssd->have_scanout) {
> +        return;
> +    }
> +
>      dprint(2, "%s: %dx%d+%d+%d\n", __func__, w, h, x, y);
>      qemu_spice_gl_block(ssd, true);
>      cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
> @@ -904,13 +978,13 @@ static void
> qemu_spice_gl_update(DisplayChangeListener *dcl,
>  }
>
>  static const DisplayChangeListenerOps display_listener_gl_ops = {
> -    .dpy_name             = "spice-egl",
> -    .dpy_gfx_update       = display_update,
> -    .dpy_gfx_switch       = display_switch,
> -    .dpy_gfx_check_format = qemu_pixman_check_format,
> -    .dpy_refresh          = display_refresh,
> -    .dpy_mouse_set        = display_mouse_set,
> -    .dpy_cursor_define    = display_mouse_define,
> +    .dpy_name                = "spice-egl",
> +    .dpy_gfx_update          = spice_gl_update,
> +    .dpy_gfx_switch          = spice_gl_switch,
> +    .dpy_gfx_check_format    = console_gl_check_format,
> +    .dpy_refresh             = spice_gl_refresh,
> +    .dpy_mouse_set           = display_mouse_set,
> +    .dpy_cursor_define       = display_mouse_define,
>
>      .dpy_gl_ctx_create       = qemu_spice_gl_create_context,
>      .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
> @@ -933,10 +1007,12 @@ static void qemu_spice_display_init_one(QemuConsole
> *con)
>  #ifdef HAVE_SPICE_GL
>      if (display_opengl) {
>          ssd->dcl.ops = &display_listener_gl_ops;
> -        ssd->dmabuf_fd = -1;
>          ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
>          ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
>                                               qemu_spice_gl_block_timer,
> ssd);
> +        ssd->gls = console_gl_init_context();
> +        ssd->have_surface = false;
> +        ssd->have_scanout = false;
>      }
>  #endif
>      ssd->dcl.con = con;
> --
> 1.8.3.1
>
>
> --
Marc-André Lureau

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-09-23  9:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-23  7:50 [Qemu-devel] [PATCH 0/2] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
2016-09-23  7:50 ` [Qemu-devel] [PATCH 1/2] console: track gl_block state in QemuConsole Gerd Hoffmann
2016-09-23  7:50 ` [Qemu-devel] [PATCH 2/2] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
2016-09-23  9:26   ` Marc-André Lureau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.