Merge tag 'v2.6.0' into develop
[sdk/emulator/qemu.git] / ui / spice-display.c
index 904fb33..1860492 100644 (file)
 
 #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, ...)
@@ -196,17 +200,26 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
 
 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;
     }
@@ -255,6 +268,27 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
             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));
 }
@@ -360,6 +394,11 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
     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);
 }
 
@@ -568,7 +607,7 @@ static int interface_get_command(QXLInstance *sin, QXLCommandExt *ext)
 
 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;
 }
 
@@ -621,7 +660,7 @@ static int interface_get_cursor_command(QXLInstance *sin, QXLCommandExt *ext)
 
 static int interface_req_cursor_notification(QXLInstance *sin)
 {
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(2, "%s:\n", __func__);
     return 1;
 }
 
@@ -797,6 +836,15 @@ static const DisplayChangeListenerOps display_listener_ops = {
 
 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);
 }
 
@@ -807,6 +855,11 @@ static void qemu_spice_gl_unblock_bh(void *opaque)
     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)
 {
@@ -831,9 +884,11 @@ static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
             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);
 
@@ -850,7 +905,7 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
     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);
@@ -888,6 +943,8 @@ static void qemu_spice_display_init_one(QemuConsole *con)
         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;