diff options
Diffstat (limited to 'hw/display/vga.c')
-rw-r--r-- | hw/display/vga.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/hw/display/vga.c b/hw/display/vga.c index 69c3e1d674..b2516c8d21 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1434,6 +1434,14 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2) } } +static bool vga_scanline_invalidated(VGACommonState *s, int y) +{ + if (y >= VGA_MAX_HEIGHT) { + return false; + } + return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f)); +} + void vga_sync_dirty_bitmap(VGACommonState *s) { memory_region_sync_dirty_bitmap(&s->vram); @@ -1457,7 +1465,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) DisplaySurface *surface = qemu_console_surface(s->con); int y1, y, update, linesize, y_start, double_scan, mask, depth; int width, height, shift_control, line_offset, bwidth, bits; - ram_addr_t page0, page1, page_min, page_max; + ram_addr_t page0, page1; + DirtyBitmapSnapshot *snap = NULL; int disp_width, multi_scan, multi_run; uint8_t *d; uint32_t v, addr1, addr; @@ -1472,9 +1481,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) full_update |= update_basic_params(s); - if (!full_update) - vga_sync_dirty_bitmap(s); - s->get_resolution(s, &width, &height); disp_width = width; @@ -1617,11 +1623,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) addr1 = (s->start_addr * 4); bwidth = (width * bits + 7) / 8; y_start = -1; - page_min = -1; - page_max = 0; d = surface_data(surface); linesize = surface_stride(surface); y1 = 0; + + if (!full_update) { + vga_sync_dirty_bitmap(s); + snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1, + bwidth * height, + DIRTY_MEMORY_VGA); + } + for(y = 0; y < height; y++) { addr = addr1; if (!(s->cr[VGA_CRTC_MODE] & 1)) { @@ -1636,17 +1648,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) update = full_update; page0 = addr; page1 = addr + bwidth - 1; - update |= memory_region_get_dirty(&s->vram, page0, page1 - page0, - DIRTY_MEMORY_VGA); - /* explicit invalidation for the hardware cursor */ - update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; + if (full_update) { + update = 1; + } else { + update = memory_region_snapshot_get_dirty(&s->vram, snap, + page0, page1 - page0); + } + /* explicit invalidation for the hardware cursor (cirrus only) */ + update |= vga_scanline_invalidated(s, y); if (update) { if (y_start < 0) y_start = y; - if (page0 < page_min) - page_min = page0; - if (page1 > page_max) - page_max = page1; if (!(is_buffer_shared(surface))) { vga_draw_line(s, d, s->vram_ptr + addr, width); if (s->cursor_draw_line) @@ -1679,14 +1691,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) dpy_gfx_update(s->con, 0, y_start, disp_width, y - y_start); } - /* reset modified pages */ - if (page_max >= page_min) { - memory_region_reset_dirty(&s->vram, - page_min, - page_max - page_min, - DIRTY_MEMORY_VGA); - } - memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); + g_free(snap); + memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table)); } static void vga_draw_blank(VGACommonState *s, int full_update) |