> > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > 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 \ I think this file should cursor-channel.h as renamed some patches later > 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); > Beside above rename I would ack Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel