Re: [Spice-devel] [PATCH] Remove goto within switch statement

2016-06-14 Thread Pavel Grunt
Hi Jonathon,

On Tue, 2016-06-14 at 16:04 -0500, Jonathon Jongsma wrote:
> Having a goto label in the middle of a switch/case statement is a bit
> confusing. But the same behavior can be achieved 

it changes the behavior - if LZ4 compression is selected on server but it is not
supported on the client, then LZ compression should be used.

With your patch it skips compression and fallback to spice_error() call.

Pavel

> by simply rearranging
> the cases so that we fall through to the one that we wanted to jump to.
> ---
> 
> This should apply on top of frediano's encapsulation patch series.
> 
>  server/dcc.c | 15 +++
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/server/dcc.c b/server/dcc.c
> index ca5569e..cf4fc77 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -747,7 +747,13 @@ int dcc_compress_image(DisplayChannelClient *dcc,
>  if (success) {
>  break;
>  }
> -goto lz_compress;
> +/* on failure, fall through to compress with LZ */
> +case SPICE_IMAGE_COMPRESSION_LZ:
> +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));
> +}
> +break;
>  #ifdef USE_LZ4
>  case SPICE_IMAGE_COMPRESSION_LZ4:
>  if (red_channel_client_test_remote_cap(&dcc->common.base,
> @@ -756,13 +762,6 @@ int dcc_compress_image(DisplayChannelClient *dcc,
>  break;
>  }
>  #endif
> -lz_compress:
> -case SPICE_IMAGE_COMPRESSION_LZ:
> -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));
> -}
> -break;
>  default:
>  spice_error("invalid image compression type %u", image_compression);
>  }
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 13/19] Change RedGlzDrawable::drawable from pointer to boolean

2016-06-14 Thread Jonathon Jongsma
On Tue, 2016-06-14 at 10:33 +0100, Frediano Ziglio wrote:
> The field was used just as a flag.
> This has the advantage to make clear to not use the pointer as we don't
> have ownership.
> Also many the structure a bit smaller.

s/many/makes/

Acked-by: Jonathon Jongsma 

> 
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c | 12 +---
>  1 file changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 22cfcf3..00349fe 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -48,10 +48,10 @@ struct RedGlzDrawable {
>  RingItem link;// ordered by the time it was encoded
>  RingItem drawable_link;
>  RedDrawable *red_drawable;
> -struct Drawable*drawable;
>  GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
>  Ring instances;
>  uint8_t instances_count;
> +gboolean has_drawable;
>  ImageEncoders *encoders;
>  };
>  
> @@ -505,9 +505,7 @@ static void
> image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
>  if (ring_is_empty(&glz_drawable->instances)) {
>  spice_assert(glz_drawable->instances_count == 0);
>  
> -Drawable *drawable = glz_drawable->drawable;
> -
> -if (drawable) {
> +if (glz_drawable->has_drawable) {
>  ring_remove(&glz_drawable->drawable_link);
>  }
>  red_drawable_unref(glz_drawable->red_drawable);
> @@ -569,7 +567,7 @@ int
> image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc)
>  while ((n < RED_RELEASE_BUNCH_SIZE) && (ring_link != NULL)) {
>  RedGlzDrawable *glz_drawable = SPICE_CONTAINEROF(ring_link,
> RedGlzDrawable, link);
>  ring_link = ring_next(&enc->glz_drawables, ring_link);
> -if (!glz_drawable->drawable) {
> +if (!glz_drawable->has_drawable) {
>  image_encoders_free_glz_drawable(enc, glz_drawable);
>  n++;
>  }
> @@ -630,7 +628,7 @@ void image_encoders_glz_detach_from_drawable(struct
> Drawable *drawable)
>  RingItem *item, *next;
>  
>  RING_FOREACH_SAFE(item, next, &drawable->glz_ring) {
> -SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable =
> NULL;
> +SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->has_drawable
> = FALSE;
>  ring_remove(item);
>  }
>  }
> @@ -1143,7 +1141,7 @@ static RedGlzDrawable *get_glz_drawable(ImageEncoders
> *enc, Drawable *drawable)
>  
>  ret->encoders = enc;
>  ret->red_drawable = red_drawable_ref(drawable->red_drawable);
> -ret->drawable = drawable;
> +ret->has_drawable = TRUE;
>  ret->instances_count = 0;
>  ring_init(&ret->instances);
>  
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 12/19] Better encoders encapsulation

2016-06-14 Thread Jonathon Jongsma
Acked-by: Jonathon Jongsma 


On Tue, 2016-06-14 at 10:33 +0100, Frediano Ziglio wrote:
> Avoid to access some fields from dcc.c
> 
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c | 4 
>  server/dcc.c  | 3 ---
>  2 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 3547adc..22cfcf3 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -710,6 +710,8 @@ gboolean image_encoders_get_glz_dictionary(ImageEncoders
> *enc,
>  {
>  GlzSharedDictionary *shared_dict;
>  
> +spice_return_val_if_fail(!enc->glz_dict, FALSE);
> +
>  pthread_mutex_lock(&glz_dictionary_list_lock);
>  
>  shared_dict = find_glz_dictionary(client, id);
> @@ -743,6 +745,8 @@ gboolean
> image_encoders_restore_glz_dictionary(ImageEncoders *enc,
>  {
>  GlzSharedDictionary *shared_dict = NULL;
>  
> +spice_return_val_if_fail(!enc->glz_dict, FALSE);
> +
>  pthread_mutex_lock(&glz_dictionary_list_lock);
>  
>  shared_dict = find_glz_dictionary(client, id);
> diff --git a/server/dcc.c b/server/dcc.c
> index 3190c94..039229d 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -903,7 +903,6 @@ 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->encoders.glz_dict, FALSE);
>  success = image_encoders_get_glz_dictionary(&dcc->encoders,
>  RED_CHANNEL_CLIENT(dcc)-
> >client,
>  init->glz_dictionary_id,
> @@ -1008,8 +1007,6 @@ 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->encoders.glz_dict, FALSE);
> -
>  return image_encoders_restore_glz_dictionary(&dcc->encoders,
>   RED_CHANNEL_CLIENT(dcc)-
> >client,
>   migrate->glz_dict_id,
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH] Remove goto within switch statement

2016-06-14 Thread Jonathon Jongsma
Having a goto label in the middle of a switch/case statement is a bit
confusing. But the same behavior can be achieved by simply rearranging
the cases so that we fall through to the one that we wanted to jump to.
---

This should apply on top of frediano's encapsulation patch series.

 server/dcc.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/server/dcc.c b/server/dcc.c
index ca5569e..cf4fc77 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -747,7 +747,13 @@ int dcc_compress_image(DisplayChannelClient *dcc,
 if (success) {
 break;
 }
-goto lz_compress;
+/* on failure, fall through to compress with LZ */
+case SPICE_IMAGE_COMPRESSION_LZ:
+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));
+}
+break;
 #ifdef USE_LZ4
 case SPICE_IMAGE_COMPRESSION_LZ4:
 if (red_channel_client_test_remote_cap(&dcc->common.base,
@@ -756,13 +762,6 @@ int dcc_compress_image(DisplayChannelClient *dcc,
 break;
 }
 #endif
-lz_compress:
-case SPICE_IMAGE_COMPRESSION_LZ:
-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));
-}
-break;
 default:
 spice_error("invalid image compression type %u", image_compression);
 }
-- 
2.5.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 11/19] Better encapsulation for image_encoders_compress_glz call

2016-06-14 Thread Jonathon Jongsma
On Tue, 2016-06-14 at 10:33 +0100, Frediano Ziglio wrote:
> Do not access too much encoders data.
> Slightly different as now if glz is frozen lz compression is used.

This *seems* safe, though I don't know the code enough to know what 
side-effects 
it might have. Would like a second opinion.

> 
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c | 15 +++
>  server/dcc.c  | 17 -
>  2 files changed, 19 insertions(+), 13 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 6668dff..3547adc 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -1191,6 +1191,17 @@ int image_encoders_compress_glz(ImageEncoders *enc,
>  spice_info("LZ global compress fmt=%d", src->format);
>  #endif
>  
> +if ((src->x * src->y) >= glz_enc_dictionary_get_size(enc->glz_dict-
> >dict)) {
> +return FALSE;
> +}
> +
> +pthread_rwlock_rdlock(&enc->glz_dict->encode_lock);
> +/* using the global dictionary only if it is not frozen */
> +if (enc->glz_dict->migrate_freeze) {
> +pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
> +return FALSE;
> +}
> +
>  encoder_data_init(&glz_data->data);
>  
>  glz_drawable = get_glz_drawable(enc, drawable);
> @@ -1241,8 +1252,12 @@ int image_encoders_compress_glz(ImageEncoders *enc,
>  o_comp_data->comp_buf_size = zlib_size;
>  
>  stat_compress_add(&enc->shared_data->zlib_glz_stat, start_time, glz_size,
> zlib_size);
> +pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
>  return TRUE;
> +
>  glz:
> +pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
> +
>  dest->descriptor.type = SPICE_IMAGE_TYPE_GLZ_RGB;
>  dest->u.lz_rgb.data_size = glz_size;
>  
> diff --git a/server/dcc.c b/server/dcc.c
> index e44feb7..3190c94 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -740,19 +740,10 @@ 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-
> >encoders.glz_dict->dict)) {
> -int frozen;
> -/* using the global dictionary only if it is not frozen */
> -pthread_rwlock_rdlock(&dcc->encoders.glz_dict->encode_lock);
> -frozen = dcc->encoders.glz_dict->migrate_freeze;
> -if (!frozen) {
> -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) {
> -break;
> -}
> +success = image_encoders_compress_glz(&dcc->encoders, dest, src,
> drawable, o_comp_data,
> +  display_channel-
> >enable_zlib_glz_wrap);
> +if (success) {
> +break;
>  }
>  goto lz_compress;
>  #ifdef USE_LZ4
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 10/19] Encapsulate dcc_release_glz

2016-06-14 Thread Jonathon Jongsma
Acked-by: Jonathon Jongsma 


On Tue, 2016-06-14 at 10:33 +0100, Frediano Ziglio wrote:
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c | 4 +++-
>  server/dcc-encoders.h | 1 -
>  server/dcc.c  | 1 -
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index f423f22..6668dff 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -64,6 +64,7 @@ static void
> image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
>    GlzDrawableInstanceItem
> *instance);
>  static void encoder_data_init(EncoderData *data);
>  static void encoder_data_reset(EncoderData *data);
> +static void image_encoders_release_glz(ImageEncoders *enc);
>  
>  
>  static SPICE_GNUC_NORETURN SPICE_GNUC_PRINTF(2, 3) void
> @@ -459,6 +460,7 @@ void image_encoders_init(ImageEncoders *enc,
> ImageEncoderSharedData *shared_data
>  
>  void image_encoders_free(ImageEncoders *enc)
>  {
> +image_encoders_release_glz(enc);
>  quic_destroy(enc->quic);
>  enc->quic = NULL;
>  lz_destroy(enc->lz);
> @@ -764,7 +766,7 @@ gboolean image_encoders_glz_create(ImageEncoders *enc,
> uint8_t id)
>  }
>  
>  /* destroy encoder, and dictionary if no one uses it*/
> -void image_encoders_release_glz(ImageEncoders *enc)
> +static void image_encoders_release_glz(ImageEncoders *enc)
>  {
>  GlzSharedDictionary *shared_dict;
>  
> diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
> index 9674465..bdfffe7 100644
> --- a/server/dcc-encoders.h
> +++ b/server/dcc-encoders.h
> @@ -46,7 +46,6 @@ 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_release_glz(ImageEncoders *enc);
>  void image_encoders_glz_free_from_drawable(struct Drawable *drawable);
>  void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
>  void image_encoders_glz_get_restore_data(ImageEncoders *enc,
> diff --git a/server/dcc.c b/server/dcc.c
> index 6511ce5..e44feb7 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -489,7 +489,6 @@ void dcc_stop(DisplayChannelClient *dcc)
>  
>  pixmap_cache_unref(dcc->pixmap_cache);
>  dcc->pixmap_cache = NULL;
> -image_encoders_release_glz(&dcc->encoders);
>  dcc_palette_cache_reset(dcc);
>  free(dcc->send_data.stream_outbuf);
>  free(dcc->send_data.free_list.res);
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 08/19] Encapsulate code to save glz state

2016-06-14 Thread Jonathon Jongsma
Acked-by: Jonathon Jongsma 


On Tue, 2016-06-14 at 10:33 +0100, Frediano Ziglio wrote:
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c | 10 ++
>  server/dcc-encoders.h |  2 ++
>  server/dcc-send.c |  8 ++--
>  3 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 13dbff5..2e5984a 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -640,6 +640,16 @@ void image_encoders_freeze_glz(ImageEncoders *enc)
>  pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
>  }
>  
> +void image_encoders_glz_get_restore_data(ImageEncoders *enc,
> + uint8_t *out_id,
> GlzEncDictRestoreData *out_data)
> +{
> +spice_assert(enc->glz_dict);
> +image_encoders_freeze_glz(enc);
> +*out_id = enc->glz_dict->id;
> +glz_enc_dictionary_get_restore_data(enc->glz_dict->dict, out_data,
> +&enc->glz_data.usr);
> +}
> +
>  static GlzSharedDictionary *glz_shared_dictionary_new(RedClient *client,
> uint8_t id,
>    GlzEncDictContext
> *dict)
>  {
> diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
> index 68fd5a5..ce8010c 100644
> --- a/server/dcc-encoders.h
> +++ b/server/dcc-encoders.h
> @@ -51,6 +51,8 @@ void image_encoders_freeze_glz(ImageEncoders *enc);
>  void image_encoders_release_glz(ImageEncoders *enc);
>  void image_encoders_glz_free_from_drawable(struct Drawable *drawable);
>  void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
> +void image_encoders_glz_get_restore_data(ImageEncoders *enc,
> + uint8_t *out_id,
> GlzEncDictRestoreData *out_data);
>  
>  #define RED_COMPRESS_BUF_SIZE (1024 * 64)
>  struct RedCompressBuf {
> diff --git a/server/dcc-send.c b/server/dcc-send.c
> index c0c7573..ba695ef 100644
> --- a/server/dcc-send.c
> +++ b/server/dcc-send.c
> @@ -1859,12 +1859,8 @@ 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->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->encoders.glz_data.usr);
> +image_encoders_glz_get_restore_data(&dcc->encoders,
> &display_data.glz_dict_id,
> +&display_data.glz_dict_data);
>  
>  /* all data besided the surfaces ref */
>  spice_marshaller_add(base_marshaller,
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [streaming v16 00/23] Add GStreamer support for video streaming

2016-06-14 Thread Jeremy White
On 06/14/2016 10:24 AM, Christophe Fergeau wrote:
> Hey,
> 
> So I've finally pushed all of the spice-server bits save for the
> patch trying to guess the number of CPUs to use for the vp8 encoder
> (hopefully I did not introduce rebase issues).
> 
> Thanks a lot (again) for all the work, and sorry for the time it took to
> get this in :(

Hurray!

Thanks,

Jeremy

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [spice-gtk PATCH] Handle single headed monitors that have a non-zero x, y config offset

2016-06-14 Thread Marc-André Lureau
Hi

On Tue, Jun 14, 2016 at 10:46 AM, Christophe Fergeau
 wrote:
>> Imho, the fix should be on server or guest/driver side, it shouldn't
>> use a display monitor config with a scanout offset if there is none to
>> be applied by the client.
>
> Regarding fixing this on the server, isn't it going to have similar
> issues? Ie once we get QXL_IO_MONITORS_CONFIG_ASYNC in QEMU, we could
> make sure that display channels with just one monitor will get (0, 0) as
> their primary position, but this is not correct with virgl, so we'd need
> some gl check in the server before doing the zero-ing out?

virtio-gpu/virgl do not use QXL_IO_MONITORS (or any QXL io/device).

It's not an issue if a QXL driver want to use a single monitor with a
position different from +0+0 imho.

Apparently, this change was made by Sandy to fix #1202419, although I
fail to reproduce the problem (I am still using older drivers/agents).

I think we can just use the solution I proposed for the virgl case,
until someone else is hurt by this again and we can find a proper
solution.




-- 
Marc-André Lureau
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [streaming v16 00/23] Add GStreamer support for video streaming

2016-06-14 Thread Frediano Ziglio
Great job both of you!

Frediano

> 
> Hey,
> 
> So I've finally pushed all of the spice-server bits save for the
> patch trying to guess the number of CPUs to use for the vp8 encoder
> (hopefully I did not introduce rebase issues).
> 
> Thanks a lot (again) for all the work, and sorry for the time it took to
> get this in :(
> 
> Christophe
> 
> 
> On Tue, Jun 07, 2016 at 03:57:21PM +0200, Francois Gouget wrote:
> > 
> > This patch series adds support for using GStreamer to encode the video
> > streams, adding support for VP8 and h264 codecs.
> > 
> > As before the patches can also be grabbed from the gst branch of the
> > repositories below. Note that this time around the required support is
> > already present in the client.
> > 
> > spice:  https://github.com/fgouget/spice
> > xf86-video-qxl: https://github.com/fgouget/xf86-video-qxl
> > spice-protocol: https://github.com/fgouget/spice-protocol
> > 
> > 
> > There's also 'extras' branches with more experimental/future patches for
> > the curious, and gst-vNN branches to help comparing the various
> > revisions.
> > 
> > Note that to test GStreamer support with QEMU you probably need to grab
> > the patch below and set the video-codecs option to something like
> > gstreamer:h264 or gstreamer:vp8.
> > 
> > https://lists.freedesktop.org/archives/spice-devel/2015-May/019771.html
> > 
> > 
> > Changes from v15:
> > * Added a patch to better check for sized frames.
> > 
> > * Added a patch to get rid of RedDrawable.sized_stream to simplify the
> >   code.
> > 
> > 
> > Changes from v14:
> > 
> > * In this round the width / height removal is back because I think it
> >   is relevant to the discussion around the gstreamer-encoder code for
> >   copying the frames.
> > 
> > * I also split that change in two parts : one removing the use of the
> >   width / height parameters in the MJPEG encoder, and another removing
> >   them from the video-encoder API.
> > 
> > * Added a comment and tweaked the warning in
> >   is_chunk_stride_aligned().
> > 
> > * Added a comment in line_copy() wrt 0-byte chunks.
> > 
> > * Renamed max_mem to max_block_count in zero_copy().
> > 
> > * I also changed the patchset prefix to 'streaming' as suggested by
> >   Pavel Grunt.
> > 
> > 
> > Changes from v13:
> > 
> > Rebased + some changes suggested by Christophe Fergeau.
> > 
> > 
> > --
> > Francois Gouget 
> > 
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [streaming v16 00/23] Add GStreamer support for video streaming

2016-06-14 Thread Christophe Fergeau
Hey,

So I've finally pushed all of the spice-server bits save for the
patch trying to guess the number of CPUs to use for the vp8 encoder
(hopefully I did not introduce rebase issues).

Thanks a lot (again) for all the work, and sorry for the time it took to
get this in :(

Christophe


On Tue, Jun 07, 2016 at 03:57:21PM +0200, Francois Gouget wrote:
> 
> This patch series adds support for using GStreamer to encode the video 
> streams, adding support for VP8 and h264 codecs.
> 
> As before the patches can also be grabbed from the gst branch of the 
> repositories below. Note that this time around the required support is 
> already present in the client.
> 
> spice:  https://github.com/fgouget/spice
> xf86-video-qxl: https://github.com/fgouget/xf86-video-qxl
> spice-protocol: https://github.com/fgouget/spice-protocol
> 
> 
> There's also 'extras' branches with more experimental/future patches for 
> the curious, and gst-vNN branches to help comparing the various 
> revisions.
> 
> Note that to test GStreamer support with QEMU you probably need to grab 
> the patch below and set the video-codecs option to something like 
> gstreamer:h264 or gstreamer:vp8.
> 
> https://lists.freedesktop.org/archives/spice-devel/2015-May/019771.html
> 
> 
> Changes from v15:
> * Added a patch to better check for sized frames.
> 
> * Added a patch to get rid of RedDrawable.sized_stream to simplify the 
>   code.
> 
> 
> Changes from v14:
> 
> * In this round the width / height removal is back because I think it 
>   is relevant to the discussion around the gstreamer-encoder code for 
>   copying the frames.
> 
> * I also split that change in two parts : one removing the use of the
>   width / height parameters in the MJPEG encoder, and another removing 
>   them from the video-encoder API.
> 
> * Added a comment and tweaked the warning in 
>   is_chunk_stride_aligned().
> 
> * Added a comment in line_copy() wrt 0-byte chunks.
> 
> * Renamed max_mem to max_block_count in zero_copy().
> 
> * I also changed the patchset prefix to 'streaming' as suggested by 
>   Pavel Grunt.
> 
> 
> Changes from v13:
> 
> Rebased + some changes suggested by Christophe Fergeau.
> 
> 
> -- 
> Francois Gouget 
> 
> ___
> Spice-devel mailing list
> Spice-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel


signature.asc
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 09/19] Make some function static

2016-06-14 Thread Jonathon Jongsma
Acked-by: Jonathon Jongsma 


On Tue, 2016-06-14 at 10:33 +0100, Frediano Ziglio wrote:
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c | 4 ++--
>  server/dcc-encoders.h | 2 --
>  2 files changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 2e5984a..f423f22 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -523,7 +523,7 @@ static void
> image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
>   * if possible.
>   * NOTE - the caller should prevent encoding using the dictionary during this
> operation
>   */
> -void image_encoders_free_glz_drawable(ImageEncoders *enc, RedGlzDrawable
> *drawable)
> +static void image_encoders_free_glz_drawable(ImageEncoders *enc,
> RedGlzDrawable *drawable)
>  {
>  RingItem *head_instance = ring_get_head(&drawable->instances);
>  int cont = (head_instance != NULL);
> @@ -633,7 +633,7 @@ void image_encoders_glz_detach_from_drawable(struct
> Drawable *drawable)
>  }
>  }
>  
> -void image_encoders_freeze_glz(ImageEncoders *enc)
> +static void image_encoders_freeze_glz(ImageEncoders *enc)
>  {
>  pthread_rwlock_wrlock(&enc->glz_dict->encode_lock);
>  enc->glz_dict->migrate_freeze = TRUE;
> diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
> index ce8010c..9674465 100644
> --- a/server/dcc-encoders.h
> +++ b/server/dcc-encoders.h
> @@ -42,12 +42,10 @@ 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 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 image_encoders_release_glz(ImageEncoders *enc);
>  void image_encoders_glz_free_from_drawable(struct Drawable *drawable);
>  void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH 2/2] Rename image_encoders_free_glz_drawable()

2016-06-14 Thread Jonathon Jongsma
On Tue, 2016-06-14 at 10:14 -0500, Jonathon Jongsma wrote:
> Rename this function to red_glz_drawable_free() and remove the
> ImageEncoders argument since the RedGlzDrawable already holds a pointer
> to the ImageEncoders structure
> ---
>  server/dcc-encoders.c | 17 +
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 32908d0..4049eec 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -534,14 +534,15 @@ static void
> glz_drawable_instance_item_free(GlzDrawableInstanceItem *instance)
>   * if possible.
>   * NOTE - the caller should prevent encoding using the dictionary during this
> operation
>   */
> -static void image_encoders_free_glz_drawable(ImageEncoders *enc,
> RedGlzDrawable *drawable)
> +static void red_glz_drawable_free(RedGlzDrawable *glz_drawable)

I renamed the argument from drawable to glz_drawable to avoid confusion between
Drawable and RedGlzDrawable types, but perhaps that change should not be
included in this patch as it's unrelated the the main goal of the patch.

>  {
> -RingItem *head_instance = ring_get_head(&drawable->instances);
> +ImageEncoders *enc = glz_drawable->encoders;
> +RingItem *head_instance = ring_get_head(&glz_drawable->instances);
>  int cont = (head_instance != NULL);
>  
>  while (cont) {
> -if (drawable->instances_count == 1) {
> -/* Last instance: image_encoders_free_glz_drawable_instance will
> free the drawable */
> +if (glz_drawable->instances_count == 1) {
> +/* Last instance: glz_drawable_instance_item_free will free the
> glz_drawable */
>  cont = FALSE;
>  }
>  GlzDrawableInstanceItem *instance = SPICE_CONTAINEROF(head_instance,
> @@ -556,7 +557,7 @@ static void image_encoders_free_glz_drawable(ImageEncoders
> *enc, RedGlzDrawable
>  glz_drawable_instance_item_free(instance);
>  
>  if (cont) {
> -head_instance = ring_get_head(&drawable->instances);
> +head_instance = ring_get_head(&glz_drawable->instances);
>  }
>  }
>  }
> @@ -593,7 +594,7 @@ int
> image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc)
>  RedGlzDrawable *glz_drawable = SPICE_CONTAINEROF(ring_link,
> RedGlzDrawable, link);
>  ring_link = ring_next(&enc->glz_drawables, ring_link);
>  if (!glz_drawable->has_drawable) {
> -image_encoders_free_glz_drawable(enc, glz_drawable);
> +red_glz_drawable_free(glz_drawable);
>  n++;
>  }
>  }
> @@ -634,7 +635,7 @@ void image_encoders_free_glz_drawables(ImageEncoders *enc)
>  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
> -image_encoders_free_glz_drawable(enc, drawable);
> +red_glz_drawable_free(drawable);
>  }
>  pthread_rwlock_unlock(&glz_dict->encode_lock);
>  }
> @@ -644,7 +645,7 @@ void image_encoders_glz_free_from_drawable_ring(Ring
> *drawable_ring)
>  RingItem *glz_item, *next_item;
>  RedGlzDrawable *glz;
>  SAFE_FOREACH(glz_item, next_item, TRUE, drawable_ring, glz,
> LINK_TO_GLZ(glz_item)) {
> -image_encoders_free_glz_drawable(glz->encoders, glz);
> +red_glz_drawable_free(glz);
>  }
>  }
>  
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 2/2] Rename image_encoders_free_glz_drawable()

2016-06-14 Thread Jonathon Jongsma
Rename this function to red_glz_drawable_free() and remove the
ImageEncoders argument since the RedGlzDrawable already holds a pointer
to the ImageEncoders structure
---
 server/dcc-encoders.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 32908d0..4049eec 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -534,14 +534,15 @@ static void 
glz_drawable_instance_item_free(GlzDrawableInstanceItem *instance)
  * if possible.
  * NOTE - the caller should prevent encoding using the dictionary during this 
operation
  */
-static void image_encoders_free_glz_drawable(ImageEncoders *enc, 
RedGlzDrawable *drawable)
+static void red_glz_drawable_free(RedGlzDrawable *glz_drawable)
 {
-RingItem *head_instance = ring_get_head(&drawable->instances);
+ImageEncoders *enc = glz_drawable->encoders;
+RingItem *head_instance = ring_get_head(&glz_drawable->instances);
 int cont = (head_instance != NULL);
 
 while (cont) {
-if (drawable->instances_count == 1) {
-/* Last instance: image_encoders_free_glz_drawable_instance will 
free the drawable */
+if (glz_drawable->instances_count == 1) {
+/* Last instance: glz_drawable_instance_item_free will free the 
glz_drawable */
 cont = FALSE;
 }
 GlzDrawableInstanceItem *instance = SPICE_CONTAINEROF(head_instance,
@@ -556,7 +557,7 @@ static void image_encoders_free_glz_drawable(ImageEncoders 
*enc, RedGlzDrawable
 glz_drawable_instance_item_free(instance);
 
 if (cont) {
-head_instance = ring_get_head(&drawable->instances);
+head_instance = ring_get_head(&glz_drawable->instances);
 }
 }
 }
@@ -593,7 +594,7 @@ int 
image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc)
 RedGlzDrawable *glz_drawable = SPICE_CONTAINEROF(ring_link, 
RedGlzDrawable, link);
 ring_link = ring_next(&enc->glz_drawables, ring_link);
 if (!glz_drawable->has_drawable) {
-image_encoders_free_glz_drawable(enc, glz_drawable);
+red_glz_drawable_free(glz_drawable);
 n++;
 }
 }
@@ -634,7 +635,7 @@ void image_encoders_free_glz_drawables(ImageEncoders *enc)
 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
-image_encoders_free_glz_drawable(enc, drawable);
+red_glz_drawable_free(drawable);
 }
 pthread_rwlock_unlock(&glz_dict->encode_lock);
 }
@@ -644,7 +645,7 @@ void image_encoders_glz_free_from_drawable_ring(Ring 
*drawable_ring)
 RingItem *glz_item, *next_item;
 RedGlzDrawable *glz;
 SAFE_FOREACH(glz_item, next_item, TRUE, drawable_ring, glz, 
LINK_TO_GLZ(glz_item)) {
-image_encoders_free_glz_drawable(glz->encoders, glz);
+red_glz_drawable_free(glz);
 }
 }
 
-- 
2.5.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 1/2] Rename image_encoders_free_glz_drawable_instance()

2016-06-14 Thread Jonathon Jongsma
Rename this function to glz_drawable_instance_item_free() and remove the
ImageEncoders argument since the RedGlzDrawable already holds a pointer
to the ImageEncoders structure.
---
 server/dcc-encoders.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index e18dadb..32908d0 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -72,8 +72,7 @@ struct RedGlzDrawable {
 #define DRAWABLE_FOREACH_GLZ_SAFE(drawable, link, next, glz) \
 SAFE_FOREACH(link, next, drawable, &(drawable)->glz_ring, glz, 
LINK_TO_GLZ(link))
 
-static void image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
-  GlzDrawableInstanceItem 
*instance);
+static void glz_drawable_instance_item_free(GlzDrawableInstanceItem *instance);
 static void encoder_data_init(EncoderData *data);
 static void encoder_data_reset(EncoderData *data);
 static void image_encoders_release_glz(ImageEncoders *enc);
@@ -384,7 +383,7 @@ static void glz_usr_free_image(GlzEncoderUsrContext *usr, 
GlzUsrImageContext *im
 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);
+glz_drawable_instance_item_free(glz_drawable_instance);
 } else {
 /* The glz dictionary is shared between all DisplayChannelClient
  * instances that belong to the same client, and glz_usr_free_image
@@ -494,8 +493,7 @@ 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 image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
-  GlzDrawableInstanceItem 
*instance)
+static void glz_drawable_instance_item_free(GlzDrawableInstanceItem *instance)
 {
 RedGlzDrawable *glz_drawable;
 
@@ -504,7 +502,6 @@ static void 
image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
 
 glz_drawable = instance->glz_drawable;
 
-spice_assert(glz_drawable->encoders == enc);
 spice_assert(glz_drawable->instances_count > 0);
 
 ring_remove(&instance->glz_link);
@@ -523,7 +520,7 @@ static void 
image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
 ring_remove(&glz_drawable->drawable_link);
 }
 red_drawable_unref(glz_drawable->red_drawable);
-enc->shared_data->glz_drawable_count--;
+glz_drawable->encoders->shared_data->glz_drawable_count--;
 if (ring_item_is_linked(&glz_drawable->link)) {
 ring_remove(&glz_drawable->link);
 }
@@ -556,7 +553,7 @@ static void image_encoders_free_glz_drawable(ImageEncoders 
*enc, RedGlzDrawable
 instance->context,
 &enc->glz_data.usr);
 }
-image_encoders_free_glz_drawable_instance(enc, instance);
+glz_drawable_instance_item_free(instance);
 
 if (cont) {
 head_instance = ring_get_head(&drawable->instances);
@@ -615,7 +612,7 @@ void 
image_encoders_free_glz_drawables_to_free(ImageEncoders* enc)
 GlzDrawableInstanceItem *drawable_instance = 
SPICE_CONTAINEROF(ring_link,
  
GlzDrawableInstanceItem,
  free_link);
-image_encoders_free_glz_drawable_instance(enc, drawable_instance);
+glz_drawable_instance_item_free(drawable_instance);
 }
 pthread_mutex_unlock(&enc->glz_drawables_inst_to_free_lock);
 }
-- 
2.5.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 0/2] RFC: cleanup glz drawable stuff

2016-06-14 Thread Jonathon Jongsma
These patches should apply on top of Frediano's "Better encapsulation of image
encoding stuff" patch series.

Jonathon Jongsma (2):
  Rename image_encoders_free_glz_drawable_instance()
  Rename image_encoders_free_glz_drawable()

 server/dcc-encoders.c | 32 +++-
 1 file changed, 15 insertions(+), 17 deletions(-)

-- 
2.5.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 07/19] Encapsulate some data in dcc-encoders

2016-06-14 Thread Jonathon Jongsma
On Tue, 2016-06-14 at 10:32 +0100, Frediano Ziglio wrote:
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c| 60 ++-
> -
>  server/dcc-encoders.h| 33 ++
>  server/display-channel.c | 13 +++
>  server/display-channel.h |  5 
>  4 files changed, 63 insertions(+), 48 deletions(-)
> 
> diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> index 4de780d..13dbff5 100644
> --- a/server/dcc-encoders.c
> +++ b/server/dcc-encoders.c
> @@ -26,8 +26,45 @@
>  
>  #define ZLIB_DEFAULT_COMPRESSION_LEVEL 3
>  
> +#define MAX_GLZ_DRAWABLE_INSTANCES 2
> +
> +typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
> +
> +/* for each qxl drawable, there may be several instances of lz drawables */
> +/* TODO - reuse this stuff for the top level. I just added a second level of
> multiplicity
> + * at the Drawable by keeping a ring, so:
> + * Drawable -> (ring of) RedGlzDrawable -> (up to 2) GlzDrawableInstanceItem
> + * and it should probably (but need to be sure...) be
> + * Drawable -> ring of GlzDrawableInstanceItem.
> + */
> +struct GlzDrawableInstanceItem {
> +RingItem glz_link;
> +RingItem free_link;
> +GlzEncDictImageContext *context;
> +RedGlzDrawable *glz_drawable;
> +};
> +
> +struct RedGlzDrawable {
> +RingItem link;// ordered by the time it was encoded
> +RingItem drawable_link;
> +RedDrawable *red_drawable;
> +struct Drawable*drawable;
> +GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
> +Ring instances;
> +uint8_t instances_count;
> +ImageEncoders *encoders;
> +};
> +
> +#define LINK_TO_GLZ(ptr) SPICE_CONTAINEROF((ptr), RedGlzDrawable, \
> +   drawable_link)
> +#define DRAWABLE_FOREACH_GLZ_SAFE(drawable, link, next, glz) \
> +SAFE_FOREACH(link, next, drawable, &(drawable)->glz_ring, glz,
> LINK_TO_GLZ(link))
> +
>  static void image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
>    GlzDrawableInstanceItem
> *instance);
> +static void encoder_data_init(EncoderData *data);
> +static void encoder_data_reset(EncoderData *data);
> +
>  
>  static SPICE_GNUC_NORETURN SPICE_GNUC_PRINTF(2, 3) void
>  quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
> @@ -139,14 +176,14 @@ static void glz_usr_free(GlzEncoderUsrContext *usr, void
> *ptr)
>  free(ptr);
>  }
>  
> -void encoder_data_init(EncoderData *data)
> +static void encoder_data_init(EncoderData *data)
>  {
>  data->bufs_tail = g_new(RedCompressBuf, 1);
>  data->bufs_head = data->bufs_tail;
>  data->bufs_head->send_next = NULL;
>  }
>  
> -void encoder_data_reset(EncoderData *data)
> +static void encoder_data_reset(EncoderData *data)
>  {
>  RedCompressBuf *buf = data->bufs_head;
>  while (buf) {
> @@ -577,6 +614,25 @@ void image_encoders_free_glz_drawables(ImageEncoders
> *enc)
>  pthread_rwlock_unlock(&glz_dict->encode_lock);
>  }
>  
> +void image_encoders_glz_free_from_drawable(struct Drawable *drawable)
> +{
> +RingItem *glz_item, *next_item;
> +RedGlzDrawable *glz;
> +DRAWABLE_FOREACH_GLZ_SAFE(drawable, glz_item, next_item, glz) {
> +image_encoders_free_glz_drawable(glz->encoders, glz);
> +}
> +}

I find that the name of this function is not very clear. Basically, it is
freeing and removing all of the RedGlzDrawables attached to the given Drawable.
In my opinion, the fact that ImageEncoders is used internally should not
necessarily be relevant to the name of the function. I think something like
drawable_free_glz_drawables(Drawable*) would be a lot easier to understand.

Digging a bit deeper, it seems that the only reason that
image_encoders_free_glz_drawable needs ImageEncoders here is to update the glz
dictionary and decrement glz_drawable_count. I'll send a couple additional
patches that refactor this to remove the ImageEncoders parameter from this
function. 

> +
> +void image_encoders_glz_detach_from_drawable(struct Drawable *drawable)
> +{
> +RingItem *item, *next;
> +
> +RING_FOREACH_SAFE(item, next, &drawable->glz_ring) {
> +SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable =
> NULL;
> +ring_remove(item);
> +}
> +}

Here again, I think that the image_encoders_ function prefix confuses
things slightly. The ImageEncoders structure is not used at all in this
function, even internally. So, I think a more fitting name might be something
like drawable_detach_glz_drawables(Drawable*)... 

(Long-term, I think the 'Drawable' type badly needs to be renamed as there's
just way too much confusion between Drawable, QXLDrawable, RedGlzDrawable,
RedDrawable, etc. It's impossible for me to keep straight which struct is for
what.)

Also, it's not clear why this function uses RING_FOREACH_SAFE() when the
previous one uses DRAWABLE_FOREACH_GLZ_SAFE(). I realize that this w

Re: [Spice-devel] [PATCH] Remove a warning compiling under Windows

2016-06-14 Thread Jonathon Jongsma
Acked-by: Jonathon Jongsma 

On Mon, 2016-06-13 at 12:31 +0100, Frediano Ziglio wrote:
> On Windows long is always 32 bit so under x64 the cast from pointer to
> "unsigned long" cause a warning.
> 
> Signed-off-by: Frediano Ziglio 
> ---
>  common/quic.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/common/quic.c b/common/quic.c
> index f014a2a..5b00d65 100644
> --- a/common/quic.c
> +++ b/common/quic.c
> @@ -1073,7 +1073,7 @@ static int init_encoder(Encoder *encoder, QuicUsrContext
> *usr)
>  
>  static int encoder_reste(Encoder *encoder, uint32_t *io_ptr, uint32_t
> *io_ptr_end)
>  {
> -spice_assert(((unsigned long)io_ptr % 4) == ((unsigned long)io_ptr_end %
> 4));
> +spice_assert(((uintptr_t)io_ptr % 4) == ((uintptr_t)io_ptr_end % 4));
>  spice_assert(io_ptr <= io_ptr_end);
>  
>  encoder->rgb_state.waitcnt = 0;
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 03/19] Change dcc_encoders_init to take ImageEncoders instead of DisplayChannelClient

2016-06-14 Thread Jonathon Jongsma
Acked-by: Jonathon Jongsma 


On Tue, 2016-06-14 at 10:32 +0100, Frediano Ziglio wrote:
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c | 4 +---
>  server/dcc-encoders.h | 2 +-
>  server/dcc.c  | 2 +-
>  3 files changed, 3 insertions(+), 5 deletions(-)
> 
> 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   (DisplayChannelC
> lient *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;
>  }
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v4 01/19] Add a structure to hold ImageEncoders shared data

2016-06-14 Thread Jonathon Jongsma
Acked-by: Jonathon Jongsma 



On Tue, 2016-06-14 at 10:32 +0100, Frediano Ziglio wrote:
> Signed-off-by: Frediano Ziglio 
> ---
>  server/dcc-encoders.c| 121 +++---
> -
>  server/dcc-encoders.h|  33 +
>  server/dcc.c |  26 +-
>  server/display-channel.c |  73 ++--
>  server/display-channel.h |   9 +---
>  5 files changed, 141 insertions(+), 121 deletions(-)
> 
> 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_c

[Spice-devel] [spice-gtk] main: channel-main to increase file-transfer reference

2016-06-14 Thread Victor Toso
This is a minor fix in the logic as in both situations (with or
without the patch) the reference count for the SpiceFileTransferTask
object is the same.

The change is interesting as SpiceFileTransferTask is created but on
g_file_read_async() it increases its reference count while
c->file_xfer_tasks keeps the original one.

It should be the other way around.
---
 src/channel-main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/channel-main.c b/src/channel-main.c
index 4736e13..7731943 100644
--- a/src/channel-main.c
+++ b/src/channel-main.c
@@ -3112,7 +3112,7 @@ static void 
file_xfer_send_start_msg_async(SpiceMainChannel *channel,
 CHANNEL_DEBUG(channel, "Insert a xfer task:%u to task list", task->id);
 g_hash_table_insert(c->file_xfer_tasks,
 GUINT_TO_POINTER(task->id),
-task);
+g_object_ref(task));
 g_signal_connect(task, "finished", G_CALLBACK(task_finished), channel);
 g_signal_emit(channel, signals[SPICE_MAIN_NEW_FILE_TRANSFER], 0, task);
 
@@ -3120,7 +3120,7 @@ static void 
file_xfer_send_start_msg_async(SpiceMainChannel *channel,
   G_PRIORITY_DEFAULT,
   cancellable,
   file_xfer_read_async_cb,
-  g_object_ref(task));
+  task);
 task->pending = TRUE;
 
 /* if we created a per-task cancellable above, free it */
-- 
2.5.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [spice-gtk] main: assign variable after check for null

2016-06-14 Thread Pavel Grunt
On Tue, 2016-06-14 at 14:28 +0200, Victor Toso wrote:
Acked-by: Pavel Grunt 
> ---
>  src/channel-main.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/src/channel-main.c b/src/channel-main.c
> index 89675d5..e7171c1 100644
> --- a/src/channel-main.c
> +++ b/src/channel-main.c
> @@ -3181,12 +3181,13 @@ void spice_main_file_copy_async(SpiceMainChannel
> *channel,
>  GAsyncReadyCallback callback,
>  gpointer user_data)
>  {
> -SpiceMainChannelPrivate *c = channel->priv;
> +SpiceMainChannelPrivate *c;
>  
>  g_return_if_fail(channel != NULL);
>  g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
>  g_return_if_fail(sources != NULL);
>  
> +c = channel->priv;
>  if (!c->agent_connected) {
>  g_task_report_new_error(channel,
>  callback,
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [spice-gtk] main: assign variable after check for null

2016-06-14 Thread Victor Toso
---
 src/channel-main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/channel-main.c b/src/channel-main.c
index 89675d5..e7171c1 100644
--- a/src/channel-main.c
+++ b/src/channel-main.c
@@ -3181,12 +3181,13 @@ void spice_main_file_copy_async(SpiceMainChannel 
*channel,
 GAsyncReadyCallback callback,
 gpointer user_data)
 {
-SpiceMainChannelPrivate *c = channel->priv;
+SpiceMainChannelPrivate *c;
 
 g_return_if_fail(channel != NULL);
 g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
 g_return_if_fail(sources != NULL);
 
+c = channel->priv;
 if (!c->agent_connected) {
 g_task_report_new_error(channel,
 callback,
-- 
2.5.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 10/19] Encapsulate dcc_release_glz

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 4 +++-
 server/dcc-encoders.h | 1 -
 server/dcc.c  | 1 -
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index f423f22..6668dff 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -64,6 +64,7 @@ static void 
image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
   GlzDrawableInstanceItem 
*instance);
 static void encoder_data_init(EncoderData *data);
 static void encoder_data_reset(EncoderData *data);
+static void image_encoders_release_glz(ImageEncoders *enc);
 
 
 static SPICE_GNUC_NORETURN SPICE_GNUC_PRINTF(2, 3) void
@@ -459,6 +460,7 @@ void image_encoders_init(ImageEncoders *enc, 
ImageEncoderSharedData *shared_data
 
 void image_encoders_free(ImageEncoders *enc)
 {
+image_encoders_release_glz(enc);
 quic_destroy(enc->quic);
 enc->quic = NULL;
 lz_destroy(enc->lz);
@@ -764,7 +766,7 @@ gboolean image_encoders_glz_create(ImageEncoders *enc, 
uint8_t id)
 }
 
 /* destroy encoder, and dictionary if no one uses it*/
-void image_encoders_release_glz(ImageEncoders *enc)
+static void image_encoders_release_glz(ImageEncoders *enc)
 {
 GlzSharedDictionary *shared_dict;
 
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 9674465..bdfffe7 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -46,7 +46,6 @@ 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_release_glz(ImageEncoders *enc);
 void image_encoders_glz_free_from_drawable(struct Drawable *drawable);
 void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
 void image_encoders_glz_get_restore_data(ImageEncoders *enc,
diff --git a/server/dcc.c b/server/dcc.c
index 6511ce5..e44feb7 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -489,7 +489,6 @@ void dcc_stop(DisplayChannelClient *dcc)
 
 pixmap_cache_unref(dcc->pixmap_cache);
 dcc->pixmap_cache = NULL;
-image_encoders_release_glz(&dcc->encoders);
 dcc_palette_cache_reset(dcc);
 free(dcc->send_data.stream_outbuf);
 free(dcc->send_data.free_list.res);
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 14/19] Use Ring instead of accessing Drawable internals

2016-06-14 Thread Frediano Ziglio
Remove some coupling, we mainly need to store a list of RedGlzDrawables.

Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c| 8 
 server/dcc-encoders.h| 4 ++--
 server/display-channel.c | 4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 00349fe..a83794e 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -614,20 +614,20 @@ void image_encoders_free_glz_drawables(ImageEncoders *enc)
 pthread_rwlock_unlock(&glz_dict->encode_lock);
 }
 
-void image_encoders_glz_free_from_drawable(struct Drawable *drawable)
+void image_encoders_glz_free_from_drawable_ring(Ring *drawable_ring)
 {
 RingItem *glz_item, *next_item;
 RedGlzDrawable *glz;
-DRAWABLE_FOREACH_GLZ_SAFE(drawable, glz_item, next_item, glz) {
+SAFE_FOREACH(glz_item, next_item, TRUE, drawable_ring, glz, 
LINK_TO_GLZ(glz_item)) {
 image_encoders_free_glz_drawable(glz->encoders, glz);
 }
 }
 
-void image_encoders_glz_detach_from_drawable(struct Drawable *drawable)
+void image_encoders_glz_detach_from_drawable_ring(Ring *drawable_ring)
 {
 RingItem *item, *next;
 
-RING_FOREACH_SAFE(item, next, &drawable->glz_ring) {
+RING_FOREACH_SAFE(item, next, drawable_ring) {
 SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->has_drawable = 
FALSE;
 ring_remove(item);
 }
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index bdfffe7..ac61a70 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -46,8 +46,8 @@ 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_glz_free_from_drawable(struct Drawable *drawable);
-void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
+void image_encoders_glz_free_from_drawable_ring(Ring *drawable_ring);
+void image_encoders_glz_detach_from_drawable_ring(Ring *drawable_ring);
 void image_encoders_glz_get_restore_data(ImageEncoders *enc,
  uint8_t *out_id, 
GlzEncDictRestoreData *out_data);
 
diff --git a/server/display-channel.c b/server/display-channel.c
index f923be8..bddedd9 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -1171,7 +1171,7 @@ static bool free_one_drawable(DisplayChannel *display, 
int force_glz_free)
 
 drawable = SPICE_CONTAINEROF(ring_item, Drawable, list_link);
 if (force_glz_free) {
-image_encoders_glz_free_from_drawable(drawable);
+image_encoders_glz_free_from_drawable_ring(&drawable->glz_ring);
 }
 drawable_draw(display, drawable);
 container = drawable->tree_item.base.container;
@@ -1340,7 +1340,7 @@ void drawable_unref(Drawable *drawable)
 drawable_unref_surface_deps(display, drawable);
 display_channel_surface_unref(display, drawable->surface_id);
 
-image_encoders_glz_detach_from_drawable(drawable);
+image_encoders_glz_detach_from_drawable_ring(&drawable->glz_ring);
 
 if (drawable->red_drawable) {
 red_drawable_unref(drawable->red_drawable);
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 07/19] Encapsulate some data in dcc-encoders

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c| 60 ++--
 server/dcc-encoders.h| 33 ++
 server/display-channel.c | 13 +++
 server/display-channel.h |  5 
 4 files changed, 63 insertions(+), 48 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 4de780d..13dbff5 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -26,8 +26,45 @@
 
 #define ZLIB_DEFAULT_COMPRESSION_LEVEL 3
 
+#define MAX_GLZ_DRAWABLE_INSTANCES 2
+
+typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
+
+/* for each qxl drawable, there may be several instances of lz drawables */
+/* TODO - reuse this stuff for the top level. I just added a second level of 
multiplicity
+ * at the Drawable by keeping a ring, so:
+ * Drawable -> (ring of) RedGlzDrawable -> (up to 2) GlzDrawableInstanceItem
+ * and it should probably (but need to be sure...) be
+ * Drawable -> ring of GlzDrawableInstanceItem.
+ */
+struct GlzDrawableInstanceItem {
+RingItem glz_link;
+RingItem free_link;
+GlzEncDictImageContext *context;
+RedGlzDrawable *glz_drawable;
+};
+
+struct RedGlzDrawable {
+RingItem link;// ordered by the time it was encoded
+RingItem drawable_link;
+RedDrawable *red_drawable;
+struct Drawable*drawable;
+GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
+Ring instances;
+uint8_t instances_count;
+ImageEncoders *encoders;
+};
+
+#define LINK_TO_GLZ(ptr) SPICE_CONTAINEROF((ptr), RedGlzDrawable, \
+   drawable_link)
+#define DRAWABLE_FOREACH_GLZ_SAFE(drawable, link, next, glz) \
+SAFE_FOREACH(link, next, drawable, &(drawable)->glz_ring, glz, 
LINK_TO_GLZ(link))
+
 static void image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
   GlzDrawableInstanceItem 
*instance);
+static void encoder_data_init(EncoderData *data);
+static void encoder_data_reset(EncoderData *data);
+
 
 static SPICE_GNUC_NORETURN SPICE_GNUC_PRINTF(2, 3) void
 quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
@@ -139,14 +176,14 @@ static void glz_usr_free(GlzEncoderUsrContext *usr, void 
*ptr)
 free(ptr);
 }
 
-void encoder_data_init(EncoderData *data)
+static void encoder_data_init(EncoderData *data)
 {
 data->bufs_tail = g_new(RedCompressBuf, 1);
 data->bufs_head = data->bufs_tail;
 data->bufs_head->send_next = NULL;
 }
 
-void encoder_data_reset(EncoderData *data)
+static void encoder_data_reset(EncoderData *data)
 {
 RedCompressBuf *buf = data->bufs_head;
 while (buf) {
@@ -577,6 +614,25 @@ void image_encoders_free_glz_drawables(ImageEncoders *enc)
 pthread_rwlock_unlock(&glz_dict->encode_lock);
 }
 
+void image_encoders_glz_free_from_drawable(struct Drawable *drawable)
+{
+RingItem *glz_item, *next_item;
+RedGlzDrawable *glz;
+DRAWABLE_FOREACH_GLZ_SAFE(drawable, glz_item, next_item, glz) {
+image_encoders_free_glz_drawable(glz->encoders, glz);
+}
+}
+
+void image_encoders_glz_detach_from_drawable(struct Drawable *drawable)
+{
+RingItem *item, *next;
+
+RING_FOREACH_SAFE(item, next, &drawable->glz_ring) {
+SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable = 
NULL;
+ring_remove(item);
+}
+}
+
 void image_encoders_freeze_glz(ImageEncoders *enc)
 {
 pthread_rwlock_wrlock(&enc->glz_dict->encode_lock);
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 655c1b3..68fd5a5 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -32,7 +32,6 @@
 #include "zlib-encoder.h"
 
 typedef struct RedCompressBuf RedCompressBuf;
-typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
 typedef struct RedGlzDrawable RedGlzDrawable;
 typedef struct ImageEncoders ImageEncoders;
 typedef struct ImageEncoderSharedData ImageEncoderSharedData;
@@ -50,6 +49,8 @@ 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 image_encoders_release_glz(ImageEncoders *enc);
+void image_encoders_glz_free_from_drawable(struct Drawable *drawable);
+void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
 
 #define RED_COMPRESS_BUF_SIZE (1024 * 64)
 struct RedCompressBuf {
@@ -106,9 +107,6 @@ typedef struct  {
 char message_buf[512];
 } EncoderData;
 
-void encoder_data_init(EncoderData *data);
-void encoder_data_reset(EncoderData *data);
-
 typedef struct {
 QuicUsrContext usr;
 EncoderData data;
@@ -141,33 +139,6 @@ typedef struct {
 EncoderData data;
 } GlzData;
 
-#define MAX_GLZ_DRAWABLE_INSTANCES 2
-
-/* for each qxl drawable, there may be several instances of lz drawables */
-/* TODO - reuse this stuff for the top level. I just added a second level of 
multiplicity
- * at the Draw

[Spice-devel] [PATCH v4 19/19] Remove message_buf from EncoderData

2016-06-14 Thread Frediano Ziglio
This buffer was just written and then used, no reason to store into
a more persistent structure.

Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 34 ++
 server/dcc-encoders.h |  1 -
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index beacb30..e18dadb 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -84,11 +84,12 @@ quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
 {
 EncoderData *usr_data = &(((QuicData *)usr)->data);
 va_list ap;
+char message_buf[512];
 
 va_start(ap, fmt);
-vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+vsnprintf(message_buf, sizeof(message_buf), fmt, ap);
 va_end(ap);
-spice_critical("%s", usr_data->message_buf);
+spice_critical("%s", message_buf);
 
 longjmp(usr_data->jmp_env, 1);
 }
@@ -98,11 +99,12 @@ lz_usr_error(LzUsrContext *usr, const char *fmt, ...)
 {
 EncoderData *usr_data = &(((LzData *)usr)->data);
 va_list ap;
+char message_buf[512];
 
 va_start(ap, fmt);
-vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+vsnprintf(message_buf, sizeof(message_buf), fmt, ap);
 va_end(ap);
-spice_critical("%s", usr_data->message_buf);
+spice_critical("%s", message_buf);
 
 longjmp(usr_data->jmp_env, 1);
 }
@@ -110,14 +112,14 @@ lz_usr_error(LzUsrContext *usr, const char *fmt, ...)
 static SPICE_GNUC_PRINTF(2, 3) void
 glz_usr_error(GlzEncoderUsrContext *usr, const char *fmt, ...)
 {
-EncoderData *usr_data = &(((GlzData *)usr)->data);
 va_list ap;
+char message_buf[512];
 
 va_start(ap, fmt);
-vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+vsnprintf(message_buf, sizeof(message_buf), fmt, ap);
 va_end(ap);
 
-spice_critical("%s", usr_data->message_buf); // if global lz fails in the 
middle
+spice_critical("%s", message_buf); // if global lz fails in the middle
 // the consequences are not 
predictable since the window
 // can turn to be unsynchronized 
between the server and
 // and the client
@@ -126,37 +128,37 @@ glz_usr_error(GlzEncoderUsrContext *usr, const char *fmt, 
...)
 static SPICE_GNUC_PRINTF(2, 3) void
 quic_usr_warn(QuicUsrContext *usr, const char *fmt, ...)
 {
-EncoderData *usr_data = &(((QuicData *)usr)->data);
 va_list ap;
+char message_buf[512];
 
 va_start(ap, fmt);
-vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+vsnprintf(message_buf, sizeof(message_buf), fmt, ap);
 va_end(ap);
-spice_warning("%s", usr_data->message_buf);
+spice_warning("%s", message_buf);
 }
 
 static SPICE_GNUC_PRINTF(2, 3) void
 lz_usr_warn(LzUsrContext *usr, const char *fmt, ...)
 {
-EncoderData *usr_data = &(((LzData *)usr)->data);
 va_list ap;
+char message_buf[512];
 
 va_start(ap, fmt);
-vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+vsnprintf(message_buf, sizeof(message_buf), fmt, ap);
 va_end(ap);
-spice_warning("%s", usr_data->message_buf);
+spice_warning("%s", message_buf);
 }
 
 static SPICE_GNUC_PRINTF(2, 3) void
 glz_usr_warn(GlzEncoderUsrContext *usr, const char *fmt, ...)
 {
-EncoderData *usr_data = &(((GlzData *)usr)->data);
 va_list ap;
+char message_buf[512];
 
 va_start(ap, fmt);
-vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+vsnprintf(message_buf, sizeof(message_buf), fmt, ap);
 va_end(ap);
-spice_warning("%s", usr_data->message_buf);
+spice_warning("%s", message_buf);
 }
 
 static void *quic_usr_malloc(QuicUsrContext *usr, int size)
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 75962ad..0e072b5 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -98,7 +98,6 @@ typedef struct  {
 int size_left;
 } compressed_data; // for encoding data that was already compressed by 
another method
 } u;
-char message_buf[512];
 } EncoderData;
 
 typedef struct {
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 08/19] Encapsulate code to save glz state

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 10 ++
 server/dcc-encoders.h |  2 ++
 server/dcc-send.c |  8 ++--
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 13dbff5..2e5984a 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -640,6 +640,16 @@ void image_encoders_freeze_glz(ImageEncoders *enc)
 pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
 }
 
+void image_encoders_glz_get_restore_data(ImageEncoders *enc,
+ uint8_t *out_id, 
GlzEncDictRestoreData *out_data)
+{
+spice_assert(enc->glz_dict);
+image_encoders_freeze_glz(enc);
+*out_id = enc->glz_dict->id;
+glz_enc_dictionary_get_restore_data(enc->glz_dict->dict, out_data,
+&enc->glz_data.usr);
+}
+
 static GlzSharedDictionary *glz_shared_dictionary_new(RedClient *client, 
uint8_t id,
   GlzEncDictContext *dict)
 {
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 68fd5a5..ce8010c 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -51,6 +51,8 @@ void image_encoders_freeze_glz(ImageEncoders *enc);
 void image_encoders_release_glz(ImageEncoders *enc);
 void image_encoders_glz_free_from_drawable(struct Drawable *drawable);
 void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
+void image_encoders_glz_get_restore_data(ImageEncoders *enc,
+ uint8_t *out_id, 
GlzEncDictRestoreData *out_data);
 
 #define RED_COMPRESS_BUF_SIZE (1024 * 64)
 struct RedCompressBuf {
diff --git a/server/dcc-send.c b/server/dcc-send.c
index c0c7573..ba695ef 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -1859,12 +1859,8 @@ 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->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->encoders.glz_data.usr);
+image_encoders_glz_get_restore_data(&dcc->encoders, 
&display_data.glz_dict_id,
+&display_data.glz_dict_data);
 
 /* all data besided the surfaces ref */
 spice_marshaller_add(base_marshaller,
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 11/19] Better encapsulation for image_encoders_compress_glz call

2016-06-14 Thread Frediano Ziglio
Do not access too much encoders data.
Slightly different as now if glz is frozen lz compression is used.

Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 15 +++
 server/dcc.c  | 17 -
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 6668dff..3547adc 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -1191,6 +1191,17 @@ int image_encoders_compress_glz(ImageEncoders *enc,
 spice_info("LZ global compress fmt=%d", src->format);
 #endif
 
+if ((src->x * src->y) >= glz_enc_dictionary_get_size(enc->glz_dict->dict)) 
{
+return FALSE;
+}
+
+pthread_rwlock_rdlock(&enc->glz_dict->encode_lock);
+/* using the global dictionary only if it is not frozen */
+if (enc->glz_dict->migrate_freeze) {
+pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
+return FALSE;
+}
+
 encoder_data_init(&glz_data->data);
 
 glz_drawable = get_glz_drawable(enc, drawable);
@@ -1241,8 +1252,12 @@ int image_encoders_compress_glz(ImageEncoders *enc,
 o_comp_data->comp_buf_size = zlib_size;
 
 stat_compress_add(&enc->shared_data->zlib_glz_stat, start_time, glz_size, 
zlib_size);
+pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
 return TRUE;
+
 glz:
+pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
+
 dest->descriptor.type = SPICE_IMAGE_TYPE_GLZ_RGB;
 dest->u.lz_rgb.data_size = glz_size;
 
diff --git a/server/dcc.c b/server/dcc.c
index e44feb7..3190c94 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -740,19 +740,10 @@ 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->encoders.glz_dict->dict)) {
-int frozen;
-/* using the global dictionary only if it is not frozen */
-pthread_rwlock_rdlock(&dcc->encoders.glz_dict->encode_lock);
-frozen = dcc->encoders.glz_dict->migrate_freeze;
-if (!frozen) {
-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) {
-break;
-}
+success = image_encoders_compress_glz(&dcc->encoders, dest, src, 
drawable, o_comp_data,
+  
display_channel->enable_zlib_glz_wrap);
+if (success) {
+break;
 }
 goto lz_compress;
 #ifdef USE_LZ4
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 05/19] Make dcc_compress_image_glz independent to DisplayChannelClient

2016-06-14 Thread Frediano Ziglio
Also rename to image_encoders_compress_glz

Signed-off-by: Frediano Ziglio 
Acked-by: Jonathon Jongsma 
---
 server/dcc.c | 31 ---
 1 file changed, 16 insertions(+), 15 deletions(-)

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) {
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 04/19] Move others glz fields to dcc-encoders

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
Acked-by: Jonathon Jongsma 
---
 server/dcc-encoders.c| 76 +---
 server/dcc-encoders.h| 19 +++-
 server/dcc.c | 18 +---
 server/dcc.h |  5 
 server/display-channel.c | 12 
 server/display-channel.h |  2 --
 server/red-worker.c  |  4 +--
 7 files changed, 66 insertions(+), 70 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 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 *drawabl

[Spice-devel] [PATCH v4 09/19] Make some function static

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 4 ++--
 server/dcc-encoders.h | 2 --
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 2e5984a..f423f22 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -523,7 +523,7 @@ static void 
image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
  * if possible.
  * NOTE - the caller should prevent encoding using the dictionary during this 
operation
  */
-void image_encoders_free_glz_drawable(ImageEncoders *enc, RedGlzDrawable 
*drawable)
+static void image_encoders_free_glz_drawable(ImageEncoders *enc, 
RedGlzDrawable *drawable)
 {
 RingItem *head_instance = ring_get_head(&drawable->instances);
 int cont = (head_instance != NULL);
@@ -633,7 +633,7 @@ void image_encoders_glz_detach_from_drawable(struct 
Drawable *drawable)
 }
 }
 
-void image_encoders_freeze_glz(ImageEncoders *enc)
+static void image_encoders_freeze_glz(ImageEncoders *enc)
 {
 pthread_rwlock_wrlock(&enc->glz_dict->encode_lock);
 enc->glz_dict->migrate_freeze = TRUE;
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index ce8010c..9674465 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -42,12 +42,10 @@ 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 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 image_encoders_release_glz(ImageEncoders *enc);
 void image_encoders_glz_free_from_drawable(struct Drawable *drawable);
 void image_encoders_glz_detach_from_drawable(struct Drawable *drawable);
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 12/19] Better encoders encapsulation

2016-06-14 Thread Frediano Ziglio
Avoid to access some fields from dcc.c

Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 4 
 server/dcc.c  | 3 ---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 3547adc..22cfcf3 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -710,6 +710,8 @@ gboolean image_encoders_get_glz_dictionary(ImageEncoders 
*enc,
 {
 GlzSharedDictionary *shared_dict;
 
+spice_return_val_if_fail(!enc->glz_dict, FALSE);
+
 pthread_mutex_lock(&glz_dictionary_list_lock);
 
 shared_dict = find_glz_dictionary(client, id);
@@ -743,6 +745,8 @@ gboolean 
image_encoders_restore_glz_dictionary(ImageEncoders *enc,
 {
 GlzSharedDictionary *shared_dict = NULL;
 
+spice_return_val_if_fail(!enc->glz_dict, FALSE);
+
 pthread_mutex_lock(&glz_dictionary_list_lock);
 
 shared_dict = find_glz_dictionary(client, id);
diff --git a/server/dcc.c b/server/dcc.c
index 3190c94..039229d 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -903,7 +903,6 @@ 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->encoders.glz_dict, FALSE);
 success = image_encoders_get_glz_dictionary(&dcc->encoders,
 
RED_CHANNEL_CLIENT(dcc)->client,
 init->glz_dictionary_id,
@@ -1008,8 +1007,6 @@ 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->encoders.glz_dict, FALSE);
-
 return image_encoders_restore_glz_dictionary(&dcc->encoders,
  
RED_CHANNEL_CLIENT(dcc)->client,
  migrate->glz_dict_id,
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 06/19] Move image_encoders_compress_glz to dcc-encoders.c

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
Acked-by: Jonathon Jongsma 
---
 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 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 {
+

[Spice-devel] [PATCH v4 18/19] Reduce header dependency

2016-06-14 Thread Frediano Ziglio
Avoid dependencies from RedChannel stuff.

Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.h | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 47051b4..75962ad 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -20,10 +20,10 @@
 
 #include 
 #include 
+#include 
 
-#include "red-channel.h"
+#include "stat.h"
 #include "red-parse-qxl.h"
-#include "image-cache.h"
 #include "glz-encoder.h"
 #include "jpeg-encoder.h"
 #ifdef USE_LZ4
@@ -31,6 +31,8 @@
 #endif
 #include "zlib-encoder.h"
 
+struct RedClient;
+
 typedef struct RedCompressBuf RedCompressBuf;
 typedef struct RedGlzDrawable RedGlzDrawable;
 typedef struct ImageEncoders ImageEncoders;
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 13/19] Change RedGlzDrawable::drawable from pointer to boolean

2016-06-14 Thread Frediano Ziglio
The field was used just as a flag.
This has the advantage to make clear to not use the pointer as we don't
have ownership.
Also many the structure a bit smaller.

Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 22cfcf3..00349fe 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -48,10 +48,10 @@ struct RedGlzDrawable {
 RingItem link;// ordered by the time it was encoded
 RingItem drawable_link;
 RedDrawable *red_drawable;
-struct Drawable*drawable;
 GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
 Ring instances;
 uint8_t instances_count;
+gboolean has_drawable;
 ImageEncoders *encoders;
 };
 
@@ -505,9 +505,7 @@ static void 
image_encoders_free_glz_drawable_instance(ImageEncoders *enc,
 if (ring_is_empty(&glz_drawable->instances)) {
 spice_assert(glz_drawable->instances_count == 0);
 
-Drawable *drawable = glz_drawable->drawable;
-
-if (drawable) {
+if (glz_drawable->has_drawable) {
 ring_remove(&glz_drawable->drawable_link);
 }
 red_drawable_unref(glz_drawable->red_drawable);
@@ -569,7 +567,7 @@ int 
image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc)
 while ((n < RED_RELEASE_BUNCH_SIZE) && (ring_link != NULL)) {
 RedGlzDrawable *glz_drawable = SPICE_CONTAINEROF(ring_link, 
RedGlzDrawable, link);
 ring_link = ring_next(&enc->glz_drawables, ring_link);
-if (!glz_drawable->drawable) {
+if (!glz_drawable->has_drawable) {
 image_encoders_free_glz_drawable(enc, glz_drawable);
 n++;
 }
@@ -630,7 +628,7 @@ void image_encoders_glz_detach_from_drawable(struct 
Drawable *drawable)
 RingItem *item, *next;
 
 RING_FOREACH_SAFE(item, next, &drawable->glz_ring) {
-SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable = 
NULL;
+SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->has_drawable = 
FALSE;
 ring_remove(item);
 }
 }
@@ -1143,7 +1141,7 @@ static RedGlzDrawable *get_glz_drawable(ImageEncoders 
*enc, Drawable *drawable)
 
 ret->encoders = enc;
 ret->red_drawable = red_drawable_ref(drawable->red_drawable);
-ret->drawable = drawable;
+ret->has_drawable = TRUE;
 ret->instances_count = 0;
 ring_init(&ret->instances);
 
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 15/19] Do not access ImageEncoders internal to lock/unlock glz encoding

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c| 14 ++
 server/dcc-encoders.h|  2 ++
 server/display-channel.c | 18 +-
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index a83794e..7b129e4 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -550,6 +550,20 @@ static void image_encoders_free_glz_drawable(ImageEncoders 
*enc, RedGlzDrawable
 }
 }
 
+void image_encoders_glz_encode_lock(ImageEncoders *enc)
+{
+if (enc->glz_dict) {
+pthread_rwlock_wrlock(&enc->glz_dict->encode_lock);
+}
+}
+
+void image_encoders_glz_encode_unlock(ImageEncoders *enc)
+{
+if (enc->glz_dict) {
+pthread_rwlock_unlock(&enc->glz_dict->encode_lock);
+}
+}
+
 /*
  * Remove from the global lz dictionary some glz_drawables that have no 
reference to
  * Drawable (their qxl drawables are released too).
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index ac61a70..4587a0b 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -50,6 +50,8 @@ void image_encoders_glz_free_from_drawable_ring(Ring 
*drawable_ring);
 void image_encoders_glz_detach_from_drawable_ring(Ring *drawable_ring);
 void image_encoders_glz_get_restore_data(ImageEncoders *enc,
  uint8_t *out_id, 
GlzEncDictRestoreData *out_data);
+void image_encoders_glz_encode_lock(ImageEncoders *enc);
+void image_encoders_glz_encode_unlock(ImageEncoders *enc);
 
 #define RED_COMPRESS_BUF_SIZE (1024 * 64)
 struct RedCompressBuf {
diff --git a/server/display-channel.c b/server/display-channel.c
index bddedd9..15d69c4 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -1198,14 +1198,10 @@ void display_channel_free_some(DisplayChannel *display)
 spice_debug("#draw=%d, #glz_draw=%d", display->drawable_count,
 display->encoder_globals.glz_drawable_count);
 FOREACH_CLIENT(display, link, next, dcc) {
-GlzSharedDictionary *glz_dict = dcc->encoders.glz_dict;
-
-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 = 
image_encoders_free_some_independent_glz_drawables(&dcc->encoders);
-}
+// encoding using the dictionary is prevented since the following 
operations might
+// change the dictionary
+image_encoders_glz_encode_lock(&dcc->encoders);
+n = image_encoders_free_some_independent_glz_drawables(&dcc->encoders);
 }
 
 while (!ring_is_empty(&display->current_list) && n++ < 
RED_RELEASE_BUNCH_SIZE) {
@@ -1213,11 +1209,7 @@ void display_channel_free_some(DisplayChannel *display)
 }
 
 FOREACH_CLIENT(display, link, next, dcc) {
-GlzSharedDictionary *glz_dict = dcc->encoders.glz_dict;
-
-if (glz_dict) {
-pthread_rwlock_unlock(&glz_dict->encode_lock);
-}
+image_encoders_glz_encode_unlock(&dcc->encoders);
 }
 }
 
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 01/19] Add a structure to hold ImageEncoders shared data

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c| 121 +++
 server/dcc-encoders.h|  33 +
 server/dcc.c |  26 +-
 server/display-channel.c |  73 ++--
 server/display-channel.h |   9 +---
 5 files changed, 141 insertions(+), 121 deletions(-)

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,
 

[Spice-devel] [PATCH v4 17/19] Remove dependency from dcc-encoders to Drawable

2016-06-14 Thread Frediano Ziglio
Encoding image requires a RedDrawable (where the data is stored) and
a Ring where to store information to free Glz structures.

Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 17 ++---
 server/dcc-encoders.h |  3 ++-
 server/dcc.c  |  4 +++-
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 4c7d73e..beacb30 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -22,7 +22,9 @@
 #include 
 
 #include "dcc-encoders.h"
-#include "display-channel.h"
+#include "spice-bitmap-utils.h"
+#include "red-worker.h" // red_drawable_unref
+#include "pixmap-cache.h" // MAX_CACHE_CLIENTS
 
 #define ZLIB_DEFAULT_COMPRESSION_LEVEL 3
 
@@ -1147,7 +1149,7 @@ int image_encoders_compress_lz4(ImageEncoders *enc, 
SpiceImage *dest,
 
 /* 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)
+static RedGlzDrawable *get_glz_drawable(ImageEncoders *enc, RedDrawable 
*red_drawable, Ring *drawable_ring)
 {
 RedGlzDrawable *ret;
 RingItem *item, *next;
@@ -1155,7 +1157,7 @@ static RedGlzDrawable *get_glz_drawable(ImageEncoders 
*enc, Drawable *drawable)
 // 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) {
+SAFE_FOREACH(item, next, TRUE, drawable_ring, ret, LINK_TO_GLZ(item)) {
 if (ret->encoders == enc) {
 return ret;
 }
@@ -1164,7 +1166,7 @@ static RedGlzDrawable *get_glz_drawable(ImageEncoders 
*enc, Drawable *drawable)
 ret = spice_new(RedGlzDrawable, 1);
 
 ret->encoders = enc;
-ret->red_drawable = red_drawable_ref(drawable->red_drawable);
+ret->red_drawable = red_drawable_ref(red_drawable);
 ret->has_drawable = TRUE;
 ret->instances_count = 0;
 ring_init(&ret->instances);
@@ -1172,7 +1174,7 @@ static RedGlzDrawable *get_glz_drawable(ImageEncoders 
*enc, Drawable *drawable)
 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);
+ring_add(drawable_ring, &ret->drawable_link);
 enc->shared_data->glz_drawable_count++;
 return ret;
 }
@@ -1198,7 +1200,8 @@ static GlzDrawableInstanceItem 
*add_glz_drawable_instance(RedGlzDrawable *glz_dr
 #define MIN_GLZ_SIZE_FOR_ZLIB 100
 
 int image_encoders_compress_glz(ImageEncoders *enc,
-SpiceImage *dest, SpiceBitmap *src, Drawable 
*drawable,
+SpiceImage *dest, SpiceBitmap *src,
+RedDrawable *red_drawable, Ring *drawable_ring,
 compress_send_data_t* o_comp_data,
 gboolean enable_zlib_glz_wrap)
 {
@@ -1230,7 +1233,7 @@ int image_encoders_compress_glz(ImageEncoders *enc,
 
 encoder_data_init(&glz_data->data);
 
-glz_drawable = get_glz_drawable(enc, drawable);
+glz_drawable = get_glz_drawable(enc, red_drawable, drawable_ring);
 glz_drawable_instance = add_glz_drawable_instance(glz_drawable);
 
 glz_data->data.u.lines_data.chunks = src->data;
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 5966b59..47051b4 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -195,7 +195,8 @@ int image_encoders_compress_jpeg(ImageEncoders *enc, 
SpiceImage *dest,
 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,
+SpiceImage *dest, SpiceBitmap *src,
+RedDrawable *red_drawable, Ring *drawable_ring,
 compress_send_data_t* o_comp_data,
 gboolean enable_zlib_glz_wrap);
 
diff --git a/server/dcc.c b/server/dcc.c
index 039229d..ca5569e 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -740,7 +740,9 @@ int dcc_compress_image(DisplayChannelClient *dcc,
 success = image_encoders_compress_quic(&dcc->encoders, dest, src, 
o_comp_data);
 break;
 case SPICE_IMAGE_COMPRESSION_GLZ:
-success = image_encoders_compress_glz(&dcc->encoders, dest, src, 
drawable, o_comp_data,
+success = image_encoders_compress_glz(&dcc->encoders, dest, src,
+  drawable->red_drawable, 
&drawable->glz_ring,
+  

[Spice-devel] [PATCH v4 16/19] Make GlzSharedDictionary structure private in dcc-encoders.c

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 10 ++
 server/dcc-encoders.h | 11 +--
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index 7b129e4..4c7d73e 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -30,6 +30,16 @@
 
 typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
 
+struct GlzSharedDictionary {
+RingItem base;
+GlzEncDictContext *dict;
+uint32_t refs;
+uint8_t id;
+pthread_rwlock_t encode_lock;
+int migrate_freeze;
+RedClient *client; // channel clients of the same client share the dict
+};
+
 /* for each qxl drawable, there may be several instances of lz drawables */
 /* TODO - reuse this stuff for the top level. I just added a second level of 
multiplicity
  * at the Drawable by keeping a ring, so:
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 4587a0b..5966b59 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -35,6 +35,7 @@ typedef struct RedCompressBuf RedCompressBuf;
 typedef struct RedGlzDrawable RedGlzDrawable;
 typedef struct ImageEncoders ImageEncoders;
 typedef struct ImageEncoderSharedData ImageEncoderSharedData;
+typedef struct GlzSharedDictionary GlzSharedDictionary;
 
 void image_encoder_shared_init(ImageEncoderSharedData *shared_data);
 void image_encoder_shared_stat_reset(ImageEncoderSharedData *shared_data);
@@ -71,16 +72,6 @@ static inline void compress_buf_free(RedCompressBuf *buf)
 g_free(buf);
 }
 
-typedef struct GlzSharedDictionary {
-RingItem base;
-GlzEncDictContext *dict;
-uint32_t refs;
-uint8_t id;
-pthread_rwlock_t encode_lock;
-int migrate_freeze;
-RedClient *client; // channel clients of the same client share the dict
-} GlzSharedDictionary;
-
 gboolean image_encoders_get_glz_dictionary(ImageEncoders *enc,
struct RedClient *client,
uint8_t id, int window_size);
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 00/19] Better encapsulation of image encoding stuff

2016-06-14 Thread Frediano Ziglio
Hi,
  after the discussion and tests to reduce typedef mess I realized
the code lack some proper encapsulation.
In DisplayChannel there are multiple files to handle different stuff
but all code needs to know all structures and basically include all
stuff.
Looking at code one stuff that could/should be separate is the image
encoding. There is no high level reason why to compress an image a
connection to a client is required.
So I started moving encoding fields into a structure and
encapsulating code reducing access and knowledge about image
encoding.

Results:
- dcc-encoders.c does not include or use DisplayChannel stuff;
- more structures are now defined in dcc-encoders.c;
- dcc-encoders does not use Drawable but just a Ring to store
  internal data.

Future improvements (not strictly related to this patchset):
- dcc_compress_image should be moved to dcc-encoders.c;
- there is no reason dcc-encoders.h should use RedClient,
  this is just as the Glz dictionaries are bound to client;
- Glz code is still messy although more encapsulated;
- ImageEncoders is quite huge, could be optimized;
- dcc-encoders.[ch] should be renamed to image-encoders.[ch];
- implements lazy allocation for encoders to reduce memory
  footprint.

Changes from v3:
- renamed ImageEncoderGlobals to ImageEncoderSharedData
  (and globals variables to shared_data);
- split a rename patch;
- added small optimization for ImageEncoders.

Changes from v2:
- minor comment fixes;
- added a structure to store global data. This allowed to
  store the old "glz_drawable_count". Also this reduce
  the number or parameters to pass to
  image_encoders_compress_XX functions.

Changes from v1:
- EncodersData structure renamed to ImageEncoders;
- all encoders function have the image_encoders_ prefix;
- split patches that move encoder fields from part that prepare
  dcc_compress_XX to be moved;
- merged some not strictly related patches.

Frediano Ziglio (19):
  Add a structure to hold ImageEncoders shared data
  Move some glz fields to ImageEncoders
  Change dcc_encoders_init to take ImageEncoders instead of
DisplayChannelClient
  Move others glz fields to dcc-encoders
  Make dcc_compress_image_glz independent to DisplayChannelClient
  Move image_encoders_compress_glz to dcc-encoders.c
  Encapsulate some data in dcc-encoders
  Encapsulate code to save glz state
  Make some function static
  Encapsulate dcc_release_glz
  Better encapsulation for image_encoders_compress_glz call
  Better encoders encapsulation
  Change RedGlzDrawable::drawable from pointer to boolean
  Use Ring instead of accessing Drawable internals
  Do not access ImageEncoders internal to lock/unlock glz encoding
  Make GlzSharedDictionary structure private in dcc-encoders.c
  Remove dependency from dcc-encoders to Drawable
  Reduce header dependency
  Remove message_buf from EncoderData

 server/dcc-encoders.c| 573 +--
 server/dcc-encoders.h| 123 +-
 server/dcc-send.c|   8 +-
 server/dcc.c | 218 +++---
 server/dcc.h |   9 -
 server/display-channel.c | 112 ++---
 server/display-channel.h |  16 +-
 server/red-worker.c  |   4 +-
 8 files changed, 565 insertions(+), 498 deletions(-)

-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 03/19] Change dcc_encoders_init to take ImageEncoders instead of DisplayChannelClient

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
---
 server/dcc-encoders.c | 4 +---
 server/dcc-encoders.h | 2 +-
 server/dcc.c  | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

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;
 }
-- 
2.7.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4 02/19] Move some glz fields to ImageEncoders

2016-06-14 Thread Frediano Ziglio
Signed-off-by: Frediano Ziglio 
Acked-by: Jonathon Jongsma 
---
 server/dcc-encoders.c| 95 +++-
 server/dcc-encoders.h| 20 +++---
 server/dcc-send.c| 10 ++---
 server/dcc.c | 43 +++---
 server/dcc.h |  4 --
 server/display-channel.c |  4 +-
 6 files changed, 97 insertions(+), 79 deletions(-)

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,
 

Re: [Spice-devel] [spice-gtk PATCH] Handle single headed monitors that have a non-zero x, y config offset

2016-06-14 Thread Christophe Fergeau
On Mon, Jun 13, 2016 at 07:09:29PM +0200, Marc-André Lureau wrote:
> My understanding is that there is some confusing between monitor
> configuration position (the monitor config on main channel), and the
> scanout/primary position (the monitor config on display channel).
> 
> Imho, the fix should be on server or guest/driver side, it shouldn't
> use a display monitor config with a scanout offset if there is none to
> be applied by the client.

Regarding fixing this on the server, isn't it going to have similar
issues? Ie once we get QXL_IO_MONITORS_CONFIG_ASYNC in QEMU, we could
make sure that display channels with just one monitor will get (0, 0) as
their primary position, but this is not correct with virgl, so we'd need
some gl check in the server before doing the zero-ing out?

Christophe


signature.asc
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [spice-gtk] widget: Disable IME context on main widget

2016-06-14 Thread Christophe Fergeau
Hey,

On Mon, Jun 13, 2016 at 06:07:53AM -0400, Frediano Ziglio wrote:
> > 
> > On Fri, Jun 10, 2016 at 08:45:56AM -0400, Frediano Ziglio wrote:
> > > 
> > > This seems quite strong! I think this will remove the IME context
> > > even from the Windows desktop :)
> > 
> > Oh? I just assumed that the win32 hierarchy was more or less the same as
> > the GTK+ hierarchy, and that iterating win32 windows between the current
> > GTK+ widget and it's GTK+ parent would let us not hardcode just one
> > GetParent()
> > 
> > Forget it if it's all wrong ;)
> > 
> > Christophe
> > 
> 
> Added some debug to the code to understand the hierarchy.
> The HWND parent of the widget if the HWND of GTK parent so at
> least for these 2 classes there is a 1-to-1 relationship.
> These first 2 windows have the same exact size and position
> taking all client area (without title and borders) while the
> grand parent take all window (so even title and borders).
> 
> The Gtk parent of SpiceDisplay, at least used in remote-viewer
> is a GtkBin created in virt-viewer.
> So in the end we are changing a property of another Gtk
> window. I don't know how this would work with spicy or other
> users of this class. I think the reason of this is the way Gtk
> handle the events basically taking all events from all windows
> and dispatching with Gtk logic. This is different from classic
> Windows programs where the dispatching is done by Windows itself.

In short, ImmAssociateContext needs to be called both on the
SpiceDisplay widget (handled by spice-gtk), and on the GTK+ container
it's in, which is owned by the application using spice-gtk? I think I
might be fine with calling ImmAssociateContext on
gtk_widget_get_parent(SpiceDisplay) from within spice-gtk as this is the
more generic solution (ie will do what is needed for every application
using spice-gtk).

Christophe


signature.asc
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [spice-gtk PATCH] Handle single headed monitors that have a non-zero x, y config offset

2016-06-14 Thread Christophe Fergeau
Hey,

On Mon, Jun 13, 2016 at 07:09:29PM +0200, Marc-André Lureau wrote:
> >> On Thu, Jun 18, 2015 at 07:14:13PM -0400, sstut...@redhat.com wrote:
> >> > From: Sandy Stutsman 
> >> >
> >> > Each monitor on a Windows guest is represented as a separate, 
> >> > single-headed
> >> > device with its own framebuffer.  When there are multiple monitors, all
> >> > monitors but one will have a non-zero xy config position.  But even in
> >> > these cases the whole area (frame-buffer) of each monitor should be
> >> > updated.
> >> >
> >> > Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1202419


> 
> That's not compatible with virgl, which may use a monitor scanout
> different than +0+0 (in multimonitor for ex, but one monitor per
> display channel).
> 
> I could probably workaround the issue with an extra test such as if
> (monitors->len == 1 && !d->egl.enabled)... But that condition looks
> wrong to me anyway.
> 
> My understanding is that there is some confusing between monitor
> configuration position (the monitor config on main channel), and the
> scanout/primary position (the monitor config on display channel).

To be honest, I'm not sure about the difference between these... Is this
documented anywhere?
If you mean that the main channel monitor configuration message should
describe the overall monitor layout (including the (x, y) position) of
all monitors across all display channels, and then the display channel
monitor configuration message only describes the offset of the
monitor(s) within the scanout of the current display channel, then yes,
the agent changes corresponding to that patch were probably wrong.

Christophe


signature.asc
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v7 server] LZ4 compression is now available at the Spicevmc channel

2016-06-14 Thread Frediano Ziglio
> 
> Compressed message type is CompressedData which contains compression
> type (1 byte) followed by the uncompressed data size (4 bytes - exists
> only if data was compressed) followed by the compressed data
> 
> If SPICE_USBREDIR_CAP_DATA_COMPRESS_LZ4 capability is available &&
> data_size > COMPRESS_THRESHOLD && !AF_LOCAL data will be sent
> compressed otherwise data will be sent uncompressed (also if
> compression has failed)
> 
> Update the required protocol to 0.12.12
> 
> Signed-off-by: Frediano Ziglio 
> Signed-off-by: Snir Sheriber 
> ---
>  configure.ac  |   2 +-
>  server/spicevmc.c | 140
>  ++
>  2 files changed, 132 insertions(+), 10 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index c743875..856833b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -98,7 +98,7 @@ AS_IF([test x"$have_smartcard" = "xyes"], [
>  AS_VAR_APPEND([SPICE_REQUIRES], [" libcacard >= 0.1.2"])
>  ])
>  
> -SPICE_PROTOCOL_MIN_VER=0.12.11
> +SPICE_PROTOCOL_MIN_VER=0.12.12
>  PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >=
>  $SPICE_PROTOCOL_MIN_VER])
>  AC_SUBST([SPICE_PROTOCOL_MIN_VER])
>  
> diff --git a/server/spicevmc.c b/server/spicevmc.c
> index b662d94..908ad5f 100644
> --- a/server/spicevmc.c
> +++ b/server/spicevmc.c
> @@ -34,6 +34,9 @@
>  #include "red-channel.h"
>  #include "reds.h"
>  #include "migration-protocol.h"
> +#ifdef USE_LZ4
> +#include 
> +#endif
>  
>  /* todo: add flow control. i.e.,
>   * (a) limit the tokens available for the client
> @@ -41,10 +44,13 @@
>   */
>  /* 64K should be enough for all but the largest writes + 32 bytes hdr */
>  #define BUF_SIZE (64 * 1024 + 32)
> +#define COMPRESS_THRESHOLD 1000
>  
>  typedef struct RedVmcPipeItem {
>  RedPipeItem base;
>  
> +SpiceDataCompressionType type;
> +uint32_t uncompressed_data_size;
>  /* writes which don't fit this will get split, this is not a problem */
>  uint8_t buf[BUF_SIZE];
>  uint32_t buf_used;
> @@ -105,6 +111,53 @@ enum {
>  RED_PIPE_ITEM_TYPE_PORT_EVENT,
>  };
>  
> +static void spicevmc_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
> + uint16_t type,
> + uint32_t size,
> + uint8_t *msg);
> +/* n is the data size (uncompressed)
> + * msg_item -- the current pipe item with the uncompressed data
> + * This function returns:
> + *  - NULL upon failure.
> + *  - a new pipe item with the compressed data in it upon success
> + */
> +static RedVmcPipeItem* try_compress_lz4(SpiceVmcState *state, int n,
> RedVmcPipeItem *msg_item)
> +{
> +RedVmcPipeItem *msg_item_compressed;
> +int compressed_data_count;
> +
> +if (reds_stream_get_family(state->rcc->stream) == AF_UNIX) {
> +/* AF_LOCAL - data will not be compressed */
> +return NULL;
> +}
> +if (n <= COMPRESS_THRESHOLD) {
> +/* n <= threshold - data will not be compressed */
> +return NULL;
> +}
> +if (!red_channel_test_remote_cap(&state->channel,
> SPICE_SPICEVMC_CAP_DATA_COMPRESS_LZ4)) {
> +/* Client doesn't have compression cap - data will not be compressed
> */
> +return NULL;
> +}
> +msg_item_compressed = spice_new0(RedVmcPipeItem, 1);
> +red_pipe_item_init(&msg_item_compressed->base,
> RED_PIPE_ITEM_TYPE_SPICEVMC_DATA);
> +compressed_data_count = LZ4_compress_default((char*)&msg_item->buf,
> +
> (char*)&msg_item_compressed->buf,
> + n,
> + BUF_SIZE);
> +
> +if (compressed_data_count > 0 && compressed_data_count < n) {
> +msg_item_compressed->type = SPICE_DATA_COMPRESSION_TYPE_LZ4;
> +msg_item_compressed->uncompressed_data_size = n;
> +msg_item_compressed->buf_used = compressed_data_count;
> +free(msg_item);
> +return msg_item_compressed;
> +}
> +
> +/* LZ4 compression failed or did non compress, fallback a non-compressed
> data is to be sent */
> +free(msg_item_compressed);
> +return NULL;
> +}
> +
>  static RedPipeItem
>  *spicevmc_chardev_read_msg_from_dev(SpiceCharDeviceInstance *sin,
> void *opaque)
>  {
> @@ -121,6 +174,7 @@ static RedPipeItem
> *spicevmc_chardev_read_msg_from_dev(SpiceCharDeviceInstance *
>  
>  if (!state->pipe_item) {
>  msg_item = spice_new0(RedVmcPipeItem, 1);
> +msg_item->type = SPICE_DATA_COMPRESSION_TYPE_NONE;
>  red_pipe_item_init(&msg_item->base,
>  RED_PIPE_ITEM_TYPE_SPICEVMC_DATA);
>  } else {
>  spice_assert(state->pipe_item->buf_used == 0);
> @@ -132,6 +186,15 @@ static RedPipeItem
> *spicevmc_chardev_read_msg_from_dev(SpiceCharDeviceInstance *
>sizeof(msg_item->buf));
>  if (n > 0) {
>  spice_de

Re: [Spice-devel] [PATCH v7 spice-common 3/3] Add LZ4 data compression and use it in spicevmc channel

2016-06-14 Thread Frediano Ziglio
> 
> Compressed message type is CompressedData which contains compression
> type (1 byte) followed by the uncompressed data size (4 bytes-exists
> only if data was compressed) followed by the compressed data
> 
> Update the required protocol to 0.12.12:
> 
> Signed-off-by: Frediano Ziglio 
> Signed-off-by: Snir Sheriber 
> ---
>  common/client_marshallers.h |  1 +
>  common/messages.h   |  7 +++
>  configure.ac|  2 +-
>  spice.proto | 24 
>  4 files changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/common/client_marshallers.h b/common/client_marshallers.h
> index 728987e..2074323 100644
> --- a/common/client_marshallers.h
> +++ b/common/client_marshallers.h
> @@ -33,6 +33,7 @@ SPICE_BEGIN_DECLS
>  typedef struct {
>  void (*msg_SpiceMsgEmpty)(SpiceMarshaller *m, SpiceMsgEmpty *msg);
>  void (*msg_SpiceMsgData)(SpiceMarshaller *m, SpiceMsgData *msg);
> +void (*msg_SpiceMsgCompressedData)(SpiceMarshaller *m,
> SpiceMsgCompressedData *msg);
>  void (*msgc_ack_sync)(SpiceMarshaller *m, SpiceMsgcAckSync *msg);
>  void (*msgc_pong)(SpiceMarshaller *m, SpiceMsgPing *msg);
>  void (*msgc_disconnecting)(SpiceMarshaller *m, SpiceMsgDisconnect *msg);
> diff --git a/common/messages.h b/common/messages.h
> index f537950..516a345 100644
> --- a/common/messages.h
> +++ b/common/messages.h
> @@ -55,6 +55,13 @@ typedef struct SpiceMsgData {
>  uint8_t data[0];
>  } SpiceMsgData;
>  
> +typedef struct SpiceMsgCompressedData {
> +uint8_t type;
> +uint32_t uncompressed_size;
> +uint32_t compressed_size;
> +uint8_t *compressed_data;
> +} SpiceMsgCompressedData;
> +
>  typedef struct SpiceMsgEmpty {
>  uint8_t padding;
>  } SpiceMsgEmpty;
> diff --git a/configure.ac b/configure.ac
> index f8ff024..c3ad5a4 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -28,7 +28,7 @@ AM_PROG_CC_C_O
>  SPICE_CHECK_SYSDEPS
>  
>  # Checks for libraries
> -PKG_CHECK_MODULES([PROTOCOL], [spice-protocol >= 0.12.10])
> +PKG_CHECK_MODULES([PROTOCOL], [spice-protocol >= 0.12.12])
>  
>  SPICE_CHECK_PYTHON_MODULES()
>  
> diff --git a/spice.proto b/spice.proto
> index d21510d..0bfc515 100644
> --- a/spice.proto
> +++ b/spice.proto
> @@ -120,6 +120,28 @@ message Data {
>  uint8 data[] @end @ctype(uint8_t);
>  } @nocopy;
>  
> +enum8 data_compression_type {
> +NONE,
> +LZ4,
> +};
> +
> +struct EmptyStructure {
> +};
> +
> +message CompressedData {
> +data_compression_type type;
> +switch (type) {
> +/* we cannot use !NONE (works only with flags) */
> +case NONE:
> +/* due to the way cases are defined after NONE we must have
> something */
> +/* due to a bug we cannot use @virtual to write 0 to compressed_size
> */
> +EmptyStructure empty;
> +default:
> +uint32 uncompressed_size;
> +} u @anon;
> +uint8 compressed_data[] @as_ptr(compressed_size);
> +} @ctype(SpiceMsgCompressedData);
> +
>  struct ChannelWait {
>  uint8 channel_type;
>  uint8 channel_id;
> @@ -1373,8 +1395,10 @@ channel SmartcardChannel : BaseChannel {
>  channel SpicevmcChannel : BaseChannel {
>  server:
>  Data data = 101;
> +CompressedData compressed_data = 102;
>  client:
>  Data data = 101;
> +CompressedData compressed_data = 102;
>  };
>  
>  channel UsbredirChannel : SpicevmcChannel {

Acked-by: Frediano Ziglio 

Frediano
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH v7 spice-protocol] LZ4 compression is now available at the Spicevmc channel

2016-06-14 Thread Frediano Ziglio
> 
> -New message type for compressed messages has been added to the protocol
> 
> Compressed message type is CompressedData which contains compression
> type (1 byte) followed by the uncompressed data size (4 bytes -exists
> only if data was compressed) followed by the compressed data
> 
> -SPICE_SPICEVMC_CAP_DATA_COMPRESS_LZ4 capability has been added
> 
> When both sides has the capabilty all usb redirected data will be compressed
> (only if size > threshold and AF_LOCAL socket is not in use)
> 
> To send compressed msg use SpiceMsgCompressedData type with
> spice_marshall_SpiceMsgCompressedData and then use add_ref to add the
> compressed data
> 
> Signed-off-by: Snir Sheriber 
> ---
>  spice/enums.h| 9 +
>  spice/protocol.h | 4 
>  2 files changed, 13 insertions(+)
> 
> diff --git a/spice/enums.h b/spice/enums.h
> index c6e9840..1d0c2db 100644
> --- a/spice/enums.h
> +++ b/spice/enums.h
> @@ -106,6 +106,13 @@ typedef enum SpiceMouseMode {
>  SPICE_MOUSE_MODE_MASK = 0x3
>  } SpiceMouseMode;
>  
> +typedef enum SpiceDataCompressionType {
> +SPICE_DATA_COMPRESSION_TYPE_NONE,
> +SPICE_DATA_COMPRESSION_TYPE_LZ4,
> +
> +SPICE_DATA_COMPRESSION_TYPE_ENUM_END
> +} SpiceDataCompressionType;
> +
>  typedef enum SpicePubkeyType {
>  SPICE_PUBKEY_TYPE_INVALID,
>  SPICE_PUBKEY_TYPE_RSA,
> @@ -634,12 +641,14 @@ enum {
>  
>  enum {
>  SPICE_MSG_SPICEVMC_DATA = 101,
> +SPICE_MSG_SPICEVMC_COMPRESSED_DATA,
>  
>  SPICE_MSG_END_SPICEVMC
>  };
>  
>  enum {
>  SPICE_MSGC_SPICEVMC_DATA = 101,
> +SPICE_MSGC_SPICEVMC_COMPRESSED_DATA,
>  
>  SPICE_MSGC_END_SPICEVMC
>  };
> diff --git a/spice/protocol.h b/spice/protocol.h
> index f4a2259..d742eda 100644
> --- a/spice/protocol.h
> +++ b/spice/protocol.h
> @@ -148,6 +148,10 @@ enum {
>  };
>  
>  enum {
> +SPICE_SPICEVMC_CAP_DATA_COMPRESS_LZ4,
> +};
> +
> +enum {
>  SPICE_PORT_EVENT_OPENED,
>  SPICE_PORT_EVENT_CLOSED,
>  SPICE_PORT_EVENT_BREAK,

Acked-by: Frediano Ziglio 

Frediano
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel