[Spice-devel] [PATCH v2 07/18] worker: move compress to dcc_compress_image()

Frediano Ziglio fziglio at redhat.com
Thu Nov 19 05:26:49 PST 2015


> 
> This is a reduced diff (removed the move)
> 
> --- before.c	2015-11-19 13:04:55.376919069 +0000
> +++ after.c	2015-11-19 12:53:18.732173333 +0000
> @@ -305,21 +305,21 @@
>          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);
>  }
>  
>  /* if already exists, returns it. Otherwise allocates and adds it (1) to the
>  ring tail
>     in the channel (2) to the Drawable*/
> -static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannelClient
> *dcc, Drawable *drawable)
> +static RedGlzDrawable *get_glz_drawable(DisplayChannelClient *dcc, Drawable
> *drawable)
>  {
>      RedGlzDrawable *ret;
>      RingItem *item, *next;
>  
>      // TODO - I don't really understand what's going on here, so doing the
>      technical equivalent
>      // 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) {
>              return ret;
> @@ -332,67 +332,67 @@
>      ret->red_drawable = red_drawable_ref(drawable->red_drawable);
>      ret->drawable = drawable;
>      ret->group_id = drawable->group_id;
>      ret->instances_count = 0;
>      ring_init(&ret->instances);
>  
>      ring_item_init(&ret->link);
>      ring_item_init(&ret->drawable_link);
>      ring_add_before(&ret->link, &dcc->glz_drawables);
>      ring_add(&drawable->glz_ring, &ret->drawable_link);
> -    DCC_TO_WORKER(dcc)->glz_drawable_count++;
> +    dcc->glz_drawable_count++;
>      return ret;
>  }
>  
>  /* allocates new instance and adds it to instances in the given drawable.
>     NOTE - the caller should set the glz_instance returned by the encoder by
>     itself.*/
> -static GlzDrawableInstanceItem
> *red_display_add_glz_drawable_instance(RedGlzDrawable *glz_drawable)
> +static GlzDrawableInstanceItem *add_glz_drawable_instance(RedGlzDrawable
> *glz_drawable)
>  {
>      spice_assert(glz_drawable->instances_count <
>      MAX_GLZ_DRAWABLE_INSTANCES);
>      // NOTE: We assume the additions are performed consecutively, without
>      removals in the middle
>      GlzDrawableInstanceItem *ret = glz_drawable->instances_pool +
>      glz_drawable->instances_count;
>      glz_drawable->instances_count++;
>  
>      ring_item_init(&ret->free_link);
>      ring_item_init(&ret->glz_link);
>      ring_add(&glz_drawable->instances, &ret->glz_link);
>      ret->context = NULL;
>      ret->glz_drawable = glz_drawable;
>  
>      return ret;
>  }
>  
>  #define MIN_GLZ_SIZE_FOR_ZLIB 100
>  
> -static inline int red_glz_compress_image(DisplayChannelClient *dcc,
> +int dcc_compress_image_glz(DisplayChannelClient *dcc,
>                                           SpiceImage *dest, SpiceBitmap *src,
>                                           Drawable *drawable,
>                                           compress_send_data_t* o_comp_data)
>  {
>      DisplayChannel *display_channel = DCC_TO_DC(dcc);
>  #ifdef COMPRESS_STAT
> -    stat_time_t start_time = stat_now(display_channel->zlib_glz_stat.clock);
> +    stat_time_t start_time = stat_now(display_channel->glz_stat.clock);
>  #endif
>      spice_assert(bitmap_fmt_is_rgb(src->format));
>      GlzData *glz_data = &dcc->glz_data;
>      ZlibData *zlib_data;
>      LzImageType type = MAP_BITMAP_FMT_TO_LZ_IMAGE_TYPE[src->format];
>      RedGlzDrawable *glz_drawable;
>      GlzDrawableInstanceItem *glz_drawable_instance;
>      int glz_size;
>      int zlib_size;
>  
>      glz_data->data.bufs_tail = compress_buf_new();
>      glz_data->data.bufs_head = glz_data->data.bufs_tail;
>      glz_data->data.dcc = dcc;
>  
> -    glz_drawable = red_display_get_glz_drawable(dcc, drawable);
> -    glz_drawable_instance =
> red_display_add_glz_drawable_instance(glz_drawable);
> +    glz_drawable = get_glz_drawable(dcc, drawable);
> +    glz_drawable_instance = add_glz_drawable_instance(glz_drawable);
>  
>      glz_data->data.u.lines_data.chunks = src->data;
>      glz_data->data.u.lines_data.stride = src->stride;
>      glz_data->data.u.lines_data.next = 0;
>      glz_data->data.u.lines_data.reverse = 0;
>  
>      glz_size = glz_encode(dcc->glz, type, src->x, src->y,
>                            (src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN), NULL,
>                            0,
>                            src->stride, glz_data->data.bufs_head->buf.bytes,
>                            sizeof(glz_data->data.bufs_head->buf),
> @@ -442,21 +442,21 @@
>  glz:
>      dest->descriptor.type = SPICE_IMAGE_TYPE_GLZ_RGB;
>      dest->u.lz_rgb.data_size = glz_size;
>  
>      o_comp_data->comp_buf = glz_data->data.bufs_head;
>      o_comp_data->comp_buf_size = glz_size;
>  
>      return TRUE;
>  }
>  
> -static inline int red_lz_compress_image(DisplayChannelClient *dcc,
> +int dcc_compress_image_lz(DisplayChannelClient *dcc,
>                                          SpiceImage *dest, SpiceBitmap *src,
>                                          compress_send_data_t* o_comp_data,
>                                          uint32_t group_id)
>  {
>      LzData *lz_data = &dcc->lz_data;
>      LzContext *lz = dcc->lz;
>      LzImageType type = MAP_BITMAP_FMT_TO_LZ_IMAGE_TYPE[src->format];
>      int size;            // size of the compressed data
>  
>  #ifdef COMPRESS_STAT
>      stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->lz_stat.clock);
> @@ -502,48 +502,48 @@
>           * (see fill_mask) */
>          spice_assert(src->palette);
>          dest->descriptor.type = SPICE_IMAGE_TYPE_LZ_PLT;
>          dest->u.lz_plt.data_size = size;
>          dest->u.lz_plt.flags = src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN;
>          dest->u.lz_plt.palette = src->palette;
>          dest->u.lz_plt.palette_id = src->palette->unique;
>          o_comp_data->comp_buf = lz_data->data.bufs_head;
>          o_comp_data->comp_buf_size = size;
>  
> -        fill_palette(dcc, dest->u.lz_plt.palette, &(dest->u.lz_plt.flags));
> +        dcc_palette_cache_palette(dcc, dest->u.lz_plt.palette,
> &(dest->u.lz_plt.flags));
>          o_comp_data->lzplt_palette = dest->u.lz_plt.palette;
>      }
>  
>      stat_compress_add(&DCC_TO_DC(dcc)->lz_stat, start_time, src->stride *
>      src->y,
>                        o_comp_data->comp_buf_size);
>      return TRUE;
>  }
>  
> -static int red_jpeg_compress_image(DisplayChannelClient *dcc, SpiceImage
> *dest,
> +int dcc_compress_image_jpeg(DisplayChannelClient *dcc, SpiceImage *dest,
>                                     SpiceBitmap *src, compress_send_data_t*
>                                     o_comp_data,
>                                     uint32_t group_id)
>  {
>      JpegData *jpeg_data = &dcc->jpeg_data;
>      LzData *lz_data = &dcc->lz_data;
>      JpegEncoderContext *jpeg = dcc->jpeg;
>      LzContext *lz = dcc->lz;
>      volatile JpegEncoderImageType jpeg_in_type;
>      int jpeg_size = 0;
>      volatile int has_alpha = FALSE;
>      int alpha_lz_size = 0;
>      int comp_head_filled;
>      int comp_head_left;
>      int stride;
>      uint8_t *lz_out_start_byte;
>  
>  #ifdef COMPRESS_STAT
> -    stat_time_t start_time =
> stat_now(DCC_TO_DC(dcc)->jpeg_alpha_stat.clock);
> +    stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->jpeg_stat.clock);
>  #endif
>      switch (src->format) {
>      case SPICE_BITMAP_FMT_16BIT:
>          jpeg_in_type = JPEG_IMAGE_TYPE_RGB16;
>          break;
>      case SPICE_BITMAP_FMT_24BIT:
>          jpeg_in_type = JPEG_IMAGE_TYPE_BGR24;
>          break;
>      case SPICE_BITMAP_FMT_32BIT:
>          jpeg_in_type = JPEG_IMAGE_TYPE_BGRX32;
> @@ -643,30 +643,31 @@
>  
>      o_comp_data->comp_buf = jpeg_data->data.bufs_head;
>      o_comp_data->comp_buf_size = jpeg_size + alpha_lz_size;
>      o_comp_data->is_lossy = TRUE;
>      stat_compress_add(&DCC_TO_DC(dcc)->jpeg_alpha_stat, start_time,
>      src->stride * src->y,
>                        o_comp_data->comp_buf_size);
>      return TRUE;
>  }
>  
>  #ifdef USE_LZ4
> -static int red_lz4_compress_image(DisplayChannelClient *dcc, SpiceImage
> *dest,
> +int dcc_compress_image_lz4(DisplayChannelClient *dcc, SpiceImage *dest,
>                                    SpiceBitmap *src, compress_send_data_t*
>                                    o_comp_data,
>                                    uint32_t group_id)
>  {
> +    DisplayChannel *display_channel = DCC_TO_DC(dcc);
>      Lz4Data *lz4_data = &dcc->lz4_data;
>      Lz4EncoderContext *lz4 = dcc->lz4;
>      int lz4_size = 0;
>  
>  #ifdef COMPRESS_STAT
> -    stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->lz4_stat.clock);
> +    stat_time_t start_time = stat_now(display_channel->lz4_stat.clock);
>  #endif
>  
>      lz4_data->data.bufs_tail = compress_buf_new();
>      lz4_data->data.bufs_head = lz4_data->data.bufs_tail;
>  
>      if (!lz4_data->data.bufs_head) {
>          spice_warning("failed to allocate compress buffer");
>          return FALSE;
>      }
>  
> @@ -683,44 +684,43 @@
>      }
>  
>      if (src->data->flags & SPICE_CHUNKS_FLAGS_UNSTABLE) {
>          spice_chunks_linearize(src->data);
>      }
>  
>      lz4_data->data.u.lines_data.chunks = src->data;
>      lz4_data->data.u.lines_data.stride = src->stride;
>      lz4_data->data.u.lines_data.next = 0;
>      lz4_data->data.u.lines_data.reverse = 0;
> -    /* fixme remove? lz4_data->usr.more_lines = lz4_usr_more_lines; */
>  
>      lz4_size = lz4_encode(lz4, src->y, src->stride,
>      lz4_data->data.bufs_head->buf.bytes,
>                            sizeof(lz4_data->data.bufs_head->buf),
>                            src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN,
>                            src->format);
>  
>      // the compressed buffer is bigger than the original data
>      if (lz4_size > (src->y * src->stride)) {
>          longjmp(lz4_data->data.jmp_env, 1);
>      }
>  
>      dest->descriptor.type = SPICE_IMAGE_TYPE_LZ4;
>      dest->u.lz4.data_size = lz4_size;
>  
>      o_comp_data->comp_buf = lz4_data->data.bufs_head;
>      o_comp_data->comp_buf_size = lz4_size;
>  
> -    stat_compress_add(&DCC_TO_DC(dcc)->lz4_stat, start_time, src->stride *
> src->y,
> +    stat_compress_add(&display_channel->lz4_stat, start_time, src->stride *
> src->y,
>                        o_comp_data->comp_buf_size);
>      return TRUE;
>  }
>  #endif
>  
> -static inline int red_quic_compress_image(DisplayChannelClient *dcc,
> SpiceImage *dest,
> +int dcc_compress_image_quic(DisplayChannelClient *dcc, SpiceImage *dest,
>                                            SpiceBitmap *src,
>                                            compress_send_data_t*
>                                            o_comp_data,
>                                            uint32_t group_id)
>  {
>      QuicData *quic_data = &dcc->quic_data;
>      QuicContext *quic = dcc->quic;
>      volatile QuicImageType type;
>      int size, stride;
>  
>  #ifdef COMPRESS_STAT
>      stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->quic_stat.clock);
> @@ -786,21 +786,21 @@
>      o_comp_data->comp_buf = quic_data->data.bufs_head;
>      o_comp_data->comp_buf_size = size << 2;
>  
>      stat_compress_add(&DCC_TO_DC(dcc)->quic_stat, start_time, src->stride *
>      src->y,
>                        o_comp_data->comp_buf_size);
>      return TRUE;
>  }
>  
>  #define MIN_SIZE_TO_COMPRESS 54
>  #define MIN_DIMENSION_TO_QUIC 3
> -static inline int red_compress_image(DisplayChannelClient *dcc,
> +int dcc_compress_image(DisplayChannelClient *dcc,
>                                       SpiceImage *dest, SpiceBitmap *src,
>                                       Drawable *drawable,
>                                       int can_lossy,
>                                       compress_send_data_t* o_comp_data)
>  {
>      DisplayChannel *display_channel = DCC_TO_DC(dcc);
>      SpiceImageCompression image_compression = dcc->image_compression;
>      int quic_compress = FALSE;
>  
>      if ((image_compression == SPICE_IMAGE_COMPRESSION_OFF) ||
>          ((src->y * src->stride) < MIN_SIZE_TO_COMPRESS)) { // TODO: change
>          the size cond
> @@ -847,25 +847,25 @@
>      if (quic_compress) {
>  #ifdef COMPRESS_DEBUG
>          spice_info("QUIC compress");
>  #endif
>          // if bitmaps is picture-like, compress it using jpeg
>          if (can_lossy && display_channel->enable_jpeg &&
>              ((image_compression == SPICE_IMAGE_COMPRESSION_AUTO_LZ) ||
>              (image_compression == SPICE_IMAGE_COMPRESSION_AUTO_GLZ))) {
>              // if we use lz for alpha, the stride can't be extra
>              if (src->format != SPICE_BITMAP_FMT_RGBA ||
>              !bitmap_has_extra_stride(src)) {
> -                return red_jpeg_compress_image(dcc, dest,
> +                return dcc_compress_image_jpeg(dcc, dest,
>                                                 src, o_comp_data,
>                                                 drawable->group_id);
>              }
>          }
> -        return red_quic_compress_image(dcc, dest,
> +        return dcc_compress_image_quic(dcc, dest,
>                                         src, o_comp_data,
>                                         drawable->group_id);
>      } else {
>          int glz;
>          int ret;
>          if ((image_compression == SPICE_IMAGE_COMPRESSION_AUTO_GLZ) ||
>              (image_compression == SPICE_IMAGE_COMPRESSION_GLZ)) {
>              glz = bitmap_fmt_has_graduality(src->format) && (
>                      (src->x * src->y) < glz_enc_dictionary_get_size(
>                          dcc->glz_dict->dict));
>          } else if ((image_compression == SPICE_IMAGE_COMPRESSION_AUTO_LZ) ||
> @@ -874,77 +874,76 @@
>              glz = FALSE;
>          } else {
>              spice_error("invalid image compression type %u",
>              image_compression);
>              return FALSE;
>          }
>  
>          if (glz) {
>              /* using the global dictionary only if it is not frozen */
>              pthread_rwlock_rdlock(&dcc->glz_dict->encode_lock);
>              if (!dcc->glz_dict->migrate_freeze) {
> -                ret = red_glz_compress_image(dcc,
> +                ret = dcc_compress_image_glz(dcc,
>                                               dest, src,
>                                               drawable, o_comp_data);
>              } else {
>                  glz = FALSE;
>              }
>              pthread_rwlock_unlock(&dcc->glz_dict->encode_lock);
>          }
>  
>          if (!glz) {
>  #ifdef USE_LZ4
>              if (image_compression == SPICE_IMAGE_COMPRESSION_LZ4 &&
>                  bitmap_fmt_is_rgb(src->format) &&
>                  red_channel_client_test_remote_cap(&dcc->common.base,
>                          SPICE_DISPLAY_CAP_LZ4_COMPRESSION)) {
> -                ret = red_lz4_compress_image(dcc, dest, src, o_comp_data,
> +                ret = dcc_compress_image_lz4(dcc, dest, src, o_comp_data,
>                                               drawable->group_id);
>              } else
>  #endif
> -                ret = red_lz_compress_image(dcc, dest, src, o_comp_data,
> +                ret = dcc_compress_image_lz(dcc, dest, src, o_comp_data,
>                                              drawable->group_id);
>  #ifdef COMPRESS_DEBUG
>              spice_info("LZ LOCAL compress");
>  #endif
>          }
>  #ifdef COMPRESS_DEBUG
>          else {
>              spice_info("LZ global compress fmt=%d", src->format);
>          }
>  #endif
>          return ret;
>      }
>  }
>  
>  #define CLIENT_PALETTE_CACHE
>  #include "cache_item.tmpl.c"
>  #undef CLIENT_PALETTE_CACHE
>  
> -static inline void fill_palette(DisplayChannelClient *dcc,
> -                                SpicePalette *palette,
> +void dcc_palette_cache_palette(DisplayChannelClient *dcc, SpicePalette
> *palette,
>                                  uint8_t *flags)
>  {
>      if (palette == NULL) {
>          return;
>      }
>      if (palette->unique) {
>          if (red_palette_cache_find(dcc, palette->unique)) {
>              *flags |= SPICE_BITMAP_FLAGS_PAL_FROM_CACHE;
>              return;
>          }
>          if (red_palette_cache_add(dcc, palette->unique, 1)) {
>              *flags |= SPICE_BITMAP_FLAGS_PAL_CACHE_ME;
>          }
>      }
>  }
>  
> -static void red_reset_palette_cache(DisplayChannelClient *dcc)
> +void dcc_palette_cache_reset(DisplayChannelClient *dcc)
>  {
>      red_palette_cache_reset(dcc, CLIENT_PALETTE_CACHE_SIZE);
>  }
>  /* -*- 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
> @@ -1043,20 +1042,22 @@
>      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;
> +
> +    uint32_t glz_drawable_count;
>  };
>  

glz_drawable_count is moved to DisplayChannel, while red_drawable_count
remains in RedWorker. I'll leave red_drawable_count there I don't know
if it would be better to move too or remove entirely the reference counting
on it.

I'll separate the move of this field.

>  #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)
>  
>  typedef struct SurfaceCreateItem {
>      SpiceMsgSurfaceCreate surface_create;
> @@ -1099,27 +1100,51 @@
>                                                                        Stream
>                                                                        *stream);
>  void                       dcc_create_surface
>  (DisplayChannelClient *dcc,
>                                                                        int
>                                                                        surface_id);
>  void                       dcc_push_surface_image
>  (DisplayChannelClient *dcc,
>                                                                        int
>                                                                        surface_id);
>  ImageItem *                dcc_add_surface_area_image
>  (DisplayChannelClient *dcc,
>                                                                        int
>                                                                        surface_id,
>                                                                        SpiceRect
>                                                                        *area,
>                                                                        PipeItem
>                                                                        *pos,
>                                                                        int
>                                                                        can_lossy);
> +void                       dcc_palette_cache_reset
> (DisplayChannelClient *dcc);
> +void                       dcc_palette_cache_palette
> (DisplayChannelClient *dcc,
> +
> SpicePalette
> *palette,
> +
> uint8_t
> *flags);
> +
>  typedef struct compress_send_data_t {
>      void*    comp_buf;
>      uint32_t comp_buf_size;
>      SpicePalette *lzplt_palette;
>      int is_lossy;
>  } compress_send_data_t;
>  
> +int                        dcc_compress_image
> (DisplayChannelClient *dcc,
> +
> SpiceImage
> *dest, SpiceBitmap *src, Drawable *drawable,
> +                                                                      int
> can_lossy,
> +
> compress_send_data_t*
> o_comp_data);
> +int                        dcc_compress_image_glz
> (DisplayChannelClient *dcc,
> +
> SpiceImage
> *dest, SpiceBitmap *src, Drawable *drawable,
> +
> compress_send_data_t*
> o_comp_data);
> +int                        dcc_compress_image_lz
> (DisplayChannelClient *dcc,
> +
> SpiceImage
> *dest, SpiceBitmap *src,
> +
> compress_send_data_t*
> o_comp_data, uint32_t group_id);
> +int                        dcc_compress_image_jpeg
> (DisplayChannelClient *dcc, SpiceImage *dest,
> +
> SpiceBitmap
> *src, compress_send_data_t* o_comp_data,
> +
> uint32_t
> group_id);
> +int                        dcc_compress_image_quic
> (DisplayChannelClient *dcc, SpiceImage *dest,
> +
> SpiceBitmap
> *src, compress_send_data_t* o_comp_data,
> +
> uint32_t
> group_id);
> +int                        dcc_compress_image_lz4
> (DisplayChannelClient *dcc, SpiceImage *dest,
> +
> SpiceBitmap
> *src, compress_send_data_t* o_comp_data,
> +
> uint32_t
> group_id);
>  
>  #endif /* DCC_H_ */
>  /* -*- 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.
> @@ -1568,21 +1593,21 @@
>          SpiceRop3 rop3;
>          SpiceStroke stroke;
>          SpiceText text;
>          SpiceBlackness blackness;
>          SpiceInvers invers;
>          SpiceWhiteness whiteness;
>          SpiceComposite composite;
>      } u;
>  } RedDrawable;
>  
> -static RedDrawable *red_drawable_ref(RedDrawable *drawable)
> +static inline RedDrawable *red_drawable_ref(RedDrawable *drawable)
>  {
>      drawable->refs++;
>      return drawable;
>  }
>  
>  typedef struct RedUpdateCmd {
>      QXLReleaseInfo *release_info;
>      SpiceRect area;
>      uint32_t update_id;
>      uint32_t surface_id;
> @@ -1729,24 +1754,20 @@
>  #include "tree.h"
>  
>  //#define COMPRESS_STAT
>  //#define DUMP_BITMAP
>  //#define COMPRESS_DEBUG
>  
>  #define CMD_RING_POLL_TIMEOUT 10 //milli
>  #define CMD_RING_POLL_RETRIES 200
>  
>  #define DISPLAY_CLIENT_SHORT_TIMEOUT 15000000000ULL //nano
> -#define DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT 10000000000ULL //nano, 10 sec
> -#define DISPLAY_CLIENT_RETRY_INTERVAL 10000 //micro
> -
> -#define DISPLAY_FREE_LIST_DEFAULT_SIZE 128
>  
>  #define VALIDATE_SURFACE_RET(worker, surface_id) \
>      if (!validate_surface(worker, surface_id)) { \
>          rendering_incorrect(__func__); \
>          return; \
>      }
>  
>  #define VALIDATE_SURFACE_RETVAL(worker, surface_id, ret) \
>      if (!validate_surface(worker, surface_id)) { \
>          rendering_incorrect(__func__); \
> @@ -1800,21 +1821,20 @@
>      struct SpiceWatch watches[MAX_EVENT_SOURCES];
>      unsigned int event_timeout;
>  
>      DisplayChannel *display_channel;
>      uint32_t display_poll_tries;
>  
>      CursorChannel *cursor_channel;
>      uint32_t cursor_poll_tries;
>  
>      uint32_t red_drawable_count;
> -    uint32_t glz_drawable_count;
>      uint32_t bits_unique;
>  
>      RedMemSlotInfo mem_slots;
>  
>      SpiceImageCompression image_compression;
>      spice_wan_compression_t jpeg_state;
>      spice_wan_compression_t zlib_glz_state;
>  
>      uint32_t process_commands_generation;
>  #ifdef RED_STATISTICS
> @@ -3556,22 +3576,24 @@
>  
>  #define RED_RELEASE_BUNCH_SIZE 64
>  
>  static void red_free_some(RedWorker *worker)
>  {
>      DisplayChannel *display = worker->display_channel;
>      int n = 0;
>      DisplayChannelClient *dcc;
>      RingItem *item, *next;
>  
> +#if FIXME
>      spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d",
>      display->drawable_count,
>                  worker->red_drawable_count, worker->glz_drawable_count);
> +#endif
>      FOREACH_DCC(worker->display_channel, item, next, dcc) {
>          GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
>  
>          if (glz_dict) {
>              // encoding using the dictionary is prevented since the
>              following operations might
>              // change the dictionary
>              pthread_rwlock_wrlock(&glz_dict->encode_lock);
>              n = red_display_free_some_independent_glz_drawables(dcc);
>          }
>      }
> @@ -3703,21 +3725,21 @@
>      if (ring_is_empty(&glz_drawable->instances)) {
>          spice_assert(!glz_drawable->instances_count);
>  
>          Drawable *drawable = glz_drawable->drawable;
>  
>          if (drawable) {
>              ring_remove(&glz_drawable->drawable_link);
>          }
>          red_drawable_unref(worker, glz_drawable->red_drawable,
>                             glz_drawable->group_id);
> -        worker->glz_drawable_count--;
> +        dcc->glz_drawable_count--;
>          if (ring_item_is_linked(&glz_drawable->link)) {
>              ring_remove(&glz_drawable->link);
>          }
>          free(glz_drawable);
>      }
>  }
>  
>  static void red_display_handle_glz_drawables_to_free(DisplayChannelClient*
>  dcc)
>  {
>      RingItem *ring_link;
> @@ -4044,31 +4066,31 @@
>      }
>      case SPICE_IMAGE_TYPE_BITMAP: {
>          SpiceBitmap *bitmap = &image.u.bitmap;
>  #ifdef DUMP_BITMAP
>          dump_bitmap(&simage->u.bitmap);
>  #endif
>          /* Images must be added to the cache only after they are compressed
>             in order to prevent starvation in the client between pixmap_cache
>             and
>             global dictionary (in cases of multiple monitors) */
>          if (reds_stream_get_family(rcc->stream) == AF_UNIX ||
> -            !red_compress_image(dcc, &image, &simage->u.bitmap,
> +            !dcc_compress_image(dcc, &image, &simage->u.bitmap,
>                                  drawable, can_lossy, &comp_send_data)) {
>              SpicePalette *palette;
>  
>              red_display_add_image_to_pixmap_cache(rcc, simage, &image,
>              FALSE);
>  
>              *bitmap = simage->u.bitmap;
>              bitmap->flags = bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN;
>  
>              palette = bitmap->palette;
> -            fill_palette(dcc, palette, &bitmap->flags);
> +            dcc_palette_cache_palette(dcc, palette, &bitmap->flags);
>              spice_marshall_Image(m, &image,
>                                   &bitmap_palette_out, &lzplt_palette_out);
>              spice_assert(lzplt_palette_out == NULL);
>  
>              if (bitmap_palette_out && palette) {
>                  spice_marshall_Palette(bitmap_palette_out, palette);
>              }
>  
>              spice_marshaller_add_ref_chunks(m, bitmap->data);
>              pthread_mutex_unlock(&dcc->pixmap_cache->lock);
> @@ -6022,38 +6044,38 @@
>                  // if we use lz for alpha, the stride can't be extra
>                  lossy_comp = display_channel->enable_jpeg &&
>                  item->can_lossy;
>                  quic_comp = TRUE;
>              }
>          }
>      } else if (comp_mode == SPICE_IMAGE_COMPRESSION_QUIC) {
>          quic_comp = TRUE;
>      }
>  
>      if (lossy_comp) {
> -        comp_succeeded = red_jpeg_compress_image(dcc, &red_image,
> +        comp_succeeded = dcc_compress_image_jpeg(dcc, &red_image,
>                                                   &bitmap, &comp_send_data,
>                                                   worker->mem_slots.internal_groupslot_id);
>      } else if (quic_comp) {
> -        comp_succeeded = red_quic_compress_image(dcc, &red_image, &bitmap,
> +        comp_succeeded = dcc_compress_image_quic(dcc, &red_image, &bitmap,
>                                                   &comp_send_data,
>                                                   worker->mem_slots.internal_groupslot_id);
>  #ifdef USE_LZ4
>      } else if (comp_mode == SPICE_IMAGE_COMPRESSION_LZ4 &&
>                 bitmap_fmt_is_rgb(bitmap.format) &&
>                 red_channel_client_test_remote_cap(&dcc->common.base,
>                                                    SPICE_DISPLAY_CAP_LZ4_COMPRESSION))
>                                                    {
> -        comp_succeeded = red_lz4_compress_image(dcc, &red_image, &bitmap,
> +        comp_succeeded = dcc_compress_image_lz4(dcc, &red_image, &bitmap,
>                                                  &comp_send_data,
>                                                  worker->mem_slots.internal_groupslot_id);
>  #endif
>      } else if (comp_mode != SPICE_IMAGE_COMPRESSION_OFF) {
> -        comp_succeeded = red_lz_compress_image(dcc, &red_image, &bitmap,
> +        comp_succeeded = dcc_compress_image_lz(dcc, &red_image, &bitmap,
>                                                 &comp_send_data,
>                                                 worker->mem_slots.internal_groupslot_id);
>      }
>  
>      surface_lossy_region =
>      &dcc->surface_client_lossy_region[item->surface_id];
>      if (comp_succeeded) {
>          spice_marshall_Image(src_bitmap_out, &red_image,
>                               &bitmap_palette_out, &lzplt_palette_out);
>  
>          marshaller_add_compressed(src_bitmap_out,
> @@ -6287,21 +6309,21 @@
>      case PIPE_ITEM_TYPE_IMAGE:
>          red_marshall_image(rcc, m, (ImageItem *)pipe_item);
>          break;
>      case PIPE_ITEM_TYPE_PIXMAP_SYNC:
>          display_channel_marshall_pixmap_sync(rcc, m);
>          break;
>      case PIPE_ITEM_TYPE_PIXMAP_RESET:
>          display_channel_marshall_reset_cache(rcc, m);
>          break;
>      case PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE:
> -        red_reset_palette_cache(dcc);
> +        dcc_palette_cache_reset(dcc);
>          red_channel_client_init_send_data(rcc,
>          SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES, NULL);
>          break;
>      case PIPE_ITEM_TYPE_CREATE_SURFACE: {
>          SurfaceCreateItem *surface_create = SPICE_CONTAINEROF(pipe_item,
>          SurfaceCreateItem,
>                                                                pipe_item);
>          red_marshall_surface_create(rcc, m,
>          &surface_create->surface_create);
>          break;
>      }
>      case PIPE_ITEM_TYPE_DESTROY_SURFACE: {
>          SurfaceDestroyItem *surface_destroy = SPICE_CONTAINEROF(pipe_item,
>          SurfaceDestroyItem,
> @@ -6356,29 +6378,31 @@
>      }
>      spice_info(NULL);
>      common = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base);
>      worker = common->worker;
>      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);
> -    red_reset_palette_cache(dcc);
> +    dcc_palette_cache_reset(dcc);
>      free(dcc->send_data.stream_outbuf);
>      free(dcc->send_data.free_list.res);
>      dcc_destroy_stream_agents(dcc);
>  
>      // this was the last channel client
> +#if FIXME
>      spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d",
>                  display->drawable_count, worker->red_drawable_count,
>                  worker->glz_drawable_count);
> +#endif
>  }
>  
>  void red_disconnect_all_display_TODO_remove_me(RedChannel *channel)
>  {
>      // TODO: we need to record the client that actually causes the timeout.
>      So
>      // we need to check the locations of the various pipe heads when
>      counting,
>      // and disconnect only those/that.
>      if (!channel) {
>          return;
>      }
> @@ -7940,48 +7964,52 @@
>  {
>      RedWorker *worker = opaque;
>  
>      stat_inc_counter(worker->wakeup_counter, 1);
>      red_dispatcher_clear_pending(worker->red_dispatcher,
>      RED_DISPATCHER_PENDING_WAKEUP);
>  }
>  
>  static void handle_dev_oom(void *opaque, void *payload)
>  {
>      RedWorker *worker = opaque;
> -    DisplayChannel *display = worker->display_channel;
> -
> -    RedChannel *display_red_channel = &worker->display_channel->common.base;
>      int ring_is_empty;
>  
> -    spice_assert(worker->running);
> +    spice_return_if_fail(worker->running);
>      // streams? but without streams also leak
> +
> +#if FIXME
> +    DisplayChannel *display = worker->display_channel;
> +    RedChannel *display_red_channel = &worker->display_channel->common.base;
>      spice_debug("OOM1 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes
>      %u",
>                  display->drawable_count,
>                  worker->red_drawable_count,
>                  worker->glz_drawable_count,
>                  display->current_size,
>                  worker->display_channel ?
>                  red_channel_sum_pipes_size(display_red_channel) : 0);
> +#endif
>      while (red_process_commands(worker, MAX_PIPE_SIZE, &ring_is_empty)) {
>          red_channel_push(&worker->display_channel->common.base);
>      }
>      if (worker->qxl->st->qif->flush_resources(worker->qxl) == 0) {
>          red_free_some(worker);
>          worker->qxl->st->qif->flush_resources(worker->qxl);
>      }
> +#if FIXME
>      spice_debug("OOM2 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes
>      %u",
>                  display->drawable_count,
>                  worker->red_drawable_count,
>                  worker->glz_drawable_count,
>                  display->current_size,
>                  worker->display_channel ?
>                  red_channel_sum_pipes_size(display_red_channel) : 0);
> +#endif
>      red_dispatcher_clear_pending(worker->red_dispatcher,
>      RED_DISPATCHER_PENDING_OOM);
>  }
>  
>  static void handle_dev_reset_cursor(void *opaque, void *payload)
>  {
>      RedWorker *worker = opaque;
>  
>      cursor_channel_reset(worker->cursor_channel);
>  }
> 

I'll also remove the #if FIXME code

Frediano


More information about the Spice-devel mailing list