/* 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. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include "display-channel.h" void display_channel_compress_stats_reset(DisplayChannel *display_channel) { spice_return_if_fail(display_channel); #ifdef COMPRESS_STAT stat_reset(&worker->display_channel->quic_stat); stat_reset(&worker->display_channel->lz_stat); stat_reset(&worker->display_channel->glz_stat); stat_reset(&worker->display_channel->jpeg_stat); stat_reset(&worker->display_channel->zlib_glz_stat); stat_reset(&worker->display_channel->jpeg_alpha_stat); stat_reset(&worker->display_channel->lz4_stat); #endif } void display_channel_compress_stats_print(const DisplayChannel *display_channel) { spice_return_if_fail(display_channel); #ifdef COMPRESS_STAT uint64_t glz_enc_size; glz_enc_size = display_channel->enable_zlib_glz_wrap ? display_channel->zlib_glz_stat.comp_size : display_channel->glz_stat.comp_size; spice_info("==> Compression stats for display %u", display_channel->common.id); spice_info("Method \t count \torig_size(MB)\tenc_size(MB)\tenc_time(s)"); spice_info("QUIC \t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->quic_stat.count, stat_byte_to_mega(display_channel->quic_stat.orig_size), stat_byte_to_mega(display_channel->quic_stat.comp_size), stat_cpu_time_to_sec(display_channel->quic_stat.total) ); spice_info("GLZ \t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->glz_stat.count, stat_byte_to_mega(display_channel->glz_stat.orig_size), stat_byte_to_mega(display_channel->glz_stat.comp_size), stat_cpu_time_to_sec(display_channel->glz_stat.total) ); spice_info("ZLIB GLZ \t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->zlib_glz_stat.count, stat_byte_to_mega(display_channel->zlib_glz_stat.orig_size), stat_byte_to_mega(display_channel->zlib_glz_stat.comp_size), stat_cpu_time_to_sec(display_channel->zlib_glz_stat.total) ); spice_info("LZ \t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->lz_stat.count, stat_byte_to_mega(display_channel->lz_stat.orig_size), stat_byte_to_mega(display_channel->lz_stat.comp_size), stat_cpu_time_to_sec(display_channel->lz_stat.total) ); spice_info("JPEG \t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->jpeg_stat.count, stat_byte_to_mega(display_channel->jpeg_stat.orig_size), stat_byte_to_mega(display_channel->jpeg_stat.comp_size), stat_cpu_time_to_sec(display_channel->jpeg_stat.total) ); spice_info("JPEG-RGBA\t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->jpeg_alpha_stat.count, stat_byte_to_mega(display_channel->jpeg_alpha_stat.orig_size), stat_byte_to_mega(display_channel->jpeg_alpha_stat.comp_size), stat_cpu_time_to_sec(display_channel->jpeg_alpha_stat.total) ); spice_info("LZ4 \t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->lz4_stat.count, stat_byte_to_mega(display_channel->lz4_stat.orig_size), stat_byte_to_mega(display_channel->lz4_stat.comp_size), stat_cpu_time_to_sec(display_channel->lz4_stat.total) ); spice_info("-------------------------------------------------------------------"); spice_info("Total \t%8d\t%13.2f\t%12.2f\t%12.2f", display_channel->lz_stat.count + display_channel->glz_stat.count + display_channel->quic_stat.count + display_channel->jpeg_stat.count + display_channel->lz4_stat.count + display_channel->jpeg_alpha_stat.count, stat_byte_to_mega(display_channel->lz_stat.orig_size + display_channel->glz_stat.orig_size + display_channel->quic_stat.orig_size + display_channel->jpeg_stat.orig_size + display_channel->lz4_stat.orig_size + display_channel->jpeg_alpha_stat.orig_size), stat_byte_to_mega(display_channel->lz_stat.comp_size + glz_enc_size + display_channel->quic_stat.comp_size + display_channel->jpeg_stat.comp_size + display_channel->lz4_stat.comp_size + display_channel->jpeg_alpha_stat.comp_size), stat_cpu_time_to_sec(display_channel->lz_stat.total + display_channel->glz_stat.total + display_channel->zlib_glz_stat.total + display_channel->quic_stat.total + display_channel->jpeg_stat.total + display_channel->lz4_stat.total + display_channel->jpeg_alpha_stat.total) ); #endif } DisplayChannelClient *dcc_new(DisplayChannel *display, RedClient *client, RedsStream *stream, int mig_target, uint32_t *common_caps, int num_common_caps, uint32_t *caps, int num_caps) { DisplayChannelClient *dcc; dcc = (DisplayChannelClient*)common_channel_new_client( (CommonChannel *)display, sizeof(DisplayChannelClient), client, stream, mig_target, TRUE, common_caps, num_common_caps, caps, num_caps); spice_return_val_if_fail(dcc, NULL); ring_init(&dcc->palette_cache_lru); dcc->palette_cache_available = CLIENT_PALETTE_CACHE_SIZE; return dcc; } MonitorsConfig* monitors_config_ref(MonitorsConfig *monitors_config) { monitors_config->refs++; return monitors_config; } void monitors_config_unref(MonitorsConfig *monitors_config) { if (!monitors_config) { return; } if (--monitors_config->refs != 0) { return; } spice_debug("freeing monitors config"); free(monitors_config); } static void monitors_config_debug(MonitorsConfig *mc) { int i; spice_debug("monitors config count:%d max:%d", mc->count, mc->max_allowed); for (i = 0; i < mc->count; i++) spice_debug("+%d+%d %dx%d", mc->heads[i].x, mc->heads[i].y, mc->heads[i].width, mc->heads[i].height); } MonitorsConfig* monitors_config_new(QXLHead *heads, ssize_t nheads, ssize_t max) { MonitorsConfig *mc; mc = spice_malloc(sizeof(MonitorsConfig) + nheads * sizeof(QXLHead)); mc->refs = 1; mc->count = nheads; mc->max_allowed = max; memcpy(mc->heads, heads, nheads * sizeof(QXLHead)); monitors_config_debug(mc); return mc; } static MonitorsConfigItem *monitors_config_item_new(RedChannel* channel, MonitorsConfig *monitors_config) { MonitorsConfigItem *mci; mci = (MonitorsConfigItem *)spice_malloc(sizeof(*mci)); mci->monitors_config = monitors_config; red_channel_pipe_item_init(channel, &mci->pipe_item, PIPE_ITEM_TYPE_MONITORS_CONFIG); return mci; } static inline void red_monitors_config_item_add(DisplayChannelClient *dcc) { DisplayChannel *dc = DCC_TO_DC(dcc); MonitorsConfigItem *mci; mci = monitors_config_item_new(dcc->common.base.channel, monitors_config_ref(dc->monitors_config)); red_channel_client_pipe_add(&dcc->common.base, &mci->pipe_item); } void dcc_push_monitors_config(DisplayChannelClient *dcc) { MonitorsConfig *monitors_config = DCC_TO_DC(dcc)->monitors_config; if (monitors_config == NULL) { spice_warning("monitors_config is NULL"); return; } if (!red_channel_client_test_remote_cap(&dcc->common.base, SPICE_DISPLAY_CAP_MONITORS_CONFIG)) { return; } red_monitors_config_item_add(dcc); red_channel_client_push(&dcc->common.base); }