qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 3/3] spice: add cursor_dmabuf support


From: Marc-André Lureau
Subject: Re: [Qemu-devel] [PATCH v2 3/3] spice: add cursor_dmabuf support
Date: Tue, 6 Mar 2018 12:56:55 +0100

Hi

On Tue, Mar 6, 2018 at 9:38 AM, Gerd Hoffmann <address@hidden> wrote:
> Add support for cursor dmabufs.  qemu has to render the cursor for
> that, so in case a cursor is present qemu allocates a new dmabuf, blits
> the scanout, blends in the pointer and passes on the new dmabuf to
> spice-server.  Without cursor qemu continues to simply pass on the
> scanout dmabuf as-is.
>
> Signed-off-by: Gerd Hoffmann <address@hidden>

What about client side rendering mode? (for responsiveness etc)

Why not read the cursor data and pass it as regular cursor update? I
don't think such a small and infrequent CPU read will impact
performance much. Perhaps less than drawing the cursor ourself in qemu
on each frame (rather than using the client side
rendering/composition, it's hard to tell I guess).

> ---
>  include/ui/spice-display.h |   9 ++++
>  ui/spice-display.c         | 114 
> +++++++++++++++++++++++++++++++++++++++++++--
>  ui/trace-events            |   3 ++
>  3 files changed, 121 insertions(+), 5 deletions(-)
>
> diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
> index 6b5c73b21c..87a84a59d4 100644
> --- a/include/ui/spice-display.h
> +++ b/include/ui/spice-display.h
> @@ -122,6 +122,15 @@ struct SimpleSpiceDisplay {
>      int gl_updates;
>      bool have_scanout;
>      bool have_surface;
> +
> +    QemuDmaBuf *guest_dmabuf;
> +    bool guest_dmabuf_refresh;
> +    bool render_cursor;
> +
> +    egl_fb guest_fb;
> +    egl_fb blit_fb;
> +    egl_fb cursor_fb;
> +    bool have_hot;
>  #endif
>  };
>
> diff --git a/ui/spice-display.c b/ui/spice-display.c
> index a494db1196..61edc9d1ea 100644
> --- a/ui/spice-display.c
> +++ b/ui/spice-display.c
> @@ -941,25 +941,126 @@ static void 
> qemu_spice_gl_scanout_dmabuf(DisplayChangeListener *dcl,
>  {
>      SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
>
> -    /* note: spice server will close the fd, so hand over a dup */
> -    spice_qxl_gl_scanout(&ssd->qxl, dup(dmabuf->fd),
> -                         dmabuf->width, dmabuf->height,
> -                         dmabuf->stride, dmabuf->fourcc, false);
> -    qemu_spice_gl_monitor_config(ssd, 0, 0, dmabuf->width, dmabuf->height);
> +    ssd->guest_dmabuf = dmabuf;
> +    ssd->guest_dmabuf_refresh = true;
> +
>      ssd->have_surface = false;
>      ssd->have_scanout = true;
>  }
>
> +static void qemu_spice_gl_cursor_dmabuf(DisplayChangeListener *dcl,
> +                                        QemuDmaBuf *dmabuf, bool have_hot,
> +                                        uint32_t hot_x, uint32_t hot_y)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +
> +    ssd->have_hot = have_hot;
> +    ssd->hot_x = hot_x;
> +    ssd->hot_y = hot_y;
> +
> +    trace_qemu_spice_gl_cursor(ssd->qxl.id, dmabuf != NULL, have_hot);
> +    if (dmabuf) {
> +        egl_dmabuf_import_texture(dmabuf);
> +        if (!dmabuf->texture) {
> +            return;
> +        }
> +        egl_fb_setup_for_tex(&ssd->cursor_fb, dmabuf->width, dmabuf->height,
> +                             dmabuf->texture, false);
> +    } else {
> +        egl_fb_destroy(&ssd->cursor_fb);
> +    }
> +}
> +
> +static void qemu_spice_gl_cursor_position(DisplayChangeListener *dcl,
> +                                          uint32_t pos_x, uint32_t pos_y)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +
> +    ssd->ptr_x = pos_x;
> +    ssd->ptr_y = pos_y;
> +}
> +
> +static void qemu_spice_gl_release_dmabuf(DisplayChangeListener *dcl,
> +                                         QemuDmaBuf *dmabuf)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +
> +    if (ssd->guest_dmabuf == dmabuf) {
> +        ssd->guest_dmabuf = NULL;
> +        ssd->guest_dmabuf_refresh = false;
> +    }
> +    egl_dmabuf_release_texture(dmabuf);
> +}
> +
>  static void qemu_spice_gl_update(DisplayChangeListener *dcl,
>                                   uint32_t x, uint32_t y, uint32_t w, 
> uint32_t h)
>  {
>      SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +    EGLint stride = 0, fourcc = 0;
> +    bool render_cursor = false;
> +    bool y_0_top = false; /* FIXME */
>      uint64_t cookie;
> +    int fd;
>
>      if (!ssd->have_scanout) {
>          return;
>      }
>
> +    if (ssd->cursor_fb.texture) {
> +        render_cursor = true;
> +    }
> +    if (ssd->render_cursor != render_cursor) {
> +        ssd->render_cursor = render_cursor;
> +        ssd->guest_dmabuf_refresh = true;
> +        egl_fb_destroy(&ssd->blit_fb);
> +    }
> +
> +    if (ssd->guest_dmabuf_refresh) {
> +        QemuDmaBuf *dmabuf = ssd->guest_dmabuf;
> +        if (render_cursor) {
> +            egl_dmabuf_import_texture(dmabuf);
> +            if (!dmabuf->texture) {
> +                return;
> +            }
> +
> +            /* source framebuffer */
> +            egl_fb_setup_for_tex(&ssd->guest_fb,
> +                                 dmabuf->width, dmabuf->height,
> +                                 dmabuf->texture, false);
> +
> +            /* dest framebuffer */
> +            if (ssd->blit_fb.width  != dmabuf->width ||
> +                ssd->blit_fb.height != dmabuf->height) {
> +                trace_qemu_spice_gl_render_dmabuf(ssd->qxl.id, dmabuf->width,
> +                                                  dmabuf->height);
> +                egl_fb_destroy(&ssd->blit_fb);
> +                egl_fb_setup_new_tex(&ssd->blit_fb,
> +                                     dmabuf->width, dmabuf->height);
> +                fd = egl_get_fd_for_texture(ssd->blit_fb.texture,
> +                                            &stride, &fourcc);
> +                spice_qxl_gl_scanout(&ssd->qxl, fd,
> +                                     dmabuf->width, dmabuf->height,
> +                                     stride, fourcc, false);
> +            }
> +        } else {
> +            trace_qemu_spice_gl_forward_dmabuf(ssd->qxl.id,
> +                                               dmabuf->width, 
> dmabuf->height);
> +            /* note: spice server will close the fd, so hand over a dup */
> +            spice_qxl_gl_scanout(&ssd->qxl, dup(dmabuf->fd),
> +                                 dmabuf->width, dmabuf->height,
> +                                 dmabuf->stride, dmabuf->fourcc, false);
> +        }
> +        qemu_spice_gl_monitor_config(ssd, 0, 0, dmabuf->width, 
> dmabuf->height);
> +        ssd->guest_dmabuf_refresh = false;
> +    }
> +
> +    if (render_cursor) {
> +        egl_texture_blit(ssd->gls, &ssd->blit_fb, &ssd->guest_fb,
> +                         !y_0_top);
> +        egl_texture_blend(ssd->gls, &ssd->blit_fb, &ssd->cursor_fb,
> +                          !y_0_top, ssd->ptr_x, ssd->ptr_y);
> +        glFlush();
> +    }
>
>      trace_qemu_spice_gl_update(ssd->qxl.id, w, h, x, y);
>      qemu_spice_gl_block(ssd, true);
> @@ -984,6 +1085,9 @@ static const DisplayChangeListenerOps 
> display_listener_gl_ops = {
>      .dpy_gl_scanout_disable  = qemu_spice_gl_scanout_disable,
>      .dpy_gl_scanout_texture  = qemu_spice_gl_scanout_texture,
>      .dpy_gl_scanout_dmabuf   = qemu_spice_gl_scanout_dmabuf,
> +    .dpy_gl_cursor_dmabuf    = qemu_spice_gl_cursor_dmabuf,
> +    .dpy_gl_cursor_position  = qemu_spice_gl_cursor_position,
> +    .dpy_gl_release_dmabuf   = qemu_spice_gl_release_dmabuf,
>      .dpy_gl_update           = qemu_spice_gl_update,
>  };
>
> diff --git a/ui/trace-events b/ui/trace-events
> index 518e950a01..a957f363f1 100644
> --- a/ui/trace-events
> +++ b/ui/trace-events
> @@ -83,6 +83,9 @@ qemu_spice_ui_info(int qid, uint32_t width, uint32_t 
> height) "%d %dx%d"
>  qemu_spice_gl_surface(int qid, uint32_t w, uint32_t h, uint32_t fourcc) "%d 
> %dx%d, fourcc 0x%x"
>  qemu_spice_gl_scanout_disable(int qid) "%d"
>  qemu_spice_gl_scanout_texture(int qid, uint32_t w, uint32_t h, uint32_t 
> fourcc) "%d %dx%d, fourcc 0x%x"
> +qemu_spice_gl_cursor(int qid, bool enabled, bool hotspot) "%d enabled %d, 
> hotspot %d"
> +qemu_spice_gl_forward_dmabuf(int qid, uint32_t width, uint32_t height) "%d 
> %dx%d"
> +qemu_spice_gl_render_dmabuf(int qid, uint32_t width, uint32_t height) "%d 
> %dx%d"
>  qemu_spice_gl_update(int qid, uint32_t x, uint32_t y, uint32_t w, uint32_t 
> h) "%d +%d+%d %dx%d"
>
>  # ui/keymaps.c
> --
> 2.9.3
>
>



-- 
Marc-André Lureau



reply via email to

[Prev in Thread] Current Thread [Next in Thread]