This is a reduced diff (removed the move) --- before.c 2015-11-19 13:04:55.376919069 +0000 +++ after.c 2015-11-19 12:53:18.732173333 +0000 @@ -305,21 +305,21 @@ return; } dcc->surface_client_created[surface_id] = FALSE; destroy = surface_destroy_item_new(channel, surface_id); red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &destroy->pipe_item); } /* if already exists, returns it. Otherwise allocates and adds it (1) to the ring tail in the channel (2) to the Drawable*/ -static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannelClient *dcc, Drawable *drawable) +static RedGlzDrawable *get_glz_drawable(DisplayChannelClient *dcc, Drawable *drawable) { RedGlzDrawable *ret; RingItem *item, *next; // TODO - I don't really understand what's going on here, so doing the technical equivalent // now that we have multiple glz_dicts, so the only way to go from dcc to drawable glz is to go // over the glz_ring (unless adding some better data structure then a ring) DRAWABLE_FOREACH_GLZ_SAFE(drawable, item, next, ret) { if (ret->dcc == dcc) { return ret; @@ -332,67 +332,67 @@ ret->red_drawable = red_drawable_ref(drawable->red_drawable); ret->drawable = drawable; ret->group_id = drawable->group_id; ret->instances_count = 0; ring_init(&ret->instances); ring_item_init(&ret->link); ring_item_init(&ret->drawable_link); ring_add_before(&ret->link, &dcc->glz_drawables); ring_add(&drawable->glz_ring, &ret->drawable_link); - DCC_TO_WORKER(dcc)->glz_drawable_count++; + dcc->glz_drawable_count++; return ret; } /* allocates new instance and adds it to instances in the given drawable. NOTE - the caller should set the glz_instance returned by the encoder by itself.*/ -static GlzDrawableInstanceItem *red_display_add_glz_drawable_instance(RedGlzDrawable *glz_drawable) +static GlzDrawableInstanceItem *add_glz_drawable_instance(RedGlzDrawable *glz_drawable) { spice_assert(glz_drawable->instances_count < MAX_GLZ_DRAWABLE_INSTANCES); // NOTE: We assume the additions are performed consecutively, without removals in the middle GlzDrawableInstanceItem *ret = glz_drawable->instances_pool + glz_drawable->instances_count; glz_drawable->instances_count++; ring_item_init(&ret->free_link); ring_item_init(&ret->glz_link); ring_add(&glz_drawable->instances, &ret->glz_link); ret->context = NULL; ret->glz_drawable = glz_drawable; return ret; } #define MIN_GLZ_SIZE_FOR_ZLIB 100 -static inline int red_glz_compress_image(DisplayChannelClient *dcc, +int dcc_compress_image_glz(DisplayChannelClient *dcc, SpiceImage *dest, SpiceBitmap *src, Drawable *drawable, compress_send_data_t* o_comp_data) { DisplayChannel *display_channel = DCC_TO_DC(dcc); #ifdef COMPRESS_STAT - stat_time_t start_time = stat_now(display_channel->zlib_glz_stat.clock); + stat_time_t start_time = stat_now(display_channel->glz_stat.clock); #endif spice_assert(bitmap_fmt_is_rgb(src->format)); GlzData *glz_data = &dcc->glz_data; ZlibData *zlib_data; LzImageType type = MAP_BITMAP_FMT_TO_LZ_IMAGE_TYPE[src->format]; RedGlzDrawable *glz_drawable; GlzDrawableInstanceItem *glz_drawable_instance; int glz_size; int zlib_size; glz_data->data.bufs_tail = compress_buf_new(); glz_data->data.bufs_head = glz_data->data.bufs_tail; glz_data->data.dcc = dcc; - glz_drawable = red_display_get_glz_drawable(dcc, drawable); - glz_drawable_instance = red_display_add_glz_drawable_instance(glz_drawable); + glz_drawable = get_glz_drawable(dcc, drawable); + glz_drawable_instance = add_glz_drawable_instance(glz_drawable); glz_data->data.u.lines_data.chunks = src->data; glz_data->data.u.lines_data.stride = src->stride; glz_data->data.u.lines_data.next = 0; glz_data->data.u.lines_data.reverse = 0; glz_size = glz_encode(dcc->glz, type, src->x, src->y, (src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN), NULL, 0, src->stride, glz_data->data.bufs_head->buf.bytes, sizeof(glz_data->data.bufs_head->buf), @@ -442,21 +442,21 @@ glz: dest->descriptor.type = SPICE_IMAGE_TYPE_GLZ_RGB; dest->u.lz_rgb.data_size = glz_size; o_comp_data->comp_buf = glz_data->data.bufs_head; o_comp_data->comp_buf_size = glz_size; return TRUE; } -static inline int red_lz_compress_image(DisplayChannelClient *dcc, +int dcc_compress_image_lz(DisplayChannelClient *dcc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data, uint32_t group_id) { LzData *lz_data = &dcc->lz_data; LzContext *lz = dcc->lz; LzImageType type = MAP_BITMAP_FMT_TO_LZ_IMAGE_TYPE[src->format]; int size; // size of the compressed data #ifdef COMPRESS_STAT stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->lz_stat.clock); @@ -502,48 +502,48 @@ * (see fill_mask) */ spice_assert(src->palette); dest->descriptor.type = SPICE_IMAGE_TYPE_LZ_PLT; dest->u.lz_plt.data_size = size; dest->u.lz_plt.flags = src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN; dest->u.lz_plt.palette = src->palette; dest->u.lz_plt.palette_id = src->palette->unique; o_comp_data->comp_buf = lz_data->data.bufs_head; o_comp_data->comp_buf_size = size; - fill_palette(dcc, dest->u.lz_plt.palette, &(dest->u.lz_plt.flags)); + dcc_palette_cache_palette(dcc, dest->u.lz_plt.palette, &(dest->u.lz_plt.flags)); o_comp_data->lzplt_palette = dest->u.lz_plt.palette; } stat_compress_add(&DCC_TO_DC(dcc)->lz_stat, start_time, src->stride * src->y, o_comp_data->comp_buf_size); return TRUE; } -static int red_jpeg_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, +int dcc_compress_image_jpeg(DisplayChannelClient *dcc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data, uint32_t group_id) { JpegData *jpeg_data = &dcc->jpeg_data; LzData *lz_data = &dcc->lz_data; JpegEncoderContext *jpeg = dcc->jpeg; LzContext *lz = dcc->lz; volatile JpegEncoderImageType jpeg_in_type; int jpeg_size = 0; volatile int has_alpha = FALSE; int alpha_lz_size = 0; int comp_head_filled; int comp_head_left; int stride; uint8_t *lz_out_start_byte; #ifdef COMPRESS_STAT - stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->jpeg_alpha_stat.clock); + stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->jpeg_stat.clock); #endif switch (src->format) { case SPICE_BITMAP_FMT_16BIT: jpeg_in_type = JPEG_IMAGE_TYPE_RGB16; break; case SPICE_BITMAP_FMT_24BIT: jpeg_in_type = JPEG_IMAGE_TYPE_BGR24; break; case SPICE_BITMAP_FMT_32BIT: jpeg_in_type = JPEG_IMAGE_TYPE_BGRX32; @@ -643,30 +643,31 @@ o_comp_data->comp_buf = jpeg_data->data.bufs_head; o_comp_data->comp_buf_size = jpeg_size + alpha_lz_size; o_comp_data->is_lossy = TRUE; stat_compress_add(&DCC_TO_DC(dcc)->jpeg_alpha_stat, start_time, src->stride * src->y, o_comp_data->comp_buf_size); return TRUE; } #ifdef USE_LZ4 -static int red_lz4_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, +int dcc_compress_image_lz4(DisplayChannelClient *dcc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data, uint32_t group_id) { + DisplayChannel *display_channel = DCC_TO_DC(dcc); Lz4Data *lz4_data = &dcc->lz4_data; Lz4EncoderContext *lz4 = dcc->lz4; int lz4_size = 0; #ifdef COMPRESS_STAT - stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->lz4_stat.clock); + stat_time_t start_time = stat_now(display_channel->lz4_stat.clock); #endif lz4_data->data.bufs_tail = compress_buf_new(); lz4_data->data.bufs_head = lz4_data->data.bufs_tail; if (!lz4_data->data.bufs_head) { spice_warning("failed to allocate compress buffer"); return FALSE; } @@ -683,44 +684,43 @@ } if (src->data->flags & SPICE_CHUNKS_FLAGS_UNSTABLE) { spice_chunks_linearize(src->data); } lz4_data->data.u.lines_data.chunks = src->data; lz4_data->data.u.lines_data.stride = src->stride; lz4_data->data.u.lines_data.next = 0; lz4_data->data.u.lines_data.reverse = 0; - /* fixme remove? lz4_data->usr.more_lines = lz4_usr_more_lines; */ lz4_size = lz4_encode(lz4, src->y, src->stride, lz4_data->data.bufs_head->buf.bytes, sizeof(lz4_data->data.bufs_head->buf), src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN, src->format); // the compressed buffer is bigger than the original data if (lz4_size > (src->y * src->stride)) { longjmp(lz4_data->data.jmp_env, 1); } dest->descriptor.type = SPICE_IMAGE_TYPE_LZ4; dest->u.lz4.data_size = lz4_size; o_comp_data->comp_buf = lz4_data->data.bufs_head; o_comp_data->comp_buf_size = lz4_size; - stat_compress_add(&DCC_TO_DC(dcc)->lz4_stat, start_time, src->stride * src->y, + stat_compress_add(&display_channel->lz4_stat, start_time, src->stride * src->y, o_comp_data->comp_buf_size); return TRUE; } #endif -static inline int red_quic_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, +int dcc_compress_image_quic(DisplayChannelClient *dcc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data, uint32_t group_id) { QuicData *quic_data = &dcc->quic_data; QuicContext *quic = dcc->quic; volatile QuicImageType type; int size, stride; #ifdef COMPRESS_STAT stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->quic_stat.clock); @@ -786,21 +786,21 @@ o_comp_data->comp_buf = quic_data->data.bufs_head; o_comp_data->comp_buf_size = size << 2; stat_compress_add(&DCC_TO_DC(dcc)->quic_stat, start_time, src->stride * src->y, o_comp_data->comp_buf_size); return TRUE; } #define MIN_SIZE_TO_COMPRESS 54 #define MIN_DIMENSION_TO_QUIC 3 -static inline int red_compress_image(DisplayChannelClient *dcc, +int dcc_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, SpiceBitmap *src, Drawable *drawable, int can_lossy, compress_send_data_t* o_comp_data) { DisplayChannel *display_channel = DCC_TO_DC(dcc); SpiceImageCompression image_compression = dcc->image_compression; int quic_compress = FALSE; if ((image_compression == SPICE_IMAGE_COMPRESSION_OFF) || ((src->y * src->stride) < MIN_SIZE_TO_COMPRESS)) { // TODO: change the size cond @@ -847,25 +847,25 @@ if (quic_compress) { #ifdef COMPRESS_DEBUG spice_info("QUIC compress"); #endif // if bitmaps is picture-like, compress it using jpeg if (can_lossy && display_channel->enable_jpeg && ((image_compression == SPICE_IMAGE_COMPRESSION_AUTO_LZ) || (image_compression == SPICE_IMAGE_COMPRESSION_AUTO_GLZ))) { // if we use lz for alpha, the stride can't be extra if (src->format != SPICE_BITMAP_FMT_RGBA || !bitmap_has_extra_stride(src)) { - return red_jpeg_compress_image(dcc, dest, + return dcc_compress_image_jpeg(dcc, dest, src, o_comp_data, drawable->group_id); } } - return red_quic_compress_image(dcc, dest, + return dcc_compress_image_quic(dcc, dest, src, o_comp_data, drawable->group_id); } else { int glz; int ret; if ((image_compression == SPICE_IMAGE_COMPRESSION_AUTO_GLZ) || (image_compression == SPICE_IMAGE_COMPRESSION_GLZ)) { glz = bitmap_fmt_has_graduality(src->format) && ( (src->x * src->y) < glz_enc_dictionary_get_size( dcc->glz_dict->dict)); } else if ((image_compression == SPICE_IMAGE_COMPRESSION_AUTO_LZ) || @@ -874,77 +874,76 @@ glz = FALSE; } else { spice_error("invalid image compression type %u", image_compression); return FALSE; } if (glz) { /* using the global dictionary only if it is not frozen */ pthread_rwlock_rdlock(&dcc->glz_dict->encode_lock); if (!dcc->glz_dict->migrate_freeze) { - ret = red_glz_compress_image(dcc, + ret = dcc_compress_image_glz(dcc, dest, src, drawable, o_comp_data); } else { glz = FALSE; } pthread_rwlock_unlock(&dcc->glz_dict->encode_lock); } if (!glz) { #ifdef USE_LZ4 if (image_compression == SPICE_IMAGE_COMPRESSION_LZ4 && bitmap_fmt_is_rgb(src->format) && red_channel_client_test_remote_cap(&dcc->common.base, SPICE_DISPLAY_CAP_LZ4_COMPRESSION)) { - ret = red_lz4_compress_image(dcc, dest, src, o_comp_data, + ret = dcc_compress_image_lz4(dcc, dest, src, o_comp_data, drawable->group_id); } else #endif - ret = red_lz_compress_image(dcc, dest, src, o_comp_data, + ret = dcc_compress_image_lz(dcc, dest, src, o_comp_data, drawable->group_id); #ifdef COMPRESS_DEBUG spice_info("LZ LOCAL compress"); #endif } #ifdef COMPRESS_DEBUG else { spice_info("LZ global compress fmt=%d", src->format); } #endif return ret; } } #define CLIENT_PALETTE_CACHE #include "cache_item.tmpl.c" #undef CLIENT_PALETTE_CACHE -static inline void fill_palette(DisplayChannelClient *dcc, - SpicePalette *palette, +void dcc_palette_cache_palette(DisplayChannelClient *dcc, SpicePalette *palette, uint8_t *flags) { if (palette == NULL) { return; } if (palette->unique) { if (red_palette_cache_find(dcc, palette->unique)) { *flags |= SPICE_BITMAP_FLAGS_PAL_FROM_CACHE; return; } if (red_palette_cache_add(dcc, palette->unique, 1)) { *flags |= SPICE_BITMAP_FLAGS_PAL_CACHE_ME; } } } -static void red_reset_palette_cache(DisplayChannelClient *dcc) +void dcc_palette_cache_reset(DisplayChannelClient *dcc) { red_palette_cache_reset(dcc, CLIENT_PALETTE_CACHE_SIZE); } /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* Copyright (C) 2009-2015 Red Hat, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -1043,20 +1042,22 @@ Ring glz_drawables_inst_to_free; // list of instances to be freed pthread_mutex_t glz_drawables_inst_to_free_lock; uint8_t surface_client_created[NUM_SURFACES]; QRegion surface_client_lossy_region[NUM_SURFACES]; StreamAgent stream_agents[NUM_STREAMS]; int use_mjpeg_encoder_rate_control; uint32_t streams_max_latency; uint64_t streams_max_bit_rate; + + uint32_t glz_drawable_count; }; #define DCC_TO_WORKER(dcc) \ (SPICE_CONTAINEROF((dcc)->common.base.channel, CommonChannel, base)->worker) #define DCC_TO_DC(dcc) \ SPICE_CONTAINEROF((dcc)->common.base.channel, DisplayChannel, common.base) #define RCC_TO_DCC(rcc) SPICE_CONTAINEROF((rcc), DisplayChannelClient, common.base) typedef struct SurfaceCreateItem { SpiceMsgSurfaceCreate surface_create; @@ -1099,27 +1100,51 @@ Stream *stream); void dcc_create_surface (DisplayChannelClient *dcc, int surface_id); void dcc_push_surface_image (DisplayChannelClient *dcc, int surface_id); ImageItem * dcc_add_surface_area_image (DisplayChannelClient *dcc, int surface_id, SpiceRect *area, PipeItem *pos, int can_lossy); +void dcc_palette_cache_reset (DisplayChannelClient *dcc); +void dcc_palette_cache_palette (DisplayChannelClient *dcc, + SpicePalette *palette, + uint8_t *flags); + typedef struct compress_send_data_t { void* comp_buf; uint32_t comp_buf_size; SpicePalette *lzplt_palette; int is_lossy; } compress_send_data_t; +int dcc_compress_image (DisplayChannelClient *dcc, + SpiceImage *dest, SpiceBitmap *src, Drawable *drawable, + int can_lossy, + compress_send_data_t* o_comp_data); +int dcc_compress_image_glz (DisplayChannelClient *dcc, + SpiceImage *dest, SpiceBitmap *src, Drawable *drawable, + compress_send_data_t* o_comp_data); +int dcc_compress_image_lz (DisplayChannelClient *dcc, + SpiceImage *dest, SpiceBitmap *src, + compress_send_data_t* o_comp_data, uint32_t group_id); +int dcc_compress_image_jpeg (DisplayChannelClient *dcc, SpiceImage *dest, + SpiceBitmap *src, compress_send_data_t* o_comp_data, + uint32_t group_id); +int dcc_compress_image_quic (DisplayChannelClient *dcc, SpiceImage *dest, + SpiceBitmap *src, compress_send_data_t* o_comp_data, + uint32_t group_id); +int dcc_compress_image_lz4 (DisplayChannelClient *dcc, SpiceImage *dest, + SpiceBitmap *src, compress_send_data_t* o_comp_data, + uint32_t group_id); #endif /* DCC_H_ */ /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* Copyright (C) 2009-2015 Red Hat, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. @@ -1568,21 +1593,21 @@ SpiceRop3 rop3; SpiceStroke stroke; SpiceText text; SpiceBlackness blackness; SpiceInvers invers; SpiceWhiteness whiteness; SpiceComposite composite; } u; } RedDrawable; -static RedDrawable *red_drawable_ref(RedDrawable *drawable) +static inline RedDrawable *red_drawable_ref(RedDrawable *drawable) { drawable->refs++; return drawable; } typedef struct RedUpdateCmd { QXLReleaseInfo *release_info; SpiceRect area; uint32_t update_id; uint32_t surface_id; @@ -1729,24 +1754,20 @@ #include "tree.h" //#define COMPRESS_STAT //#define DUMP_BITMAP //#define COMPRESS_DEBUG #define CMD_RING_POLL_TIMEOUT 10 //milli #define CMD_RING_POLL_RETRIES 200 #define DISPLAY_CLIENT_SHORT_TIMEOUT 15000000000ULL //nano -#define DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT 10000000000ULL //nano, 10 sec -#define DISPLAY_CLIENT_RETRY_INTERVAL 10000 //micro - -#define DISPLAY_FREE_LIST_DEFAULT_SIZE 128 #define VALIDATE_SURFACE_RET(worker, surface_id) \ if (!validate_surface(worker, surface_id)) { \ rendering_incorrect(__func__); \ return; \ } #define VALIDATE_SURFACE_RETVAL(worker, surface_id, ret) \ if (!validate_surface(worker, surface_id)) { \ rendering_incorrect(__func__); \ @@ -1800,21 +1821,20 @@ struct SpiceWatch watches[MAX_EVENT_SOURCES]; unsigned int event_timeout; DisplayChannel *display_channel; uint32_t display_poll_tries; CursorChannel *cursor_channel; uint32_t cursor_poll_tries; uint32_t red_drawable_count; - uint32_t glz_drawable_count; uint32_t bits_unique; RedMemSlotInfo mem_slots; SpiceImageCompression image_compression; spice_wan_compression_t jpeg_state; spice_wan_compression_t zlib_glz_state; uint32_t process_commands_generation; #ifdef RED_STATISTICS @@ -3556,22 +3576,24 @@ #define RED_RELEASE_BUNCH_SIZE 64 static void red_free_some(RedWorker *worker) { DisplayChannel *display = worker->display_channel; int n = 0; DisplayChannelClient *dcc; RingItem *item, *next; +#if FIXME spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", display->drawable_count, worker->red_drawable_count, worker->glz_drawable_count); +#endif FOREACH_DCC(worker->display_channel, item, next, dcc) { GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL; if (glz_dict) { // encoding using the dictionary is prevented since the following operations might // change the dictionary pthread_rwlock_wrlock(&glz_dict->encode_lock); n = red_display_free_some_independent_glz_drawables(dcc); } } @@ -3703,21 +3725,21 @@ if (ring_is_empty(&glz_drawable->instances)) { spice_assert(!glz_drawable->instances_count); Drawable *drawable = glz_drawable->drawable; if (drawable) { ring_remove(&glz_drawable->drawable_link); } red_drawable_unref(worker, glz_drawable->red_drawable, glz_drawable->group_id); - worker->glz_drawable_count--; + dcc->glz_drawable_count--; if (ring_item_is_linked(&glz_drawable->link)) { ring_remove(&glz_drawable->link); } free(glz_drawable); } } static void red_display_handle_glz_drawables_to_free(DisplayChannelClient* dcc) { RingItem *ring_link; @@ -4044,31 +4066,31 @@ } case SPICE_IMAGE_TYPE_BITMAP: { SpiceBitmap *bitmap = &image.u.bitmap; #ifdef DUMP_BITMAP dump_bitmap(&simage->u.bitmap); #endif /* Images must be added to the cache only after they are compressed in order to prevent starvation in the client between pixmap_cache and global dictionary (in cases of multiple monitors) */ if (reds_stream_get_family(rcc->stream) == AF_UNIX || - !red_compress_image(dcc, &image, &simage->u.bitmap, + !dcc_compress_image(dcc, &image, &simage->u.bitmap, drawable, can_lossy, &comp_send_data)) { SpicePalette *palette; red_display_add_image_to_pixmap_cache(rcc, simage, &image, FALSE); *bitmap = simage->u.bitmap; bitmap->flags = bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN; palette = bitmap->palette; - fill_palette(dcc, palette, &bitmap->flags); + dcc_palette_cache_palette(dcc, palette, &bitmap->flags); spice_marshall_Image(m, &image, &bitmap_palette_out, &lzplt_palette_out); spice_assert(lzplt_palette_out == NULL); if (bitmap_palette_out && palette) { spice_marshall_Palette(bitmap_palette_out, palette); } spice_marshaller_add_ref_chunks(m, bitmap->data); pthread_mutex_unlock(&dcc->pixmap_cache->lock); @@ -6022,38 +6044,38 @@ // if we use lz for alpha, the stride can't be extra lossy_comp = display_channel->enable_jpeg && item->can_lossy; quic_comp = TRUE; } } } else if (comp_mode == SPICE_IMAGE_COMPRESSION_QUIC) { quic_comp = TRUE; } if (lossy_comp) { - comp_succeeded = red_jpeg_compress_image(dcc, &red_image, + comp_succeeded = dcc_compress_image_jpeg(dcc, &red_image, &bitmap, &comp_send_data, worker->mem_slots.internal_groupslot_id); } else if (quic_comp) { - comp_succeeded = red_quic_compress_image(dcc, &red_image, &bitmap, + comp_succeeded = dcc_compress_image_quic(dcc, &red_image, &bitmap, &comp_send_data, worker->mem_slots.internal_groupslot_id); #ifdef USE_LZ4 } else if (comp_mode == SPICE_IMAGE_COMPRESSION_LZ4 && bitmap_fmt_is_rgb(bitmap.format) && red_channel_client_test_remote_cap(&dcc->common.base, SPICE_DISPLAY_CAP_LZ4_COMPRESSION)) { - comp_succeeded = red_lz4_compress_image(dcc, &red_image, &bitmap, + comp_succeeded = dcc_compress_image_lz4(dcc, &red_image, &bitmap, &comp_send_data, worker->mem_slots.internal_groupslot_id); #endif } else if (comp_mode != SPICE_IMAGE_COMPRESSION_OFF) { - comp_succeeded = red_lz_compress_image(dcc, &red_image, &bitmap, + comp_succeeded = dcc_compress_image_lz(dcc, &red_image, &bitmap, &comp_send_data, worker->mem_slots.internal_groupslot_id); } surface_lossy_region = &dcc->surface_client_lossy_region[item->surface_id]; if (comp_succeeded) { spice_marshall_Image(src_bitmap_out, &red_image, &bitmap_palette_out, &lzplt_palette_out); marshaller_add_compressed(src_bitmap_out, @@ -6287,21 +6309,21 @@ case PIPE_ITEM_TYPE_IMAGE: red_marshall_image(rcc, m, (ImageItem *)pipe_item); break; case PIPE_ITEM_TYPE_PIXMAP_SYNC: display_channel_marshall_pixmap_sync(rcc, m); break; case PIPE_ITEM_TYPE_PIXMAP_RESET: display_channel_marshall_reset_cache(rcc, m); break; case PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE: - red_reset_palette_cache(dcc); + dcc_palette_cache_reset(dcc); red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES, NULL); break; case PIPE_ITEM_TYPE_CREATE_SURFACE: { SurfaceCreateItem *surface_create = SPICE_CONTAINEROF(pipe_item, SurfaceCreateItem, pipe_item); red_marshall_surface_create(rcc, m, &surface_create->surface_create); break; } case PIPE_ITEM_TYPE_DESTROY_SURFACE: { SurfaceDestroyItem *surface_destroy = SPICE_CONTAINEROF(pipe_item, SurfaceDestroyItem, @@ -6356,29 +6378,31 @@ } spice_info(NULL); common = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base); worker = common->worker; display = (DisplayChannel *)rcc->channel; spice_assert(display == worker->display_channel); display_channel_compress_stats_print(display); pixmap_cache_unref(dcc->pixmap_cache); dcc->pixmap_cache = NULL; red_release_glz(dcc); - red_reset_palette_cache(dcc); + dcc_palette_cache_reset(dcc); free(dcc->send_data.stream_outbuf); free(dcc->send_data.free_list.res); dcc_destroy_stream_agents(dcc); // this was the last channel client +#if FIXME spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", display->drawable_count, worker->red_drawable_count, worker->glz_drawable_count); +#endif } void red_disconnect_all_display_TODO_remove_me(RedChannel *channel) { // TODO: we need to record the client that actually causes the timeout. So // we need to check the locations of the various pipe heads when counting, // and disconnect only those/that. if (!channel) { return; } @@ -7940,48 +7964,52 @@ { RedWorker *worker = opaque; stat_inc_counter(worker->wakeup_counter, 1); red_dispatcher_clear_pending(worker->red_dispatcher, RED_DISPATCHER_PENDING_WAKEUP); } static void handle_dev_oom(void *opaque, void *payload) { RedWorker *worker = opaque; - DisplayChannel *display = worker->display_channel; - - RedChannel *display_red_channel = &worker->display_channel->common.base; int ring_is_empty; - spice_assert(worker->running); + spice_return_if_fail(worker->running); // streams? but without streams also leak + +#if FIXME + DisplayChannel *display = worker->display_channel; + RedChannel *display_red_channel = &worker->display_channel->common.base; spice_debug("OOM1 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes %u", display->drawable_count, worker->red_drawable_count, worker->glz_drawable_count, display->current_size, worker->display_channel ? red_channel_sum_pipes_size(display_red_channel) : 0); +#endif while (red_process_commands(worker, MAX_PIPE_SIZE, &ring_is_empty)) { red_channel_push(&worker->display_channel->common.base); } if (worker->qxl->st->qif->flush_resources(worker->qxl) == 0) { red_free_some(worker); worker->qxl->st->qif->flush_resources(worker->qxl); } +#if FIXME spice_debug("OOM2 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes %u", display->drawable_count, worker->red_drawable_count, worker->glz_drawable_count, display->current_size, worker->display_channel ? red_channel_sum_pipes_size(display_red_channel) : 0); +#endif red_dispatcher_clear_pending(worker->red_dispatcher, RED_DISPATCHER_PENDING_OOM); } static void handle_dev_reset_cursor(void *opaque, void *payload) { RedWorker *worker = opaque; cursor_channel_reset(worker->cursor_channel); } _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel