[Spice-devel] [PATCH 04/14] server: start separate display/cursor channel headers

Frediano Ziglio fziglio at redhat.com
Fri Oct 23 05:13:28 PDT 2015


From: Marc-André Lureau <marcandre.lureau at gmail.com>

Just move some declarations around
---
 server/Makefile.am       |   2 +
 server/cursor_channel.h  |  62 +++++++++++
 server/display-channel.h | 211 +++++++++++++++++++++++++++++++++++++
 server/red_worker.c      | 264 +----------------------------------------------
 server/red_worker.h      |  20 ++++
 5 files changed, 297 insertions(+), 262 deletions(-)
 create mode 100644 server/cursor_channel.h
 create mode 100644 server/display-channel.h

diff --git a/server/Makefile.am b/server/Makefile.am
index cd4686a..a701170 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -106,6 +106,8 @@ libspice_server_la_SOURCES =			\
 	red_time.h				\
 	red_worker.c				\
 	red_worker.h				\
+	display-channel.h			\
+	cursor_channel.h			\
 	reds.c					\
 	reds.h					\
 	reds-private.h				\
diff --git a/server/cursor_channel.h b/server/cursor_channel.h
new file mode 100644
index 0000000..0104988
--- /dev/null
+++ b/server/cursor_channel.h
@@ -0,0 +1,62 @@
+#ifndef CURSOR_CHANNEL_H_
+# define CURSOR_CHANNEL_H_
+
+#include "red_worker.h"
+#include "stat.h"
+
+#define CLIENT_CURSOR_CACHE_SIZE 256
+
+#define CURSOR_CACHE_HASH_SHIFT 8
+#define CURSOR_CACHE_HASH_SIZE (1 << CURSOR_CACHE_HASH_SHIFT)
+#define CURSOR_CACHE_HASH_MASK (CURSOR_CACHE_HASH_SIZE - 1)
+#define CURSOR_CACHE_HASH_KEY(id) ((id) & CURSOR_CACHE_HASH_MASK)
+
+typedef struct CursorItem {
+    uint32_t group_id;
+    int refs;
+    RedCursorCmd *red_cursor;
+} CursorItem;
+
+typedef struct CursorPipeItem {
+    PipeItem base;
+    CursorItem *cursor_item;
+    int refs;
+} CursorPipeItem;
+
+typedef struct LocalCursor {
+    CursorItem base;
+    SpicePoint16 position;
+    uint32_t data_size;
+    SpiceCursor red_cursor;
+} LocalCursor;
+
+typedef struct CursorChannelClient {
+    CommonChannelClient common;
+
+    CacheItem *cursor_cache[CURSOR_CACHE_HASH_SIZE];
+    Ring cursor_cache_lru;
+    long cursor_cache_available;
+    uint32_t cursor_cache_items;
+} CursorChannelClient;
+
+typedef struct CursorChannel {
+    CommonChannel common; // Must be the first thing
+
+#ifdef RED_STATISTICS
+    StatNodeRef stat;
+#endif
+} CursorChannel;
+
+typedef struct _CursorItem _CursorItem;
+
+struct _CursorItem {
+    union {
+        CursorItem cursor_item;
+        _CursorItem *next;
+    } u;
+};
+
+G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
+
+
+#endif /* CURSOR_CHANNEL_H_ */
diff --git a/server/display-channel.h b/server/display-channel.h
new file mode 100644
index 0000000..ecf764d
--- /dev/null
+++ b/server/display-channel.h
@@ -0,0 +1,211 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2009-2015 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef RED_WORKER_CLIENT_H_
+# define RED_WORKER_CLIENT_H_
+
+#include "red_worker.h"
+#include "pixmap-cache.h"
+
+typedef int64_t red_time_t;
+
+typedef struct Drawable Drawable;
+
+#define PALETTE_CACHE_HASH_SHIFT 8
+#define PALETTE_CACHE_HASH_SIZE (1 << PALETTE_CACHE_HASH_SHIFT)
+#define PALETTE_CACHE_HASH_MASK (PALETTE_CACHE_HASH_SIZE - 1)
+#define PALETTE_CACHE_HASH_KEY(id) ((id) & PALETTE_CACHE_HASH_MASK)
+
+/* Each drawable can refer to at most 3 images: src, brush and mask */
+#define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3
+
+#define NUM_STREAMS 50
+#define NUM_SURFACES 10000
+
+typedef struct CacheItem CacheItem;
+
+struct CacheItem {
+    union {
+        PipeItem pipe_data;
+        struct {
+            RingItem lru_link;
+            CacheItem *next;
+        } cache_data;
+    } u;
+    uint64_t id;
+    size_t size;
+    uint32_t inval_type;
+};
+
+#define RED_COMPRESS_BUF_SIZE (1024 * 64)
+typedef struct RedCompressBuf RedCompressBuf;
+struct RedCompressBuf {
+    uint32_t buf[RED_COMPRESS_BUF_SIZE / 4];
+    RedCompressBuf *next;
+    RedCompressBuf *send_next;
+};
+
+typedef struct WaitForChannels {
+    SpiceMsgWaitForChannels header;
+    SpiceWaitForChannel buf[MAX_CACHE_CLIENTS];
+} WaitForChannels;
+
+typedef struct FreeList {
+    int res_size;
+    SpiceResourceList *res;
+    uint64_t sync[MAX_CACHE_CLIENTS];
+    WaitForChannels wait;
+} FreeList;
+
+typedef struct GlzSharedDictionary {
+    RingItem base;
+    GlzEncDictContext *dict;
+    uint32_t refs;
+    uint8_t id;
+    pthread_rwlock_t encode_lock;
+    int migrate_freeze;
+    RedClient *client; // channel clients of the same client share the dict
+} GlzSharedDictionary;
+
+typedef struct  {
+    DisplayChannelClient *dcc;
+    RedCompressBuf *bufs_head;
+    RedCompressBuf *bufs_tail;
+    jmp_buf jmp_env;
+    union {
+        struct {
+            SpiceChunks *chunks;
+            int next;
+            int stride;
+            int reverse;
+        } lines_data;
+        struct {
+            RedCompressBuf* next;
+            int size_left;
+        } compressed_data; // for encoding data that was already compressed by another method
+    } u;
+    char message_buf[512];
+} EncoderData;
+
+typedef struct {
+    GlzEncoderUsrContext usr;
+    EncoderData data;
+} GlzData;
+
+typedef struct Stream Stream;
+struct Stream {
+    uint8_t refs;
+    Drawable *current;
+    red_time_t last_time;
+    int width;
+    int height;
+    SpiceRect dest_area;
+    int top_down;
+    Stream *next;
+    RingItem link;
+
+    uint32_t num_input_frames;
+    uint64_t input_fps_start_time;
+    uint32_t input_fps;
+};
+
+#define STREAM_STATS
+#ifdef STREAM_STATS
+typedef struct StreamStats {
+   uint64_t num_drops_pipe;
+   uint64_t num_drops_fps;
+   uint64_t num_frames_sent;
+   uint64_t num_input_frames;
+   uint64_t size_sent;
+
+   uint64_t start;
+   uint64_t end;
+} StreamStats;
+#endif
+
+typedef struct StreamAgent {
+    QRegion vis_region; /* the part of the surface area that is currently occupied by video
+                           fragments */
+    QRegion clip;       /* the current video clipping. It can be different from vis_region:
+                           for example, let c1 be the clip area at time t1, and c2
+                           be the clip area at time t2, where t1 < t2. If c1 contains c2, and
+                           at least part of c1/c2, hasn't been covered by a non-video images,
+                           vis_region will contain c2 and also the part of c1/c2 that still
+                           displays fragments of the video */
+
+    PipeItem create_item;
+    PipeItem destroy_item;
+    Stream *stream;
+    uint64_t last_send_time;
+    MJpegEncoder *mjpeg_encoder;
+    DisplayChannelClient *dcc;
+
+    int frames;
+    int drops;
+    int fps;
+
+    uint32_t report_id;
+    uint32_t client_required_latency;
+#ifdef STREAM_STATS
+    StreamStats stats;
+#endif
+} StreamAgent;
+
+struct DisplayChannelClient {
+    CommonChannelClient common;
+
+    int expect_init;
+
+    PixmapCache *pixmap_cache;
+    uint32_t pixmap_cache_generation;
+    int pending_pixmaps_sync;
+
+    CacheItem *palette_cache[PALETTE_CACHE_HASH_SIZE];
+    Ring palette_cache_lru;
+    long palette_cache_available;
+    uint32_t palette_cache_items;
+
+    struct {
+        uint32_t stream_outbuf_size;
+        uint8_t *stream_outbuf; // caution stream buffer is also used as compress bufs!!!
+
+        RedCompressBuf *used_compress_bufs;
+
+        FreeList free_list;
+        uint64_t pixmap_cache_items[MAX_DRAWABLE_PIXMAP_CACHE_ITEMS];
+        int num_pixmap_cache_items;
+    } send_data;
+
+    /* global lz encoding entities */
+    GlzSharedDictionary *glz_dict;
+    GlzEncoderContext   *glz;
+    GlzData glz_data;
+
+    Ring glz_drawables;               // all the living lz drawable, ordered by encoding time
+    Ring glz_drawables_inst_to_free;               // list of instances to be freed
+    pthread_mutex_t glz_drawables_inst_to_free_lock;
+
+    uint8_t surface_client_created[NUM_SURFACES];
+    QRegion surface_client_lossy_region[NUM_SURFACES];
+
+    StreamAgent stream_agents[NUM_STREAMS];
+    int use_mjpeg_encoder_rate_control;
+    uint32_t streams_max_latency;
+    uint64_t streams_max_bit_rate;
+};
+
+#endif /* RED_WORKER_CLIENT_H_ */
diff --git a/server/red_worker.c b/server/red_worker.c
index b254ee0..4b69a38 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -93,6 +93,8 @@
 #include "spice_bitmap_utils.h"
 #include "spice_image_cache.h"
 #include "pixmap-cache.h"
+#include "display-channel.h"
+#include "cursor_channel.h"
 
 //#define COMPRESS_STAT
 //#define DUMP_BITMAP
@@ -127,13 +129,9 @@
 #define FPS_TEST_INTERVAL 1
 #define MAX_FPS 30
 
-#define RED_COMPRESS_BUF_SIZE (1024 * 64)
-
 #define ZLIB_DEFAULT_COMPRESSION_LEVEL 3
 #define MIN_GLZ_SIZE_FOR_ZLIB 100
 
-typedef int64_t red_time_t;
-
 #define VALIDATE_SURFACE_RET(worker, surface_id) \
     if (!validate_surface(worker, surface_id)) { \
         rendering_incorrect(__func__); \
@@ -300,21 +298,6 @@ typedef struct VerbItem {
 
 #define MAX_LZ_ENCODERS MAX_CACHE_CLIENTS
 
-typedef struct CacheItem CacheItem;
-
-struct CacheItem {
-    union {
-        PipeItem pipe_data;
-        struct {
-            RingItem lru_link;
-            CacheItem *next;
-        } cache_data;
-    } u;
-    uint64_t id;
-    size_t size;
-    uint32_t inval_type;
-};
-
 typedef struct SurfaceCreateItem {
     SpiceMsgSurfaceCreate surface_create;
     PipeItem pipe_item;
@@ -343,45 +326,13 @@ typedef struct StreamActivateReportItem {
     uint32_t stream_id;
 } StreamActivateReportItem;
 
-typedef struct CursorItem {
-    uint32_t group_id;
-    int refs;
-    RedCursorCmd *red_cursor;
-} CursorItem;
-
-typedef struct CursorPipeItem {
-    PipeItem base;
-    CursorItem *cursor_item;
-    int refs;
-} CursorPipeItem;
-
-typedef struct LocalCursor {
-    CursorItem base;
-    SpicePoint16 position;
-    uint32_t data_size;
-    SpiceCursor red_cursor;
-} LocalCursor;
-
 #define MAX_PIPE_SIZE 50
-#define CHANNEL_RECEIVE_BUF_SIZE 1024
 
 #define WIDE_CLIENT_ACK_WINDOW 40
 #define NARROW_CLIENT_ACK_WINDOW 20
 
-#define CLIENT_CURSOR_CACHE_SIZE 256
-
-#define CURSOR_CACHE_HASH_SHIFT 8
-#define CURSOR_CACHE_HASH_SIZE (1 << CURSOR_CACHE_HASH_SHIFT)
-#define CURSOR_CACHE_HASH_MASK (CURSOR_CACHE_HASH_SIZE - 1)
-#define CURSOR_CACHE_HASH_KEY(id) ((id) & CURSOR_CACHE_HASH_MASK)
-
 #define CLIENT_PALETTE_CACHE_SIZE 128
 
-#define PALETTE_CACHE_HASH_SHIFT 8
-#define PALETTE_CACHE_HASH_SIZE (1 << PALETTE_CACHE_HASH_SHIFT)
-#define PALETTE_CACHE_HASH_MASK (PALETTE_CACHE_HASH_SIZE - 1)
-#define PALETTE_CACHE_HASH_KEY(id) ((id) & PALETTE_CACHE_HASH_MASK)
-
 typedef struct ImageItem {
     PipeItem link;
     int refs;
@@ -397,8 +348,6 @@ typedef struct ImageItem {
     uint8_t data[0];
 } ImageItem;
 
-typedef struct Drawable Drawable;
-
 typedef struct DisplayChannel DisplayChannel;
 
 enum {
@@ -407,65 +356,6 @@ enum {
     STREAM_FRAME_CONTAINER,
 };
 
-typedef struct Stream Stream;
-struct Stream {
-    uint8_t refs;
-    Drawable *current;
-    red_time_t last_time;
-    int width;
-    int height;
-    SpiceRect dest_area;
-    int top_down;
-    Stream *next;
-    RingItem link;
-
-    uint32_t num_input_frames;
-    uint64_t input_fps_start_time;
-    uint32_t input_fps;
-};
-
-#define STREAM_STATS
-#ifdef STREAM_STATS
-typedef struct StreamStats {
-   uint64_t num_drops_pipe;
-   uint64_t num_drops_fps;
-   uint64_t num_frames_sent;
-   uint64_t num_input_frames;
-   uint64_t size_sent;
-
-   uint64_t start;
-   uint64_t end;
-} StreamStats;
-#endif
-
-typedef struct StreamAgent {
-    QRegion vis_region; /* the part of the surface area that is currently occupied by video
-                           fragments */
-    QRegion clip;       /* the current video clipping. It can be different from vis_region:
-                           for example, let c1 be the clip area at time t1, and c2
-                           be the clip area at time t2, where t1 < t2. If c1 contains c2, and
-                           at least part of c1/c2, hasn't been covered by a non-video images,
-                           vis_region will contain c2 and also the part of c1/c2 that still
-                           displays fragments of the video */
-
-    PipeItem create_item;
-    PipeItem destroy_item;
-    Stream *stream;
-    uint64_t last_send_time;
-    MJpegEncoder *mjpeg_encoder;
-    DisplayChannelClient *dcc;
-
-    int frames;
-    int drops;
-    int fps;
-
-    uint32_t report_id;
-    uint32_t client_required_latency;
-#ifdef STREAM_STATS
-    StreamStats stats;
-#endif
-} StreamAgent;
-
 typedef struct StreamClipItem {
     PipeItem base;
     int refs;
@@ -474,13 +364,6 @@ typedef struct StreamClipItem {
     SpiceClipRects *rects;
 } StreamClipItem;
 
-typedef struct RedCompressBuf RedCompressBuf;
-struct RedCompressBuf {
-    uint32_t buf[RED_COMPRESS_BUF_SIZE / 4];
-    RedCompressBuf *next;
-    RedCompressBuf *send_next;
-};
-
 static const int BITMAP_FMT_IS_PLT[] = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
 static const int BITMAP_FMP_BYTES_PER_PIXEL[] = {0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 1};
 
@@ -488,40 +371,6 @@ static const int BITMAP_FMP_BYTES_PER_PIXEL[] = {0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 1
     (bitmap_fmt_is_rgb(f)        &&                                     \
      ((f) != SPICE_BITMAP_FMT_8BIT_A))
 
-#define NUM_STREAMS 50
-
-typedef struct WaitForChannels {
-    SpiceMsgWaitForChannels header;
-    SpiceWaitForChannel buf[MAX_CACHE_CLIENTS];
-} WaitForChannels;
-
-typedef struct FreeList {
-    int res_size;
-    SpiceResourceList *res;
-    uint64_t sync[MAX_CACHE_CLIENTS];
-    WaitForChannels wait;
-} FreeList;
-
-typedef struct  {
-    DisplayChannelClient *dcc;
-    RedCompressBuf *bufs_head;
-    RedCompressBuf *bufs_tail;
-    jmp_buf jmp_env;
-    union {
-        struct {
-            SpiceChunks *chunks;
-            int next;
-            int stride;
-            int reverse;
-        } lines_data;
-        struct {
-            RedCompressBuf* next;
-            int size_left;
-        } compressed_data; // for encoding data that was already compressed by another method
-    } u;
-    char message_buf[512];
-} EncoderData;
-
 typedef struct {
     QuicUsrContext usr;
     EncoderData data;
@@ -533,11 +382,6 @@ typedef struct {
 } LzData;
 
 typedef struct {
-    GlzEncoderUsrContext usr;
-    EncoderData data;
-} GlzData;
-
-typedef struct {
     JpegEncoderUsrContext usr;
     EncoderData data;
 } JpegData;
@@ -590,83 +434,6 @@ struct RedGlzDrawable {
 pthread_mutex_t glz_dictionary_list_lock = PTHREAD_MUTEX_INITIALIZER;
 Ring glz_dictionary_list = {&glz_dictionary_list, &glz_dictionary_list};
 
-typedef struct GlzSharedDictionary {
-    RingItem base;
-    GlzEncDictContext *dict;
-    uint32_t refs;
-    uint8_t id;
-    pthread_rwlock_t encode_lock;
-    int migrate_freeze;
-    RedClient *client; // channel clients of the same client share the dict
-} GlzSharedDictionary;
-
-#define NUM_SURFACES 10000
-
-typedef struct CommonChannel {
-    RedChannel base; // Must be the first thing
-    struct RedWorker *worker;
-    uint8_t recv_buf[CHANNEL_RECEIVE_BUF_SIZE];
-    uint32_t id_alloc; // bitfield. TODO - use this instead of shift scheme.
-    int during_target_migrate; /* TRUE when the client that is associated with the channel
-                                  is during migration. Turned off when the vm is started.
-                                  The flag is used to avoid sending messages that are artifacts
-                                  of the transition from stopped vm to loaded vm (e.g., recreation
-                                  of the primary surface) */
-} CommonChannel;
-
-typedef struct CommonChannelClient {
-    RedChannelClient base;
-    uint32_t id;
-    struct RedWorker *worker;
-    int is_low_bandwidth;
-} CommonChannelClient;
-
-/* Each drawable can refer to at most 3 images: src, brush and mask */
-#define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3
-
-struct DisplayChannelClient {
-    CommonChannelClient common;
-
-    int expect_init;
-
-    PixmapCache *pixmap_cache;
-    uint32_t pixmap_cache_generation;
-    int pending_pixmaps_sync;
-
-    CacheItem *palette_cache[PALETTE_CACHE_HASH_SIZE];
-    Ring palette_cache_lru;
-    long palette_cache_available;
-    uint32_t palette_cache_items;
-
-    struct {
-        uint32_t stream_outbuf_size;
-        uint8_t *stream_outbuf; // caution stream buffer is also used as compress bufs!!!
-
-        RedCompressBuf *used_compress_bufs;
-
-        FreeList free_list;
-        uint64_t pixmap_cache_items[MAX_DRAWABLE_PIXMAP_CACHE_ITEMS];
-        int num_pixmap_cache_items;
-    } send_data;
-
-    /* global lz encoding entities */
-    GlzSharedDictionary *glz_dict;
-    GlzEncoderContext   *glz;
-    GlzData glz_data;
-
-    Ring glz_drawables;               // all the living lz drawable, ordered by encoding time
-    Ring glz_drawables_inst_to_free;               // list of instances to be freed
-    pthread_mutex_t glz_drawables_inst_to_free_lock;
-
-    uint8_t surface_client_created[NUM_SURFACES];
-    QRegion surface_client_lossy_region[NUM_SURFACES];
-
-    StreamAgent stream_agents[NUM_STREAMS];
-    int use_mjpeg_encoder_rate_control;
-    uint32_t streams_max_latency;
-    uint64_t streams_max_bit_rate;
-};
-
 struct DisplayChannel {
     CommonChannel common; // Must be the first thing
 
@@ -694,23 +461,6 @@ struct DisplayChannel {
 #endif
 };
 
-typedef struct CursorChannelClient {
-    CommonChannelClient common;
-
-    CacheItem *cursor_cache[CURSOR_CACHE_HASH_SIZE];
-    Ring cursor_cache_lru;
-    long cursor_cache_available;
-    uint32_t cursor_cache_items;
-} CursorChannelClient;
-
-typedef struct CursorChannel {
-    CommonChannel common; // Must be the first thing
-
-#ifdef RED_STATISTICS
-    StatNodeRef stat;
-#endif
-} CursorChannel;
-
 enum {
     TREE_ITEM_TYPE_DRAWABLE,
     TREE_ITEM_TYPE_CONTAINER,
@@ -802,14 +552,6 @@ struct _Drawable {
     } u;
 };
 
-typedef struct _CursorItem _CursorItem;
-struct _CursorItem {
-    union {
-        CursorItem cursor_item;
-        _CursorItem *next;
-    } u;
-};
-
 typedef struct UpgradeItem {
     PipeItem base;
     int refs;
@@ -11859,8 +11601,6 @@ RedWorker* red_worker_new(QXLInstance *qxl, RedDispatcher *red_dispatcher)
     int i;
     const char *record_filename;
 
-    spice_assert(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
-
     qxl->st->qif->get_init_info(qxl, &init_info);
 
     worker = spice_new0(RedWorker, 1);
diff --git a/server/red_worker.h b/server/red_worker.h
index c1adca4..0f5fac7 100644
--- a/server/red_worker.h
+++ b/server/red_worker.h
@@ -25,6 +25,26 @@
 
 typedef struct RedWorker RedWorker;
 
+typedef struct CommonChannelClient {
+    RedChannelClient base;
+    uint32_t id;
+    struct RedWorker *worker;
+    int is_low_bandwidth;
+} CommonChannelClient;
+
+#define CHANNEL_RECEIVE_BUF_SIZE 1024
+typedef struct CommonChannel {
+    RedChannel base; // Must be the first thing
+    struct RedWorker *worker;
+    uint8_t recv_buf[CHANNEL_RECEIVE_BUF_SIZE];
+    uint32_t id_alloc; // bitfield. TODO - use this instead of shift scheme.
+    int during_target_migrate; /* TRUE when the client that is associated with the channel
+                                  is during migration. Turned off when the vm is started.
+                                  The flag is used to avoid sending messages that are artifacts
+                                  of the transition from stopped vm to loaded vm (e.g., recreation
+                                  of the primary surface) */
+} CommonChannel;
+
 RedWorker* red_worker_new(QXLInstance *qxl, RedDispatcher *red_dispatcher);
 bool       red_worker_run(RedWorker *worker);
 
-- 
2.4.3



More information about the Spice-devel mailing list