[Spice-commits] 6 commits - server/dcc-encoders.c server/dcc-encoders.h server/dcc-send.c server/dcc.c server/dcc.h server/display-channel.c server/display-channel.h server/red-worker.c
Frediano Ziglio
fziglio at kemper.freedesktop.org
Tue Jun 14 14:10:02 UTC 2016
server/dcc-encoders.c | 413 ++++++++++++++++++++++++++++++++++++-----------
server/dcc-encoders.h | 76 ++++++--
server/dcc-send.c | 10 -
server/dcc.c | 213 +++---------------------
server/dcc.h | 9 -
server/display-channel.c | 89 +---------
server/display-channel.h | 11 -
server/red-worker.c | 4
8 files changed, 424 insertions(+), 401 deletions(-)
New commits:
commit 81f3d44ee777ab143a2d1dde03565d2e31a6b45a
Author: Frediano Ziglio <fziglio at redhat.com>
Date: Mon Jun 6 08:28:22 2016 +0100
Move image_encoders_compress_glz to dcc-encoders.c
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index d33ddbd..4de780d 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->shared_data->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->shared_data->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->shared_data->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->shared_data->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->shared_data->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_shared_init(ImageEncoderSharedData *shared_data)
{
clockid_t stat_clock = CLOCK_THREAD_CPUTIME_ID;
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index bea5cca..655c1b3 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 9007afb..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->shared_data->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->shared_data->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->shared_data->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->shared_data->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->shared_data->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:
commit cb8e832c87c28f4272855e350009930b020fb43a
Author: Frediano Ziglio <fziglio at redhat.com>
Date: Mon Jun 6 08:22:45 2016 +0100
Make dcc_compress_image_glz independent to DisplayChannelClient
Also rename to image_encoders_compress_glz
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
diff --git a/server/dcc.c b/server/dcc.c
index 6060b7d..9007afb 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -698,15 +698,15 @@ static const LzImageType bitmap_fmt_to_lz_image_type[] = {
#define MIN_GLZ_SIZE_FOR_ZLIB 100
-static int dcc_compress_image_glz(DisplayChannelClient *dcc,
- SpiceImage *dest, SpiceBitmap *src, Drawable *drawable,
- compress_send_data_t* o_comp_data)
+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)
{
- DisplayChannel *display_channel = DCC_TO_DC(dcc);
stat_start_time_t start_time;
- stat_start_time_init(&start_time, &display_channel->encoder_globals.zlib_glz_stat);
+ stat_start_time_init(&start_time, &enc->shared_data->zlib_glz_stat);
spice_assert(bitmap_fmt_is_rgb(src->format));
- GlzData *glz_data = &dcc->encoders.glz_data;
+ GlzData *glz_data = &enc->glz_data;
ZlibData *zlib_data;
LzImageType type = bitmap_fmt_to_lz_image_type[src->format];
RedGlzDrawable *glz_drawable;
@@ -720,7 +720,7 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
encoder_data_init(&glz_data->data);
- glz_drawable = get_glz_drawable(&dcc->encoders, drawable);
+ 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;
@@ -728,27 +728,27 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
glz_data->data.u.lines_data.next = 0;
glz_data->data.u.lines_data.reverse = 0;
- glz_size = glz_encode(dcc->encoders.glz, type, src->x, src->y,
+ 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(&display_channel->encoder_globals.glz_stat, start_time, src->stride * src->y, glz_size);
+ stat_compress_add(&enc->shared_data->glz_stat, start_time, src->stride * src->y, glz_size);
- if (!display_channel->enable_zlib_glz_wrap || (glz_size < MIN_GLZ_SIZE_FOR_ZLIB)) {
+ if (!enable_zlib_glz_wrap || (glz_size < MIN_GLZ_SIZE_FOR_ZLIB)) {
goto glz;
}
- stat_start_time_init(&start_time, &display_channel->encoder_globals.zlib_glz_stat);
- zlib_data = &dcc->encoders.zlib_data;
+ stat_start_time_init(&start_time, &enc->shared_data->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(dcc->encoders.zlib, dcc->encoders.zlib_level,
+ 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));
@@ -767,7 +767,7 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
o_comp_data->comp_buf = zlib_data->data.bufs_head;
o_comp_data->comp_buf_size = zlib_size;
- stat_compress_add(&display_channel->encoder_globals.zlib_glz_stat, start_time, glz_size, zlib_size);
+ stat_compress_add(&enc->shared_data->zlib_glz_stat, start_time, glz_size, zlib_size);
return TRUE;
glz:
dest->descriptor.type = SPICE_IMAGE_TYPE_GLZ_RGB;
@@ -894,7 +894,8 @@ int dcc_compress_image(DisplayChannelClient *dcc,
pthread_rwlock_rdlock(&dcc->encoders.glz_dict->encode_lock);
frozen = dcc->encoders.glz_dict->migrate_freeze;
if (!frozen) {
- success = dcc_compress_image_glz(dcc, dest, src, drawable, o_comp_data);
+ success = image_encoders_compress_glz(&dcc->encoders, dest, src, drawable, o_comp_data,
+ display_channel->enable_zlib_glz_wrap);
}
pthread_rwlock_unlock(&dcc->encoders.glz_dict->encode_lock);
if (!frozen) {
commit 108d11f4aaabbabc42d80b2e7231db0f2ce823ce
Author: Frediano Ziglio <fziglio at redhat.com>
Date: Tue Jun 7 10:35:23 2016 +0100
Move others glz fields to dcc-encoders
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 7497029..d33ddbd 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, ImageEncoderSharedData *shared_data
spice_assert(shared_data);
enc->shared_data = shared_data;
+ 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->shared_data->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,
GlzDrawableInstanceItem,
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 2b4d556..bea5cca 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -43,14 +43,13 @@ void image_encoder_shared_stat_print(const ImageEncoderSharedData *shared_data);
void image_encoders_init(ImageEncoders *enc, ImageEncoderSharedData *shared_data);
void image_encoders_free(ImageEncoders *enc);
-void dcc_free_glz_drawable (DisplayChannelClient *dcc,
- RedGlzDrawable *drawable);
-int dcc_free_some_independent_glz_drawables (DisplayChannelClient *dcc);
-void dcc_free_glz_drawables (DisplayChannelClient *dcc);
-void dcc_free_glz_drawables_to_free (DisplayChannelClient* 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 (DisplayChannelClient *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 ImageEncoderSharedData {
+ 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..6060b7d 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->shared_data->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 ac6de84..e87f110 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 8c0c859..f1e8ba1 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 db1cdba..8588583 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);
commit 41231aa4f8edb12aabc2bba5daddf4b9fa398437
Author: Frediano Ziglio <fziglio at redhat.com>
Date: Tue Jun 14 09:16:28 2016 +0100
Change dcc_encoders_init to take ImageEncoders instead of DisplayChannelClient
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index c03409c..7497029 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -398,10 +398,8 @@ static void image_encoders_init_zlib(ImageEncoders *enc)
}
}
-void dcc_encoders_init(DisplayChannelClient *dcc, ImageEncoderSharedData *shared_data)
+void image_encoders_init(ImageEncoders *enc, ImageEncoderSharedData *shared_data)
{
- ImageEncoders *enc = &dcc->encoders;
-
spice_assert(shared_data);
enc->shared_data = shared_data;
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 596429c..2b4d556 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -41,7 +41,7 @@ void image_encoder_shared_init(ImageEncoderSharedData *shared_data);
void image_encoder_shared_stat_reset(ImageEncoderSharedData *shared_data);
void image_encoder_shared_stat_print(const ImageEncoderSharedData *shared_data);
-void dcc_encoders_init(DisplayChannelClient *dcc, ImageEncoderSharedData *shared_data);
+void image_encoders_init(ImageEncoders *enc, ImageEncoderSharedData *shared_data);
void image_encoders_free(ImageEncoders *enc);
void dcc_free_glz_drawable (DisplayChannelClient *dcc,
RedGlzDrawable *drawable);
diff --git a/server/dcc.c b/server/dcc.c
index d73b742..1cc85b5 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -396,7 +396,7 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
ring_init(&dcc->glz_drawables_inst_to_free);
pthread_mutex_init(&dcc->glz_drawables_inst_to_free_lock, NULL);
- dcc_encoders_init(dcc, &display->encoder_globals);
+ image_encoders_init(&dcc->encoders, &display->encoder_globals);
return dcc;
}
commit b46984ed30e69965448a6e98304f703cf80b44e1
Author: Frediano Ziglio <fziglio at redhat.com>
Date: Tue Jun 14 09:15:47 2016 +0100
Move some glz fields to ImageEncoders
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index c79cf58..c03409c 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -330,7 +330,7 @@ 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, glz_data);
+ 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);
} else {
@@ -348,16 +348,16 @@ static void glz_usr_free_image(GlzEncoderUsrContext *usr, GlzUsrImageContext *im
}
}
-static void dcc_init_glz_data(DisplayChannelClient *dcc)
+static void image_encoders_init_glz_data(ImageEncoders *enc)
{
- dcc->glz_data.usr.error = glz_usr_error;
- dcc->glz_data.usr.warn = glz_usr_warn;
- dcc->glz_data.usr.info = glz_usr_warn;
- dcc->glz_data.usr.malloc = glz_usr_malloc;
- dcc->glz_data.usr.free = glz_usr_free;
- dcc->glz_data.usr.more_space = glz_usr_more_space;
- dcc->glz_data.usr.more_lines = glz_usr_more_lines;
- dcc->glz_data.usr.free_image = glz_usr_free_image;
+ enc->glz_data.usr.error = glz_usr_error;
+ enc->glz_data.usr.warn = glz_usr_warn;
+ enc->glz_data.usr.info = glz_usr_warn;
+ enc->glz_data.usr.malloc = glz_usr_malloc;
+ enc->glz_data.usr.free = glz_usr_free;
+ enc->glz_data.usr.more_space = glz_usr_more_space;
+ enc->glz_data.usr.more_lines = glz_usr_more_lines;
+ enc->glz_data.usr.free_image = glz_usr_free_image;
}
static void image_encoders_init_jpeg(ImageEncoders *enc)
@@ -405,7 +405,7 @@ void dcc_encoders_init(DisplayChannelClient *dcc, ImageEncoderSharedData *shared
spice_assert(shared_data);
enc->shared_data = shared_data;
- dcc_init_glz_data(dcc);
+ image_encoders_init_glz_data(enc);
image_encoders_init_quic(enc);
image_encoders_init_lz(enc);
image_encoders_init_jpeg(enc);
@@ -500,9 +500,9 @@ 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->glz_dict->dict,
+ glz_enc_dictionary_remove_image(dcc->encoders.glz_dict->dict,
instance->context,
- &dcc->glz_data.usr);
+ &dcc->encoders.glz_data.usr);
}
dcc_free_glz_drawable_instance(dcc, instance);
@@ -541,7 +541,7 @@ void dcc_free_glz_drawables_to_free(DisplayChannelClient* dcc)
{
RingItem *ring_link;
- if (!dcc->glz_dict) {
+ if (!dcc->encoders.glz_dict) {
return;
}
pthread_mutex_lock(&dcc->glz_drawables_inst_to_free_lock);
@@ -559,7 +559,7 @@ void dcc_free_glz_drawables_to_free(DisplayChannelClient* dcc)
void dcc_free_glz_drawables(DisplayChannelClient *dcc)
{
RingItem *ring_link;
- GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
+ GlzSharedDictionary *glz_dict = dcc ? dcc->encoders.glz_dict : NULL;
if (!glz_dict) {
return;
@@ -576,11 +576,11 @@ void dcc_free_glz_drawables(DisplayChannelClient *dcc)
pthread_rwlock_unlock(&glz_dict->encode_lock);
}
-void dcc_freeze_glz(DisplayChannelClient *dcc)
+void image_encoders_freeze_glz(ImageEncoders *enc)
{
- pthread_rwlock_wrlock(&dcc->glz_dict->encode_lock);
- dcc->glz_dict->migrate_freeze = TRUE;
- pthread_rwlock_unlock(&dcc->glz_dict->encode_lock);
+ pthread_rwlock_wrlock(&enc->glz_dict->encode_lock);
+ enc->glz_dict->migrate_freeze = TRUE;
+ pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
}
static GlzSharedDictionary *glz_shared_dictionary_new(RedClient *client, uint8_t id,
@@ -623,82 +623,95 @@ static GlzSharedDictionary *find_glz_dictionary(RedClient *client, uint8_t dict_
#define MAX_LZ_ENCODERS MAX_CACHE_CLIENTS
-static GlzSharedDictionary *create_glz_dictionary(DisplayChannelClient *dcc,
+static GlzSharedDictionary *create_glz_dictionary(ImageEncoders *enc,
+ RedClient *client,
uint8_t id, int window_size)
{
spice_info("Lz Window %d Size=%d", id, window_size);
GlzEncDictContext *glz_dict =
- glz_enc_dictionary_create(window_size, MAX_LZ_ENCODERS, &dcc->glz_data.usr);
+ glz_enc_dictionary_create(window_size, MAX_LZ_ENCODERS, &enc->glz_data.usr);
- return glz_shared_dictionary_new(RED_CHANNEL_CLIENT(dcc)->client, id, glz_dict);
+ return glz_shared_dictionary_new(client, id, glz_dict);
}
-GlzSharedDictionary *dcc_get_glz_dictionary(DisplayChannelClient *dcc,
- uint8_t id, int window_size)
+gboolean image_encoders_get_glz_dictionary(ImageEncoders *enc,
+ RedClient *client,
+ uint8_t id, int window_size)
{
GlzSharedDictionary *shared_dict;
pthread_mutex_lock(&glz_dictionary_list_lock);
- shared_dict = find_glz_dictionary(RED_CHANNEL_CLIENT(dcc)->client, id);
+ shared_dict = find_glz_dictionary(client, id);
if (shared_dict) {
shared_dict->refs++;
} else {
- shared_dict = create_glz_dictionary(dcc, id, window_size);
+ shared_dict = create_glz_dictionary(enc, client, id, window_size);
ring_add(&glz_dictionary_list, &shared_dict->base);
}
pthread_mutex_unlock(&glz_dictionary_list_lock);
- return shared_dict;
+ enc->glz_dict = shared_dict;
+ return shared_dict != NULL;
}
-static GlzSharedDictionary *restore_glz_dictionary(DisplayChannelClient *dcc,
+static GlzSharedDictionary *restore_glz_dictionary(ImageEncoders *enc,
+ RedClient *client,
uint8_t id,
GlzEncDictRestoreData *restore_data)
{
GlzEncDictContext *glz_dict =
- glz_enc_dictionary_restore(restore_data, &dcc->glz_data.usr);
+ glz_enc_dictionary_restore(restore_data, &enc->glz_data.usr);
- return glz_shared_dictionary_new(RED_CHANNEL_CLIENT(dcc)->client, id, glz_dict);
+ return glz_shared_dictionary_new(client, id, glz_dict);
}
-GlzSharedDictionary *dcc_restore_glz_dictionary(DisplayChannelClient *dcc,
- uint8_t id,
- GlzEncDictRestoreData *restore_data)
+gboolean image_encoders_restore_glz_dictionary(ImageEncoders *enc,
+ RedClient *client,
+ uint8_t id,
+ GlzEncDictRestoreData *restore_data)
{
GlzSharedDictionary *shared_dict = NULL;
pthread_mutex_lock(&glz_dictionary_list_lock);
- shared_dict = find_glz_dictionary(RED_CHANNEL_CLIENT(dcc)->client, id);
+ shared_dict = find_glz_dictionary(client, id);
if (shared_dict) {
shared_dict->refs++;
} else {
- shared_dict = restore_glz_dictionary(dcc, id, restore_data);
+ shared_dict = restore_glz_dictionary(enc, client, id, restore_data);
ring_add(&glz_dictionary_list, &shared_dict->base);
}
pthread_mutex_unlock(&glz_dictionary_list_lock);
- return shared_dict;
+ enc->glz_dict = shared_dict;
+ return shared_dict != NULL;
+}
+
+gboolean image_encoders_glz_create(ImageEncoders *enc, uint8_t id)
+{
+ enc->glz = glz_encoder_create(id, enc->glz_dict->dict, &enc->glz_data.usr);
+ return enc->glz != NULL;
}
/* destroy encoder, and dictionary if no one uses it*/
void dcc_release_glz(DisplayChannelClient *dcc)
{
+ ImageEncoders *enc = &dcc->encoders;
GlzSharedDictionary *shared_dict;
dcc_free_glz_drawables(dcc);
- glz_encoder_destroy(dcc->glz);
- dcc->glz = NULL;
+ glz_encoder_destroy(enc->glz);
+ enc->glz = NULL;
- if (!(shared_dict = dcc->glz_dict)) {
+ if (!(shared_dict = enc->glz_dict)) {
return;
}
- dcc->glz_dict = NULL;
+ enc->glz_dict = NULL;
pthread_mutex_lock(&glz_dictionary_list_lock);
if (--shared_dict->refs != 0) {
pthread_mutex_unlock(&glz_dictionary_list_lock);
@@ -706,7 +719,7 @@ void dcc_release_glz(DisplayChannelClient *dcc)
}
ring_remove(&shared_dict->base);
pthread_mutex_unlock(&glz_dictionary_list_lock);
- glz_enc_dictionary_destroy(shared_dict->dict, &dcc->glz_data.usr);
+ glz_enc_dictionary_destroy(shared_dict->dict, &enc->glz_data.usr);
free(shared_dict);
}
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 4b89cc9..596429c 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -48,7 +48,8 @@ void dcc_free_glz_drawable (DisplayChannelClie
int dcc_free_some_independent_glz_drawables (DisplayChannelClient *dcc);
void dcc_free_glz_drawables (DisplayChannelClient *dcc);
void dcc_free_glz_drawables_to_free (DisplayChannelClient* dcc);
-void dcc_freeze_glz (DisplayChannelClient *dcc);
+gboolean image_encoders_glz_create(ImageEncoders *enc, uint8_t id);
+void image_encoders_freeze_glz(ImageEncoders *enc);
void dcc_release_glz (DisplayChannelClient *dcc);
#define RED_COMPRESS_BUF_SIZE (1024 * 64)
@@ -79,11 +80,13 @@ typedef struct GlzSharedDictionary {
RedClient *client; // channel clients of the same client share the dict
} GlzSharedDictionary;
-GlzSharedDictionary* dcc_get_glz_dictionary (DisplayChannelClient *dcc,
- uint8_t id, int window_size);
-GlzSharedDictionary* dcc_restore_glz_dictionary (DisplayChannelClient *dcc,
- uint8_t id,
- GlzEncDictRestoreData *restore_data);
+gboolean image_encoders_get_glz_dictionary(ImageEncoders *enc,
+ struct RedClient *client,
+ uint8_t id, int window_size);
+gboolean image_encoders_restore_glz_dictionary(ImageEncoders *enc,
+ struct RedClient *client,
+ uint8_t id,
+ GlzEncDictRestoreData *restore_data);
typedef struct {
RedCompressBuf *bufs_head;
@@ -200,6 +203,11 @@ struct ImageEncoders {
ZlibData zlib_data;
ZlibEncoder *zlib;
+
+ /* global lz encoding entities */
+ GlzSharedDictionary *glz_dict;
+ GlzEncoderContext *glz;
+ GlzData glz_data;
};
typedef struct compress_send_data_t {
diff --git a/server/dcc-send.c b/server/dcc-send.c
index 6c10565..c0c7573 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -1859,12 +1859,12 @@ static void display_channel_marshall_migrate_data(RedChannelClient *rcc,
memcpy(display_data.pixmap_cache_clients, dcc->pixmap_cache->sync,
sizeof(display_data.pixmap_cache_clients));
- spice_assert(dcc->glz_dict);
- dcc_freeze_glz(dcc);
- display_data.glz_dict_id = dcc->glz_dict->id;
- glz_enc_dictionary_get_restore_data(dcc->glz_dict->dict,
+ spice_assert(dcc->encoders.glz_dict);
+ image_encoders_freeze_glz(&dcc->encoders);
+ display_data.glz_dict_id = dcc->encoders.glz_dict->id;
+ glz_enc_dictionary_get_restore_data(dcc->encoders.glz_dict->dict,
&display_data.glz_dict_data,
- &dcc->glz_data.usr);
+ &dcc->encoders.glz_data.usr);
/* all data besided the surfaces ref */
spice_marshaller_add(base_marshaller,
diff --git a/server/dcc.c b/server/dcc.c
index 8f44e64..d73b742 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -422,12 +422,11 @@ static int display_channel_client_wait_for_init(DisplayChannelClient *dcc)
if (!red_channel_client_is_connected(RED_CHANNEL_CLIENT(dcc))) {
break;
}
- if (dcc->pixmap_cache && dcc->glz_dict) {
+ if (dcc->pixmap_cache && dcc->encoders.glz_dict) {
dcc->pixmap_cache_generation = dcc->pixmap_cache->generation;
/* TODO: move common.id? if it's used for a per client structure.. */
spice_info("creating encoder with id == %d", dcc->id);
- dcc->glz = glz_encoder_create(dcc->id, dcc->glz_dict->dict, &dcc->glz_data.usr);
- if (!dcc->glz) {
+ if (!image_encoders_glz_create(&dcc->encoders, dcc->id)) {
spice_critical("create global lz failed");
}
return TRUE;
@@ -711,7 +710,7 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
stat_start_time_t start_time;
stat_start_time_init(&start_time, &display_channel->encoder_globals.zlib_glz_stat);
spice_assert(bitmap_fmt_is_rgb(src->format));
- GlzData *glz_data = &dcc->glz_data;
+ GlzData *glz_data = &dcc->encoders.glz_data;
ZlibData *zlib_data;
LzImageType type = bitmap_fmt_to_lz_image_type[src->format];
RedGlzDrawable *glz_drawable;
@@ -733,7 +732,7 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
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,
+ glz_size = glz_encode(dcc->encoders.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),
@@ -893,15 +892,15 @@ int dcc_compress_image(DisplayChannelClient *dcc,
success = image_encoders_compress_quic(&dcc->encoders, dest, src, o_comp_data);
break;
case SPICE_IMAGE_COMPRESSION_GLZ:
- if ((src->x * src->y) < glz_enc_dictionary_get_size(dcc->glz_dict->dict)) {
+ if ((src->x * src->y) < glz_enc_dictionary_get_size(dcc->encoders.glz_dict->dict)) {
int frozen;
/* using the global dictionary only if it is not frozen */
- pthread_rwlock_rdlock(&dcc->glz_dict->encode_lock);
- frozen = dcc->glz_dict->migrate_freeze;
+ pthread_rwlock_rdlock(&dcc->encoders.glz_dict->encode_lock);
+ frozen = dcc->encoders.glz_dict->migrate_freeze;
if (!frozen) {
success = dcc_compress_image_glz(dcc, dest, src, drawable, o_comp_data);
}
- pthread_rwlock_unlock(&dcc->glz_dict->encode_lock);
+ pthread_rwlock_unlock(&dcc->encoders.glz_dict->encode_lock);
if (!frozen) {
break;
}
@@ -1053,6 +1052,8 @@ int dcc_pixmap_cache_unlocked_add(DisplayChannelClient *dcc, uint64_t id,
static int dcc_handle_init(DisplayChannelClient *dcc, SpiceMsgcDisplayInit *init)
{
+ gboolean success;
+
spice_return_val_if_fail(dcc->expect_init, FALSE);
dcc->expect_init = FALSE;
@@ -1062,11 +1063,12 @@ static int dcc_handle_init(DisplayChannelClient *dcc, SpiceMsgcDisplayInit *init
init->pixmap_cache_size);
spice_return_val_if_fail(dcc->pixmap_cache, FALSE);
- spice_return_val_if_fail(!dcc->glz_dict, FALSE);
- dcc->glz_dict = dcc_get_glz_dictionary(dcc,
- init->glz_dictionary_id,
- init->glz_dictionary_window_size);
- spice_return_val_if_fail(dcc->glz_dict, FALSE);
+ spice_return_val_if_fail(!dcc->encoders.glz_dict, FALSE);
+ success = image_encoders_get_glz_dictionary(&dcc->encoders,
+ RED_CHANNEL_CLIENT(dcc)->client,
+ init->glz_dictionary_id,
+ init->glz_dictionary_window_size);
+ spice_return_val_if_fail(success, FALSE);
return TRUE;
}
@@ -1166,12 +1168,12 @@ int dcc_handle_message(RedChannelClient *rcc, uint32_t size, uint16_t type, void
static int dcc_handle_migrate_glz_dictionary(DisplayChannelClient *dcc,
SpiceMigrateDataDisplay *migrate)
{
- spice_return_val_if_fail(!dcc->glz_dict, FALSE);
+ spice_return_val_if_fail(!dcc->encoders.glz_dict, FALSE);
- dcc->glz_dict = dcc_restore_glz_dictionary(dcc,
- migrate->glz_dict_id,
- &migrate->glz_dict_data);
- return dcc->glz_dict != NULL;
+ return image_encoders_restore_glz_dictionary(&dcc->encoders,
+ RED_CHANNEL_CLIENT(dcc)->client,
+ migrate->glz_dict_id,
+ &migrate->glz_dict_data);
}
static int restore_surface(DisplayChannelClient *dcc, uint32_t surface_id)
@@ -1264,8 +1266,7 @@ int dcc_handle_migrate_data(DisplayChannelClient *dcc, uint32_t size, void *mess
}
if (dcc_handle_migrate_glz_dictionary(dcc, migrate_data)) {
- dcc->glz =
- glz_encoder_create(dcc->id, dcc->glz_dict->dict, &dcc->glz_data.usr);
+ image_encoders_glz_create(&dcc->encoders, dcc->id);
} else {
spice_critical("restoring global lz dictionary failed");
}
diff --git a/server/dcc.h b/server/dcc.h
index 20f41e2..ac6de84 100644
--- a/server/dcc.h
+++ b/server/dcc.h
@@ -84,10 +84,6 @@ struct DisplayChannelClient {
} send_data;
/* global lz encoding entities */
- 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;
diff --git a/server/display-channel.c b/server/display-channel.c
index 6ec8692..8c0c859 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -1202,7 +1202,7 @@ void display_channel_free_some(DisplayChannel *display)
spice_debug("#draw=%d, #glz_draw=%d", display->drawable_count,
display->glz_drawable_count);
FOREACH_CLIENT(display, link, next, dcc) {
- GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
+ GlzSharedDictionary *glz_dict = dcc->encoders.glz_dict;
if (glz_dict) {
// encoding using the dictionary is prevented since the following operations might
@@ -1217,7 +1217,7 @@ void display_channel_free_some(DisplayChannel *display)
}
FOREACH_CLIENT(display, link, next, dcc) {
- GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
+ GlzSharedDictionary *glz_dict = dcc->encoders.glz_dict;
if (glz_dict) {
pthread_rwlock_unlock(&glz_dict->encode_lock);
commit 86b702a7d007c6c7d4b1f58bd01681bac920abcf
Author: Frediano Ziglio <fziglio at redhat.com>
Date: Fri Jun 10 05:39:25 2016 +0100
Add a structure to hold ImageEncoders shared data
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 6aaf954..c79cf58 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -398,10 +398,13 @@ static void image_encoders_init_zlib(ImageEncoders *enc)
}
}
-void dcc_encoders_init(DisplayChannelClient *dcc)
+void dcc_encoders_init(DisplayChannelClient *dcc, ImageEncoderSharedData *shared_data)
{
ImageEncoders *enc = &dcc->encoders;
+ spice_assert(shared_data);
+ enc->shared_data = shared_data;
+
dcc_init_glz_data(dcc);
image_encoders_init_quic(enc);
image_encoders_init_lz(enc);
@@ -708,15 +711,14 @@ void dcc_release_glz(DisplayChannelClient *dcc)
}
int image_encoders_compress_quic(ImageEncoders *enc, SpiceImage *dest,
- SpiceBitmap *src, compress_send_data_t* o_comp_data,
- stat_info_t *stats)
+ SpiceBitmap *src, compress_send_data_t* o_comp_data)
{
QuicData *quic_data = &enc->quic_data;
QuicContext *quic = enc->quic;
volatile QuicImageType type;
int size, stride;
stat_start_time_t start_time;
- stat_start_time_init(&start_time, stats);
+ stat_start_time_init(&start_time, &enc->shared_data->quic_stat);
#ifdef COMPRESS_DEBUG
spice_info("QUIC compress");
@@ -776,7 +778,7 @@ int image_encoders_compress_quic(ImageEncoders *enc, SpiceImage *dest,
o_comp_data->comp_buf = quic_data->data.bufs_head;
o_comp_data->comp_buf_size = size << 2;
- stat_compress_add(stats, start_time, src->stride * src->y,
+ stat_compress_add(&enc->shared_data->quic_stat, start_time, src->stride * src->y,
o_comp_data->comp_buf_size);
return TRUE;
}
@@ -797,8 +799,7 @@ static const LzImageType bitmap_fmt_to_lz_image_type[] = {
int image_encoders_compress_lz(ImageEncoders *enc,
SpiceImage *dest, SpiceBitmap *src,
- compress_send_data_t* o_comp_data,
- stat_info_t *stats)
+ compress_send_data_t* o_comp_data)
{
LzData *lz_data = &enc->lz_data;
LzContext *lz = enc->lz;
@@ -806,7 +807,7 @@ int image_encoders_compress_lz(ImageEncoders *enc,
int size; // size of the compressed data
stat_start_time_t start_time;
- stat_start_time_init(&start_time, stats);
+ stat_start_time_init(&start_time, &enc->shared_data->lz_stat);
#ifdef COMPRESS_DEBUG
spice_info("LZ LOCAL compress");
@@ -856,15 +857,13 @@ int image_encoders_compress_lz(ImageEncoders *enc,
o_comp_data->lzplt_palette = dest->u.lz_plt.palette;
}
- stat_compress_add(stats, start_time, src->stride * src->y,
+ stat_compress_add(&enc->shared_data->lz_stat, start_time, src->stride * src->y,
o_comp_data->comp_buf_size);
return TRUE;
}
int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest,
- SpiceBitmap *src, compress_send_data_t* o_comp_data,
- stat_info_t *jpeg_stats, // FIXME put all stats in a structure
- stat_info_t *jpeg_alpha_stats)
+ SpiceBitmap *src, compress_send_data_t* o_comp_data)
{
JpegData *jpeg_data = &enc->jpeg_data;
LzData *lz_data = &enc->lz_data;
@@ -879,7 +878,7 @@ int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest,
int stride;
uint8_t *lz_out_start_byte;
stat_start_time_t start_time;
- stat_start_time_init(&start_time, jpeg_alpha_stats);
+ stat_start_time_init(&start_time, &enc->shared_data->jpeg_alpha_stat);
#ifdef COMPRESS_DEBUG
spice_info("JPEG compress");
@@ -943,7 +942,7 @@ int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest,
o_comp_data->comp_buf_size = jpeg_size;
o_comp_data->is_lossy = TRUE;
- stat_compress_add(jpeg_stats, start_time, src->stride * src->y,
+ stat_compress_add(&enc->shared_data->jpeg_stat, start_time, src->stride * src->y,
o_comp_data->comp_buf_size);
return TRUE;
}
@@ -983,21 +982,20 @@ int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest,
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(jpeg_alpha_stats, start_time, src->stride * src->y,
+ stat_compress_add(&enc->shared_data->jpeg_alpha_stat, start_time, src->stride * src->y,
o_comp_data->comp_buf_size);
return TRUE;
}
#ifdef USE_LZ4
int image_encoders_compress_lz4(ImageEncoders *enc, SpiceImage *dest,
- SpiceBitmap *src, compress_send_data_t* o_comp_data,
- stat_info_t *stats)
+ SpiceBitmap *src, compress_send_data_t* o_comp_data)
{
Lz4Data *lz4_data = &enc->lz4_data;
Lz4EncoderContext *lz4 = enc->lz4;
int lz4_size = 0;
stat_start_time_t start_time;
- stat_start_time_init(&start_time, stats);
+ stat_start_time_init(&start_time, &enc->shared_data->lz4_stat);
#ifdef COMPRESS_DEBUG
spice_info("LZ4 compress");
@@ -1034,8 +1032,93 @@ int image_encoders_compress_lz4(ImageEncoders *enc, SpiceImage *dest,
o_comp_data->comp_buf = lz4_data->data.bufs_head;
o_comp_data->comp_buf_size = lz4_size;
- stat_compress_add(stats, start_time, src->stride * src->y,
+ stat_compress_add(&enc->shared_data->lz4_stat, start_time, src->stride * src->y,
o_comp_data->comp_buf_size);
return TRUE;
}
#endif
+
+void image_encoder_shared_init(ImageEncoderSharedData *shared_data)
+{
+ clockid_t stat_clock = CLOCK_THREAD_CPUTIME_ID;
+
+ stat_compress_init(&shared_data->off_stat, "off", stat_clock);
+ stat_compress_init(&shared_data->lz_stat, "lz", stat_clock);
+ stat_compress_init(&shared_data->glz_stat, "glz", stat_clock);
+ stat_compress_init(&shared_data->quic_stat, "quic", stat_clock);
+ stat_compress_init(&shared_data->jpeg_stat, "jpeg", stat_clock);
+ stat_compress_init(&shared_data->zlib_glz_stat, "zlib", stat_clock);
+ stat_compress_init(&shared_data->jpeg_alpha_stat, "jpeg_alpha", stat_clock);
+ stat_compress_init(&shared_data->lz4_stat, "lz4", stat_clock);
+}
+
+void image_encoder_shared_stat_reset(ImageEncoderSharedData *shared_data)
+{
+ stat_reset(&shared_data->off_stat);
+ stat_reset(&shared_data->quic_stat);
+ stat_reset(&shared_data->lz_stat);
+ stat_reset(&shared_data->glz_stat);
+ stat_reset(&shared_data->jpeg_stat);
+ stat_reset(&shared_data->zlib_glz_stat);
+ stat_reset(&shared_data->jpeg_alpha_stat);
+ stat_reset(&shared_data->lz4_stat);
+}
+
+#define STAT_FMT "%s\t%8u\t%13.8g\t%12.8g\t%12.8g"
+
+#ifdef COMPRESS_STAT
+static void stat_print_one(const char *name, const stat_info_t *stat)
+{
+ spice_info(STAT_FMT, name, stat->count,
+ stat_byte_to_mega(stat->orig_size),
+ stat_byte_to_mega(stat->comp_size),
+ stat_cpu_time_to_sec(stat->total));
+}
+
+static void stat_sum(stat_info_t *total, const stat_info_t *stat)
+{
+ total->count += stat->count;
+ total->orig_size += stat->orig_size;
+ total->comp_size += stat->comp_size;
+ total->total += stat->total;
+}
+#endif
+
+void image_encoder_shared_stat_print(const ImageEncoderSharedData *shared_data)
+{
+#ifdef COMPRESS_STAT
+ /* sum all statistics */
+ stat_info_t total = {
+ .count = 0,
+ .orig_size = 0,
+ .comp_size = 0,
+ .total = 0
+ };
+ stat_sum(&total, &shared_data->off_stat);
+ stat_sum(&total, &shared_data->quic_stat);
+ stat_sum(&total, &shared_data->glz_stat);
+ stat_sum(&total, &shared_data->lz_stat);
+ stat_sum(&total, &shared_data->jpeg_stat);
+ stat_sum(&total, &shared_data->jpeg_alpha_stat);
+ stat_sum(&total, &shared_data->lz4_stat);
+
+ /* fix for zlib glz */
+ total.total += shared_data->zlib_glz_stat.total;
+ if (shared_data->zlib_glz_stat.count) {
+ total.comp_size = total.comp_size - shared_data->glz_stat.comp_size +
+ shared_data->zlib_glz_stat.comp_size;
+ }
+
+ spice_info("Method \t count \torig_size(MB)\tenc_size(MB)\tenc_time(s)");
+ stat_print_one("OFF ", &shared_data->off_stat);
+ stat_print_one("QUIC ", &shared_data->quic_stat);
+ stat_print_one("GLZ ", &shared_data->glz_stat);
+ stat_print_one("ZLIB GLZ ", &shared_data->zlib_glz_stat);
+ stat_print_one("LZ ", &shared_data->lz_stat);
+ stat_print_one("JPEG ", &shared_data->jpeg_stat);
+ stat_print_one("JPEG-RGBA", &shared_data->jpeg_alpha_stat);
+ stat_print_one("LZ4 ", &shared_data->lz4_stat);
+ spice_info("-------------------------------------------------------------------");
+ stat_print_one("Total ", &total);
+#endif
+}
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 23355f7..4b89cc9 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -35,8 +35,13 @@ typedef struct RedCompressBuf RedCompressBuf;
typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
typedef struct RedGlzDrawable RedGlzDrawable;
typedef struct ImageEncoders ImageEncoders;
+typedef struct ImageEncoderSharedData ImageEncoderSharedData;
-void dcc_encoders_init (DisplayChannelClient *dcc);
+void image_encoder_shared_init(ImageEncoderSharedData *shared_data);
+void image_encoder_shared_stat_reset(ImageEncoderSharedData *shared_data);
+void image_encoder_shared_stat_print(const ImageEncoderSharedData *shared_data);
+
+void dcc_encoders_init(DisplayChannelClient *dcc, ImageEncoderSharedData *shared_data);
void image_encoders_free(ImageEncoders *enc);
void dcc_free_glz_drawable (DisplayChannelClient *dcc,
RedGlzDrawable *drawable);
@@ -161,7 +166,20 @@ struct RedGlzDrawable {
DisplayChannelClient *dcc;
};
+struct ImageEncoderSharedData {
+ stat_info_t off_stat;
+ stat_info_t lz_stat;
+ stat_info_t glz_stat;
+ stat_info_t quic_stat;
+ stat_info_t jpeg_stat;
+ stat_info_t zlib_glz_stat;
+ stat_info_t jpeg_alpha_stat;
+ stat_info_t lz4_stat;
+};
+
struct ImageEncoders {
+ ImageEncoderSharedData *shared_data;
+
QuicData quic_data;
QuicContext *quic;
@@ -192,19 +210,14 @@ typedef struct compress_send_data_t {
} compress_send_data_t;
int image_encoders_compress_quic(ImageEncoders *enc, SpiceImage *dest,
- SpiceBitmap *src, compress_send_data_t* o_comp_data,
- stat_info_t *stats);
+ SpiceBitmap *src, compress_send_data_t* o_comp_data);
int image_encoders_compress_lz(ImageEncoders *enc,
SpiceImage *dest, SpiceBitmap *src,
- compress_send_data_t* o_comp_data,
- stat_info_t *stats);
+ compress_send_data_t* o_comp_data);
int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest,
- SpiceBitmap *src, compress_send_data_t* o_comp_data,
- stat_info_t *jpeg_stats,
- stat_info_t *jpeg_alpha_stats);
+ 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,
- stat_info_t *stats);
+ SpiceBitmap *src, compress_send_data_t* o_comp_data);
#define RED_RELEASE_BUNCH_SIZE 64
diff --git a/server/dcc.c b/server/dcc.c
index 7724e11..8f44e64 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -396,7 +396,7 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
ring_init(&dcc->glz_drawables_inst_to_free);
pthread_mutex_init(&dcc->glz_drawables_inst_to_free_lock, NULL);
- dcc_encoders_init(dcc);
+ dcc_encoders_init(dcc, &display->encoder_globals);
return dcc;
}
@@ -709,7 +709,7 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
{
DisplayChannel *display_channel = DCC_TO_DC(dcc);
stat_start_time_t start_time;
- stat_start_time_init(&start_time, &display_channel->zlib_glz_stat);
+ stat_start_time_init(&start_time, &display_channel->encoder_globals.zlib_glz_stat);
spice_assert(bitmap_fmt_is_rgb(src->format));
GlzData *glz_data = &dcc->glz_data;
ZlibData *zlib_data;
@@ -740,12 +740,12 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
glz_drawable_instance,
&glz_drawable_instance->context);
- stat_compress_add(&display_channel->glz_stat, start_time, src->stride * src->y, glz_size);
+ stat_compress_add(&display_channel->encoder_globals.glz_stat, start_time, src->stride * src->y, glz_size);
if (!display_channel->enable_zlib_glz_wrap || (glz_size < MIN_GLZ_SIZE_FOR_ZLIB)) {
goto glz;
}
- stat_start_time_init(&start_time, &display_channel->zlib_glz_stat);
+ stat_start_time_init(&start_time, &display_channel->encoder_globals.zlib_glz_stat);
zlib_data = &dcc->encoders.zlib_data;
encoder_data_init(&zlib_data->data);
@@ -772,7 +772,7 @@ static int dcc_compress_image_glz(DisplayChannelClient *dcc,
o_comp_data->comp_buf = zlib_data->data.bufs_head;
o_comp_data->comp_buf_size = zlib_size;
- stat_compress_add(&display_channel->zlib_glz_stat, start_time, glz_size, zlib_size);
+ stat_compress_add(&display_channel->encoder_globals.zlib_glz_stat, start_time, glz_size, zlib_size);
return TRUE;
glz:
dest->descriptor.type = SPICE_IMAGE_TYPE_GLZ_RGB;
@@ -878,7 +878,7 @@ int dcc_compress_image(DisplayChannelClient *dcc,
stat_start_time_t start_time;
int success = FALSE;
- stat_start_time_init(&start_time, &display_channel->off_stat);
+ stat_start_time_init(&start_time, &display_channel->encoder_globals.off_stat);
image_compression = get_compression_for_bitmap(src, dcc->image_compression, drawable);
switch (image_compression) {
@@ -887,13 +887,10 @@ int dcc_compress_image(DisplayChannelClient *dcc,
case SPICE_IMAGE_COMPRESSION_QUIC:
if (can_lossy && display_channel->enable_jpeg &&
(src->format != SPICE_BITMAP_FMT_RGBA || !bitmap_has_extra_stride(src))) {
- success = image_encoders_compress_jpeg(&dcc->encoders, dest, src, o_comp_data,
- &display_channel->jpeg_stat,
- &display_channel->jpeg_alpha_stat);
+ success = image_encoders_compress_jpeg(&dcc->encoders, dest, src, o_comp_data);
break;
}
- success = image_encoders_compress_quic(&dcc->encoders, dest, src, o_comp_data,
- &display_channel->quic_stat);
+ success = image_encoders_compress_quic(&dcc->encoders, dest, src, o_comp_data);
break;
case SPICE_IMAGE_COMPRESSION_GLZ:
if ((src->x * src->y) < glz_enc_dictionary_get_size(dcc->glz_dict->dict)) {
@@ -914,14 +911,13 @@ int dcc_compress_image(DisplayChannelClient *dcc,
case SPICE_IMAGE_COMPRESSION_LZ4:
if (red_channel_client_test_remote_cap(&dcc->common.base,
SPICE_DISPLAY_CAP_LZ4_COMPRESSION)) {
- success = image_encoders_compress_lz4(&dcc->encoders, dest, src, o_comp_data,
- &display_channel->lz4_stat);
+ success = image_encoders_compress_lz4(&dcc->encoders, dest, src, o_comp_data);
break;
}
#endif
lz_compress:
case SPICE_IMAGE_COMPRESSION_LZ:
- success = image_encoders_compress_lz(&dcc->encoders, dest, src, o_comp_data, &display_channel->lz_stat);
+ success = image_encoders_compress_lz(&dcc->encoders, dest, src, o_comp_data);
if (success && !bitmap_fmt_is_rgb(src->format)) {
dcc_palette_cache_palette(dcc, dest->u.lz_plt.palette, &(dest->u.lz_plt.flags));
}
@@ -932,7 +928,7 @@ lz_compress:
if (!success) {
uint64_t image_size = src->stride * src->y;
- stat_compress_add(&display_channel->off_stat, start_time, image_size, image_size);
+ stat_compress_add(&display_channel->encoder_globals.off_stat, start_time, image_size, image_size);
}
return success;
diff --git a/server/display-channel.c b/server/display-channel.c
index 2888cad..6ec8692 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -38,75 +38,16 @@ void display_channel_compress_stats_reset(DisplayChannel *display)
{
spice_return_if_fail(display);
- stat_reset(&display->off_stat);
- stat_reset(&display->quic_stat);
- stat_reset(&display->lz_stat);
- stat_reset(&display->glz_stat);
- stat_reset(&display->jpeg_stat);
- stat_reset(&display->zlib_glz_stat);
- stat_reset(&display->jpeg_alpha_stat);
- stat_reset(&display->lz4_stat);
+ image_encoder_shared_stat_reset(&display->encoder_globals);
}
-#define STAT_FMT "%s\t%8u\t%13.8g\t%12.8g\t%12.8g"
-
-#ifdef COMPRESS_STAT
-static void stat_print_one(const char *name, const stat_info_t *stat)
-{
- spice_info(STAT_FMT, name, stat->count,
- stat_byte_to_mega(stat->orig_size),
- stat_byte_to_mega(stat->comp_size),
- stat_cpu_time_to_sec(stat->total));
-}
-
-static void stat_sum(stat_info_t *total, const stat_info_t *stat)
-{
- total->count += stat->count;
- total->orig_size += stat->orig_size;
- total->comp_size += stat->comp_size;
- total->total += stat->total;
-}
-#endif
-
void display_channel_compress_stats_print(const DisplayChannel *display_channel)
{
- spice_return_if_fail(display_channel);
-
#ifdef COMPRESS_STAT
- /* sum all statistics */
- stat_info_t total = {
- .count = 0,
- .orig_size = 0,
- .comp_size = 0,
- .total = 0
- };
- stat_sum(&total, &display_channel->off_stat);
- stat_sum(&total, &display_channel->quic_stat);
- stat_sum(&total, &display_channel->glz_stat);
- stat_sum(&total, &display_channel->lz_stat);
- stat_sum(&total, &display_channel->jpeg_stat);
- stat_sum(&total, &display_channel->jpeg_alpha_stat);
- stat_sum(&total, &display_channel->lz4_stat);
-
- /* fix for zlib glz */
- total.total += display_channel->zlib_glz_stat.total;
- if (display_channel->enable_zlib_glz_wrap) {
- total.comp_size = total.comp_size - display_channel->glz_stat.comp_size +
- display_channel->zlib_glz_stat.comp_size;
- }
+ spice_return_if_fail(display_channel);
spice_info("==> Compression stats for display %u", display_channel->common.base.id);
- spice_info("Method \t count \torig_size(MB)\tenc_size(MB)\tenc_time(s)");
- stat_print_one("OFF ", &display_channel->off_stat);
- stat_print_one("QUIC ", &display_channel->quic_stat);
- stat_print_one("GLZ ", &display_channel->glz_stat);
- stat_print_one("ZLIB GLZ ", &display_channel->zlib_glz_stat);
- stat_print_one("LZ ", &display_channel->lz_stat);
- stat_print_one("JPEG ", &display_channel->jpeg_stat);
- stat_print_one("JPEG-RGBA", &display_channel->jpeg_alpha_stat);
- stat_print_one("LZ4 ", &display_channel->lz4_stat);
- spice_info("-------------------------------------------------------------------");
- stat_print_one("Total ", &total);
+ image_encoder_shared_stat_print(&display_channel->encoder_globals);
#endif
}
@@ -1984,13 +1925,7 @@ DisplayChannel* display_channel_new(SpiceServer *reds, RedWorker *worker,
display->non_cache_counter = stat_add_counter(reds, channel->stat,
"non_cache", TRUE);
#endif
- stat_compress_init(&display->lz_stat, "lz", stat_clock);
- stat_compress_init(&display->glz_stat, "glz", stat_clock);
- stat_compress_init(&display->quic_stat, "quic", stat_clock);
- stat_compress_init(&display->jpeg_stat, "jpeg", stat_clock);
- stat_compress_init(&display->zlib_glz_stat, "zlib", stat_clock);
- stat_compress_init(&display->jpeg_alpha_stat, "jpeg_alpha", stat_clock);
- stat_compress_init(&display->lz4_stat, "lz4", stat_clock);
+ image_encoder_shared_init(&display->encoder_globals);
display->n_surfaces = n_surfaces;
display->renderer = RED_RENDERER_INVALID;
diff --git a/server/display-channel.h b/server/display-channel.h
index 16ea709..db1cdba 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -216,14 +216,7 @@ struct DisplayChannel {
uint64_t *add_to_cache_counter;
uint64_t *non_cache_counter;
#endif
- stat_info_t off_stat;
- stat_info_t lz_stat;
- stat_info_t glz_stat;
- stat_info_t quic_stat;
- stat_info_t jpeg_stat;
- stat_info_t zlib_glz_stat;
- stat_info_t jpeg_alpha_stat;
- stat_info_t lz4_stat;
+ ImageEncoderSharedData encoder_globals;
};
static inline int get_stream_id(DisplayChannel *display, Stream *stream)
More information about the Spice-commits
mailing list