mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-27 07:29:32 +00:00
worker: move display_channel_new
Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
parent
00526f0733
commit
9c828e8553
26
server/dcc.c
26
server/dcc.c
@ -372,6 +372,32 @@ void dcc_start(DisplayChannelClient *dcc)
|
||||
}
|
||||
}
|
||||
|
||||
static void dcc_destroy_stream_agents(DisplayChannelClient *dcc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_STREAMS; i++) {
|
||||
StreamAgent *agent = &dcc->stream_agents[i];
|
||||
region_destroy(&agent->vis_region);
|
||||
region_destroy(&agent->clip);
|
||||
if (agent->mjpeg_encoder) {
|
||||
mjpeg_encoder_destroy(agent->mjpeg_encoder);
|
||||
agent->mjpeg_encoder = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcc_stop(DisplayChannelClient *dcc)
|
||||
{
|
||||
pixmap_cache_unref(dcc->pixmap_cache);
|
||||
dcc->pixmap_cache = NULL;
|
||||
dcc_release_glz(dcc);
|
||||
dcc_palette_cache_reset(dcc);
|
||||
free(dcc->send_data.stream_outbuf);
|
||||
free(dcc->send_data.free_list.res);
|
||||
dcc_destroy_stream_agents(dcc);
|
||||
dcc_encoders_free(dcc);
|
||||
}
|
||||
|
||||
void dcc_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent)
|
||||
{
|
||||
|
||||
@ -161,6 +161,7 @@ DisplayChannelClient* dcc_new (DisplayCha
|
||||
spice_wan_compression_t jpeg_state,
|
||||
spice_wan_compression_t zlib_glz_state);
|
||||
void dcc_start (DisplayChannelClient *dcc);
|
||||
void dcc_stop (DisplayChannelClient *dcc);
|
||||
int dcc_handle_message (RedChannelClient *rcc,
|
||||
uint32_t size,
|
||||
uint16_t type, void *msg);
|
||||
@ -198,6 +199,8 @@ void dcc_add_drawable_after (DisplayCha
|
||||
void dcc_release_item (DisplayChannelClient *dcc,
|
||||
PipeItem *item,
|
||||
int item_pushed);
|
||||
void dcc_send_item (DisplayChannelClient *dcc,
|
||||
PipeItem *item);
|
||||
|
||||
typedef struct compress_send_data_t {
|
||||
void* comp_buf;
|
||||
|
||||
@ -1418,3 +1418,152 @@ void display_channel_draw(DisplayChannel *display, const SpiceRect *area, int su
|
||||
|
||||
surface_update_dest(surface, area);
|
||||
}
|
||||
|
||||
static void on_disconnect(RedChannelClient *rcc)
|
||||
{
|
||||
DisplayChannel *display;
|
||||
DisplayChannelClient *dcc;
|
||||
|
||||
spice_info(NULL);
|
||||
spice_return_if_fail(rcc != NULL);
|
||||
|
||||
dcc = RCC_TO_DCC(rcc);
|
||||
display = DCC_TO_DC(dcc);
|
||||
|
||||
dcc_stop(dcc); // TODO: start/stop -> connect/disconnect?
|
||||
display_channel_compress_stats_print(display);
|
||||
|
||||
// this was the last channel client
|
||||
spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d",
|
||||
display->drawable_count, display->red_drawable_count,
|
||||
display->glz_drawable_count);
|
||||
}
|
||||
|
||||
static void send_item(RedChannelClient *rcc, PipeItem *item)
|
||||
{
|
||||
dcc_send_item(RCC_TO_DCC(rcc), item);
|
||||
}
|
||||
|
||||
static void hold_item(RedChannelClient *rcc, PipeItem *item)
|
||||
{
|
||||
spice_return_if_fail(item);
|
||||
|
||||
switch (item->type) {
|
||||
case PIPE_ITEM_TYPE_DRAW:
|
||||
drawable_pipe_item_ref(SPICE_CONTAINEROF(item, DrawablePipeItem, dpi_pipe_item));
|
||||
break;
|
||||
case PIPE_ITEM_TYPE_STREAM_CLIP:
|
||||
((StreamClipItem *)item)->refs++;
|
||||
break;
|
||||
case PIPE_ITEM_TYPE_UPGRADE:
|
||||
((UpgradeItem *)item)->refs++;
|
||||
break;
|
||||
case PIPE_ITEM_TYPE_IMAGE:
|
||||
((ImageItem *)item)->refs++;
|
||||
break;
|
||||
default:
|
||||
spice_warn_if_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static void release_item(RedChannelClient *rcc, PipeItem *item, int item_pushed)
|
||||
{
|
||||
DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
|
||||
|
||||
spice_assert(item != NULL);
|
||||
dcc_release_item(dcc, item, item_pushed);
|
||||
}
|
||||
|
||||
static int handle_migrate_flush_mark(RedChannelClient *rcc)
|
||||
{
|
||||
DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
|
||||
RedChannel *channel = RED_CHANNEL(display_channel);
|
||||
|
||||
red_channel_pipes_add_type(channel, PIPE_ITEM_TYPE_MIGRATE_DATA);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static uint64_t handle_migrate_data_get_serial(RedChannelClient *rcc, uint32_t size, void *message)
|
||||
{
|
||||
SpiceMigrateDataDisplay *migrate_data;
|
||||
|
||||
migrate_data = (SpiceMigrateDataDisplay *)((uint8_t *)message + sizeof(SpiceMigrateDataHeader));
|
||||
|
||||
return migrate_data->message_serial;
|
||||
}
|
||||
|
||||
static int handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *message)
|
||||
{
|
||||
return dcc_handle_migrate_data(RCC_TO_DCC(rcc), size, message);
|
||||
}
|
||||
|
||||
static SpiceCanvas *image_surfaces_get(SpiceImageSurfaces *surfaces, uint32_t surface_id)
|
||||
{
|
||||
DisplayChannel *display = SPICE_CONTAINEROF(surfaces, DisplayChannel, image_surfaces);
|
||||
|
||||
spice_return_val_if_fail(validate_surface(display, surface_id), NULL);
|
||||
|
||||
return display->surfaces[surface_id].context.canvas;
|
||||
}
|
||||
|
||||
DisplayChannel* display_channel_new(RedWorker *worker, int migrate, int stream_video,
|
||||
uint32_t n_surfaces)
|
||||
{
|
||||
DisplayChannel *display;
|
||||
ChannelCbs cbs = {
|
||||
.on_disconnect = on_disconnect,
|
||||
.send_item = send_item,
|
||||
.hold_item = hold_item,
|
||||
.release_item = release_item,
|
||||
.handle_migrate_flush_mark = handle_migrate_flush_mark,
|
||||
.handle_migrate_data = handle_migrate_data,
|
||||
.handle_migrate_data_get_serial = handle_migrate_data_get_serial
|
||||
};
|
||||
static SpiceImageSurfacesOps image_surfaces_ops = {
|
||||
image_surfaces_get,
|
||||
};
|
||||
|
||||
spice_return_val_if_fail(num_renderers > 0, NULL);
|
||||
|
||||
spice_info("create display channel");
|
||||
display = (DisplayChannel *)red_worker_new_channel(
|
||||
worker, sizeof(*display), "display_channel",
|
||||
SPICE_CHANNEL_DISPLAY,
|
||||
SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER,
|
||||
&cbs, dcc_handle_message);
|
||||
spice_return_val_if_fail(display, NULL);
|
||||
|
||||
stat_init(&display->add_stat, "add", red_worker_get_clockid(worker));
|
||||
stat_init(&display->exclude_stat, "exclude", red_worker_get_clockid(worker));
|
||||
stat_init(&display->__exclude_stat, "__exclude", red_worker_get_clockid(worker));
|
||||
#ifdef RED_STATISTICS
|
||||
RedChannel *channel = RED_CHANNEL(display);
|
||||
display->cache_hits_counter = stat_add_counter(channel->stat,
|
||||
"cache_hits", TRUE);
|
||||
display->add_to_cache_counter = stat_add_counter(channel->stat,
|
||||
"add_to_cache", TRUE);
|
||||
display->non_cache_counter = stat_add_counter(channel->stat,
|
||||
"non_cache", TRUE);
|
||||
#endif
|
||||
stat_compress_init(&display->lz_stat, "lz");
|
||||
stat_compress_init(&display->glz_stat, "glz");
|
||||
stat_compress_init(&display->quic_stat, "quic");
|
||||
stat_compress_init(&display->jpeg_stat, "jpeg");
|
||||
stat_compress_init(&display->zlib_glz_stat, "zlib");
|
||||
stat_compress_init(&display->jpeg_alpha_stat, "jpeg_alpha");
|
||||
stat_compress_init(&display->lz4_stat, "lz4");
|
||||
|
||||
display->n_surfaces = n_surfaces;
|
||||
display->num_renderers = num_renderers;
|
||||
memcpy(display->renderers, renderers, sizeof(display->renderers));
|
||||
display->renderer = RED_RENDERER_INVALID;
|
||||
|
||||
ring_init(&display->current_list);
|
||||
display->image_surfaces.ops = &image_surfaces_ops;
|
||||
drawables_init(display);
|
||||
image_cache_init(&display->image_cache);
|
||||
display->stream_video = stream_video;
|
||||
display_channel_init_streams(display);
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
@ -251,6 +251,10 @@ typedef struct UpgradeItem {
|
||||
} UpgradeItem;
|
||||
|
||||
|
||||
DisplayChannel* display_channel_new (RedWorker *worker,
|
||||
int migrate,
|
||||
int stream_video,
|
||||
uint32_t n_surfaces);
|
||||
void display_channel_draw (DisplayChannel *display,
|
||||
const SpiceRect *area,
|
||||
int surface_id);
|
||||
@ -281,6 +285,21 @@ void display_channel_flush_all_surfaces (DisplayCha
|
||||
void display_channel_free_glz_drawables_to_free(DisplayChannel *display);
|
||||
void display_channel_free_glz_drawables (DisplayChannel *display);
|
||||
|
||||
static inline int validate_surface(DisplayChannel *display, uint32_t surface_id)
|
||||
{
|
||||
if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
|
||||
spice_warning("invalid surface_id %u", surface_id);
|
||||
return 0;
|
||||
}
|
||||
if (!display->surfaces[surface_id].context.canvas) {
|
||||
spice_warning("canvas address is %p for %d (and is NULL)\n",
|
||||
&(display->surfaces[surface_id].context.canvas), surface_id);
|
||||
spice_warning("failed on %d", surface_id);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int is_equal_path(SpicePath *path1, SpicePath *path2)
|
||||
{
|
||||
SpicePathSeg *seg1, *seg2;
|
||||
|
||||
@ -135,8 +135,6 @@ typedef struct BitmapData {
|
||||
SpiceRect lossy_rect;
|
||||
} BitmapData;
|
||||
|
||||
static inline int validate_surface(DisplayChannel *display, uint32_t surface_id);
|
||||
|
||||
static inline void display_begin_send_message(RedChannelClient *rcc);
|
||||
static void red_create_surface(DisplayChannel *display, uint32_t surface_id, uint32_t width,
|
||||
uint32_t height, int32_t stride, uint32_t format,
|
||||
@ -178,21 +176,6 @@ static int validate_drawable_bbox(DisplayChannel *display, RedDrawable *drawable
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline int validate_surface(DisplayChannel *display, uint32_t surface_id)
|
||||
{
|
||||
if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
|
||||
spice_warning("invalid surface_id %u", surface_id);
|
||||
return 0;
|
||||
}
|
||||
if (!display->surfaces[surface_id].context.canvas) {
|
||||
spice_warning("canvas address is %p for %d (and is NULL)\n",
|
||||
&(display->surfaces[surface_id].context.canvas), surface_id);
|
||||
spice_warning("failed on %d", surface_id);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int display_is_connected(RedWorker *worker)
|
||||
{
|
||||
return (worker->display_channel && red_channel_is_connected(
|
||||
@ -606,21 +589,6 @@ static void display_channel_streams_timeout(DisplayChannel *display)
|
||||
}
|
||||
}
|
||||
|
||||
static void dcc_destroy_stream_agents(DisplayChannelClient *dcc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_STREAMS; i++) {
|
||||
StreamAgent *agent = &dcc->stream_agents[i];
|
||||
region_destroy(&agent->vis_region);
|
||||
region_destroy(&agent->clip);
|
||||
if (agent->mjpeg_encoder) {
|
||||
mjpeg_encoder_destroy(agent->mjpeg_encoder);
|
||||
agent->mjpeg_encoder = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void red_get_area(DisplayChannel *display, int surface_id, const SpiceRect *area,
|
||||
uint8_t *dest, int dest_stride, int update)
|
||||
{
|
||||
@ -918,24 +886,6 @@ exit:
|
||||
free(surface);
|
||||
}
|
||||
|
||||
static SpiceCanvas *image_surfaces_get(SpiceImageSurfaces *surfaces, uint32_t surface_id)
|
||||
{
|
||||
DisplayChannel *display = SPICE_CONTAINEROF(surfaces, DisplayChannel, image_surfaces);
|
||||
|
||||
spice_return_val_if_fail(validate_surface(display, surface_id), NULL);
|
||||
|
||||
return display->surfaces[surface_id].context.canvas;
|
||||
}
|
||||
|
||||
static void image_surface_init(DisplayChannel *display)
|
||||
{
|
||||
static SpiceImageSurfacesOps image_surfaces_ops = {
|
||||
image_surfaces_get,
|
||||
};
|
||||
|
||||
display->image_surfaces.ops = &image_surfaces_ops;
|
||||
}
|
||||
|
||||
static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size, int *ring_is_empty)
|
||||
{
|
||||
QXLCommandExt ext_cmd;
|
||||
@ -1367,13 +1317,6 @@ static void fill_attr(SpiceMarshaller *m, SpiceLineAttr *attr, uint32_t group_id
|
||||
}
|
||||
}
|
||||
|
||||
static inline void red_display_reset_send_data(DisplayChannelClient *dcc)
|
||||
{
|
||||
dcc->send_data.free_list.res->count = 0;
|
||||
dcc->send_data.num_pixmap_cache_items = 0;
|
||||
memset(dcc->send_data.free_list.sync, 0, sizeof(dcc->send_data.free_list.sync));
|
||||
}
|
||||
|
||||
/* set area=NULL for testing the whole surface */
|
||||
static int is_surface_area_lossy(DisplayChannelClient *dcc, uint32_t surface_id,
|
||||
const SpiceRect *area, SpiceRect *out_lossy_area)
|
||||
@ -3447,12 +3390,19 @@ static void red_marshall_stream_activate_report(RedChannelClient *rcc,
|
||||
spice_marshall_msg_display_stream_activate_report(base_marshaller, &msg);
|
||||
}
|
||||
|
||||
static void send_item(RedChannelClient *rcc, PipeItem *pipe_item)
|
||||
static void reset_send_data(DisplayChannelClient *dcc)
|
||||
{
|
||||
SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
|
||||
DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
|
||||
dcc->send_data.free_list.res->count = 0;
|
||||
dcc->send_data.num_pixmap_cache_items = 0;
|
||||
memset(dcc->send_data.free_list.sync, 0, sizeof(dcc->send_data.free_list.sync));
|
||||
}
|
||||
|
||||
red_display_reset_send_data(dcc);
|
||||
void dcc_send_item(DisplayChannelClient *dcc, PipeItem *pipe_item)
|
||||
{
|
||||
RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
|
||||
SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
|
||||
|
||||
reset_send_data(dcc);
|
||||
switch (pipe_item->type) {
|
||||
case PIPE_ITEM_TYPE_DRAW: {
|
||||
DrawablePipeItem *dpi = SPICE_CONTAINEROF(pipe_item, DrawablePipeItem, dpi_pipe_item);
|
||||
@ -3546,37 +3496,6 @@ static inline void red_push(RedWorker *worker)
|
||||
}
|
||||
}
|
||||
|
||||
static void on_disconnect(RedChannelClient *rcc)
|
||||
{
|
||||
DisplayChannel *display;
|
||||
DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
|
||||
CommonChannel *common;
|
||||
RedWorker *worker;
|
||||
|
||||
if (!rcc) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
dcc_release_glz(dcc);
|
||||
dcc_palette_cache_reset(dcc);
|
||||
free(dcc->send_data.stream_outbuf);
|
||||
free(dcc->send_data.free_list.res);
|
||||
dcc_destroy_stream_agents(dcc);
|
||||
dcc_encoders_free(dcc);
|
||||
|
||||
// this was the last channel client
|
||||
spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d",
|
||||
display->drawable_count, display->red_drawable_count,
|
||||
display->glz_drawable_count);
|
||||
}
|
||||
|
||||
void red_disconnect_all_display_TODO_remove_me(RedChannel *channel)
|
||||
{
|
||||
// TODO: we need to record the client that actually causes the timeout. So
|
||||
@ -3823,29 +3742,6 @@ static inline void flush_all_qxl_commands(RedWorker *worker)
|
||||
flush_cursor_commands(worker);
|
||||
}
|
||||
|
||||
static int handle_migrate_flush_mark(RedChannelClient *rcc)
|
||||
{
|
||||
DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
|
||||
RedChannel *channel = RED_CHANNEL(display_channel);
|
||||
|
||||
red_channel_pipes_add_type(channel, PIPE_ITEM_TYPE_MIGRATE_DATA);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static uint64_t handle_migrate_data_get_serial(RedChannelClient *rcc, uint32_t size, void *message)
|
||||
{
|
||||
SpiceMigrateDataDisplay *migrate_data;
|
||||
|
||||
migrate_data = (SpiceMigrateDataDisplay *)((uint8_t *)message + sizeof(SpiceMigrateDataHeader));
|
||||
|
||||
return migrate_data->message_serial;
|
||||
}
|
||||
|
||||
static int handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *message)
|
||||
{
|
||||
return dcc_handle_migrate_data(RCC_TO_DCC(rcc), size, message);
|
||||
}
|
||||
|
||||
static int common_channel_config_socket(RedChannelClient *rcc)
|
||||
{
|
||||
RedClient *client = red_channel_client_get_client(rcc);
|
||||
@ -4028,94 +3924,6 @@ RedChannel *red_worker_new_channel(RedWorker *worker, int size,
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void hold_item(RedChannelClient *rcc, PipeItem *item)
|
||||
{
|
||||
spice_assert(item);
|
||||
switch (item->type) {
|
||||
case PIPE_ITEM_TYPE_DRAW:
|
||||
drawable_pipe_item_ref(SPICE_CONTAINEROF(item, DrawablePipeItem, dpi_pipe_item));
|
||||
break;
|
||||
case PIPE_ITEM_TYPE_STREAM_CLIP:
|
||||
((StreamClipItem *)item)->refs++;
|
||||
break;
|
||||
case PIPE_ITEM_TYPE_UPGRADE:
|
||||
((UpgradeItem *)item)->refs++;
|
||||
break;
|
||||
case PIPE_ITEM_TYPE_IMAGE:
|
||||
((ImageItem *)item)->refs++;
|
||||
break;
|
||||
default:
|
||||
spice_critical("invalid item type");
|
||||
}
|
||||
}
|
||||
|
||||
static void release_item(RedChannelClient *rcc, PipeItem *item, int item_pushed)
|
||||
{
|
||||
DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
|
||||
|
||||
spice_assert(item);
|
||||
dcc_release_item(dcc, item, item_pushed);
|
||||
}
|
||||
|
||||
static void display_channel_create(RedWorker *worker, int migrate, int stream_video,
|
||||
uint32_t n_surfaces)
|
||||
{
|
||||
DisplayChannel *display_channel;
|
||||
ChannelCbs cbs = {
|
||||
.on_disconnect = on_disconnect,
|
||||
.send_item = send_item,
|
||||
.hold_item = hold_item,
|
||||
.release_item = release_item,
|
||||
.handle_migrate_flush_mark = handle_migrate_flush_mark,
|
||||
.handle_migrate_data = handle_migrate_data,
|
||||
.handle_migrate_data_get_serial = handle_migrate_data_get_serial
|
||||
};
|
||||
|
||||
spice_return_if_fail(num_renderers > 0);
|
||||
|
||||
spice_info("create display channel");
|
||||
if (!(display_channel = (DisplayChannel *)red_worker_new_channel(
|
||||
worker, sizeof(*display_channel), "display_channel",
|
||||
SPICE_CHANNEL_DISPLAY,
|
||||
SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER,
|
||||
&cbs, dcc_handle_message))) {
|
||||
spice_warning("failed to create display channel");
|
||||
return;
|
||||
}
|
||||
worker->display_channel = display_channel;
|
||||
stat_init(&display_channel->add_stat, "add", worker->clockid);
|
||||
stat_init(&display_channel->exclude_stat, "exclude", worker->clockid);
|
||||
stat_init(&display_channel->__exclude_stat, "__exclude", worker->clockid);
|
||||
#ifdef RED_STATISTICS
|
||||
RedChannel *channel = RED_CHANNEL(display_channel);
|
||||
display_channel->cache_hits_counter = stat_add_counter(channel->stat,
|
||||
"cache_hits", TRUE);
|
||||
display_channel->add_to_cache_counter = stat_add_counter(channel->stat,
|
||||
"add_to_cache", TRUE);
|
||||
display_channel->non_cache_counter = stat_add_counter(channel->stat,
|
||||
"non_cache", TRUE);
|
||||
#endif
|
||||
stat_compress_init(&display_channel->lz_stat, "lz");
|
||||
stat_compress_init(&display_channel->glz_stat, "glz");
|
||||
stat_compress_init(&display_channel->quic_stat, "quic");
|
||||
stat_compress_init(&display_channel->jpeg_stat, "jpeg");
|
||||
stat_compress_init(&display_channel->zlib_glz_stat, "zlib");
|
||||
stat_compress_init(&display_channel->jpeg_alpha_stat, "jpeg_alpha");
|
||||
stat_compress_init(&display_channel->lz4_stat, "lz4");
|
||||
|
||||
display_channel->n_surfaces = n_surfaces;
|
||||
display_channel->num_renderers = num_renderers;
|
||||
memcpy(display_channel->renderers, renderers, sizeof(display_channel->renderers));
|
||||
display_channel->renderer = RED_RENDERER_INVALID;
|
||||
|
||||
ring_init(&display_channel->current_list);
|
||||
image_surface_init(display_channel);
|
||||
drawables_init(display_channel);
|
||||
image_cache_init(&display_channel->image_cache);
|
||||
display_channel->stream_video = stream_video;
|
||||
display_channel_init_streams(display_channel);
|
||||
}
|
||||
|
||||
static void guest_set_client_capabilities(RedWorker *worker)
|
||||
{
|
||||
int i;
|
||||
@ -5173,7 +4981,8 @@ RedWorker* red_worker_new(QXLInstance *qxl, RedDispatcher *red_dispatcher)
|
||||
|
||||
worker->cursor_channel = cursor_channel_new(worker);
|
||||
// TODO: handle seemless migration. Temp, setting migrate to FALSE
|
||||
display_channel_create(worker, FALSE, streaming_video, init_info.n_surfaces);
|
||||
worker->display_channel = display_channel_new(worker, FALSE, streaming_video,
|
||||
init_info.n_surfaces);
|
||||
|
||||
return worker;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user