mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-31 02:41:52 +00:00
worker: start a DisplayChannelClient unit
Signed-off-by: Marc-André Lureau <marcandre.lureau@gmail.com> Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
This commit is contained in:
parent
806433a3bd
commit
85920bb2e9
@ -138,6 +138,9 @@ libspice_server_la_SOURCES = \
|
||||
utils.h \
|
||||
stream.c \
|
||||
stream.h \
|
||||
dcc.c \
|
||||
dcc.h \
|
||||
display-limits.h \
|
||||
dcc-encoders.c \
|
||||
dcc-encoders.h \
|
||||
$(NULL)
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "dcc-encoders.h"
|
||||
#include "display-channel.h"
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#ifndef DCC_ENCODERS_H_
|
||||
#define DCC_ENCODERS_H_
|
||||
|
||||
#include <setjmp.h>
|
||||
#include "common/marshaller.h"
|
||||
#include "common/quic.h"
|
||||
#include "red_channel.h"
|
||||
|
||||
141
server/dcc.c
Normal file
141
server/dcc.c
Normal file
@ -0,0 +1,141 @@
|
||||
/* -*- 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.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "dcc.h"
|
||||
#include "display-channel.h"
|
||||
|
||||
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,
|
||||
SpiceImageCompression image_compression,
|
||||
spice_wan_compression_t jpeg_state,
|
||||
spice_wan_compression_t zlib_glz_state)
|
||||
|
||||
{
|
||||
DisplayChannelClient *dcc;
|
||||
|
||||
dcc = (DisplayChannelClient*)common_channel_new_client(
|
||||
COMMON_CHANNEL(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;
|
||||
dcc->image_compression = image_compression;
|
||||
dcc->jpeg_state = jpeg_state;
|
||||
dcc->zlib_glz_state = zlib_glz_state;
|
||||
// TODO: tune quality according to bandwidth
|
||||
dcc->jpeg_quality = 85;
|
||||
|
||||
dcc_encoders_init(dcc);
|
||||
|
||||
return dcc;
|
||||
}
|
||||
|
||||
void dcc_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent)
|
||||
{
|
||||
StreamClipItem *item = stream_clip_item_new(dcc, agent);
|
||||
int n_rects;
|
||||
|
||||
item->clip_type = SPICE_CLIP_TYPE_RECTS;
|
||||
|
||||
n_rects = pixman_region32_n_rects(&agent->clip);
|
||||
item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect), sizeof(SpiceClipRects));
|
||||
item->rects->num_rects = n_rects;
|
||||
region_ret_rects(&agent->clip, item->rects->rects, n_rects);
|
||||
|
||||
red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), (PipeItem *)item);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void dcc_push_monitors_config(DisplayChannelClient *dcc)
|
||||
{
|
||||
DisplayChannel *dc = DCC_TO_DC(dcc);
|
||||
MonitorsConfig *monitors_config = dc->monitors_config;
|
||||
MonitorsConfigItem *mci;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
red_channel_client_push(&dcc->common.base);
|
||||
}
|
||||
|
||||
static SurfaceDestroyItem *surface_destroy_item_new(RedChannel *channel,
|
||||
uint32_t surface_id)
|
||||
{
|
||||
SurfaceDestroyItem *destroy;
|
||||
|
||||
destroy = spice_malloc(sizeof(SurfaceDestroyItem));
|
||||
destroy->surface_destroy.surface_id = surface_id;
|
||||
red_channel_pipe_item_init(channel, &destroy->pipe_item,
|
||||
PIPE_ITEM_TYPE_DESTROY_SURFACE);
|
||||
|
||||
return destroy;
|
||||
}
|
||||
|
||||
void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id)
|
||||
{
|
||||
DisplayChannel *display;
|
||||
RedChannel *channel;
|
||||
SurfaceDestroyItem *destroy;
|
||||
|
||||
if (!dcc) {
|
||||
return;
|
||||
}
|
||||
|
||||
display = DCC_TO_DC(dcc);
|
||||
channel = RED_CHANNEL(display);
|
||||
|
||||
if (COMMON_CHANNEL(display)->during_target_migrate ||
|
||||
!dcc->surface_client_created[surface_id]) {
|
||||
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);
|
||||
}
|
||||
134
server/dcc.h
Normal file
134
server/dcc.h
Normal file
@ -0,0 +1,134 @@
|
||||
/* -*- 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.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DCC_H_
|
||||
# define DCC_H_
|
||||
|
||||
#include "red_worker.h"
|
||||
#include "pixmap-cache.h"
|
||||
#include "cache-item.h"
|
||||
#include "dcc-encoders.h"
|
||||
#include "stream.h"
|
||||
#include "display-limits.h"
|
||||
|
||||
#define PALETTE_CACHE_HASH_SHIFT 8
|
||||
#define PALETTE_CACHE_HASH_SIZE (1 << PALETTE_CACHE_HASH_SHIFT)
|
||||
#define PALETTE_CACHE_HASH_MASK (PALETTE_CACHE_HASH_SIZE - 1)
|
||||
#define PALETTE_CACHE_HASH_KEY(id) ((id) & PALETTE_CACHE_HASH_MASK)
|
||||
#define CLIENT_PALETTE_CACHE_SIZE 128
|
||||
|
||||
/* Each drawable can refer to at most 3 images: src, brush and mask */
|
||||
#define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3
|
||||
|
||||
typedef struct WaitForChannels {
|
||||
SpiceMsgWaitForChannels header;
|
||||
SpiceWaitForChannel buf[MAX_CACHE_CLIENTS];
|
||||
} WaitForChannels;
|
||||
|
||||
typedef struct FreeList {
|
||||
int res_size;
|
||||
SpiceResourceList *res;
|
||||
uint64_t sync[MAX_CACHE_CLIENTS];
|
||||
WaitForChannels wait;
|
||||
} FreeList;
|
||||
|
||||
struct DisplayChannelClient {
|
||||
CommonChannelClient common;
|
||||
SpiceImageCompression image_compression;
|
||||
spice_wan_compression_t jpeg_state;
|
||||
spice_wan_compression_t zlib_glz_state;
|
||||
int jpeg_quality;
|
||||
int zlib_level;
|
||||
|
||||
QuicData quic_data;
|
||||
QuicContext *quic;
|
||||
LzData lz_data;
|
||||
LzContext *lz;
|
||||
JpegData jpeg_data;
|
||||
JpegEncoderContext *jpeg;
|
||||
#ifdef USE_LZ4
|
||||
Lz4Data lz4_data;
|
||||
Lz4EncoderContext *lz4;
|
||||
#endif
|
||||
ZlibData zlib_data;
|
||||
ZlibEncoder *zlib;
|
||||
|
||||
int expect_init;
|
||||
|
||||
PixmapCache *pixmap_cache;
|
||||
uint32_t pixmap_cache_generation;
|
||||
int pending_pixmaps_sync;
|
||||
|
||||
CacheItem *palette_cache[PALETTE_CACHE_HASH_SIZE];
|
||||
Ring palette_cache_lru;
|
||||
long palette_cache_available;
|
||||
uint32_t palette_cache_items;
|
||||
|
||||
struct {
|
||||
uint32_t stream_outbuf_size;
|
||||
uint8_t *stream_outbuf; // caution stream buffer is also used as compress bufs!!!
|
||||
|
||||
FreeList free_list;
|
||||
uint64_t pixmap_cache_items[MAX_DRAWABLE_PIXMAP_CACHE_ITEMS];
|
||||
int num_pixmap_cache_items;
|
||||
} send_data;
|
||||
|
||||
/* global lz encoding entities */
|
||||
GlzSharedDictionary *glz_dict;
|
||||
GlzEncoderContext *glz;
|
||||
GlzData glz_data;
|
||||
|
||||
Ring glz_drawables; // all the living lz drawable, ordered by encoding time
|
||||
Ring glz_drawables_inst_to_free; // list of instances to be freed
|
||||
pthread_mutex_t glz_drawables_inst_to_free_lock;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
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,
|
||||
SpiceImageCompression image_compression,
|
||||
spice_wan_compression_t jpeg_state,
|
||||
spice_wan_compression_t zlib_glz_state);
|
||||
void dcc_push_monitors_config (DisplayChannelClient *dcc);
|
||||
void dcc_destroy_surface (DisplayChannelClient *dcc,
|
||||
uint32_t surface_id);
|
||||
void dcc_stream_agent_clip (DisplayChannelClient* dcc,
|
||||
StreamAgent *agent);
|
||||
void dcc_create_stream (DisplayChannelClient *dcc,
|
||||
Stream *stream);
|
||||
|
||||
#endif /* DCC_H_ */
|
||||
@ -135,53 +135,6 @@ void display_channel_compress_stats_print(const DisplayChannel *display_channel)
|
||||
#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,
|
||||
SpiceImageCompression image_compression,
|
||||
spice_wan_compression_t jpeg_state,
|
||||
spice_wan_compression_t zlib_glz_state)
|
||||
|
||||
{
|
||||
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;
|
||||
dcc->image_compression = image_compression;
|
||||
dcc->jpeg_state = jpeg_state;
|
||||
dcc->zlib_glz_state = zlib_glz_state;
|
||||
// todo: tune quality according to bandwidth
|
||||
dcc->jpeg_quality = 85;
|
||||
|
||||
dcc_encoders_init(dcc);
|
||||
|
||||
return dcc;
|
||||
}
|
||||
|
||||
void dcc_add_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent)
|
||||
{
|
||||
StreamClipItem *item = stream_clip_item_new(dcc, agent);
|
||||
int n_rects;
|
||||
|
||||
item->clip_type = SPICE_CLIP_TYPE_RECTS;
|
||||
|
||||
n_rects = pixman_region32_n_rects(&agent->clip);
|
||||
item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect), sizeof(SpiceClipRects));
|
||||
item->rects->num_rects = n_rects;
|
||||
region_ret_rects(&agent->clip, item->rects->rects, n_rects);
|
||||
|
||||
red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), (PipeItem *)item);
|
||||
}
|
||||
|
||||
MonitorsConfig* monitors_config_ref(MonitorsConfig *monitors_config)
|
||||
{
|
||||
monitors_config->refs++;
|
||||
@ -227,82 +180,6 @@ MonitorsConfig* monitors_config_new(QXLHead *heads, ssize_t nheads, ssize_t max)
|
||||
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 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);
|
||||
}
|
||||
|
||||
static SurfaceDestroyItem *surface_destroy_item_new(RedChannel *channel,
|
||||
uint32_t surface_id)
|
||||
{
|
||||
SurfaceDestroyItem *destroy;
|
||||
|
||||
destroy = spice_malloc(sizeof(SurfaceDestroyItem));
|
||||
destroy->surface_destroy.surface_id = surface_id;
|
||||
red_channel_pipe_item_init(channel, &destroy->pipe_item,
|
||||
PIPE_ITEM_TYPE_DESTROY_SURFACE);
|
||||
|
||||
return destroy;
|
||||
}
|
||||
|
||||
void dcc_push_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id)
|
||||
{
|
||||
DisplayChannel *display;
|
||||
RedChannel *channel;
|
||||
SurfaceDestroyItem *destroy;
|
||||
|
||||
if (!dcc) {
|
||||
return;
|
||||
}
|
||||
|
||||
display = DCC_TO_DC(dcc);
|
||||
channel = RED_CHANNEL(display);
|
||||
|
||||
if (COMMON_CHANNEL(display)->during_target_migrate ||
|
||||
!dcc->surface_client_created[surface_id]) {
|
||||
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);
|
||||
}
|
||||
|
||||
int display_channel_get_streams_timeout(DisplayChannel *display)
|
||||
{
|
||||
int timeout = INT_MAX;
|
||||
@ -395,7 +272,7 @@ void display_channel_surface_unref(DisplayChannel *display, uint32_t surface_id)
|
||||
region_destroy(&surface->draw_dirty_region);
|
||||
surface->context.canvas = NULL;
|
||||
FOREACH_DCC(display, link, next, dcc) {
|
||||
dcc_push_destroy_surface(dcc, surface_id);
|
||||
dcc_destroy_surface(dcc, surface_id);
|
||||
}
|
||||
|
||||
spice_warn_if(!ring_is_empty(&surface->depend_on_me));
|
||||
@ -442,7 +319,7 @@ static void streams_update_visible_region(DisplayChannel *display, Drawable *dra
|
||||
if (region_intersects(&agent->vis_region, &drawable->tree_item.base.rgn)) {
|
||||
region_exclude(&agent->vis_region, &drawable->tree_item.base.rgn);
|
||||
region_exclude(&agent->clip, &drawable->tree_item.base.rgn);
|
||||
dcc_add_stream_agent_clip(dcc, agent);
|
||||
dcc_stream_agent_clip(dcc, agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,32 +49,9 @@
|
||||
#include "utils.h"
|
||||
#include "tree.h"
|
||||
#include "stream.h"
|
||||
#include "dcc-encoders.h"
|
||||
#include "dcc.h"
|
||||
#include "display-limits.h"
|
||||
|
||||
#define PALETTE_CACHE_HASH_SHIFT 8
|
||||
#define PALETTE_CACHE_HASH_SIZE (1 << PALETTE_CACHE_HASH_SHIFT)
|
||||
#define PALETTE_CACHE_HASH_MASK (PALETTE_CACHE_HASH_SIZE - 1)
|
||||
#define PALETTE_CACHE_HASH_KEY(id) ((id) & PALETTE_CACHE_HASH_MASK)
|
||||
|
||||
#define CLIENT_PALETTE_CACHE_SIZE 128
|
||||
|
||||
/* Each drawable can refer to at most 3 images: src, brush and mask */
|
||||
#define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3
|
||||
|
||||
#define NUM_STREAMS 50
|
||||
#define NUM_SURFACES 10000
|
||||
|
||||
typedef struct WaitForChannels {
|
||||
SpiceMsgWaitForChannels header;
|
||||
SpiceWaitForChannel buf[MAX_CACHE_CLIENTS];
|
||||
} WaitForChannels;
|
||||
|
||||
typedef struct FreeList {
|
||||
int res_size;
|
||||
SpiceResourceList *res;
|
||||
uint64_t sync[MAX_CACHE_CLIENTS];
|
||||
WaitForChannels wait;
|
||||
} FreeList;
|
||||
|
||||
typedef struct DependItem {
|
||||
Drawable *drawable;
|
||||
@ -115,72 +92,6 @@ struct Drawable {
|
||||
SAFE_FOREACH(link, next, drawable, &(drawable)->pipes, dpi, LINK_TO_DPI(link))
|
||||
|
||||
|
||||
struct DisplayChannelClient {
|
||||
CommonChannelClient common;
|
||||
SpiceImageCompression image_compression;
|
||||
spice_wan_compression_t jpeg_state;
|
||||
spice_wan_compression_t zlib_glz_state;
|
||||
int jpeg_quality;
|
||||
int zlib_level;
|
||||
|
||||
QuicData quic_data;
|
||||
QuicContext *quic;
|
||||
LzData lz_data;
|
||||
LzContext *lz;
|
||||
JpegData jpeg_data;
|
||||
JpegEncoderContext *jpeg;
|
||||
#ifdef USE_LZ4
|
||||
Lz4Data lz4_data;
|
||||
Lz4EncoderContext *lz4;
|
||||
#endif
|
||||
ZlibData zlib_data;
|
||||
ZlibEncoder *zlib;
|
||||
|
||||
int expect_init;
|
||||
|
||||
PixmapCache *pixmap_cache;
|
||||
uint32_t pixmap_cache_generation;
|
||||
int pending_pixmaps_sync;
|
||||
|
||||
CacheItem *palette_cache[PALETTE_CACHE_HASH_SIZE];
|
||||
Ring palette_cache_lru;
|
||||
long palette_cache_available;
|
||||
uint32_t palette_cache_items;
|
||||
|
||||
struct {
|
||||
uint32_t stream_outbuf_size;
|
||||
uint8_t *stream_outbuf; // caution stream buffer is also used as compress bufs!!!
|
||||
|
||||
FreeList free_list;
|
||||
uint64_t pixmap_cache_items[MAX_DRAWABLE_PIXMAP_CACHE_ITEMS];
|
||||
int num_pixmap_cache_items;
|
||||
} send_data;
|
||||
|
||||
/* global lz encoding entities */
|
||||
GlzSharedDictionary *glz_dict;
|
||||
GlzEncoderContext *glz;
|
||||
GlzData glz_data;
|
||||
|
||||
Ring glz_drawables; // all the living lz drawable, ordered by encoding time
|
||||
Ring glz_drawables_inst_to_free; // list of instances to be freed
|
||||
pthread_mutex_t glz_drawables_inst_to_free_lock;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
enum {
|
||||
PIPE_ITEM_TYPE_DRAW = PIPE_ITEM_TYPE_COMMON_LAST,
|
||||
PIPE_ITEM_TYPE_IMAGE,
|
||||
@ -198,25 +109,6 @@ enum {
|
||||
PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT,
|
||||
};
|
||||
|
||||
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,
|
||||
SpiceImageCompression image_compression,
|
||||
spice_wan_compression_t jpeg_state,
|
||||
spice_wan_compression_t zlib_glz_state);
|
||||
void dcc_push_monitors_config (DisplayChannelClient *dcc);
|
||||
void dcc_push_destroy_surface (DisplayChannelClient *dcc,
|
||||
uint32_t surface_id);
|
||||
void dcc_add_stream_agent_clip (DisplayChannelClient* dcc,
|
||||
StreamAgent *agent);
|
||||
void dcc_create_stream (DisplayChannelClient *dcc,
|
||||
Stream *stream);
|
||||
|
||||
typedef struct DrawablePipeItem {
|
||||
RingItem base; /* link for a list of pipe items held by Drawable */
|
||||
PipeItem dpi_pipe_item; /* link for the client's pipe itself */
|
||||
|
||||
27
server/display-limits.h
Normal file
27
server/display-limits.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* -*- 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.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DISPLAY_LIMITS_H_
|
||||
#define DISPLAY_LIMITS_H_
|
||||
|
||||
/** Maximum number of surfaces a guest can create */
|
||||
#define NUM_SURFACES 10000
|
||||
|
||||
/** Maximum number of streams created by spice-server */
|
||||
#define NUM_STREAMS 50
|
||||
|
||||
#endif /* DISPLAY_LIMITS_H_ */
|
||||
@ -274,7 +274,7 @@ void attach_stream(DisplayChannel *display, Drawable *drawable, Stream *stream)
|
||||
if (!region_is_equal(&clip_in_draw_dest, &drawable->tree_item.base.rgn)) {
|
||||
region_remove(&agent->clip, &drawable->red_drawable->bbox);
|
||||
region_or(&agent->clip, &drawable->tree_item.base.rgn);
|
||||
dcc_add_stream_agent_clip(dcc, agent);
|
||||
dcc_stream_agent_clip(dcc, agent);
|
||||
}
|
||||
#ifdef STREAM_STATS
|
||||
agent->stats.num_input_frames++;
|
||||
@ -933,7 +933,7 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
|
||||
|
||||
/* stopping the client from playing older frames at once*/
|
||||
region_clear(&agent->clip);
|
||||
dcc_add_stream_agent_clip(dcc, agent);
|
||||
dcc_stream_agent_clip(dcc, agent);
|
||||
|
||||
if (region_is_empty(&agent->vis_region)) {
|
||||
spice_debug("stream %d: vis region empty", stream_id);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user