summaryrefslogtreecommitdiff
path: root/ui/spice-display.c
diff options
context:
space:
mode:
authorSeokYeon Hwang <syeon.hwang@samsung.com>2015-08-24 13:27:10 +0900
committerSeokYeon Hwang <syeon.hwang@samsung.com>2015-08-24 13:27:10 +0900
commite8b4a92204aa1890ae4faf9a1dce80d3aebfe699 (patch)
tree1eeef6f6598099016274bed65bbb0fda841675fb /ui/spice-display.c
parentff9caec2210acffe97c95f937e2ae4f077c02bfc (diff)
parent5c79ae3615d5dafdf1bb09b7a356a3a005714e3d (diff)
downloadqemu-e8b4a92204aa1890ae4faf9a1dce80d3aebfe699.tar.gz
qemu-e8b4a92204aa1890ae4faf9a1dce80d3aebfe699.tar.bz2
qemu-e8b4a92204aa1890ae4faf9a1dce80d3aebfe699.zip
Merge tag 'v2.4.0' into tizen_3.0_qemu_2.4
v2.4.0 release Change-Id: Icc7e11d212e4628dc751ca77e17716c7253984e5 Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Diffstat (limited to 'ui/spice-display.c')
-rw-r--r--ui/spice-display.c110
1 files changed, 74 insertions, 36 deletions
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 132966d662..74b1cebfd4 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -19,7 +19,6 @@
#include "ui/qemu-spice.h"
#include "qemu/timer.h"
#include "qemu/queue.h"
-#include "monitor/monitor.h"
#include "ui/console.h"
#include "sysemu/sysemu.h"
#include "trace.h"
@@ -182,7 +181,7 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
image->bitmap.palette = 0;
image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
- dest = pixman_image_create_bits(PIXMAN_x8r8g8b8, bw, bh,
+ dest = pixman_image_create_bits(PIXMAN_LE_x8r8g8b8, bw, bh,
(void *)update->bitmap, bw * 4);
pixman_image_composite(PIXMAN_OP_SRC, ssd->surface, NULL, ssd->mirror,
rect->left, rect->top, 0, 0,
@@ -204,7 +203,7 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
static const int blksize = 32;
int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize;
int dirty_top[blocks];
- int y, yoff, x, xoff, blk, bw;
+ int y, yoff1, yoff2, x, xoff, blk, bw;
int bpp = surface_bytes_per_pixel(ssd->ds);
uint8_t *guest, *mirror;
#endif
@@ -227,13 +226,14 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
guest = surface_data(ssd->ds);
mirror = (void *)pixman_image_get_data(ssd->mirror);
for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) {
- yoff = y * surface_stride(ssd->ds);
+ yoff1 = y * surface_stride(ssd->ds);
+ yoff2 = y * pixman_image_get_stride(ssd->mirror);
for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
xoff = x * bpp;
blk = x / blksize;
bw = MIN(blksize, ssd->dirty.right - x);
- if (memcmp(guest + yoff + xoff,
- mirror + yoff + xoff,
+ if (memcmp(guest + yoff1 + xoff,
+ mirror + yoff2 + xoff,
bw * bpp) == 0) {
if (dirty_top[blk] != -1) {
QXLRect update = {
@@ -294,7 +294,8 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
static SimpleSpiceCursor*
qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd,
- QEMUCursor *c)
+ QEMUCursor *c,
+ int on)
{
size_t size = c ? c->width * c->height * 4 : 0;
SimpleSpiceCursor *update;
@@ -309,8 +310,8 @@ qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd,
if (c) {
ccmd->type = QXL_CURSOR_SET;
- ccmd->u.set.position.x = ssd->ptr_x;
- ccmd->u.set.position.y = ssd->ptr_y;
+ ccmd->u.set.position.x = ssd->ptr_x + ssd->hot_x;
+ ccmd->u.set.position.y = ssd->ptr_y + ssd->hot_y;
ccmd->u.set.visible = true;
ccmd->u.set.shape = (uintptr_t)cursor;
cursor->header.unique = ssd->unique++;
@@ -322,10 +323,12 @@ qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd,
cursor->data_size = size;
cursor->chunk.data_size = size;
memcpy(cursor->chunk.data, c->data, size);
+ } else if (!on) {
+ ccmd->type = QXL_CURSOR_HIDE;
} else {
ccmd->type = QXL_CURSOR_MOVE;
- ccmd->u.position.x = ssd->ptr_x;
- ccmd->u.position.y = ssd->ptr_y;
+ ccmd->u.position.x = ssd->ptr_x + ssd->hot_x;
+ ccmd->u.position.y = ssd->ptr_y + ssd->hot_y;
}
ccmd->release_info.id = (uintptr_t)(&update->ext);
@@ -442,7 +445,29 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
SimpleSpiceUpdate *update;
bool need_destroy;
- dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
+ if (surface && ssd->surface &&
+ surface_width(surface) == pixman_image_get_width(ssd->surface) &&
+ surface_height(surface) == pixman_image_get_height(ssd->surface)) {
+ /* no-resize fast path: just swap backing store */
+ dprint(1, "%s/%d: fast (%dx%d)\n", __func__, ssd->qxl.id,
+ surface_width(surface), surface_height(surface));
+ qemu_mutex_lock(&ssd->lock);
+ ssd->ds = surface;
+ pixman_image_unref(ssd->surface);
+ ssd->surface = pixman_image_ref(ssd->ds->image);
+ qemu_mutex_unlock(&ssd->lock);
+ qemu_spice_display_update(ssd, 0, 0,
+ surface_width(surface),
+ surface_height(surface));
+ return;
+ }
+
+ /* full mode switch */
+ dprint(1, "%s/%d: full (%dx%d -> %dx%d)\n", __func__, ssd->qxl.id,
+ ssd->surface ? pixman_image_get_width(ssd->surface) : 0,
+ ssd->surface ? pixman_image_get_height(ssd->surface) : 0,
+ surface ? surface_width(surface) : 0,
+ surface ? surface_height(surface) : 0);
memset(&ssd->dirty, 0, sizeof(ssd->dirty));
if (ssd->surface) {
@@ -464,6 +489,9 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
qemu_spice_destroy_host_primary(ssd);
}
if (ssd->ds) {
+ ssd->surface = pixman_image_ref(ssd->ds->image);
+ ssd->mirror = qemu_pixman_mirror_create(ssd->ds->format,
+ ssd->ds->image);
qemu_spice_create_host_primary(ssd);
}
@@ -471,7 +499,7 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
ssd->notify++;
}
-void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
+static void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
{
if (ssd->cursor) {
assert(ssd->dcl.con);
@@ -487,6 +515,15 @@ void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
}
}
+void qemu_spice_cursor_refresh_bh(void *opaque)
+{
+ SimpleSpiceDisplay *ssd = opaque;
+
+ qemu_mutex_lock(&ssd->lock);
+ qemu_spice_cursor_refresh_unlocked(ssd);
+ qemu_mutex_unlock(&ssd->lock);
+}
+
void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
{
dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
@@ -497,7 +534,6 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
qemu_spice_create_update(ssd);
ssd->notify++;
}
- qemu_spice_cursor_refresh_unlocked(ssd);
qemu_mutex_unlock(&ssd->lock);
if (ssd->notify) {
@@ -542,7 +578,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
info->n_surfaces = ssd->num_surfaces;
}
-static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+static int interface_get_command(QXLInstance *sin, QXLCommandExt *ext)
{
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
SimpleSpiceUpdate *update;
@@ -569,7 +605,7 @@ static int interface_req_cmd_notification(QXLInstance *sin)
}
static void interface_release_resource(QXLInstance *sin,
- struct QXLReleaseInfoExt rext)
+ QXLReleaseInfoExt rext)
{
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
SimpleSpiceUpdate *update;
@@ -592,7 +628,7 @@ static void interface_release_resource(QXLInstance *sin,
}
}
-static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext)
+static int interface_get_cursor_command(QXLInstance *sin, QXLCommandExt *ext)
{
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
int ret;
@@ -663,7 +699,10 @@ static int interface_client_monitors_config(QXLInstance *sin,
{
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
QemuUIInfo info;
- int rc;
+
+ if (!dpy_ui_info_supported(ssd->dcl.con)) {
+ return 0; /* == not supported by guest */
+ }
if (!mc) {
return 1;
@@ -678,14 +717,10 @@ static int interface_client_monitors_config(QXLInstance *sin,
info.width = mc->monitors[0].width;
info.height = mc->monitors[0].height;
}
- rc = dpy_set_ui_info(ssd->dcl.con, &info);
- dprint(1, "%s/%d: size %dx%d, rc %d <--- ==========================\n",
- __func__, ssd->qxl.id, info.width, info.height, rc);
- if (rc != 0) {
- return 0; /* == not supported by guest */
- } else {
- return 1;
- }
+ dpy_set_ui_info(ssd->dcl.con, &info);
+ dprint(1, "%s/%d: size %dx%d\n", __func__, ssd->qxl.id,
+ info.width, info.height);
+ return 1;
}
static const QXLInterface dpy_interface = {
@@ -721,7 +756,7 @@ static void display_update(DisplayChangeListener *dcl,
}
static void display_switch(DisplayChangeListener *dcl,
- struct DisplaySurface *surface)
+ DisplaySurface *surface)
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
qemu_spice_display_switch(ssd, surface);
@@ -740,11 +775,11 @@ static void display_mouse_set(DisplayChangeListener *dcl,
qemu_mutex_lock(&ssd->lock);
ssd->ptr_x = x;
- ssd->ptr_y = x;
+ ssd->ptr_y = y;
if (ssd->ptr_move) {
g_free(ssd->ptr_move);
}
- ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL);
+ ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL, on);
qemu_mutex_unlock(&ssd->lock);
}
@@ -754,6 +789,8 @@ static void display_mouse_define(DisplayChangeListener *dcl,
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
qemu_mutex_lock(&ssd->lock);
+ ssd->hot_x = c->hot_x;
+ ssd->hot_y = c->hot_y;
if (ssd->ptr_move) {
g_free(ssd->ptr_move);
ssd->ptr_move = NULL;
@@ -761,17 +798,18 @@ static void display_mouse_define(DisplayChangeListener *dcl,
if (ssd->ptr_define) {
g_free(ssd->ptr_define);
}
- ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c);
+ ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, 0);
qemu_mutex_unlock(&ssd->lock);
}
static const DisplayChangeListenerOps display_listener_ops = {
- .dpy_name = "spice",
- .dpy_gfx_update = display_update,
- .dpy_gfx_switch = display_switch,
- .dpy_refresh = display_refresh,
- .dpy_mouse_set = display_mouse_set,
- .dpy_cursor_define = display_mouse_define,
+ .dpy_name = "spice",
+ .dpy_gfx_update = display_update,
+ .dpy_gfx_switch = display_switch,
+ .dpy_gfx_check_format = qemu_pixman_check_format,
+ .dpy_refresh = display_refresh,
+ .dpy_mouse_set = display_mouse_set,
+ .dpy_cursor_define = display_mouse_define,
};
static void qemu_spice_display_init_one(QemuConsole *con)