[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