> > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > --- > server/Makefile.am | 2 + > server/dcc-encoders.c | 1 - > server/dcc-encoders.h | 1 + > server/dcc.c | 137 > +++++++++++++++++++++++++++++++++++++++++++++++ > server/dcc.h | 133 +++++++++++++++++++++++++++++++++++++++++++++ > server/display-channel.c | 127 +------------------------------------------ > server/display-channel.h | 111 +------------------------------------- > server/red_worker.c | 4 +- > server/red_worker.h | 2 + > server/stream.h | 1 + > 10 files changed, 281 insertions(+), 238 deletions(-) > create mode 100644 server/dcc.c > create mode 100644 server/dcc.h > > diff --git a/server/Makefile.am b/server/Makefile.am > index 5907dd2..ffffd22 100644 > --- a/server/Makefile.am > +++ b/server/Makefile.am > @@ -138,6 +138,8 @@ libspice_server_la_SOURCES = \ > utils.h \ > stream.c \ > stream.h \ > + dcc.c \ > + dcc.h \ > dcc-encoders.c \ > dcc-encoders.h \ > $(NULL) > diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c > index 45db96f..0a0997a 100644 > --- a/server/dcc-encoders.c > +++ b/server/dcc-encoders.c > @@ -20,7 +20,6 @@ > #endif > > #include <glib.h> > -#include <setjmp.h> > > #include "dcc-encoders.h" > #include "display-channel.h" > diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h > index d265f24..1d40252 100644 > --- a/server/dcc-encoders.h > +++ b/server/dcc-encoders.h > @@ -18,6 +18,7 @@ > #ifndef DCC_ENCODERS_H_ > # define DCC_ENCODERS_H_ > > +#include <setjmp.h> > #include "common/marshaller.h" > #include "common/quic.h" > #include "red_channel.h" This include is moved here as some structures uses jmp_buf structure. It's fine, don't know if is worth to move in another patch. > diff --git a/server/dcc.c b/server/dcc.c > new file mode 100644 > index 0000000..5e35708 > --- /dev/null > +++ b/server/dcc.c > @@ -0,0 +1,137 @@ > +/* -*- 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/>. > +*/ config.h missing. > +#include "dcc.h" > +#include "display-channel.h" > + > +DisplayChannelClient *dcc_new(DisplayChannel *display, > + RedClient *client, RedsStream *stream, > + int mig_target, > + uint32_t *common_caps, int num_common_caps, > + uint32_t *caps, int num_caps, > + SpiceImageCompression image_compression, > + spice_wan_compression_t jpeg_state, > + spice_wan_compression_t zlib_glz_state) > + > +{ > + DisplayChannelClient *dcc; > + > + dcc = (DisplayChannelClient*)common_channel_new_client( > + COMMON_CHANNEL(display), sizeof(DisplayChannelClient), > + client, stream, mig_target, TRUE, > + common_caps, num_common_caps, > + caps, num_caps); > + spice_return_val_if_fail(dcc, NULL); > + > + ring_init(&dcc->palette_cache_lru); > + dcc->palette_cache_available = CLIENT_PALETTE_CACHE_SIZE; > + dcc->image_compression = image_compression; > + dcc->jpeg_state = jpeg_state; > + dcc->zlib_glz_state = zlib_glz_state; > + // todo: tune quality according to bandwidth > + dcc->jpeg_quality = 85; > + > + dcc_encoders_init(dcc); > + > + return dcc; > +} > + > +void dcc_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent) > +{ > + StreamClipItem *item = stream_clip_item_new(dcc, agent); > + int n_rects; > + > + item->clip_type = SPICE_CLIP_TYPE_RECTS; > + > + n_rects = pixman_region32_n_rects(&agent->clip); > + item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect), > sizeof(SpiceClipRects)); > + item->rects->num_rects = n_rects; > + region_ret_rects(&agent->clip, item->rects->rects, n_rects); > + > + red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), (PipeItem *)item); > +} > + > +static MonitorsConfigItem *monitors_config_item_new(RedChannel* channel, > + MonitorsConfig > *monitors_config) > +{ > + MonitorsConfigItem *mci; > + > + mci = (MonitorsConfigItem *)spice_malloc(sizeof(*mci)); > + mci->monitors_config = monitors_config; > + > + red_channel_pipe_item_init(channel, > + &mci->pipe_item, > PIPE_ITEM_TYPE_MONITORS_CONFIG); > + return mci; > +} > + > +void dcc_push_monitors_config(DisplayChannelClient *dcc) > +{ > + DisplayChannel *dc = DCC_TO_DC(dcc); > + MonitorsConfig *monitors_config = dc->monitors_config; > + MonitorsConfigItem *mci; > + > + 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)) > { > + return; > + } > + > + mci = monitors_config_item_new(dcc->common.base.channel, > + > monitors_config_ref(dc->monitors_config)); > + red_channel_client_pipe_add(&dcc->common.base, &mci->pipe_item); > + red_channel_client_push(&dcc->common.base); > +} > + > +static SurfaceDestroyItem *surface_destroy_item_new(RedChannel *channel, > + uint32_t surface_id) > +{ > + SurfaceDestroyItem *destroy; > + > + destroy = spice_malloc(sizeof(SurfaceDestroyItem)); > + destroy->surface_destroy.surface_id = surface_id; > + red_channel_pipe_item_init(channel, &destroy->pipe_item, > + PIPE_ITEM_TYPE_DESTROY_SURFACE); > + > + return destroy; > +} > + > +void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id) > +{ > + DisplayChannel *display; > + RedChannel *channel; > + SurfaceDestroyItem *destroy; > + > + if (!dcc) { > + return; > + } > + > + display = DCC_TO_DC(dcc); > + channel = RED_CHANNEL(display); > + > + if (COMMON_CHANNEL(display)->during_target_migrate || > + !dcc->surface_client_created[surface_id]) { > + return; > + } > + > + dcc->surface_client_created[surface_id] = FALSE; > + destroy = surface_destroy_item_new(channel, surface_id); > + red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), > &destroy->pipe_item); > +} > diff --git a/server/dcc.h b/server/dcc.h > new file mode 100644 > index 0000000..b66f730 > --- /dev/null > +++ b/server/dcc.h > @@ -0,0 +1,133 @@ > +/* -*- 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 DCC_H_ > +# define DCC_H_ > + > +#include "red_worker.h" > +#include "pixmap-cache.h" > +#include "cache-item.h" > +#include "dcc-encoders.h" > +#include "stream.h" > + > +#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) > +#define CLIENT_PALETTE_CACHE_SIZE 128 > + > +/* Each drawable can refer to at most 3 images: src, brush and mask */ > +#define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3 > + > +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; > + > +struct DisplayChannelClient { > + CommonChannelClient common; > + SpiceImageCompression image_compression; > + spice_wan_compression_t jpeg_state; > + spice_wan_compression_t zlib_glz_state; > + int jpeg_quality; > + int zlib_level; > + > + QuicData quic_data; > + QuicContext *quic; > + LzData lz_data; > + LzContext *lz; > + JpegData jpeg_data; > + JpegEncoderContext *jpeg; > +#ifdef USE_LZ4 > + Lz4Data lz4_data; > + Lz4EncoderContext *lz4; > +#endif > + ZlibData zlib_data; > + ZlibEncoder *zlib; > + > + 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!!! > + > + 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; > +}; > + > +#define DCC_TO_WORKER(dcc) \ > + (SPICE_CONTAINEROF((dcc)->common.base.channel, CommonChannel, > base)->worker) > +#define DCC_TO_DC(dcc) \ > + SPICE_CONTAINEROF((dcc)->common.base.channel, DisplayChannel, > common.base) > +#define RCC_TO_DCC(rcc) SPICE_CONTAINEROF((rcc), DisplayChannelClient, > common.base) > + > + > +DisplayChannelClient* dcc_new > (DisplayChannel *display, > + > RedClient > *client, > + > RedsStream > *stream, > + int > mig_target, > + > uint32_t > *common_caps, > + int > num_common_caps, > + > uint32_t > *caps, > + int > num_caps, > + > SpiceImageCompression > image_compression, > + > spice_wan_compression_t > jpeg_state, > + > spice_wan_compression_t > zlib_glz_state); > +void dcc_push_monitors_config > (DisplayChannelClient *dcc); > +void dcc_destroy_surface > (DisplayChannelClient *dcc, > + > uint32_t > surface_id); > +void dcc_stream_agent_clip > (DisplayChannelClient* dcc, > + > StreamAgent > *agent); > +void dcc_create_stream > (DisplayChannelClient *dcc, > + Stream > *stream); > + > +#endif /* DCC_H_ */ > diff --git a/server/display-channel.c b/server/display-channel.c > index aed2080..c671571 100644 > --- a/server/display-channel.c > +++ b/server/display-channel.c > @@ -135,53 +135,6 @@ void display_channel_compress_stats_print(const > DisplayChannel *display_channel) > #endif > } > > -DisplayChannelClient *dcc_new(DisplayChannel *display, > - RedClient *client, RedsStream *stream, > - int mig_target, > - uint32_t *common_caps, int num_common_caps, > - uint32_t *caps, int num_caps, > - SpiceImageCompression image_compression, > - spice_wan_compression_t jpeg_state, > - spice_wan_compression_t zlib_glz_state) > - > -{ > - DisplayChannelClient *dcc; > - > - dcc = (DisplayChannelClient*)common_channel_new_client( > - (CommonChannel *)display, sizeof(DisplayChannelClient), > - client, stream, mig_target, TRUE, > - common_caps, num_common_caps, > - caps, num_caps); > - spice_return_val_if_fail(dcc, NULL); > - > - ring_init(&dcc->palette_cache_lru); > - dcc->palette_cache_available = CLIENT_PALETTE_CACHE_SIZE; > - dcc->image_compression = image_compression; > - dcc->jpeg_state = jpeg_state; > - dcc->zlib_glz_state = zlib_glz_state; > - // todo: tune quality according to bandwidth > - dcc->jpeg_quality = 85; > - > - dcc_encoders_init(dcc); > - > - return dcc; > -} > - > -void dcc_add_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent > *agent) > -{ > - StreamClipItem *item = stream_clip_item_new(dcc, agent); > - int n_rects; > - > - item->clip_type = SPICE_CLIP_TYPE_RECTS; > - > - n_rects = pixman_region32_n_rects(&agent->clip); > - item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect), > sizeof(SpiceClipRects)); > - item->rects->num_rects = n_rects; > - region_ret_rects(&agent->clip, item->rects->rects, n_rects); > - > - red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), (PipeItem *)item); > -} > - > MonitorsConfig* monitors_config_ref(MonitorsConfig *monitors_config) > { > monitors_config->refs++; > @@ -227,82 +180,6 @@ MonitorsConfig* monitors_config_new(QXLHead *heads, > ssize_t nheads, ssize_t max) > return mc; > } > > -static MonitorsConfigItem *monitors_config_item_new(RedChannel* channel, > - MonitorsConfig > *monitors_config) > -{ > - MonitorsConfigItem *mci; > - > - mci = (MonitorsConfigItem *)spice_malloc(sizeof(*mci)); > - mci->monitors_config = monitors_config; > - > - red_channel_pipe_item_init(channel, > - &mci->pipe_item, > PIPE_ITEM_TYPE_MONITORS_CONFIG); > - return mci; > -} > - > -static void red_monitors_config_item_add(DisplayChannelClient *dcc) > -{ > - DisplayChannel *dc = DCC_TO_DC(dcc); > - MonitorsConfigItem *mci; > - > - mci = monitors_config_item_new(dcc->common.base.channel, > - > monitors_config_ref(dc->monitors_config)); > - red_channel_client_pipe_add(&dcc->common.base, &mci->pipe_item); > -} > - > -void dcc_push_monitors_config(DisplayChannelClient *dcc) > -{ > - MonitorsConfig *monitors_config = DCC_TO_DC(dcc)->monitors_config; > - > - 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)) > { > - return; > - } > - red_monitors_config_item_add(dcc); > - red_channel_client_push(&dcc->common.base); > -} > - > -static SurfaceDestroyItem *surface_destroy_item_new(RedChannel *channel, > - uint32_t surface_id) > -{ > - SurfaceDestroyItem *destroy; > - > - destroy = spice_malloc(sizeof(SurfaceDestroyItem)); > - destroy->surface_destroy.surface_id = surface_id; > - red_channel_pipe_item_init(channel, &destroy->pipe_item, > - PIPE_ITEM_TYPE_DESTROY_SURFACE); > - > - return destroy; > -} > - > -void dcc_push_destroy_surface(DisplayChannelClient *dcc, uint32_t > surface_id) > -{ > - DisplayChannel *display; > - RedChannel *channel; > - SurfaceDestroyItem *destroy; > - > - if (!dcc) { > - return; > - } > - > - display = DCC_TO_DC(dcc); > - channel = RED_CHANNEL(display); > - > - if (COMMON_CHANNEL(display)->during_target_migrate || > - !dcc->surface_client_created[surface_id]) { > - return; > - } > - > - dcc->surface_client_created[surface_id] = FALSE; > - destroy = surface_destroy_item_new(channel, surface_id); > - red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), > &destroy->pipe_item); > -} > - > int display_channel_get_streams_timeout(DisplayChannel *display) > { > int timeout = INT_MAX; > @@ -395,7 +272,7 @@ void display_channel_surface_unref(DisplayChannel > *display, uint32_t surface_id) > region_destroy(&surface->draw_dirty_region); > surface->context.canvas = NULL; > FOREACH_DCC(display, link, next, dcc) { > - dcc_push_destroy_surface(dcc, surface_id); > + dcc_destroy_surface(dcc, surface_id); > } > > spice_warn_if(!ring_is_empty(&surface->depend_on_me)); > @@ -442,7 +319,7 @@ static void streams_update_visible_region(DisplayChannel > *display, Drawable *dra > if (region_intersects(&agent->vis_region, > &drawable->tree_item.base.rgn)) { > region_exclude(&agent->vis_region, > &drawable->tree_item.base.rgn); > region_exclude(&agent->clip, &drawable->tree_item.base.rgn); > - dcc_add_stream_agent_clip(dcc, agent); > + dcc_stream_agent_clip(dcc, agent); > } > } > } > diff --git a/server/display-channel.h b/server/display-channel.h > index 90f8455..ee107e8 100644 > --- a/server/display-channel.h > +++ b/server/display-channel.h > @@ -49,32 +49,8 @@ > #include "utils.h" > #include "tree.h" > #include "stream.h" > -#include "dcc-encoders.h" > +#include "dcc.h" > > -#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) > - > -#define CLIENT_PALETTE_CACHE_SIZE 128 > - > -/* 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 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 DependItem { > Drawable *drawable; > @@ -115,72 +91,6 @@ struct Drawable { > SAFE_FOREACH(link, next, drawable, &(drawable)->pipes, dpi, > LINK_TO_DPI(link)) > > > -struct DisplayChannelClient { > - CommonChannelClient common; > - SpiceImageCompression image_compression; > - spice_wan_compression_t jpeg_state; > - spice_wan_compression_t zlib_glz_state; > - int jpeg_quality; > - int zlib_level; > - > - QuicData quic_data; > - QuicContext *quic; > - LzData lz_data; > - LzContext *lz; > - JpegData jpeg_data; > - JpegEncoderContext *jpeg; > -#ifdef USE_LZ4 > - Lz4Data lz4_data; > - Lz4EncoderContext *lz4; > -#endif > - ZlibData zlib_data; > - ZlibEncoder *zlib; > - > - 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!!! > - > - 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; > -}; > - > -#define DCC_TO_WORKER(dcc) \ > - (SPICE_CONTAINEROF((dcc)->common.base.channel, CommonChannel, > base)->worker) > -#define DCC_TO_DC(dcc) \ > - SPICE_CONTAINEROF((dcc)->common.base.channel, DisplayChannel, > common.base) > -#define RCC_TO_DCC(rcc) SPICE_CONTAINEROF((rcc), DisplayChannelClient, > common.base) > - > - > enum { > PIPE_ITEM_TYPE_DRAW = PIPE_ITEM_TYPE_COMMON_LAST, > PIPE_ITEM_TYPE_IMAGE, > @@ -198,25 +108,6 @@ enum { > PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT, > }; > > -DisplayChannelClient* dcc_new > (DisplayChannel *display, > - > RedClient > *client, > - > RedsStream > *stream, > - int > mig_target, > - > uint32_t > *common_caps, > - int > num_common_caps, > - > uint32_t > *caps, > - int > num_caps, > - > SpiceImageCompression > image_compression, > - > spice_wan_compression_t > jpeg_state, > - > spice_wan_compression_t > zlib_glz_state); > -void dcc_push_monitors_config > (DisplayChannelClient *dcc); > -void dcc_push_destroy_surface > (DisplayChannelClient *dcc, > - > uint32_t > surface_id); > -void dcc_add_stream_agent_clip > (DisplayChannelClient* dcc, > - > StreamAgent > *agent); > -void dcc_create_stream > (DisplayChannelClient *dcc, > - Stream > *stream); > - > typedef struct DrawablePipeItem { > RingItem base; /* link for a list of pipe items held by Drawable */ > PipeItem dpi_pipe_item; /* link for the client's pipe itself */ > diff --git a/server/red_worker.c b/server/red_worker.c > index 67493b6..f06e23b 100644 > --- a/server/red_worker.c > +++ b/server/red_worker.c > @@ -274,7 +274,7 @@ void attach_stream(DisplayChannel *display, Drawable > *drawable, Stream *stream) > if (!region_is_equal(&clip_in_draw_dest, > &drawable->tree_item.base.rgn)) { > region_remove(&agent->clip, &drawable->red_drawable->bbox); > region_or(&agent->clip, &drawable->tree_item.base.rgn); > - dcc_add_stream_agent_clip(dcc, agent); > + dcc_stream_agent_clip(dcc, agent); > } > #ifdef STREAM_STATS > agent->stats.num_input_frames++; > @@ -933,7 +933,7 @@ static void > dcc_detach_stream_gracefully(DisplayChannelClient *dcc, > > /* stopping the client from playing older frames at once*/ > region_clear(&agent->clip); > - dcc_add_stream_agent_clip(dcc, agent); > + dcc_stream_agent_clip(dcc, agent); > > if (region_is_empty(&agent->vis_region)) { > spice_debug("stream %d: vis region empty", stream_id); > diff --git a/server/red_worker.h b/server/red_worker.h > index 729ce2b..c64dcaf 100644 > --- a/server/red_worker.h > +++ b/server/red_worker.h > @@ -23,6 +23,8 @@ > #include "red_common.h" > #include "red_dispatcher.h" > > +#define NUM_SURFACES 10000 > + > typedef struct RedWorker RedWorker; > > typedef struct CommonChannelClient { sounds weird here... > diff --git a/server/stream.h b/server/stream.h > index 0577dc8..5d95ae6 100644 > --- a/server/stream.h > +++ b/server/stream.h > @@ -40,6 +40,7 @@ > #define RED_STREAM_DEFAULT_HIGH_START_BIT_RATE (10 * 1024 * 1024) // 10Mbps > #define RED_STREAM_DEFAULT_LOW_START_BIT_RATE (2.5 * 1024 * 1024) // 2.5Mbps > #define MAX_FPS 30 > +#define NUM_STREAMS 50 > > /* move back to display_channel once struct private */ > typedef struct DisplayChannel DisplayChannel; Actually this define is the size of an array inside DisplayChannel which is defined in another include. I think streams are really messy. DisplayChannel uses Streams while Streams uses DisplayChannel. This circular dependency... well, usually a sign of bad design. IMHO this define should be in display_channel.h. Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel