I'd like to propose splitting out the changes related to UpgradeItem since they're not really related. I'll post a split patch. On Tue, 2015-11-10 at 14:16 +0000, Frediano Ziglio wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > --- > server/display-channel.h | 24 ++++++++-- > server/red_worker.c | 118 ++++++++++++++++++++++------------------------ > - > 2 files changed, 74 insertions(+), 68 deletions(-) > > diff --git a/server/display-channel.h b/server/display-channel.h > index 898ff01..1566c21 100644 > --- a/server/display-channel.h > +++ b/server/display-channel.h > @@ -273,6 +273,15 @@ void monitors_config_unref > (MonitorsCo > #define NUM_TRACE_ITEMS (1 << TRACE_ITEMS_SHIFT) > #define ITEMS_TRACE_MASK (NUM_TRACE_ITEMS - 1) > > +#define NUM_DRAWABLES 1000 > +typedef struct _Drawable _Drawable; > +struct _Drawable { > + union { > + Drawable drawable; > + _Drawable *next; > + } u; > +}; > + > struct DisplayChannel { > CommonChannel common; // Must be the first thing > > @@ -281,16 +290,17 @@ struct DisplayChannel { > uint32_t num_renderers; > uint32_t renderers[RED_RENDERER_LAST]; > uint32_t renderer; > - > - Ring current_list; // of TreeItem > - uint32_t current_size; > - > int enable_jpeg; > int jpeg_quality; > int enable_zlib_glz_wrap; > int zlib_level; > > - RedCompressBuf *free_compress_bufs; > + Ring current_list; // of TreeItem > + uint32_t current_size; > + > + uint32_t drawable_count; > + _Drawable drawables[NUM_DRAWABLES]; > + _Drawable *free_drawables; > > int stream_video; > uint32_t stream_count; > @@ -302,6 +312,7 @@ struct DisplayChannel { > uint64_t streams_size_total; > > ImageCache image_cache; > + RedCompressBuf *free_compress_bufs; > > #ifdef RED_STATISTICS > uint64_t *cache_hits_counter; > @@ -344,5 +355,8 @@ void display_channel_attach_stream > (DisplayCha > int display_channel_get_streams_timeout > (DisplayChannel *display); > void display_channel_compress_stats_print (const > DisplayChannel *display); > void display_channel_compress_stats_reset > (DisplayChannel *display); > +void display_channel_drawable_unref > (DisplayChannel *display, Drawable *drawable); > + > + > > #endif /* DISPLAY_CHANNEL_H_ */ > diff --git a/server/red_worker.c b/server/red_worker.c > index 86ce7a1..23c54e8 100644 > --- a/server/red_worker.c > +++ b/server/red_worker.c > @@ -300,14 +300,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 _Drawable _Drawable; > -struct _Drawable { > - union { > - Drawable drawable; > - _Drawable *next; > - } u; > -}; > - > typedef struct DrawContext { > SpiceCanvas *canvas; > int canvas_draws_on_surface; > @@ -332,8 +324,6 @@ typedef struct RedSurface { > QXLReleaseInfoExt create, destroy; > } RedSurface; > > -#define NUM_DRAWABLES 1000 > - > typedef struct RedWorker { > pthread_t thread; > clockid_t clockid; > @@ -354,14 +344,10 @@ typedef struct RedWorker { > uint32_t n_surfaces; > SpiceImageSurfaces image_surfaces; > > - uint32_t drawable_count; > uint32_t red_drawable_count; > uint32_t glz_drawable_count; > uint32_t bits_unique; > > - _Drawable drawables[NUM_DRAWABLES]; > - _Drawable *free_drawables; > - > RedMemSlotInfo mem_slots; > > SpiceImageCompression image_compression; > @@ -435,7 +421,6 @@ static void red_draw_drawable(RedWorker *worker, Drawable > *item); > static void red_update_area(RedWorker *worker, const SpiceRect *area, int > surface_id); > static void red_update_area_till(RedWorker *worker, const SpiceRect *area, > int surface_id, > Drawable *last); > -static void red_worker_drawable_unref(RedWorker *worker, Drawable *drawable); > static void detach_stream(DisplayChannel *display, Stream *stream, int > detach_sized); > static inline void display_channel_stream_maintenance(DisplayChannel > *display, Drawable *candidate, Drawable *sect); > static inline void display_begin_send_message(RedChannelClient *rcc); > @@ -635,7 +620,7 @@ DrawablePipeItem *drawable_pipe_item_ref(DrawablePipeItem > *dpi) > > void drawable_pipe_item_unref(DrawablePipeItem *dpi) > { > - RedWorker *worker = DCC_TO_WORKER(dpi->dcc); > + DisplayChannel *display = DCC_TO_DC(dpi->dcc); > > if (--dpi->refs != 0) { > return; > @@ -643,7 +628,7 @@ void drawable_pipe_item_unref(DrawablePipeItem *dpi) > > spice_warn_if_fail(!ring_item_is_linked(&dpi->dpi_pipe_item.link)); > spice_warn_if_fail(!ring_item_is_linked(&dpi->base)); > - red_worker_drawable_unref(worker, dpi->drawable); > + display_channel_drawable_unref(display, dpi->drawable); > free(dpi); > } > > @@ -869,12 +854,12 @@ static void release_image_item(ImageItem *item) > } > } > > -static void release_upgrade_item(RedWorker* worker, UpgradeItem *item) > +static void upgrade_item_unref(DisplayChannel *display, UpgradeItem *item) > { > if (--item->refs != 0) > return; > > - red_worker_drawable_unref(worker, item->drawable); > + display_channel_drawable_unref(display, item->drawable); > free(item->rects); > free(item); > } > @@ -912,30 +897,33 @@ static void red_reset_palette_cache(DisplayChannelClient > *dcc) > red_palette_cache_reset(dcc, CLIENT_PALETTE_CACHE_SIZE); > } > > -static inline Drawable *alloc_drawable(RedWorker *worker) > +static Drawable* drawable_try_new(DisplayChannel *display) > { > Drawable *drawable; > - if (!worker->free_drawables) { > + > + if (!display->free_drawables) > return NULL; > - } > - drawable = &worker->free_drawables->u.drawable; > - worker->free_drawables = worker->free_drawables->u.next; > + > + drawable = &display->free_drawables->u.drawable; > + display->free_drawables = display->free_drawables->u.next; > + display->drawable_count++; > + > return drawable; > } > > -static inline void free_drawable(RedWorker *worker, Drawable *item) > +static void drawable_free(DisplayChannel *display, Drawable *drawable) > { > - ((_Drawable *)item)->u.next = worker->free_drawables; > - worker->free_drawables = (_Drawable *)item; > + ((_Drawable *)drawable)->u.next = display->free_drawables; > + display->free_drawables = (_Drawable *)drawable; > } > > -static void drawables_init(RedWorker *worker) > +static void drawables_init(DisplayChannel *display) > { > int i; > > - worker->free_drawables = NULL; > + display->free_drawables = NULL; > for (i = 0; i < NUM_DRAWABLES; i++) { > - free_drawable(worker, &worker->drawables[i].u.drawable); > + drawable_free(display, &display->drawables[i].u.drawable); > } > } > > @@ -1031,7 +1019,7 @@ static void remove_depended_item(DependItem *item) > ring_remove(&item->ring_item); > } > > -static void drawable_unref_surface_deps(RedWorker *worker, Drawable > *drawable) > +static void drawable_unref_surface_deps(DisplayChannel *display, Drawable > *drawable) > { > int x; > int surface_id; > @@ -1041,11 +1029,11 @@ static void drawable_unref_surface_deps(RedWorker > *worker, Drawable *drawable) > if (surface_id == -1) { > continue; > } > - red_surface_unref(worker, surface_id); > + red_surface_unref(COMMON_CHANNEL(display)->worker, surface_id); > } > } > > -static void remove_drawable_dependencies(RedWorker *worker, Drawable > *drawable) > +static void drawable_remove_dependencies(DisplayChannel *display, Drawable > *drawable) > { > int x; > int surface_id; > @@ -1058,7 +1046,7 @@ static void remove_drawable_dependencies(RedWorker > *worker, Drawable *drawable) > } > } > > -static void red_worker_drawable_unref(RedWorker *worker, Drawable *drawable) > +void display_channel_drawable_unref(DisplayChannel *display, Drawable > *drawable) > { > RingItem *item, *next; > > @@ -1069,21 +1057,21 @@ static void red_worker_drawable_unref(RedWorker > *worker, Drawable *drawable) > spice_warn_if_fail(ring_is_empty(&drawable->pipes)); > > if (drawable->stream) { > - detach_stream(worker->display_channel, drawable->stream, TRUE); > + detach_stream(display, drawable->stream, TRUE); > } > region_destroy(&drawable->tree_item.base.rgn); > > - remove_drawable_dependencies(worker, drawable); > - drawable_unref_surface_deps(worker, drawable); > - red_surface_unref(worker, drawable->surface_id); > + drawable_remove_dependencies(display, drawable); > + drawable_unref_surface_deps(display, drawable); > + red_surface_unref(COMMON_CHANNEL(display)->worker, drawable->surface_id); > > RING_FOREACH_SAFE(item, next, &drawable->glz_ring) { > SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable = > NULL; > ring_remove(item); > } > - red_drawable_unref(worker, drawable->red_drawable, drawable->group_id); > - free_drawable(worker, drawable); > - worker->drawable_count--; > + red_drawable_unref(COMMON_CHANNEL(display)->worker, drawable > ->red_drawable, drawable->group_id); > + drawable_free(display, drawable); > + display->drawable_count--; > } > > static inline void remove_shadow(DrawItem *item) > @@ -1172,7 +1160,7 @@ static inline void current_remove_drawable(RedWorker > *worker, Drawable *item) > ring_remove(&item->tree_item.base.siblings_link); > ring_remove(&item->list_link); > ring_remove(&item->surface_list_link); > - red_worker_drawable_unref(worker, item); > + display_channel_drawable_unref(display, item); > display->current_size--; > } > > @@ -2334,6 +2322,7 @@ static inline int > is_drawable_independent_from_surfaces(Drawable *drawable) > > static inline int red_current_add_equal(RedWorker *worker, DrawItem *item, > TreeItem *other) > { > + DisplayChannel *display = worker->display_channel; > DrawItem *other_draw_item; > Drawable *drawable; > Drawable *other_drawable; > @@ -2363,7 +2352,7 @@ static inline int red_current_add_equal(RedWorker > *worker, DrawItem *item, TreeI > red_pipes_add_drawable(worker, drawable); > } > red_pipes_remove_drawable(other_drawable); > - red_worker_drawable_unref(worker, other_drawable); > + display_channel_drawable_unref(display, other_drawable); > return TRUE; > } > > @@ -2406,7 +2395,7 @@ static inline int red_current_add_equal(RedWorker > *worker, DrawItem *item, TreeI > /* not sending other_drawable where possible */ > red_pipes_remove_drawable(other_drawable); > > - red_worker_drawable_unref(worker, other_drawable); > + display_channel_drawable_unref(display, other_drawable); > return TRUE; > } > break; > @@ -2879,6 +2868,7 @@ static bool free_one_drawable(RedWorker *worker, int > force_glz_free) > static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable > *red_drawable, > uint32_t group_id) > { > + DisplayChannel *display = worker->display_channel; > Drawable *drawable; > int x; > > @@ -2893,12 +2883,12 @@ static Drawable *get_drawable(RedWorker *worker, > uint8_t effect, RedDrawable *re > } > } > > - while (!(drawable = alloc_drawable(worker))) { > - if (!free_one_drawable(worker, FALSE)) > + while (!(drawable = drawable_try_new(display))) { > + if (!free_one_drawable(COMMON_CHANNEL(display)->worker, FALSE)) > return NULL; > } > - worker->drawable_count++; > - memset(drawable, 0, sizeof(Drawable)); > + > + bzero(drawable, sizeof(Drawable)); > drawable->refs = 1; > drawable->creation_time = red_get_monotonic_time(); > ring_item_init(&drawable->list_link); > @@ -2995,6 +2985,7 @@ static inline void > red_inc_surfaces_drawable_dependencies(RedWorker *worker, Dra > static inline void red_process_draw(RedWorker *worker, RedDrawable > *red_drawable, > uint32_t group_id) > { > + DisplayChannel *display = worker->display_channel; > int surface_id; > Drawable *drawable = get_drawable(worker, red_drawable->effect, > red_drawable, group_id); > > @@ -3045,7 +3036,7 @@ static inline void red_process_draw(RedWorker *worker, > RedDrawable *red_drawable > red_pipes_add_drawable(worker, drawable); > } > cleanup: > - red_worker_drawable_unref(worker, drawable); > + display_channel_drawable_unref(display, drawable); > } > > static inline void red_create_surface(RedWorker *worker, uint32_t > surface_id,uint32_t width, > @@ -3374,13 +3365,14 @@ static void red_update_area_till(RedWorker *worker, > const SpiceRect *area, int s > that red_update_area is called for, Otherwise, 'now' would have > already been rendered. > See the call for red_handle_depends_on_target_surface in > red_process_draw */ > red_draw_drawable(worker, now); > - red_worker_drawable_unref(worker, now); > + display_channel_drawable_unref(display, now); > } while (now != surface_last); > validate_area(worker, area, surface_id); > } > > static void red_update_area(RedWorker *worker, const SpiceRect *area, int > surface_id) > { > + DisplayChannel *display = worker->display_channel; > RedSurface *surface; > Ring *ring; > RingItem *ring_item; > @@ -3427,7 +3419,7 @@ static void red_update_area(RedWorker *worker, const > SpiceRect *area, int surfac > current_remove_drawable(worker, now); > container_cleanup(worker, container); > red_draw_drawable(worker, now); > - red_worker_drawable_unref(worker, now); > + display_channel_drawable_unref(display, now); > } while (now != last); > validate_area(worker, area, surface_id); > } > @@ -3612,7 +3604,7 @@ static void red_free_some(RedWorker *worker) > DisplayChannelClient *dcc; > RingItem *item, *next; > > - spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", worker > ->drawable_count, > + spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", display > ->drawable_count, > worker->red_drawable_count, worker->glz_drawable_count); > FOREACH_DCC(worker->display_channel, item, next, dcc) { > GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL; > @@ -7579,7 +7571,7 @@ void red_show_tree(RedWorker *worker) > > static void display_channel_client_on_disconnect(RedChannelClient *rcc) > { > - DisplayChannel *display_channel; > + DisplayChannel *display; > DisplayChannelClient *dcc = RCC_TO_DCC(rcc); > CommonChannel *common; > RedWorker *worker; > @@ -7590,9 +7582,9 @@ static void > display_channel_client_on_disconnect(RedChannelClient *rcc) > spice_info(NULL); > common = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base); > worker = common->worker; > - display_channel = (DisplayChannel *)rcc->channel; > - spice_assert(display_channel == worker->display_channel); > - display_channel_compress_stats_print(display_channel); > + display = (DisplayChannel *)rcc->channel; > + spice_assert(display == worker->display_channel); > + display_channel_compress_stats_print(display); > pixmap_cache_unref(dcc->pixmap_cache); > dcc->pixmap_cache = NULL; > red_release_glz(dcc); > @@ -7604,10 +7596,10 @@ static void > display_channel_client_on_disconnect(RedChannelClient *rcc) > > // this was the last channel client > if (!red_channel_is_connected(rcc->channel)) { > - red_display_destroy_compress_bufs(display_channel); > + red_display_destroy_compress_bufs(display); > } > spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", > - worker->drawable_count, worker->red_drawable_count, > + display->drawable_count, worker->red_drawable_count, > worker->glz_drawable_count); > } > > @@ -8658,7 +8650,7 @@ static void > display_channel_client_release_item_after_push(DisplayChannelClient > display_stream_clip_unref(display, (StreamClipItem *)item); > break; > case PIPE_ITEM_TYPE_UPGRADE: > - release_upgrade_item(DCC_TO_WORKER(dcc), (UpgradeItem *)item); > + upgrade_item_unref(display, (UpgradeItem *)item); > break; > case PIPE_ITEM_TYPE_IMAGE: > release_image_item((ImageItem *)item); > @@ -8706,7 +8698,7 @@ static void > display_channel_client_release_item_before_push(DisplayChannelClient > break; > } > case PIPE_ITEM_TYPE_UPGRADE: > - release_upgrade_item(DCC_TO_WORKER(dcc), (UpgradeItem *)item); > + upgrade_item_unref(display, (UpgradeItem *)item); > break; > case PIPE_ITEM_TYPE_IMAGE: > release_image_item((ImageItem *)item); > @@ -8818,6 +8810,7 @@ static void display_channel_create(RedWorker *worker, > int migrate) > init_streams(display_channel); > image_cache_init(&display_channel->image_cache); > ring_init(&display_channel->current_list); > + drawables_init(display_channel); > } > > static void guest_set_client_capabilities(RedWorker *worker) > @@ -9378,7 +9371,7 @@ static void handle_dev_oom(void *opaque, void *payload) > spice_assert(worker->running); > // streams? but without streams also leak > spice_debug("OOM1 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes > %u", > - worker->drawable_count, > + display->drawable_count, > worker->red_drawable_count, > worker->glz_drawable_count, > display->current_size, > @@ -9392,7 +9385,7 @@ static void handle_dev_oom(void *opaque, void *payload) > worker->qxl->st->qif->flush_resources(worker->qxl); > } > spice_debug("OOM2 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes > %u", > - worker->drawable_count, > + display->drawable_count, > worker->red_drawable_count, > worker->glz_drawable_count, > display->current_size, > @@ -9943,7 +9936,6 @@ RedWorker* red_worker_new(QXLInstance *qxl, > RedDispatcher *red_dispatcher) > worker->zlib_glz_state = zlib_glz_state; > worker->driver_cap_monitors_config = 0; > image_surface_init(worker); > - drawables_init(worker); > stat_init(&worker->add_stat, add_stat_name); > stat_init(&worker->exclude_stat, exclude_stat_name); > stat_init(&worker->__exclude_stat, __exclude_stat_name); _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel