Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- server/dcc-encoders.c | 133 +++++++++++++++++++++++++++++++++++++++++++++ server/dcc-encoders.h | 4 ++ server/dcc.c | 147 -------------------------------------------------- 3 files changed, 137 insertions(+), 147 deletions(-) diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c index 656ce25..09be853 100644 --- a/server/dcc-encoders.c +++ b/server/dcc-encoders.c @@ -1051,6 +1051,139 @@ int image_encoders_compress_lz4(ImageEncoders *enc, SpiceImage *dest, } #endif +/* 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(ImageEncoders *enc, 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->encoders == enc) { + return ret; + } + } + + ret = spice_new(RedGlzDrawable, 1); + + ret->encoders = enc; + ret->red_drawable = red_drawable_ref(drawable->red_drawable); + ret->drawable = drawable; + ret->instances_count = 0; + ring_init(&ret->instances); + + ring_item_init(&ret->link); + ring_item_init(&ret->drawable_link); + ring_add_before(&ret->link, &enc->glz_drawables); + ring_add(&drawable->glz_ring, &ret->drawable_link); + enc->globals->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 *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 + +int image_encoders_compress_glz(ImageEncoders *enc, + SpiceImage *dest, SpiceBitmap *src, Drawable *drawable, + compress_send_data_t* o_comp_data, + gboolean enable_zlib_glz_wrap) +{ + stat_start_time_t start_time; + stat_start_time_init(&start_time, &enc->globals->zlib_glz_stat); + spice_assert(bitmap_fmt_is_rgb(src->format)); + GlzData *glz_data = &enc->glz_data; + ZlibData *zlib_data; + LzImageType type = bitmap_fmt_to_lz_image_type[src->format]; + RedGlzDrawable *glz_drawable; + GlzDrawableInstanceItem *glz_drawable_instance; + int glz_size; + int zlib_size; + +#ifdef COMPRESS_DEBUG + spice_info("LZ global compress fmt=%d", src->format); +#endif + + encoder_data_init(&glz_data->data); + + glz_drawable = get_glz_drawable(enc, 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(enc->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), + glz_drawable_instance, + &glz_drawable_instance->context); + + stat_compress_add(&enc->globals->glz_stat, start_time, src->stride * src->y, glz_size); + + if (!enable_zlib_glz_wrap || (glz_size < MIN_GLZ_SIZE_FOR_ZLIB)) { + goto glz; + } + stat_start_time_init(&start_time, &enc->globals->zlib_glz_stat); + zlib_data = &enc->zlib_data; + + encoder_data_init(&zlib_data->data); + + zlib_data->data.u.compressed_data.next = glz_data->data.bufs_head; + zlib_data->data.u.compressed_data.size_left = glz_size; + + zlib_size = zlib_encode(enc->zlib, enc->zlib_level, + glz_size, zlib_data->data.bufs_head->buf.bytes, + sizeof(zlib_data->data.bufs_head->buf)); + + // the compressed buffer is bigger than the original data + if (zlib_size >= glz_size) { + encoder_data_reset(&zlib_data->data); + goto glz; + } else { + encoder_data_reset(&glz_data->data); + } + + dest->descriptor.type = SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB; + dest->u.zlib_glz.glz_data_size = glz_size; + dest->u.zlib_glz.data_size = zlib_size; + + o_comp_data->comp_buf = zlib_data->data.bufs_head; + o_comp_data->comp_buf_size = zlib_size; + + stat_compress_add(&enc->globals->zlib_glz_stat, start_time, glz_size, zlib_size); + return TRUE; +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; +} + void image_encoder_globals_init(ImageEncoderGlobals *globals) { clockid_t stat_clock = CLOCK_THREAD_CPUTIME_ID; diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h index b32b34b..00ad941 100644 --- a/server/dcc-encoders.h +++ b/server/dcc-encoders.h @@ -231,6 +231,10 @@ int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data); int image_encoders_compress_lz4(ImageEncoders *enc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data); +int image_encoders_compress_glz(ImageEncoders *enc, + SpiceImage *dest, SpiceBitmap *src, struct Drawable *drawable, + compress_send_data_t* o_comp_data, + gboolean enable_zlib_glz_wrap); #define RED_RELEASE_BUNCH_SIZE 64 diff --git a/server/dcc.c b/server/dcc.c index cc8892f..6511ce5 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -632,153 +632,6 @@ void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t 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 *get_glz_drawable(ImageEncoders *enc, 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->encoders == enc) { - return ret; - } - } - - ret = spice_new(RedGlzDrawable, 1); - - ret->encoders = enc; - ret->red_drawable = red_drawable_ref(drawable->red_drawable); - ret->drawable = drawable; - ret->instances_count = 0; - ring_init(&ret->instances); - - ring_item_init(&ret->link); - ring_item_init(&ret->drawable_link); - ring_add_before(&ret->link, &enc->glz_drawables); - ring_add(&drawable->glz_ring, &ret->drawable_link); - enc->globals->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 *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; -} - -static const LzImageType bitmap_fmt_to_lz_image_type[] = { - LZ_IMAGE_TYPE_INVALID, - LZ_IMAGE_TYPE_PLT1_LE, - LZ_IMAGE_TYPE_PLT1_BE, - LZ_IMAGE_TYPE_PLT4_LE, - LZ_IMAGE_TYPE_PLT4_BE, - LZ_IMAGE_TYPE_PLT8, - LZ_IMAGE_TYPE_RGB16, - LZ_IMAGE_TYPE_RGB24, - LZ_IMAGE_TYPE_RGB32, - LZ_IMAGE_TYPE_RGBA, - LZ_IMAGE_TYPE_A8 -}; - -#define MIN_GLZ_SIZE_FOR_ZLIB 100 - -static int image_encoders_compress_glz(ImageEncoders *enc, - SpiceImage *dest, SpiceBitmap *src, Drawable *drawable, - compress_send_data_t* o_comp_data, - gboolean enable_zlib_glz_wrap) -{ - stat_start_time_t start_time; - stat_start_time_init(&start_time, &enc->globals->zlib_glz_stat); - spice_assert(bitmap_fmt_is_rgb(src->format)); - GlzData *glz_data = &enc->glz_data; - ZlibData *zlib_data; - LzImageType type = bitmap_fmt_to_lz_image_type[src->format]; - RedGlzDrawable *glz_drawable; - GlzDrawableInstanceItem *glz_drawable_instance; - int glz_size; - int zlib_size; - -#ifdef COMPRESS_DEBUG - spice_info("LZ global compress fmt=%d", src->format); -#endif - - encoder_data_init(&glz_data->data); - - glz_drawable = get_glz_drawable(enc, 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(enc->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), - glz_drawable_instance, - &glz_drawable_instance->context); - - stat_compress_add(&enc->globals->glz_stat, start_time, src->stride * src->y, glz_size); - - if (!enable_zlib_glz_wrap || (glz_size < MIN_GLZ_SIZE_FOR_ZLIB)) { - goto glz; - } - stat_start_time_init(&start_time, &enc->globals->zlib_glz_stat); - zlib_data = &enc->zlib_data; - - encoder_data_init(&zlib_data->data); - - zlib_data->data.u.compressed_data.next = glz_data->data.bufs_head; - zlib_data->data.u.compressed_data.size_left = glz_size; - - zlib_size = zlib_encode(enc->zlib, enc->zlib_level, - glz_size, zlib_data->data.bufs_head->buf.bytes, - sizeof(zlib_data->data.bufs_head->buf)); - - // the compressed buffer is bigger than the original data - if (zlib_size >= glz_size) { - encoder_data_reset(&zlib_data->data); - goto glz; - } else { - encoder_data_reset(&glz_data->data); - } - - dest->descriptor.type = SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB; - dest->u.zlib_glz.glz_data_size = glz_size; - dest->u.zlib_glz.data_size = zlib_size; - - o_comp_data->comp_buf = zlib_data->data.bufs_head; - o_comp_data->comp_buf_size = zlib_size; - - stat_compress_add(&enc->globals->zlib_glz_stat, start_time, glz_size, zlib_size); - return TRUE; -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; -} - #define MIN_DIMENSION_TO_QUIC 3 /** * quic doesn't handle: -- 2.7.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel