#include "ui/spice-display.h"
+#ifdef CONFIG_MARU
+#define RATIO_SCALE 2
+#endif
+
static int debug = 0;
static void GCC_FMT_ATTR(2, 3) dprint(int level, const char *fmt, ...)
static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
{
+#ifndef CONFIG_MARU
static const int blksize = 32;
int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize;
int dirty_top[blocks];
int y, yoff1, yoff2, x, xoff, blk, bw;
int bpp = surface_bytes_per_pixel(ssd->ds);
uint8_t *guest, *mirror;
+#endif
if (qemu_spice_rect_is_empty(&ssd->dirty)) {
return;
};
+ if (ssd->surface == NULL) {
+ ssd->surface = pixman_image_ref(ssd->ds->image);
+ ssd->mirror = qemu_pixman_mirror_create(ssd->ds->format,
+ ssd->ds->image);
+ }
+
+#ifndef CONFIG_MARU
for (blk = 0; blk < blocks; blk++) {
dirty_top[blk] = -1;
}
dirty_top[blk] = -1;
}
}
+#endif
+
+#ifdef CONFIG_MARU
+ pixman_transform_t matrix;
+ struct pixman_f_transform matrix_f;
+
+ pixman_f_transform_init_identity(&matrix_f);
+ pixman_f_transform_scale(&matrix_f, NULL, RATIO_SCALE, RATIO_SCALE);
+ pixman_transform_from_pixman_f_transform(&matrix, &matrix_f);
+ pixman_image_set_transform(ssd->ds->image, &matrix);
+ pixman_image_set_filter(ssd->ds->image, PIXMAN_FILTER_BEST, NULL, 0);
+
+ QXLRect update = {
+ .top = 0,
+ .bottom = surface_height(ssd->ds),
+ .left = 0,
+ .right = surface_width(ssd->ds),
+ };
+
+ qemu_spice_create_one_update(ssd, &update);
+#endif
memset(&ssd->dirty, 0, sizeof(ssd->dirty));
}
surface.mem = (uintptr_t)ssd->buf;
surface.group_id = MEMSLOT_GROUP_HOST;
+#ifdef CONFIG_MARU
+ surface.width /= RATIO_SCALE;
+ surface.height /= RATIO_SCALE;
+#endif
+
qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
}
static int interface_req_cmd_notification(QXLInstance *sin)
{
- dprint(1, "%s/%d:\n", __func__, sin->id);
+ dprint(2, "%s/%d:\n", __func__, sin->id);
return 1;
}
static int interface_req_cursor_notification(QXLInstance *sin)
{
- dprint(1, "%s:\n", __FUNCTION__);
+ dprint(2, "%s:\n", __func__);
return 1;
}
static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd, bool block)
{
+ uint64_t timeout;
+
+ if (block) {
+ timeout = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ timeout += 1000; /* one sec */
+ timer_mod(ssd->gl_unblock_timer, timeout);
+ } else {
+ timer_del(ssd->gl_unblock_timer);
+ }
graphic_hw_gl_block(ssd->dcl.con, block);
}
qemu_spice_gl_block(ssd, false);
}
+static void qemu_spice_gl_block_timer(void *opaque)
+{
+ fprintf(stderr, "WARNING: spice: no gl-draw-done within one second\n");
+}
+
static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
QEMUGLParams *params)
{
fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
return;
}
+ dprint(1, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
+ w, h, stride, fourcc);
+ } else {
+ dprint(1, "%s: no texture (no framebuffer)\n", __func__);
}
- dprint(0, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
- w, h, stride, fourcc);
assert(!tex_id || fd >= 0);
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
uint64_t cookie;
- dprint(1, "%s\n", __func__);
+ dprint(2, "%s: %dx%d+%d+%d\n", __func__, w, h, x, y);
qemu_spice_gl_block(ssd, true);
cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
spice_qxl_gl_draw_async(&ssd->qxl, x, y, w, h, cookie);
ssd->dcl.ops = &display_listener_gl_ops;
ssd->dmabuf_fd = -1;
ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
+ ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
+ qemu_spice_gl_block_timer, ssd);
}
#endif
ssd->dcl.con = con;