diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 3d712d592fff495e6c37152acbaceccf48841e82..bdb092ee9d8df5ec84eb28cd0f70509cc36ccdf3 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -272,6 +272,9 @@ static void cirrus_update_memory_access(CirrusVGAState *s); static bool blit_region_is_unsafe(struct CirrusVGAState *s, int32_t pitch, int32_t addr) { + if (!pitch) { + return true; + } if (pitch < 0) { int64_t min = addr + ((int64_t)s->cirrus_blt_height-1) * pitch; @@ -715,7 +718,7 @@ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) s->cirrus_addr_mask)); } -static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) +static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) { int sx = 0, sy = 0; int dx = 0, dy = 0; @@ -729,6 +732,9 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) int width, height; depth = s->vga.get_bpp(&s->vga) / 8; + if (!depth) { + return 0; + } s->vga.get_resolution(&s->vga, &width, &height); /* extra x, y */ @@ -783,6 +789,8 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, s->cirrus_blt_dstpitch, s->cirrus_blt_width, s->cirrus_blt_height); + + return 1; } static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) @@ -790,11 +798,9 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) if (blit_is_unsafe(s)) return 0; - cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, + return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, s->cirrus_blt_srcaddr - s->vga.start_addr, s->cirrus_blt_width, s->cirrus_blt_height); - - return 1; } /*************************************** diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 0e2682d28b2d90d140a3e2a0bd2c870aca8eaf44..62d0c80dcfa7b9ca75965ff43d10039d81f6cb86 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -992,6 +992,34 @@ static uint32_t qxl_crc32(const uint8_t *p, unsigned len) return crc32(0xffffffff, p, len) ^ 0xffffffff; } +static bool qxl_rom_monitors_config_changed(QXLRom *rom, + VDAgentMonitorsConfig *monitors_config, + unsigned int max_outputs) +{ + int i; + unsigned int monitors_count; + + monitors_count = MIN(monitors_config->num_of_monitors, max_outputs); + + if (rom->client_monitors_config.count != monitors_count) { + return true; + } + + for (i = 0 ; i < rom->client_monitors_config.count ; ++i) { + VDAgentMonConfig *monitor = &monitors_config->monitors[i]; + QXLURect *rect = &rom->client_monitors_config.heads[i]; + /* monitor->depth ignored */ + if ((rect->left != monitor->x) || + (rect->top != monitor->y) || + (rect->right != monitor->x + monitor->width) || + (rect->bottom != monitor->y + monitor->height)) { + return true; + } + } + + return false; +} + /* called from main context only */ static int interface_client_monitors_config(QXLInstance *sin, VDAgentMonitorsConfig *monitors_config) @@ -1000,6 +1028,7 @@ static int interface_client_monitors_config(QXLInstance *sin, QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar); int i; unsigned max_outputs = ARRAY_SIZE(rom->client_monitors_config.heads); + bool config_changed = false; if (qxl->revision < 4) { trace_qxl_client_monitors_config_unsupported_by_device(qxl->id, @@ -1030,6 +1059,10 @@ static int interface_client_monitors_config(QXLInstance *sin, } #endif + config_changed = qxl_rom_monitors_config_changed(rom, + monitors_config, + max_outputs); + memset(&rom->client_monitors_config, 0, sizeof(rom->client_monitors_config)); rom->client_monitors_config.count = monitors_config->num_of_monitors; @@ -1059,7 +1092,9 @@ static int interface_client_monitors_config(QXLInstance *sin, trace_qxl_interrupt_client_monitors_config(qxl->id, rom->client_monitors_config.count, rom->client_monitors_config.heads); - qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG); + if (config_changed) { + qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG); + } return 1; } diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c index 758d33a09d9dc995b9d28850bdb33bb3870f9f8d..23f39de94d3a4e355673f14cbced5aed7e312e87 100644 --- a/hw/display/virtio-gpu-3d.c +++ b/hw/display/virtio-gpu-3d.c @@ -347,6 +347,7 @@ static void virgl_cmd_get_capset_info(VirtIOGPU *g, VIRTIO_GPU_FILL_CMD(info); + memset(&resp, 0, sizeof(resp)); if (info.capset_index == 0) { resp.capset_id = VIRTIO_GPU_CAPSET_VIRGL; virgl_renderer_get_cap_set(resp.capset_id, diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 60bce94d6b4a7ee5aabcd019f993a328119760de..5f32e1aae9ad5ffb19ea8c4dae2a3daedf43fd19 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -84,6 +84,7 @@ static void update_cursor_data_virgl(VirtIOGPU *g, if (width != s->current_cursor->width || height != s->current_cursor->height) { + free(data); return; }