Commit 79907e68 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kraxel/tags/pull-ui-20160928-1' into staging



ui: console+vnc fixes, switch spice to pure opengl with gl=on.

# gpg: Signature made Wed 28 Sep 2016 11:57:35 BST
# gpg:                using RSA key 0x4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/pull-ui-20160928-1:
  ui/vnc-enc-tight: remove switch and have single return
  spice/gl: render DisplaySurface via opengl
  console: track gl_block state in QemuConsole
  console: skip same-size resize

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 3c87fafb d9d2663c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+4 −1
Original line number Diff line number Diff line
@@ -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
};

+18 −4
Original line number Diff line number Diff line
@@ -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) {
@@ -2101,6 +2108,13 @@ void qemu_console_resize(QemuConsole *s, int width, int height)
    DisplaySurface *surface;

    assert(s->console_type == GRAPHIC_CONSOLE);

    if (s->surface &&
        pixman_image_get_width(s->surface->image) == width &&
        pixman_image_get_height(s->surface->image) == height) {
        return;
    }

    surface = qemu_create_displaysurface(width, height);
    dpy_gfx_replace_surface(s, surface);
}
+84 −8
Original line number Diff line number Diff line
@@ -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);
@@ -905,10 +979,10 @@ 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_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,

@@ -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;
+2 −4
Original line number Diff line number Diff line
@@ -707,11 +707,9 @@ check_solid_tile32(VncState *vs, int x, int y, int w, int h,
static bool check_solid_tile(VncState *vs, int x, int y, int w, int h,
                             uint32_t* color, bool samecolor)
{
    switch (VNC_SERVER_FB_BYTES) {
    case 4:
    QEMU_BUILD_BUG_ON(VNC_SERVER_FB_BYTES != 4);
    return check_solid_tile32(vs, x, y, w, h, color, samecolor);
}
}

static void find_best_solid_area(VncState *vs, int x, int y, int w, int h,
                                 uint32_t color, int *w_ptr, int *h_ptr)