* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "hw/hw.h"
+#include "qemu/error-report.h"
+#include "qemu/module.h"
#include "ui/console.h"
#include "ui/pixel_ops.h"
#include "trace.h"
#define G364_PAGE_SIZE 4096
-static inline int check_dirty(G364State *s, ram_addr_t page)
+static inline int check_dirty(G364State *s, DirtyBitmapSnapshot *snap, ram_addr_t page)
{
- return memory_region_get_dirty(&s->mem_vram, page, G364_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
-}
-
-static inline void reset_dirty(G364State *s,
- ram_addr_t page_min, ram_addr_t page_max)
-{
- memory_region_reset_dirty(&s->mem_vram,
- page_min,
- page_max + G364_PAGE_SIZE - page_min - 1,
- DIRTY_MEMORY_VGA);
+ return memory_region_snapshot_get_dirty(&s->mem_vram, snap, page, G364_PAGE_SIZE);
}
static void g364fb_draw_graphic8(G364State *s)
{
DisplaySurface *surface = qemu_console_surface(s->con);
+ DirtyBitmapSnapshot *snap;
int i, w;
uint8_t *vram;
uint8_t *data_display, *dd;
- ram_addr_t page, page_min, page_max;
+ ram_addr_t page;
int x, y;
int xmin, xmax;
int ymin, ymax;
}
page = 0;
- page_min = (ram_addr_t)-1;
- page_max = 0;
x = y = 0;
xmin = s->width;
vram = s->vram + s->top_of_screen;
/* XXX: out of range in vram? */
data_display = dd = surface_data(surface);
+ snap = memory_region_snapshot_and_clear_dirty(&s->mem_vram, 0, s->vram_size,
+ DIRTY_MEMORY_VGA);
while (y < s->height) {
- if (check_dirty(s, page)) {
+ if (check_dirty(s, snap, page)) {
if (y < ymin)
ymin = ymax = y;
- if (page_min == (ram_addr_t)-1)
- page_min = page;
- page_max = page;
if (x < xmin)
xmin = x;
for (i = 0; i < G364_PAGE_SIZE; i++) {
ymax = y;
} else {
int dy;
- if (page_min != (ram_addr_t)-1) {
- reset_dirty(s, page_min, page_max);
- page_min = (ram_addr_t)-1;
- page_max = 0;
+ if (xmax || ymax) {
dpy_gfx_update(s->con, xmin, ymin,
xmax - xmin + 1, ymax - ymin + 1);
xmin = s->width;
}
done:
- if (page_min != (ram_addr_t)-1) {
+ if (xmax || ymax) {
dpy_gfx_update(s->con, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
- reset_dirty(s, page_min, page_max);
}
+ g_free(snap);
}
static void g364fb_draw_blank(G364State *s)
d += surface_stride(surface);
}
- dpy_gfx_update(s->con, 0, 0, s->width, s->height);
+ dpy_gfx_update_full(s->con);
s->blanked = 1;
}
.name = "g364fb",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
.post_load = g364fb_post_load,
.fields = (VMStateField[]) {
- VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, 0, vram_size),
+ VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, vram_size),
VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3),
VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9),
VMSTATE_UINT16_ARRAY(cursor, G364State, 512),
memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram",
s->vram_size, s->vram);
vmstate_register_ram(&s->mem_vram, dev);
- memory_region_set_coalescing(&s->mem_vram);
+ memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
}
#define TYPE_G364 "sysbus-g364"
G364State g364;
} G364SysBusState;
-static int g364fb_sysbus_init(SysBusDevice *sbd)
+static void g364fb_sysbus_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
G364SysBusState *sbs = G364(dev);
G364State *s = &sbs->g364;
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
g364fb_init(dev, s);
sysbus_init_irq(sbd, &s->irq);
sysbus_init_mmio(sbd, &s->mem_ctrl);
sysbus_init_mmio(sbd, &s->mem_vram);
-
- return 0;
}
static void g364fb_sysbus_reset(DeviceState *d)
}
static Property g364fb_sysbus_properties[] = {
- DEFINE_PROP_UINT32("vram_size", G364SysBusState, g364.vram_size,
- 8 * 1024 * 1024),
+ DEFINE_PROP_UINT32("vram_size", G364SysBusState, g364.vram_size, 8 * MiB),
DEFINE_PROP_END_OF_LIST(),
};
static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = g364fb_sysbus_init;
+ dc->realize = g364fb_sysbus_realize;
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->desc = "G364 framebuffer";
dc->reset = g364fb_sysbus_reset;