On Thu, Nov 19, 2015 at 12:16 PM, Frediano Ziglio <fziglio@xxxxxxxxxx> wrote: > > --- > server/Makefile.am | 3 ++ > server/dcc-encoders.c | 1 - > server/dcc-encoders.h | 1 + > server/dcc.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++ > server/dcc.h | 134 +++++++++++++++++++++++++++++++++++++++++++++ > server/display-channel.c | 127 +------------------------------------------ > server/display-channel.h | 112 +------------------------------------- > server/display-limits.h | 27 ++++++++++ > server/red_worker.c | 4 +- > 9 files changed, 308 insertions(+), 238 deletions(-) > create mode 100644 server/dcc.c > create mode 100644 server/dcc.h > create mode 100644 server/display-limits.h > > > Changes: > - add a new display-limits.h header file to keep configuration limits > instead of moving define where compiler is happy. > > > diff --git a/server/Makefile.am b/server/Makefile.am > index 5907dd2..669664a 100644 > --- a/server/Makefile.am > +++ b/server/Makefile.am > @@ -138,6 +138,9 @@ libspice_server_la_SOURCES = \ > utils.h \ > stream.c \ > stream.h \ > + dcc.c \ > + dcc.h \ > + display-limits.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 c9e06e7..3c1fda1 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" > 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/>. > +*/ missing config.h include, which will break make syntax-check. > +#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 s/todo/TODO > + 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..ee2e75f > --- /dev/null > +++ b/server/dcc.h > @@ -0,0 +1,134 @@ > +/* -*- 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" > +#include "display-limits.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 d4fcc7e..9990c71 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..aba7dce 100644 > --- a/server/display-channel.h > +++ b/server/display-channel.h > @@ -49,32 +49,9 @@ > #include "utils.h" > #include "tree.h" > #include "stream.h" > -#include "dcc-encoders.h" > +#include "dcc.h" > +#include "display-limits.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 +92,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 +109,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/display-limits.h b/server/display-limits.h > new file mode 100644 > index 0000000..8d2b41d > --- /dev/null > +++ b/server/display-limits.h > @@ -0,0 +1,27 @@ > +/* -*- 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 DISPLAY_LIMITS_H_ > +#define DISPLAY_LIMITS_H_ > + > +/*** Maximum number of surfaces a guest can create */ > +#define NUM_SURFACES 10000 > + > +/*** Maximum number of streams created by spice-server */ > +#define NUM_STREAMS 50 > + > +#endif /* DISPLAY_LIMITS_H_ */ > diff --git a/server/red_worker.c b/server/red_worker.c > index 5609b47..07dcf1c 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); > -- > 2.4.3 > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel ACK with these 2 simple changes. _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel