Commit bcf9e2c0 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kraxel/tags/vga-20170913-pull-request' into staging



vga: bugfixes.
qxl: chunked cursor support.

# gpg: Signature made Wed 13 Sep 2017 08:41:08 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/vga-20170913-pull-request:
  virtio-gpu: don't clear QemuUIInfo information on reset
  vga/migration: Update memory map in post_load
  qxl: add support for chunked cursors.
  qxl: drop mono cursor support
  vga: stop passing pointers to vga_draw_line* functions
  vga: fix display update region calculation (split screen)

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 04ef3305 79d16c21
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -204,10 +204,35 @@ void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
    g_free(cookie);
}

static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
                              QXLDataChunk *chunk, uint32_t group_id)
{
    uint32_t max_chunks = 32;
    size_t offset = 0;
    size_t bytes;

    for (;;) {
        bytes = MIN(size - offset, chunk->data_size);
        memcpy(dest + offset, chunk->data, bytes);
        offset += bytes;
        if (offset == size) {
            return;
        }
        chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id);
        if (!chunk) {
            return;
        }
        max_chunks--;
        if (max_chunks == 0) {
            return;
        }
    }
}

static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor,
                              uint32_t group_id)
{
    QEMUCursor *c;
    uint8_t *image, *mask;
    size_t size;

    c = cursor_alloc(cursor->header.width, cursor->header.height);
@@ -216,19 +241,11 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
    switch (cursor->header.type) {
    case SPICE_CURSOR_TYPE_ALPHA:
        size = sizeof(uint32_t) * cursor->header.width * cursor->header.height;
        memcpy(c->data, cursor->chunk.data, size);
        qxl_unpack_chunks(c->data, size, qxl, &cursor->chunk, group_id);
        if (qxl->debug > 2) {
            cursor_print_ascii_art(c, "qxl/alpha");
        }
        break;
    case SPICE_CURSOR_TYPE_MONO:
        mask  = cursor->chunk.data;
        image = mask + cursor_get_mono_bpl(c) * c->width;
        cursor_set_mono(c, 0xffffff, 0x000000, image, 1, mask);
        if (qxl->debug > 2) {
            cursor_print_ascii_art(c, "qxl/mono");
        }
        break;
    default:
        fprintf(stderr, "%s: not implemented: type %d\n",
                __FUNCTION__, cursor->header.type);
@@ -268,11 +285,7 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
        if (!cursor) {
            return 1;
        }
        if (cursor->chunk.data_size != cursor->data_size) {
            fprintf(stderr, "%s: multiple chunks\n", __FUNCTION__);
            return 1;
        }
        c = qxl_cursor(qxl, cursor);
        c = qxl_cursor(qxl, cursor, ext->group_id);
        if (c == NULL) {
            c = cursor_builtin_left_ptr();
        }
+110 −92
Original line number Diff line number Diff line
@@ -95,20 +95,46 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
    } while (--h);
}

static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr)
{
    return vga->vram_ptr[addr & vga->vbe_size_mask];
}

static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr)
{
    uint32_t offset = addr & vga->vbe_size_mask & ~1;
    uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
    return lduw_le_p(ptr);
}

static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr)
{
    uint32_t offset = addr & vga->vbe_size_mask & ~1;
    uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
    return lduw_be_p(ptr);
}

static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr)
{
    uint32_t offset = addr & vga->vbe_size_mask & ~3;
    uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset);
    return ldl_le_p(ptr);
}

/*
 * 4 color mode
 */
static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
                           const uint8_t *s, int width)
static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
                           uint32_t addr, int width)
{
    uint32_t plane_mask, *palette, data, v;
    int x;

    palette = s1->last_palette;
    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    palette = vga->last_palette;
    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    width >>= 3;
    for(x = 0; x < width; x++) {
        data = ((uint32_t *)s)[0];
        data = vga_read_dword_le(vga, addr);
        data &= plane_mask;
        v = expand2[GET_PLANE(data, 0)];
        v |= expand2[GET_PLANE(data, 2)] << 2;
@@ -124,7 +150,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
        ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
        ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
        d += 32;
        s += 4;
        addr += 4;
    }
}

@@ -134,17 +160,17 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
/*
 * 4 color mode, dup2 horizontal
 */
static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
                             const uint8_t *s, int width)
static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
                             uint32_t addr, int width)
{
    uint32_t plane_mask, *palette, data, v;
    int x;

    palette = s1->last_palette;
    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    palette = vga->last_palette;
    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    width >>= 3;
    for(x = 0; x < width; x++) {
        data = ((uint32_t *)s)[0];
        data = vga_read_dword_le(vga, addr);
        data &= plane_mask;
        v = expand2[GET_PLANE(data, 0)];
        v |= expand2[GET_PLANE(data, 2)] << 2;
@@ -160,24 +186,24 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
        d += 64;
        s += 4;
        addr += 4;
    }
}

/*
 * 16 color mode
 */
static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
                           const uint8_t *s, int width)
static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
                           uint32_t addr, int width)
{
    uint32_t plane_mask, data, v, *palette;
    int x;

    palette = s1->last_palette;
    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    palette = vga->last_palette;
    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    width >>= 3;
    for(x = 0; x < width; x++) {
        data = ((uint32_t *)s)[0];
        data = vga_read_dword_le(vga, addr);
        data &= plane_mask;
        v = expand4[GET_PLANE(data, 0)];
        v |= expand4[GET_PLANE(data, 1)] << 1;
@@ -192,24 +218,24 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
        ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
        ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
        d += 32;
        s += 4;
        addr += 4;
    }
}

/*
 * 16 color mode, dup2 horizontal
 */
static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
                             const uint8_t *s, int width)
static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
                             uint32_t addr, int width)
{
    uint32_t plane_mask, data, v, *palette;
    int x;

    palette = s1->last_palette;
    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    palette = vga->last_palette;
    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
    width >>= 3;
    for(x = 0; x < width; x++) {
        data = ((uint32_t *)s)[0];
        data = vga_read_dword_le(vga, addr);
        data &= plane_mask;
        v = expand4[GET_PLANE(data, 0)];
        v |= expand4[GET_PLANE(data, 1)] << 1;
@@ -224,7 +250,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
        d += 64;
        s += 4;
        addr += 4;
    }
}

@@ -233,21 +259,21 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
 *
 * XXX: add plane_mask support (never used in standard VGA modes)
 */
static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
                             const uint8_t *s, int width)
static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
                             uint32_t addr, int width)
{
    uint32_t *palette;
    int x;

    palette = s1->last_palette;
    palette = vga->last_palette;
    width >>= 3;
    for(x = 0; x < width; x++) {
        PUT_PIXEL2(d, 0, palette[s[0]]);
        PUT_PIXEL2(d, 1, palette[s[1]]);
        PUT_PIXEL2(d, 2, palette[s[2]]);
        PUT_PIXEL2(d, 3, palette[s[3]]);
        PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
        PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
        PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
        PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
        d += 32;
        s += 4;
        addr += 4;
    }
}

@@ -256,63 +282,63 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
 *
 * XXX: add plane_mask support (never used in standard VGA modes)
 */
static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
                           const uint8_t *s, int width)
static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
                           uint32_t addr, int width)
{
    uint32_t *palette;
    int x;

    palette = s1->last_palette;
    palette = vga->last_palette;
    width >>= 3;
    for(x = 0; x < width; x++) {
        ((uint32_t *)d)[0] = palette[s[0]];
        ((uint32_t *)d)[1] = palette[s[1]];
        ((uint32_t *)d)[2] = palette[s[2]];
        ((uint32_t *)d)[3] = palette[s[3]];
        ((uint32_t *)d)[4] = palette[s[4]];
        ((uint32_t *)d)[5] = palette[s[5]];
        ((uint32_t *)d)[6] = palette[s[6]];
        ((uint32_t *)d)[7] = palette[s[7]];
        ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
        ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
        ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
        ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
        ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
        ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
        ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
        ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
        d += 32;
        s += 8;
        addr += 8;
    }
}

/*
 * 15 bit color
 */
static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
    int w;
    uint32_t v, r, g, b;

    w = width;
    do {
        v = lduw_le_p((void *)s);
        v = vga_read_word_le(vga, addr);
        r = (v >> 7) & 0xf8;
        g = (v >> 2) & 0xf8;
        b = (v << 3) & 0xf8;
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 2;
        addr += 2;
        d += 4;
    } while (--w != 0);
}

static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
    int w;
    uint32_t v, r, g, b;

    w = width;
    do {
        v = lduw_be_p((void *)s);
        v = vga_read_word_be(vga, addr);
        r = (v >> 7) & 0xf8;
        g = (v >> 2) & 0xf8;
        b = (v << 3) & 0xf8;
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 2;
        addr += 2;
        d += 4;
    } while (--w != 0);
}
@@ -320,38 +346,38 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
/*
 * 16 bit color
 */
static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
    int w;
    uint32_t v, r, g, b;

    w = width;
    do {
        v = lduw_le_p((void *)s);
        v = vga_read_word_le(vga, addr);
        r = (v >> 8) & 0xf8;
        g = (v >> 3) & 0xfc;
        b = (v << 3) & 0xf8;
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 2;
        addr += 2;
        d += 4;
    } while (--w != 0);
}

static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
    int w;
    uint32_t v, r, g, b;

    w = width;
    do {
        v = lduw_be_p((void *)s);
        v = vga_read_word_be(vga, addr);
        r = (v >> 8) & 0xf8;
        g = (v >> 3) & 0xfc;
        b = (v << 3) & 0xf8;
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 2;
        addr += 2;
        d += 4;
    } while (--w != 0);
}
@@ -359,36 +385,36 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
/*
 * 24 bit color
 */
static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
    int w;
    uint32_t r, g, b;

    w = width;
    do {
        b = s[0];
        g = s[1];
        r = s[2];
        b = vga_read_byte(vga, addr + 0);
        g = vga_read_byte(vga, addr + 1);
        r = vga_read_byte(vga, addr + 2);
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 3;
        addr += 3;
        d += 4;
    } while (--w != 0);
}

static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
    int w;
    uint32_t r, g, b;

    w = width;
    do {
        r = s[0];
        g = s[1];
        b = s[2];
        r = vga_read_byte(vga, addr + 0);
        g = vga_read_byte(vga, addr + 1);
        b = vga_read_byte(vga, addr + 2);
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 3;
        addr += 3;
        d += 4;
    } while (--w != 0);
}
@@ -396,44 +422,36 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
/*
 * 32 bit color
 */
static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
#ifndef HOST_WORDS_BIGENDIAN
    memcpy(d, s, width * 4);
#else
    int w;
    uint32_t r, g, b;

    w = width;
    do {
        b = s[0];
        g = s[1];
        r = s[2];
        b = vga_read_byte(vga, addr + 0);
        g = vga_read_byte(vga, addr + 1);
        r = vga_read_byte(vga, addr + 2);
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 4;
        addr += 4;
        d += 4;
    } while (--w != 0);
#endif
}

static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
                               const uint8_t *s, int width)
static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
                               uint32_t addr, int width)
{
#ifdef HOST_WORDS_BIGENDIAN
    memcpy(d, s, width * 4);
#else
    int w;
    uint32_t r, g, b;

    w = width;
    do {
        r = s[1];
        g = s[2];
        b = s[3];
        r = vga_read_byte(vga, addr + 1);
        g = vga_read_byte(vga, addr + 2);
        b = vga_read_byte(vga, addr + 3);
        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
        s += 4;
        addr += 4;
        d += 4;
    } while (--w != 0);
#endif
}
+12 −4
Original line number Diff line number Diff line
@@ -1005,7 +1005,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
}

typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
                                const uint8_t *s, int width);
                                uint32_t srcaddr, int width);

#include "vga-helpers.h"

@@ -1628,9 +1628,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
    y1 = 0;

    if (!full_update) {
        ram_addr_t region_start = addr1;
        ram_addr_t region_end = addr1 + line_offset * height;
        vga_sync_dirty_bitmap(s);
        snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
                                                      line_offset * height,
        if (s->line_compare < height) {
            /* split screen mode */
            region_start = 0;
        }
        snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
                                                      region_end - region_start,
                                                      DIRTY_MEMORY_VGA);
    }

@@ -1660,7 +1666,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
            if (y_start < 0)
                y_start = y;
            if (!(is_buffer_shared(surface))) {
                vga_draw_line(s, d, s->vram_ptr + addr, width);
                vga_draw_line(s, d, addr, width);
                if (s->cursor_draw_line)
                    s->cursor_draw_line(s, d, y);
            }
@@ -2044,6 +2050,7 @@ static int vga_common_post_load(void *opaque, int version_id)
    /* force refresh */
    s->graphic_mode = -1;
    vbe_update_vgaregs(s);
    vga_update_memory_access(s);
    return 0;
}

@@ -2164,6 +2171,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
    if (!s->vbe_size) {
        s->vbe_size = s->vram_size;
    }
    s->vbe_size_mask = s->vbe_size - 1;

    s->is_vbe_vmstate = 1;
    memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
+1 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ typedef struct VGACommonState {
    uint32_t vram_size;
    uint32_t vram_size_mb; /* property */
    uint32_t vbe_size;
    uint32_t vbe_size_mask;
    uint32_t latch;
    bool has_chain4_alias;
    MemoryRegion chain4_alias;
+0 −12
Original line number Diff line number Diff line
@@ -1195,17 +1195,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
        virtio_gpu_resource_destroy(g, res);
    }
    for (i = 0; i < g->conf.max_outputs; i++) {
#if 0
        g->req_state[i].x = 0;
        g->req_state[i].y = 0;
        if (i == 0) {
            g->req_state[0].width = 1024;
            g->req_state[0].height = 768;
        } else {
            g->req_state[i].width = 0;
            g->req_state[i].height = 0;
        }
#endif
        g->scanout[i].resource_id = 0;
        g->scanout[i].width = 0;
        g->scanout[i].height = 0;
@@ -1213,7 +1202,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
        g->scanout[i].y = 0;
        g->scanout[i].ds = NULL;
    }
    g->enabled_output_bitmask = 1;

#ifdef CONFIG_VIRGL
    if (g->use_virgl_renderer) {