[Spice-devel] [PATCH v3 03/17] Move others glz fields to dcc-encoders

Jonathon Jongsma jjongsma at redhat.com
Mon Jun 13 22:07:06 UTC 2016


(I see here we add a non-stats field to ImageEncoderGlobals. So per my earlier
suggestion, i'd prefer a name of something like ImageEncoderSharedData.)

Acked-by: Jonathon Jongsma <jjongsma at redhat.com>


On Fri, 2016-06-10 at 09:48 +0100, Frediano Ziglio wrote:
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  server/dcc-encoders.c    | 76 +++++++++++++++++++++++++--------------------
> ---
>  server/dcc-encoders.h    | 19 +++++++-----
>  server/dcc.c             | 18 +++++-------
>  server/dcc.h             |  5 ----
>  server/display-channel.c | 12 ++++----
>  server/display-channel.h |  2 --
>  server/red-worker.c      |  4 +--
>  7 files changed, 66 insertions(+), 70 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 94b07fe..656ce25 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -26,8 +26,8 @@
>  
>  #define ZLIB_DEFAULT_COMPRESSION_LEVEL 3
>  
> -static void dcc_free_glz_drawable_instance(DisplayChannelClient *dcc,
> -                                           GlzDrawableInstanceItem *item);
> +static void image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
> +                                                      GlzDrawableInstanceItem
> *instance);
>  
>  static SPICE_GNUC_NORETURN SPICE_GNUC_PRINTF(2, 3) void
>  quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
> @@ -329,10 +329,10 @@ static void glz_usr_free_image(GlzEncoderUsrContext
> *usr, GlzUsrImageContext *im
>  {
>      GlzData *lz_data = (GlzData *)usr;
>      GlzDrawableInstanceItem *glz_drawable_instance = (GlzDrawableInstanceItem
> *)image;
> -    DisplayChannelClient *drawable_cc = glz_drawable_instance->glz_drawable-
> >dcc;
> -    DisplayChannelClient *this_cc = SPICE_CONTAINEROF(lz_data,
> DisplayChannelClient, encoders.glz_data);
> -    if (this_cc == drawable_cc) {
> -        dcc_free_glz_drawable_instance(drawable_cc, glz_drawable_instance);
> +    ImageEncoders *drawable_enc = glz_drawable_instance->glz_drawable-
> >encoders;
> +    ImageEncoders *this_enc = SPICE_CONTAINEROF(lz_data, ImageEncoders,
> glz_data);
> +    if (this_enc == drawable_enc) {
> +        image_encoders_free_glz_drawable_instance(drawable_enc,
> glz_drawable_instance);
>      } else {
>          /* The glz dictionary is shared between all DisplayChannelClient
>           * instances that belong to the same client, and glz_usr_free_image
> @@ -341,10 +341,10 @@ static void glz_usr_free_image(GlzEncoderUsrContext
> *usr, GlzUsrImageContext *im
>           * called from any DisplayChannelClient thread, hence the need for
>           * this check.
>           */
> -        pthread_mutex_lock(&drawable_cc->glz_drawables_inst_to_free_lock);
> +        pthread_mutex_lock(&drawable_enc->glz_drawables_inst_to_free_lock);
>          ring_add_before(&glz_drawable_instance->free_link,
> -                        &drawable_cc->glz_drawables_inst_to_free);
> -        pthread_mutex_unlock(&drawable_cc->glz_drawables_inst_to_free_lock);
> +                        &drawable_enc->glz_drawables_inst_to_free);
> +        pthread_mutex_unlock(&drawable_enc->glz_drawables_inst_to_free_lock);
>      }
>  }
>  
> @@ -403,6 +403,10 @@ void image_encoders_init(ImageEncoders *enc,
> ImageEncoderGlobals *globals)
>      spice_assert(globals);
>      enc->globals = globals;
>  
> +    ring_init(&enc->glz_drawables);
> +    ring_init(&enc->glz_drawables_inst_to_free);
> +    pthread_mutex_init(&enc->glz_drawables_inst_to_free_lock, NULL);
> +
>      image_encoders_init_glz_data(enc);
>      image_encoders_init_quic(enc);
>      image_encoders_init_lz(enc);
> @@ -437,10 +441,9 @@ void image_encoders_free(ImageEncoders *enc)
>     it is not used by Drawable).
>     NOTE - 1) can be called only by the display channel that created the
> drawable
>            2) it is assumed that the instance was already removed from the
> dictionary*/
> -static void dcc_free_glz_drawable_instance(DisplayChannelClient *dcc,
> -                                           GlzDrawableInstanceItem *instance)
> +static void image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
> +                                                      GlzDrawableInstanceItem
> *instance)
>  {
> -    DisplayChannel *display_channel = DCC_TO_DC(dcc);
>      RedGlzDrawable *glz_drawable;
>  
>      spice_assert(instance);
> @@ -448,7 +451,7 @@ static void
> dcc_free_glz_drawable_instance(DisplayChannelClient *dcc,
>  
>      glz_drawable = instance->glz_drawable;
>  
> -    spice_assert(glz_drawable->dcc == dcc);
> +    spice_assert(glz_drawable->encoders == enc);
>      spice_assert(glz_drawable->instances_count > 0);
>  
>      ring_remove(&instance->glz_link);
> @@ -469,7 +472,7 @@ static void
> dcc_free_glz_drawable_instance(DisplayChannelClient *dcc,
>              ring_remove(&glz_drawable->drawable_link);
>          }
>          red_drawable_unref(glz_drawable->red_drawable);
> -        display_channel->glz_drawable_count--;
> +        enc->globals->glz_drawable_count--;
>          if (ring_item_is_linked(&glz_drawable->link)) {
>              ring_remove(&glz_drawable->link);
>          }
> @@ -483,14 +486,14 @@ static void
> dcc_free_glz_drawable_instance(DisplayChannelClient *dcc,
>   * if possible.
>   * NOTE - the caller should prevent encoding using the dictionary during this
> operation
>   */
> -void dcc_free_glz_drawable(DisplayChannelClient *dcc, RedGlzDrawable
> *drawable)
> +void image_encoders_free_glz_drawable(ImageEncoders *enc, 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 */
> +            /* Last instance: image_encoders_free_glz_drawable_instance will
> free the drawable */
>              cont = FALSE;
>          }
>          GlzDrawableInstanceItem *instance = SPICE_CONTAINEROF(head_instance,
> @@ -498,11 +501,11 @@ void dcc_free_glz_drawable(DisplayChannelClient *dcc,
> RedGlzDrawable *drawable)
>                                                          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->encoders.glz_dict->dict,
> +            glz_enc_dictionary_remove_image(enc->glz_dict->dict,
>                                              instance->context,
> -                                            &dcc->encoders.glz_data.usr);
> +                                            &enc->glz_data.usr);
>          }
> -        dcc_free_glz_drawable_instance(dcc, instance);
> +        image_encoders_free_glz_drawable_instance(enc, instance);
>  
>          if (cont) {
>              head_instance = ring_get_head(&drawable->instances);
> @@ -515,49 +518,49 @@ void dcc_free_glz_drawable(DisplayChannelClient *dcc,
> RedGlzDrawable *drawable)
>   * Drawable (their qxl drawables are released too).
>   * NOTE - the caller should prevent encoding using the dictionary during the
> operation
>   */
> -int dcc_free_some_independent_glz_drawables(DisplayChannelClient *dcc)
> +int image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc)
>  {
>      RingItem *ring_link;
>      int n = 0;
>  
> -    if (!dcc) {
> +    if (!enc) {
>          return 0;
>      }
> -    ring_link = ring_get_head(&dcc->glz_drawables);
> +    ring_link = ring_get_head(&enc->glz_drawables);
>      while ((n < RED_RELEASE_BUNCH_SIZE) && (ring_link != NULL)) {
>          RedGlzDrawable *glz_drawable = SPICE_CONTAINEROF(ring_link,
> RedGlzDrawable, link);
> -        ring_link = ring_next(&dcc->glz_drawables, ring_link);
> +        ring_link = ring_next(&enc->glz_drawables, ring_link);
>          if (!glz_drawable->drawable) {
> -            dcc_free_glz_drawable(dcc, glz_drawable);
> +            image_encoders_free_glz_drawable(enc, glz_drawable);
>              n++;
>          }
>      }
>      return n;
>  }
>  
> -void dcc_free_glz_drawables_to_free(DisplayChannelClient* dcc)
> +void image_encoders_free_glz_drawables_to_free(ImageEncoders* enc)
>  {
>      RingItem *ring_link;
>  
> -    if (!dcc->encoders.glz_dict) {
> +    if (!enc->glz_dict) {
>          return;
>      }
> -    pthread_mutex_lock(&dcc->glz_drawables_inst_to_free_lock);
> -    while ((ring_link = ring_get_head(&dcc->glz_drawables_inst_to_free))) {
> +    pthread_mutex_lock(&enc->glz_drawables_inst_to_free_lock);
> +    while ((ring_link = ring_get_head(&enc->glz_drawables_inst_to_free))) {
>          GlzDrawableInstanceItem *drawable_instance =
> SPICE_CONTAINEROF(ring_link,
>                                                                   GlzDrawableI
> nstanceItem,
>                                                                   free_link);
> -        dcc_free_glz_drawable_instance(dcc, drawable_instance);
> +        image_encoders_free_glz_drawable_instance(enc, drawable_instance);
>      }
> -    pthread_mutex_unlock(&dcc->glz_drawables_inst_to_free_lock);
> +    pthread_mutex_unlock(&enc->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)
> +void image_encoders_free_glz_drawables(ImageEncoders *enc)
>  {
>      RingItem *ring_link;
> -    GlzSharedDictionary *glz_dict = dcc ? dcc->encoders.glz_dict : NULL;
> +    GlzSharedDictionary *glz_dict = enc ? enc->glz_dict : NULL;
>  
>      if (!glz_dict) {
>          return;
> @@ -565,11 +568,11 @@ void dcc_free_glz_drawables(DisplayChannelClient *dcc)
>  
>      // 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))) {
> +    while ((ring_link = ring_get_head(&enc->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);
> +        image_encoders_free_glz_drawable(enc, drawable);
>      }
>      pthread_rwlock_unlock(&glz_dict->encode_lock);
>  }
> @@ -695,12 +698,11 @@ gboolean image_encoders_glz_create(ImageEncoders *enc,
> uint8_t id)
>  }
>  
>  /* destroy encoder, and dictionary if no one uses it*/
> -void dcc_release_glz(DisplayChannelClient *dcc)
> +void image_encoders_release_glz(ImageEncoders *enc)
>  {
> -    ImageEncoders *enc = &dcc->encoders;
>      GlzSharedDictionary *shared_dict;
>  
> -    dcc_free_glz_drawables(dcc);
> +    image_encoders_free_glz_drawables(enc);
>  
>      glz_encoder_destroy(enc->glz);
>      enc->glz = NULL;
> diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
> index 51f0cfe..b32b34b 100644
> --- a/server/dcc-encoders.h
> +++ b/server/dcc-encoders.h
> @@ -43,14 +43,13 @@ void image_encoder_globals_stat_print(const
> ImageEncoderGlobals *globals);
>  
>  void image_encoders_init(ImageEncoders *enc, ImageEncoderGlobals *globals);
>  void image_encoders_free(ImageEncoders *enc);
> -void             dcc_free_glz_drawable                       (DisplayChannelC
> lient *dcc,
> -                                                              RedGlzDrawable
> *drawable);
> -int              dcc_free_some_independent_glz_drawables     (DisplayChannelC
> lient *dcc);
> -void             dcc_free_glz_drawables                      (DisplayChannelC
> lient *dcc);
> -void             dcc_free_glz_drawables_to_free              (DisplayChannelC
> lient* dcc);
> +void image_encoders_free_glz_drawable(ImageEncoders *enc, RedGlzDrawable
> *drawable);
> +int image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc);
> +void image_encoders_free_glz_drawables(ImageEncoders *enc);
> +void image_encoders_free_glz_drawables_to_free(ImageEncoders* enc);
>  gboolean image_encoders_glz_create(ImageEncoders *enc, uint8_t id);
>  void image_encoders_freeze_glz(ImageEncoders *enc);
> -void             dcc_release_glz                             (DisplayChannelC
> lient *dcc);
> +void image_encoders_release_glz(ImageEncoders *enc);
>  
>  #define RED_COMPRESS_BUF_SIZE (1024 * 64)
>  struct RedCompressBuf {
> @@ -166,10 +165,12 @@ struct RedGlzDrawable {
>      GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
>      Ring instances;
>      uint8_t instances_count;
> -    DisplayChannelClient *dcc;
> +    ImageEncoders *encoders;
>  };
>  
>  struct ImageEncoderGlobals {
> +    uint32_t glz_drawable_count;
> +
>      stat_info_t off_stat;
>      stat_info_t lz_stat;
>      stat_info_t glz_stat;
> @@ -208,6 +209,10 @@ struct ImageEncoders {
>      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;
>  };
>  
>  typedef struct compress_send_data_t {
> diff --git a/server/dcc.c b/server/dcc.c
> index 1cc85b5..82862af 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -392,10 +392,6 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
>  
>      dcc_init_stream_agents(dcc);
>  
> -    ring_init(&dcc->glz_drawables);
> -    ring_init(&dcc->glz_drawables_inst_to_free);
> -    pthread_mutex_init(&dcc->glz_drawables_inst_to_free_lock, NULL);
> -
>      image_encoders_init(&dcc->encoders, &display->encoder_globals);
>  
>      return dcc;
> @@ -493,7 +489,7 @@ void dcc_stop(DisplayChannelClient *dcc)
>  
>      pixmap_cache_unref(dcc->pixmap_cache);
>      dcc->pixmap_cache = NULL;
> -    dcc_release_glz(dcc);
> +    image_encoders_release_glz(&dcc->encoders);
>      dcc_palette_cache_reset(dcc);
>      free(dcc->send_data.stream_outbuf);
>      free(dcc->send_data.free_list.res);
> @@ -638,7 +634,7 @@ void dcc_destroy_surface(DisplayChannelClient *dcc,
> uint32_t surface_id)
>  
>  /* if already exists, returns it. Otherwise allocates and adds it (1) to the
> ring tail
>     in the channel (2) to the Drawable*/
> -static RedGlzDrawable *get_glz_drawable(DisplayChannelClient *dcc, Drawable
> *drawable)
> +static RedGlzDrawable *get_glz_drawable(ImageEncoders *enc, Drawable
> *drawable)
>  {
>      RedGlzDrawable *ret;
>      RingItem *item, *next;
> @@ -647,14 +643,14 @@ static RedGlzDrawable
> *get_glz_drawable(DisplayChannelClient *dcc, Drawable *dra
>      // now that we have multiple glz_dicts, so the only way to go from dcc to
> drawable glz is to go
>      // over the glz_ring (unless adding some better data structure then a
> ring)
>      DRAWABLE_FOREACH_GLZ_SAFE(drawable, item, next, ret) {
> -        if (ret->dcc == dcc) {
> +        if (ret->encoders == enc) {
>              return ret;
>          }
>      }
>  
>      ret = spice_new(RedGlzDrawable, 1);
>  
> -    ret->dcc = dcc;
> +    ret->encoders = enc;
>      ret->red_drawable = red_drawable_ref(drawable->red_drawable);
>      ret->drawable = drawable;
>      ret->instances_count = 0;
> @@ -662,9 +658,9 @@ static RedGlzDrawable
> *get_glz_drawable(DisplayChannelClient *dcc, Drawable *dra
>  
>      ring_item_init(&ret->link);
>      ring_item_init(&ret->drawable_link);
> -    ring_add_before(&ret->link, &dcc->glz_drawables);
> +    ring_add_before(&ret->link, &enc->glz_drawables);
>      ring_add(&drawable->glz_ring, &ret->drawable_link);
> -    DCC_TO_DC(dcc)->glz_drawable_count++;
> +    enc->globals->glz_drawable_count++;
>      return ret;
>  }
>  
> @@ -724,7 +720,7 @@ static int dcc_compress_image_glz(DisplayChannelClient
> *dcc,
>  
>      encoder_data_init(&glz_data->data);
>  
> -    glz_drawable = get_glz_drawable(dcc, drawable);
> +    glz_drawable = get_glz_drawable(&dcc->encoders, drawable);
>      glz_drawable_instance = add_glz_drawable_instance(glz_drawable);
>  
>      glz_data->data.u.lines_data.chunks = src->data;
> diff --git a/server/dcc.h b/server/dcc.h
> index a4b917b..362237d 100644
> --- a/server/dcc.h
> +++ b/server/dcc.h
> @@ -83,11 +83,6 @@ struct DisplayChannelClient {
>          int num_pixmap_cache_items;
>      } send_data;
>  
> -    /* global lz encoding entities */
> -    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];
>  
> diff --git a/server/display-channel.c b/server/display-channel.c
> index 4aa912a..c48db00 100644
> --- a/server/display-channel.c
> +++ b/server/display-channel.c
> @@ -1143,7 +1143,7 @@ void
> display_channel_free_glz_drawables_to_free(DisplayChannel *display)
>      spice_return_if_fail(display);
>  
>      FOREACH_CLIENT(display, link, next, dcc) {
> -        dcc_free_glz_drawables_to_free(dcc);
> +        image_encoders_free_glz_drawables_to_free(&dcc->encoders);
>      }
>  }
>  
> @@ -1155,7 +1155,7 @@ void display_channel_free_glz_drawables(DisplayChannel
> *display)
>      spice_return_if_fail(display);
>  
>      FOREACH_CLIENT(display, link, next, dcc) {
> -        dcc_free_glz_drawables(dcc);
> +        image_encoders_free_glz_drawables(&dcc->encoders);
>      }
>  }
>  
> @@ -1174,7 +1174,7 @@ static bool free_one_drawable(DisplayChannel *display,
> int force_glz_free)
>          RingItem *glz_item, *next_item;
>          RedGlzDrawable *glz;
>          DRAWABLE_FOREACH_GLZ_SAFE(drawable, glz_item, next_item, glz) {
> -            dcc_free_glz_drawable(glz->dcc, glz);
> +            image_encoders_free_glz_drawable(glz->encoders, glz);
>          }
>      }
>      drawable_draw(display, drawable);
> @@ -1200,7 +1200,7 @@ void display_channel_free_some(DisplayChannel *display)
>      GList *link, *next;
>  
>      spice_debug("#draw=%d, #glz_draw=%d", display->drawable_count,
> -                display->glz_drawable_count);
> +                display->encoder_globals.glz_drawable_count);
>      FOREACH_CLIENT(display, link, next, dcc) {
>          GlzSharedDictionary *glz_dict = dcc->encoders.glz_dict;
>  
> @@ -1208,7 +1208,7 @@ void display_channel_free_some(DisplayChannel *display)
>              // encoding using the dictionary is prevented since the following
> operations might
>              // change the dictionary
>              pthread_rwlock_wrlock(&glz_dict->encode_lock);
> -            n = dcc_free_some_independent_glz_drawables(dcc);
> +            n = image_encoders_free_some_independent_glz_drawables(&dcc-
> >encoders);
>          }
>      }
>  
> @@ -1853,7 +1853,7 @@ static void on_disconnect(RedChannelClient *rcc)
>      // this was the last channel client
>      spice_debug("#draw=%d, #glz_draw=%d",
>                  display->drawable_count,
> -                display->glz_drawable_count);
> +                display->encoder_globals.glz_drawable_count);
>  }
>  
>  static int handle_migrate_flush_mark(RedChannelClient *rcc)
> diff --git a/server/display-channel.h b/server/display-channel.h
> index cdf1dce..8bf4d5d 100644
> --- a/server/display-channel.h
> +++ b/server/display-channel.h
> @@ -183,8 +183,6 @@ struct DisplayChannel {
>      _Drawable drawables[NUM_DRAWABLES];
>      _Drawable *free_drawables;
>  
> -    uint32_t glz_drawable_count;
> -
>      int stream_video;
>      uint32_t stream_count;
>      Stream streams_buf[NUM_STREAMS];
> diff --git a/server/red-worker.c b/server/red-worker.c
> index c53bc15..aba3e6f 100644
> --- a/server/red-worker.c
> +++ b/server/red-worker.c
> @@ -823,7 +823,7 @@ static void handle_dev_oom(void *opaque, void *payload)
>      // streams? but without streams also leak
>      spice_debug("OOM1 #draw=%u, #glz_draw=%u current %u pipes %u",
>                  display->drawable_count,
> -                display->glz_drawable_count,
> +                display->encoder_globals.glz_drawable_count,
>                  display->current_size,
>                  red_channel_sum_pipes_size(display_red_channel));
>      while (red_process_display(worker, &ring_is_empty)) {
> @@ -835,7 +835,7 @@ static void handle_dev_oom(void *opaque, void *payload)
>      }
>      spice_debug("OOM2 #draw=%u, #glz_draw=%u current %u pipes %u",
>                  display->drawable_count,
> -                display->glz_drawable_count,
> +                display->encoder_globals.glz_drawable_count,
>                  display->current_size,
>                  red_channel_sum_pipes_size(display_red_channel));
>      red_qxl_clear_pending(worker->qxl->st, RED_DISPATCHER_PENDING_OOM);


More information about the Spice-devel mailing list