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

Fabiano FidĂȘncio fidencio at redhat.com
Fri Oct 23 06:24:02 PDT 2015


On Fri, Oct 23, 2015 at 2:13 PM, Frediano Ziglio <fziglio at redhat.com> wrote:
> From: Marc-André Lureau <marcandre.lureau at gmail.com>
>
> Just move some declarations around

Even if it's just moving some declarations around I personally would
prefer it split in two patches (and it seems doable), one with the
split of the cursor channel and another with the split of display
channel.
Anyways, looks good and my suggestion can be ignored :-)

> ---
>  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
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list