Blob Blame History Raw
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
Date: Sun, 2 Nov 2014 22:11:58 +0100
Subject: [PATCH] Remove guest side video time-stamping

The multimedia time is defined by the server side monotonic time [1],
but the drawing time-stamp is done in guest side, so it requires
synchronization between host and guest. This is expensive, when no audio
is playing, there is a ~30x/sec wakeup to update the qxl device mmtime,
and it requires marking dirty the rom region.

Instead, the video timestamping can be done more efficiently on server
side, without visible drawbacks.

[1] a better timestamp could be the audio time, since audio players are
    usually sync with audio time)

Related to:
https://bugzilla.redhat.com/show_bug.cgi?id=912763
---
 server/red_dispatcher.c |  9 ---------
 server/red_worker.c     |  1 +
 server/reds-private.h   |  2 --
 server/reds.c           | 13 -------------
 server/snd_worker.c     |  1 -
 server/spice.h          |  3 ++-
 6 files changed, 3 insertions(+), 26 deletions(-)

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 2ebde63..6ecd3d4 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -749,15 +749,6 @@ static void qxl_worker_loadvm_commands(QXLWorker *qxl_worker,
     red_dispatcher_loadvm_commands((RedDispatcher*)qxl_worker, ext, count);
 }
 
-void red_dispatcher_set_mm_time(uint32_t mm_time)
-{
-    RedDispatcher *now = dispatchers;
-    while (now) {
-        now->qxl->st->qif->set_mm_time(now->qxl, mm_time);
-        now = now->next;
-    }
-}
-
 static inline int calc_compression_level(void)
 {
     spice_assert(streaming_video != STREAM_VIDEO_INVALID);
diff --git a/server/red_worker.c b/server/red_worker.c
index f9179a6..dfa5274 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -4237,6 +4237,7 @@ static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable
         return;
     }
 
+    drawable->mm_time = reds_get_mm_time();
     surface_id = item->surface_id;
 
     worker->surfaces[surface_id].refs++;
diff --git a/server/reds-private.h b/server/reds-private.h
index 9358d27..46899f6 100644
--- a/server/reds-private.h
+++ b/server/reds-private.h
@@ -6,7 +6,6 @@
 #include <spice/protocol.h>
 
 #define MIGRATE_TIMEOUT (1000 * 10) /* 10sec */
-#define MM_TIMER_GRANULARITY_MS (1000 / 30)
 #define MM_TIME_DELTA 400 /*ms*/
 
 typedef struct TicketAuthentication {
@@ -159,7 +158,6 @@ typedef struct RedsState {
     int dispatcher_allows_client_mouse;
     MonitorMode monitor_mode;
     SpiceTimer *mig_timer;
-    SpiceTimer *mm_timer;
 
     int vm_running;
     Ring char_devs_states; /* list of SpiceCharDeviceStateItem */
diff --git a/server/reds.c b/server/reds.c
index 53f21bd..f4c6d1d 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -3574,7 +3574,6 @@ uint32_t reds_get_mm_time(void)
 
 void reds_enable_mm_timer(void)
 {
-    core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
     reds->mm_timer_enabled = TRUE;
     reds->mm_time_latency = MM_TIME_DELTA;
     reds_send_mm_time();
@@ -3582,16 +3581,9 @@ void reds_enable_mm_timer(void)
 
 void reds_disable_mm_timer(void)
 {
-    core->timer_cancel(reds->mm_timer);
     reds->mm_timer_enabled = FALSE;
 }
 
-static void mm_timer_proc(void *opaque)
-{
-    red_dispatcher_set_mm_time(reds_get_mm_time());
-    core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
-}
-
 static SpiceCharDeviceState *attach_to_red_agent(SpiceCharDeviceInstance *sin)
 {
     VDIPortState *state = &reds->agent_state;
@@ -4029,11 +4021,6 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     }
 #endif
 
-    if (!(reds->mm_timer = core->timer_add(mm_timer_proc, NULL))) {
-        spice_error("mm timer create failed");
-    }
-    reds_enable_mm_timer();
-
     if (reds_init_net() < 0) {
         goto err;
     }
diff --git a/server/snd_worker.c b/server/snd_worker.c
index c451031..b6cb62b 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -1113,7 +1113,6 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
         snd_playback_free_frame(playback_channel, playback_channel->pending_frame);
     }
     frame->time = reds_get_mm_time();
-    red_dispatcher_set_mm_time(frame->time);
     playback_channel->pending_frame = frame;
     snd_set_command(&playback_channel->base, SND_PLAYBACK_PCM_MASK);
     snd_playback_send(&playback_channel->base);
diff --git a/server/spice.h b/server/spice.h
index 7b5e04e..9c8e18a 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 #include <sys/socket.h>
+#include <spice/macros.h>
 #include <spice/qxl_dev.h>
 #include <spice/vd_agent.h>
 
@@ -228,7 +229,7 @@ struct QXLInterface {
 
     void (*attache_worker)(QXLInstance *qin, QXLWorker *qxl_worker);
     void (*set_compression_level)(QXLInstance *qin, int level);
-    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time);
+    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time) SPICE_GNUC_DEPRECATED;
 
     void (*get_init_info)(QXLInstance *qin, QXLDevInitInfo *info);
     int (*get_command)(QXLInstance *qin, struct QXLCommandExt *cmd);