[Spice-devel] [PATCH 12/18] worker: move display_channel_new
Frediano Ziglio
fziglio at redhat.com
Wed Nov 25 02:29:04 PST 2015
---
server/dcc.c | 26 ++++++
server/dcc.h | 3 +
server/display-channel.c | 149 ++++++++++++++++++++++++++++++++
server/display-channel.h | 19 +++++
server/red_worker.c | 215 +++--------------------------------------------
5 files changed, 209 insertions(+), 203 deletions(-)
diff --git a/server/dcc.c b/server/dcc.c
index 5d666cb..e3b0c55 100644
--- a/server/dcc.c
+++ b/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)
{
diff --git a/server/dcc.h b/server/dcc.h
index 62261e8..dc6f1e7 100644
--- a/server/dcc.h
+++ b/server/dcc.h
@@ -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;
diff --git a/server/display-channel.c b/server/display-channel.c
index 855b65a..9e2375c 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -1402,3 +1402,152 @@ void display_channel_draw(DisplayChannel *display, const SpiceRect *area, int su
draw_until(display, surface, last);
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_return_if_fail(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;
+}
diff --git a/server/display-channel.h b/server/display-channel.h
index 0a6f120..42b3850 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -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;
diff --git a/server/red_worker.c b/server/red_worker.c
index 67978ac..8db2f78 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -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)
@@ -3446,12 +3389,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)
+{
+ 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));
+}
+
+void dcc_send_item(DisplayChannelClient *dcc, PipeItem *pipe_item)
{
+ RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
- DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
- red_display_reset_send_data(dcc);
+ reset_send_data(dcc);
switch (pipe_item->type) {
case PIPE_ITEM_TYPE_DRAW: {
DrawablePipeItem *dpi = SPICE_CONTAINEROF(pipe_item, DrawablePipeItem, dpi_pipe_item);
@@ -3545,37 +3495,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
@@ -3822,29 +3741,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);
@@ -4027,94 +3923,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_return_if_fail(item != NULL);
- 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;
@@ -5172,7 +4980,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;
}
--
2.4.3
More information about the Spice-devel
mailing list