[Spice-commits] 9 commits - configure.ac NEWS server/main_dispatcher.c server/red_dispatcher.c server/red_dispatcher.h server/red_parse_qxl.c server/red_worker.c server/tests
Alon Levy
alon at kemper.freedesktop.org
Fri May 17 10:59:23 PDT 2013
NEWS | 18 ++++++
configure.ac | 4 -
server/main_dispatcher.c | 2
server/red_dispatcher.c | 8 +-
server/red_dispatcher.h | 4 -
server/red_parse_qxl.c | 4 -
server/red_worker.c | 30 +++++-----
server/tests/Makefile.am | 8 ++
server/tests/test_display_base.c | 60 +++++++++++++++++---
server/tests/test_display_base.h | 13 ++++
server/tests/test_display_width_stride.c | 92 +++++++++++++++++++++++++++++++
11 files changed, 211 insertions(+), 32 deletions(-)
New commits:
commit 59ff2f9221f3d78d4a12b7da6d8d6e2fb499ca10
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:34:54 2013 -0400
0.12.3 release
diff --git a/NEWS b/NEWS
index 30912c5..acfffb8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,21 @@
+Major changes in 0.12.3:
+========================
+* monitor client bandwidth and latency.
+* dynamically adjust video stream quality based on client bandwidth & latency.
+** new SPICE_MSGC_DISPLAY_STREAM_REPORT
+** can also set SPICE_BIT_RATE environment variable to override.
+* support arbitrary latency of audio stream wrt video stream:
+** new SPICE_MSG_PLAYBACK_LATENCY
+* notify agent on client disconnection
+** new VD_AGENT_CLIENT_DISCONNECTED message
+* better support for switching from qxl to vga mode
+** new library export spice_qxl_driver_unload
+* multiple monitor support in single channel fixes.
+* stop streams before migration.
+* don't send empty volume messages.
+* Bugs fixed: rhbz#891326, rhbz#958276, rhbz#956345
+* fixes to inputs, chardev, build fixes.
+
Major changes in 0.12.2:
========================
* Stable Release
diff --git a/configure.ac b/configure.ac
index fc0216f..78896cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,9 +13,9 @@ AC_PREREQ([2.57])
# 4. Follow the libtool manual for the so version:
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-m4_define([SPICE_CURRENT], [7])
+m4_define([SPICE_CURRENT], [8])
m4_define([SPICE_REVISION], [0])
-m4_define([SPICE_AGE], [6])
+m4_define([SPICE_AGE], [7])
# Note on the library name on linux (SONAME) produced by libtool (for reference, gleaned
# from looking at libtool 2.4.2)
commit 5170589c21f183b5eee13b1eab5e37793f5426e3
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:36:30 2013 -0400
server/red_parse_qxl: two coding convention pointer cast fix
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
index 4b39029..65781e7 100644
--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -104,7 +104,7 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
red_prev = red;
red = spice_new(RedDataChunk, 1);
memslot_id = get_memslot_id(slots, qxl->next_chunk);
- qxl = (QXLDataChunk*)get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id,
+ qxl = (QXLDataChunk *)get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id,
&error);
if (error) {
return 0;
@@ -130,7 +130,7 @@ static size_t red_get_data_chunks(RedMemSlotInfo *slots, int group_id,
int error;
int memslot_id = get_memslot_id(slots, addr);
- qxl = (QXLDataChunk*)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+ qxl = (QXLDataChunk *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
if (error) {
return 0;
}
commit e9cf575938df398d38d36cfb96213cc98fb8daf7
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:36:26 2013 -0400
server/dispatchers: initialize stack to 0 for valgrind
diff --git a/server/main_dispatcher.c b/server/main_dispatcher.c
index 92b0791..e7a451a 100644
--- a/server/main_dispatcher.c
+++ b/server/main_dispatcher.c
@@ -78,7 +78,7 @@ static void main_dispatcher_handle_channel_event(void *opaque,
void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info)
{
- MainDispatcherChannelEventMessage msg;
+ MainDispatcherChannelEventMessage msg = {0,};
if (pthread_self() == main_dispatcher.base.self) {
main_dispatcher_self_handle_channel_event(event, info);
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index f4b140c..ef47c28 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -97,7 +97,7 @@ static void red_dispatcher_set_display_peer(RedChannel *channel, RedClient *clie
int num_common_caps, uint32_t *common_caps, int num_caps,
uint32_t *caps)
{
- RedWorkerMessageDisplayConnect payload;
+ RedWorkerMessageDisplayConnect payload = {0,};
RedDispatcher *dispatcher;
spice_debug("%s", "");
@@ -159,7 +159,7 @@ static void red_dispatcher_set_cursor_peer(RedChannel *channel, RedClient *clien
uint32_t *common_caps, int num_caps,
uint32_t *caps)
{
- RedWorkerMessageCursorConnect payload;
+ RedWorkerMessageCursorConnect payload = {0,};
RedDispatcher *dispatcher = (RedDispatcher *)channel->data;
spice_printerr("");
payload.client = client;
@@ -292,7 +292,7 @@ static void red_dispatcher_update_area(RedDispatcher *dispatcher, uint32_t surfa
QXLRect *qxl_area, QXLRect *qxl_dirty_rects,
uint32_t num_dirty_rects, uint32_t clear_dirty_region)
{
- RedWorkerMessageUpdate payload;
+ RedWorkerMessageUpdate payload = {0,};
payload.surface_id = surface_id;
payload.qxl_area = qxl_area;
@@ -522,7 +522,7 @@ static void
red_dispatcher_create_primary_surface_sync(RedDispatcher *dispatcher, uint32_t surface_id,
QXLDevSurfaceCreate *surface)
{
- RedWorkerMessageCreatePrimarySurface payload;
+ RedWorkerMessageCreatePrimarySurface payload = {0,};
dispatcher->surface_create = *surface;
payload.surface_id = surface_id;
commit feb913e56b65a11e64294850ffe83e397df41d7c
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:36:21 2013 -0400
server/red_dispatcher: close pa hole in RedWorkerMessageDisplayConnect for valgrind
diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h
index 4d0d2a8..7d23b11 100644
--- a/server/red_dispatcher.h
+++ b/server/red_dispatcher.h
@@ -43,10 +43,10 @@ void red_dispatcher_client_monitors_config(VDAgentMonitorsConfig *monitors_confi
typedef struct RedWorkerMessageDisplayConnect {
RedClient * client;
RedsStream * stream;
- int migration;
uint32_t *common_caps; // red_worker should free
- int num_common_caps;
uint32_t *caps; // red_worker should free
+ int migration;
+ int num_common_caps;
int num_caps;
} RedWorkerMessageDisplayConnect;
commit bcd7c4e0977a80059193819fe28832c50678eefc
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:36:17 2013 -0400
server/tests: test_display_width_stride
diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
index e0472f3..655bc83 100644
--- a/server/tests/Makefile.am
+++ b/server/tests/Makefile.am
@@ -35,6 +35,7 @@ noinst_PROGRAMS = \
test_display_resolution_changes \
test_two_servers \
test_vdagent \
+ test_display_width_stride \
$(NULL)
test_vdagent_SOURCES = \
@@ -90,4 +91,9 @@ test_two_servers_SOURCES = \
test_two_servers.c \
$(NULL)
-
+test_display_width_stride_SOURCES = \
+ $(COMMON_BASE) \
+ test_display_base.c \
+ test_display_base.h \
+ test_display_width_stride.c \
+ $(NULL)
diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
index 8657e91..b4c93f3 100644
--- a/server/tests/test_display_base.c
+++ b/server/tests/test_display_base.c
@@ -309,20 +309,36 @@ static SimpleSpiceUpdate *test_spice_create_update_copy_bits(Test *test, uint32_
return update;
}
-static SimpleSurfaceCmd *create_surface(int surface_id, int width, int height, uint8_t *data)
+static int format_to_bpp(int format)
+{
+ switch (format) {
+ case SPICE_SURFACE_FMT_8_A:
+ return 1;
+ case SPICE_SURFACE_FMT_16_555:
+ case SPICE_SURFACE_FMT_16_565:
+ return 2;
+ case SPICE_SURFACE_FMT_32_xRGB:
+ case SPICE_SURFACE_FMT_32_ARGB:
+ return 4;
+ }
+ abort();
+}
+
+static SimpleSurfaceCmd *create_surface(int surface_id, int format, int width, int height, uint8_t *data)
{
SimpleSurfaceCmd *simple_cmd = calloc(sizeof(SimpleSurfaceCmd), 1);
QXLSurfaceCmd *surface_cmd = &simple_cmd->surface_cmd;
+ int bpp = format_to_bpp(format);
set_cmd(&simple_cmd->ext, QXL_CMD_SURFACE, (intptr_t)surface_cmd);
simple_set_release_info(&surface_cmd->release_info, (intptr_t)simple_cmd);
surface_cmd->type = QXL_SURFACE_CMD_CREATE;
surface_cmd->flags = 0; // ?
surface_cmd->surface_id = surface_id;
- surface_cmd->u.surface_create.format = SPICE_SURFACE_FMT_32_xRGB;
+ surface_cmd->u.surface_create.format = format;
surface_cmd->u.surface_create.width = width;
surface_cmd->u.surface_create.height = height;
- surface_cmd->u.surface_create.stride = -width * 4;
+ surface_cmd->u.surface_create.stride = -width * bpp;
surface_cmd->u.surface_create.data = (intptr_t)data;
return simple_cmd;
}
@@ -471,7 +487,10 @@ static void produce_command(Test *test)
if (test->has_secondary)
test->target_surface = 1;
- ASSERT(test->num_commands);
+ if (!test->num_commands) {
+ usleep(1000);
+ return;
+ }
command = &test->commands[test->cmd_index];
if (command->cb) {
@@ -538,8 +557,17 @@ static void produce_command(Test *test)
case SIMPLE_CREATE_SURFACE: {
SimpleSurfaceCmd *update;
test->target_surface = MAX_SURFACE_NUM - 1;
- update = create_surface(test->target_surface, SURF_WIDTH, SURF_HEIGHT,
- test->secondary_surface);
+ if (command) {
+ update = create_surface(command->create_surface.surface_id,
+ command->create_surface.format,
+ command->create_surface.width,
+ command->create_surface.height,
+ command->create_surface.data);
+ } else {
+ update = create_surface(test->target_surface, SPICE_SURFACE_FMT_32_xRGB,
+ SURF_WIDTH, SURF_HEIGHT,
+ test->secondary_surface);
+ }
push_command(&update->ext);
test->has_secondary = 1;
break;
@@ -716,7 +744,15 @@ static void set_client_capabilities(QXLInstance *qin,
uint8_t client_present,
uint8_t caps[58])
{
+ Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);
+
printf("%s: present %d caps %d\n", __func__, client_present, caps[0]);
+ if (test->on_client_connected && client_present) {
+ test->on_client_connected(test);
+ }
+ if (test->on_client_disconnected && !client_present) {
+ test->on_client_disconnected(test);
+ }
}
QXLInterface display_sif = {
diff --git a/server/tests/test_display_base.h b/server/tests/test_display_base.h
index c3b9fea..d2823a7 100644
--- a/server/tests/test_display_base.h
+++ b/server/tests/test_display_base.h
@@ -32,6 +32,14 @@ typedef struct CommandCreatePrimary {
uint32_t height;
} CommandCreatePrimary;
+typedef struct CommandCreateSurface {
+ uint32_t surface_id;
+ uint32_t format;
+ uint32_t width;
+ uint32_t height;
+ uint8_t *data;
+} CommandCreateSurface;
+
typedef struct CommandDrawBitmap {
QXLRect bbox;
uint8_t *bitmap;
@@ -62,6 +70,7 @@ struct Command {
CommandDrawBitmap bitmap;
CommandDrawSolid solid;
CommandSleep sleep;
+ CommandCreateSurface create_surface;
};
};
@@ -100,6 +109,10 @@ struct Test {
int cmd_index;
int target_surface;
+
+ // callbacks
+ void (*on_client_connected)(Test *test);
+ void (*on_client_disconnected)(Test *test);
};
void test_set_simple_command_list(Test *test, int *command, int num_commands);
diff --git a/server/tests/test_display_width_stride.c b/server/tests/test_display_width_stride.c
new file mode 100644
index 0000000..20de57a
--- /dev/null
+++ b/server/tests/test_display_width_stride.c
@@ -0,0 +1,92 @@
+/**
+ * Recreate the primary surface endlessly.
+ */
+
+#include <config.h>
+#include <math.h>
+#include <stdlib.h>
+#include "test_display_base.h"
+
+SpiceTimer *ping_timer;
+
+void show_channels(SpiceServer *server);
+
+int ping_ms = 100;
+
+void pinger(void *opaque)
+{
+ Test *test = opaque;
+ // show_channels is not thread safe - fails if disconnections / connections occur
+ //show_channels(server);
+
+ test->core->timer_start(ping_timer, ping_ms);
+}
+
+static int g_surface_id = 1;
+static uint8_t *g_surface_data;
+
+void set_draw_parameters(Test *test, Command *command)
+{
+ static int count = 17;
+ CommandDrawSolid *solid = &command->solid;
+
+ solid->bbox.top = 0;
+ solid->bbox.left = 0;
+ solid->bbox.bottom = 20;
+ solid->bbox.right = count;
+ solid->surface_id = g_surface_id;
+ count++;
+}
+
+void set_surface_params(Test *test, Command *command)
+{
+ CommandCreateSurface *create = &command->create_surface;
+
+ // UGLY
+ if (g_surface_data) {
+ exit(0);
+ }
+ create->format = SPICE_SURFACE_FMT_8_A;
+ create->width = 128;
+ create->height = 128;
+ g_surface_data = realloc(g_surface_data, create->width * create->height * 1);
+ create->surface_id = g_surface_id;
+ create->data = g_surface_data;
+}
+
+static Command commands[] = {
+ {SIMPLE_CREATE_SURFACE, set_surface_params},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+ {SIMPLE_DRAW_SOLID, set_draw_parameters},
+};
+
+void on_client_connected(Test *test)
+{
+ test_set_command_list(test, commands, COUNT(commands));
+}
+
+int main(void)
+{
+ SpiceCoreInterface *core;
+ Test *test;
+
+ core = basic_event_loop_init();
+ test = test_new(core);
+ test->on_client_connected = on_client_connected;
+ //spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF);
+ test_add_display_interface(test);
+
+ ping_timer = core->timer_add(pinger, test);
+ core->timer_start(ping_timer, ping_ms);
+
+ basic_event_loop_mainloop();
+
+ return 0;
+}
commit 3ace9a3333c72495b2ea674fc663473611d8144d
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:36:13 2013 -0400
server/red_worker: simplify monitors_config update
diff --git a/server/red_worker.c b/server/red_worker.c
index 14d219b..f047d29 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1279,6 +1279,9 @@ static MonitorsConfig *monitors_config_getref(MonitorsConfig *monitors_config)
static void monitors_config_decref(MonitorsConfig *monitors_config)
{
+ if (!monitors_config) {
+ return;
+ }
if (--monitors_config->refs > 0) {
return;
}
@@ -11339,9 +11342,7 @@ static void worker_update_monitors_config(RedWorker *worker,
MonitorsConfig *monitors_config;
int i;
- if (worker->monitors_config) {
- monitors_config_decref(worker->monitors_config);
- }
+ monitors_config_decref(worker->monitors_config);
spice_debug("monitors config %d(%d)",
dev_monitors_config->count,
@@ -11396,12 +11397,10 @@ static void set_monitors_config_to_primary(RedWorker *worker)
DrawContext *context;
if (!worker->surfaces[0].context.canvas) {
- spice_warning("%s: no primary surface", __FUNCTION__);
+ spice_warning("no primary surface");
return;
}
- if (worker->monitors_config) {
- monitors_config_decref(worker->monitors_config);
- }
+ monitors_config_decref(worker->monitors_config);
context = &worker->surfaces[0].context;
worker->monitors_config =
spice_malloc(sizeof(*worker->monitors_config) + sizeof(QXLHead));
commit 7d6e813b2c3009d124edf97e557598a69a6b4fc4
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:36:09 2013 -0400
server/tests/test_display_base: add missing set_client_capabilities, fix client_monitors_config signature
diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
index 588e960..8657e91 100644
--- a/server/tests/test_display_base.c
+++ b/server/tests/test_display_base.c
@@ -701,13 +701,22 @@ static int flush_resources(QXLInstance *qin)
return TRUE;
}
-static void client_monitors_config(QXLInstance *qin, VDAgentMonitorsConfig *monitors_config)
+static int client_monitors_config(QXLInstance *qin,
+ VDAgentMonitorsConfig *monitors_config)
{
if (!monitors_config) {
printf("%s: NULL monitors_config\n", __func__);
} else {
printf("%s: %d\n", __func__, monitors_config->num_of_monitors);
}
+ return 0;
+}
+
+static void set_client_capabilities(QXLInstance *qin,
+ uint8_t client_present,
+ uint8_t caps[58])
+{
+ printf("%s: present %d caps %d\n", __func__, client_present, caps[0]);
}
QXLInterface display_sif = {
@@ -731,6 +740,7 @@ QXLInterface display_sif = {
.notify_update = notify_update,
.flush_resources = flush_resources,
.client_monitors_config = client_monitors_config,
+ .set_client_capabilities = set_client_capabilities,
};
/* interface for tests */
commit f844a995bb6c4ac39cd0b115335f27f9ee1b747e
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:36:05 2013 -0400
server/red_worker: turn critical (assert) non error into warning
The situation causing this assert is unknown but it doesn't cause
correctness issues with later rendering, and it is causing an abort.
diff --git a/server/red_worker.c b/server/red_worker.c
index 8f3e478..14d219b 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -11367,7 +11367,10 @@ static void red_push_monitors_config(DisplayChannelClient *dcc)
{
MonitorsConfig *monitors_config = DCC_TO_WORKER(dcc)->monitors_config;
- spice_return_if_fail(monitors_config != NULL);
+ if (monitors_config == NULL) {
+ spice_warning("monitors_config is NULL");
+ return;
+ }
if (!red_channel_client_test_remote_cap(&dcc->common.base,
SPICE_DISPLAY_CAP_MONITORS_CONFIG)) {
commit 97459ddfdb0b1d5456bccb60d0943d94495ac890
Author: Alon Levy <alevy at redhat.com>
Date: Fri May 17 10:35:29 2013 -0400
server/red_worker: s/driver_has_monitors_config/driver_cap_monitors_config/ (plus small comment)
diff --git a/server/red_worker.c b/server/red_worker.c
index fb736b5..8f3e478 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1040,7 +1040,7 @@ typedef struct RedWorker {
uint64_t *command_counter;
#endif
- int driver_has_monitors_config;
+ int driver_cap_monitors_config;
int set_client_capabilities_pending;
} RedWorker;
@@ -11442,7 +11442,9 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
set_monitors_config_to_primary(worker);
if (display_is_connected(worker) && !worker->display_channel->common.during_target_migrate) {
- if (!worker->driver_has_monitors_config) {
+ /* guest created primary, so it will (hopefully) send a monitors_config
+ * now, don't send our own temporary one */
+ if (!worker->driver_cap_monitors_config) {
red_worker_push_monitors_config(worker);
}
red_pipes_add_verb(&worker->display_channel->common.base,
@@ -11746,7 +11748,7 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
/* TODO: raise guest bug (requires added QXL interface) */
return;
}
- worker->driver_has_monitors_config = 1;
+ worker->driver_cap_monitors_config = 1;
if (dev_monitors_config->count == 0) {
spice_warning("ignoring an empty monitors config message from driver");
return;
@@ -11902,7 +11904,7 @@ void handle_dev_driver_unload(void *opaque, void *payload)
{
RedWorker *worker = opaque;
- worker->driver_has_monitors_config = 0;
+ worker->driver_cap_monitors_config = 0;
}
void handle_dev_loadvm_commands(void *opaque, void *payload)
@@ -12171,7 +12173,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
worker->jpeg_state = init_data->jpeg_state;
worker->zlib_glz_state = init_data->zlib_glz_state;
worker->streaming_video = init_data->streaming_video;
- worker->driver_has_monitors_config = 0;
+ worker->driver_cap_monitors_config = 0;
ring_init(&worker->current_list);
image_cache_init(&worker->image_cache);
image_surface_init(worker);
More information about the Spice-commits
mailing list