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:
parent
a77549b3ff
commit
4c38762fb5
@ -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)
|
||||
{
|
||||
|
61
ui/console.c
61
ui/console.c
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user