console: add dpy_gfx_update_dirty

Calls dpy_gfx_update for all dirty scanlines. Works for
DisplaySurfaces backed by guest memory (i.e. the ones created
using qemu_create_displaysurface_guestmem).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2014-06-19 08:52:17 +02:00
parent a77549b3ff
commit 4c38762fb5
2 changed files with 65 additions and 0 deletions

View file

@ -232,6 +232,10 @@ void dpy_text_resize(QemuConsole *con, int w, int h);
void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
bool dpy_cursor_define_supported(QemuConsole *con);
void dpy_gfx_update_dirty(QemuConsole *con,
MemoryRegion *address_space,
uint64_t base,
bool invalidate);
static inline int surface_stride(DisplaySurface *s)
{

View file

@ -1581,6 +1581,67 @@ bool dpy_cursor_define_supported(QemuConsole *con)
return false;
}
/*
* Call dpy_gfx_update for all dirity scanlines. Works for
* DisplaySurfaces backed by guest memory (i.e. the ones created
* using qemu_create_displaysurface_guestmem).
*/
void dpy_gfx_update_dirty(QemuConsole *con,
MemoryRegion *address_space,
hwaddr base,
bool invalidate)
{
DisplaySurface *ds = qemu_console_surface(con);
int width = surface_stride(ds);
int height = surface_height(ds);
hwaddr size = width * height;
MemoryRegionSection mem_section;
MemoryRegion *mem;
ram_addr_t addr;
int first, last, i;
bool dirty;
mem_section = memory_region_find(address_space, base, size);
mem = mem_section.mr;
if (int128_get64(mem_section.size) != size ||
!memory_region_is_ram(mem_section.mr)) {
goto out;
}
assert(mem);
memory_region_sync_dirty_bitmap(mem);
addr = mem_section.offset_within_region;
first = -1;
last = -1;
for (i = 0; i < height; i++, addr += width) {
dirty = invalidate ||
memory_region_get_dirty(mem, addr, width, DIRTY_MEMORY_VGA);
if (dirty) {
if (first == -1) {
first = i;
}
last = i;
}
if (first != -1 && !dirty) {
assert(last != -1 && last >= first);
dpy_gfx_update(con, 0, first, surface_width(ds),
last - first + 1);
first = -1;
}
}
if (first != -1) {
assert(last != -1 && last >= first);
dpy_gfx_update(con, 0, first, surface_width(ds),
last - first + 1);
}
memory_region_reset_dirty(mem, mem_section.offset_within_region, size,
DIRTY_MEMORY_VGA);
out:
memory_region_unref(mem);
}
/***********************************************************/
/* register display */