> > On Fri, 2015-11-20 at 11:17 +0000, Frediano Ziglio wrote: > > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > > > Acked-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> > > ^^^^^^^^^^^ > > > Do we need further review on this? Were there changes? > > > Yes, sorry, already pushed. I did some additional checks, patches was not looking just some move.. but it was! Frediano > > > --- > > server/dcc-encoders.c | 55 ++++++++++++++++++++++++++++++++++++++ > > server/dcc-encoders.h | 7 +++-- > > server/display-channel.c | 22 +++++++++++---- > > server/display-channel.h | 1 + > > server/red_worker.c | 69 > > ----------------------------------------------- > > - > > 5 files changed, 78 insertions(+), 76 deletions(-) > > > > diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c > > index e2e25e5..e39697a 100644 > > --- a/server/dcc-encoders.c > > +++ b/server/dcc-encoders.c > > @@ -473,6 +473,39 @@ void > > dcc_free_glz_drawable_instance(DisplayChannelClient > > *dcc, > > } > > } > > > > +/* > > + * Releases all the instances of the drawable from the dictionary and the > > display channel client. > > + * The release of the last instance will also release the drawable itself > > and > > the qxl drawable > > + * if possible. > > + * NOTE - the caller should prevent encoding using the dictionary during > > this > > operation > > + */ > > +void dcc_free_glz_drawable(DisplayChannelClient *dcc, RedGlzDrawable > > *drawable) > > +{ > > + RingItem *head_instance = ring_get_head(&drawable->instances); > > + int cont = (head_instance != NULL); > > + > > + while (cont) { > > + if (drawable->instances_count == 1) { > > + /* Last instance: dcc_free_glz_drawable_instance will free the > > drawable */ > > + cont = FALSE; > > + } > > + GlzDrawableInstanceItem *instance = > > SPICE_CONTAINEROF(head_instance, > > + > > GlzDrawableInstanceItem, > > + glz_link); > > + if (!ring_item_is_linked(&instance->free_link)) { > > + // the instance didn't get out from window yet > > + glz_enc_dictionary_remove_image(dcc->glz_dict->dict, > > + instance->context, > > + &dcc->glz_data.usr); > > + } > > + dcc_free_glz_drawable_instance(dcc, instance); > > + > > + if (cont) { > > + head_instance = ring_get_head(&drawable->instances); > > + } > > + } > > +} > > + > > void dcc_free_glz_drawables_to_free(DisplayChannelClient* dcc) > > { > > RingItem *ring_link; > > @@ -490,6 +523,28 @@ void > > dcc_free_glz_drawables_to_free(DisplayChannelClient* > > dcc) > > pthread_mutex_unlock(&dcc->glz_drawables_inst_to_free_lock); > > } > > > > +/* Clear all lz drawables - enforce their removal from the global > > dictionary. > > + NOTE - prevents encoding using the dictionary during the operation*/ > > +void dcc_free_glz_drawables(DisplayChannelClient *dcc) > > +{ > > + RingItem *ring_link; > > + GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL; > > + > > + if (!glz_dict) { > > + return; > > + } > > + > > + // assure no display channel is during global lz encoding > > + pthread_rwlock_wrlock(&glz_dict->encode_lock); > > + while ((ring_link = ring_get_head(&dcc->glz_drawables))) { > > + RedGlzDrawable *drawable = SPICE_CONTAINEROF(ring_link, > > RedGlzDrawable, link); > > + // no need to lock the to_free list, since we assured no other > > thread > > is encoding and > > + // thus not other thread access the to_free list of the channel > > + dcc_free_glz_drawable(dcc, drawable); > > + } > > + pthread_rwlock_unlock(&glz_dict->encode_lock); > > +} > > + > > void dcc_freeze_glz(DisplayChannelClient *dcc) > > { > > pthread_rwlock_wrlock(&dcc->glz_dict->encode_lock); > > diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h > > index 5ae15ba..8c769df 100644 > > --- a/server/dcc-encoders.h > > +++ b/server/dcc-encoders.h > > @@ -34,10 +34,15 @@ > > > > typedef struct RedCompressBuf RedCompressBuf; > > typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem; > > +typedef struct RedGlzDrawable RedGlzDrawable; > > + > > > > void dcc_encoders_init > > (DisplayChannelClient *dcc); > > void dcc_free_glz_drawable_instance > > (DisplayChannelClient *dcc, > > > > GlzDrawableInstanceItem *item); > > +void dcc_free_glz_drawable > > (DisplayChannelClient *dcc, > > + > > RedGlzDrawable > > *drawable); > > +void dcc_free_glz_drawables > > (DisplayChannelClient *dcc); > > void dcc_free_glz_drawables_to_free > > (DisplayChannelClient* dcc); > > void dcc_freeze_glz > > (DisplayChannelClient *dcc); > > > > @@ -125,8 +130,6 @@ typedef struct { > > > > #define MAX_GLZ_DRAWABLE_INSTANCES 2 > > > > -typedef struct RedGlzDrawable RedGlzDrawable; > > - > > /* for each qxl drawable, there may be several instances of lz drawables > > */ > > /* TODO - reuse this stuff for the top level. I just added a second level > > of > > multiplicity > > * at the Drawable by keeping a ring, so: > > diff --git a/server/display-channel.c b/server/display-channel.c > > index 3b7a016..d455a0d 100644 > > --- a/server/display-channel.c > > +++ b/server/display-channel.c > > @@ -850,14 +850,26 @@ void > > display_channel_flush_all_surfaces(DisplayChannel > > *display) > > } > > } > > > > -static void rcc_free_glz_drawables_to_free(RedChannelClient *rcc) > > +void display_channel_free_glz_drawables_to_free(DisplayChannel *display) > > { > > - DisplayChannelClient *dcc = RCC_TO_DCC(rcc); > > + RingItem *link, *next; > > + DisplayChannelClient *dcc; > > > > - dcc_free_glz_drawables_to_free(dcc); > > + spice_return_if_fail(display); > > + > > + DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display)) { > > + dcc_free_glz_drawables_to_free(dcc); > > + } > > } > > > > -void display_channel_free_glz_drawables_to_free(DisplayChannel *display) > > +void display_channel_free_glz_drawables(DisplayChannel *display) > > { > > - red_channel_apply_clients(RED_CHANNEL(display), > > rcc_free_glz_drawables_to_free); > > + RingItem *link, *next; > > + DisplayChannelClient *dcc; > > + > > + spice_return_if_fail(display); > > + > > + DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display)) { > > + dcc_free_glz_drawables(dcc); > > + } > > } > > diff --git a/server/display-channel.h b/server/display-channel.h > > index d47abf7..bad61d1 100644 > > --- a/server/display-channel.h > > +++ b/server/display-channel.h > > @@ -277,6 +277,7 @@ void > > display_channel_current_flush > > (DisplayCha > > int display_channel_wait_for_migrate_data > > (DisplayChannel *display); > > void display_channel_flush_all_surfaces > > (DisplayChannel *display); > > void > > display_channel_free_glz_drawables_to_free(DisplayChannel *display); > > +void display_channel_free_glz_drawables > > (DisplayChannel *display); > > > > static inline int is_equal_path(SpicePath *path1, SpicePath *path2) > > { > > diff --git a/server/red_worker.c b/server/red_worker.c > > index 6d974d6..1963b0c 100644 > > --- a/server/red_worker.c > > +++ b/server/red_worker.c > > @@ -183,7 +183,6 @@ static void red_update_area_till(DisplayChannel > > *display, > > const SpiceRect *area, > > static inline void display_begin_send_message(RedChannelClient *rcc); > > static void dcc_release_glz(DisplayChannelClient *dcc); > > static int > > red_display_free_some_independent_glz_drawables(DisplayChannelClient *dcc); > > -static void dcc_free_glz_drawable(DisplayChannelClient *dcc, > > RedGlzDrawable > > *drawable); > > static void > > display_channel_client_release_item_before_push(DisplayChannelClient *dcc, > > PipeItem > > *item); > > static void > > display_channel_client_release_item_after_push(DisplayChannelClient *dcc, > > @@ -1988,74 +1987,6 @@ static void fill_base(SpiceMarshaller > > *base_marshaller, > > Drawable *drawable) > > } > > > > /* > > - * Releases all the instances of the drawable from the dictionary and the > > display channel client. > > - * The release of the last instance will also release the drawable itself > > and > > the qxl drawable > > - * if possible. > > - * NOTE - the caller should prevent encoding using the dictionary during > > this > > operation > > - */ > > -static void dcc_free_glz_drawable(DisplayChannelClient *dcc, > > RedGlzDrawable > > *drawable) > > -{ > > - RingItem *head_instance = ring_get_head(&drawable->instances); > > - int cont = (head_instance != NULL); > > - > > - while (cont) { > > - if (drawable->instances_count == 1) { > > - /* Last instance: dcc_free_glz_drawable_instance will free the > > drawable */ > > - cont = FALSE; > > - } > > - GlzDrawableInstanceItem *instance = > > SPICE_CONTAINEROF(head_instance, > > - > > GlzDrawableInstanceItem, > > - glz_link); > > - if (!ring_item_is_linked(&instance->free_link)) { > > - // the instance didn't get out from window yet > > - glz_enc_dictionary_remove_image(dcc->glz_dict->dict, > > - instance->context, > > - &dcc->glz_data.usr); > > - } > > - dcc_free_glz_drawable_instance(dcc, instance); > > - > > - if (cont) { > > - head_instance = ring_get_head(&drawable->instances); > > - } > > - } > > -} > > - > > -/* Clear all lz drawables - enforce their removal from the global > > dictionary. > > - NOTE - prevents encoding using the dictionary during the operation*/ > > -static void dcc_free_glz_drawables(DisplayChannelClient *dcc) > > -{ > > - RingItem *ring_link; > > - GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL; > > - > > - if (!glz_dict) { > > - return; > > - } > > - > > - // assure no display channel is during global lz encoding > > - pthread_rwlock_wrlock(&glz_dict->encode_lock); > > - while ((ring_link = ring_get_head(&dcc->glz_drawables))) { > > - RedGlzDrawable *drawable = SPICE_CONTAINEROF(ring_link, > > RedGlzDrawable, link); > > - // no need to lock the to_free list, since we assured no other > > thread > > is encoding and > > - // thus not other thread access the to_free list of the channel > > - dcc_free_glz_drawable(dcc, drawable); > > - } > > - pthread_rwlock_unlock(&glz_dict->encode_lock); > > -} > > - > > -static void display_channel_free_glz_drawables(DisplayChannel > > *display_channel) > > -{ > > - RingItem *link, *next; > > - DisplayChannelClient *dcc; > > - > > - if (!display_channel) { > > - return; > > - } > > - DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display_channel)) { > > - dcc_free_glz_drawables(dcc); > > - } > > -} > > - > > -/* > > * Remove from the global lz dictionary some glz_drawables that have no > > reference to > > * Drawable (their qxl drawables are released too). > > * NOTE - the caller should prevent encoding using the dictionary during > > the > > operation > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel