> On Wed, Nov 18, 2015 at 5:17 PM, Frediano Ziglio <fziglio@xxxxxxxxxx> wrote: > > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > > > Author: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > --- > > server/dcc.c | 170 +++++++++++++++++++++++++++++++++ > > server/dcc.h | 33 +++++++ > > server/display-channel.h | 7 +- > > server/red_worker.c | 237 > > ++++------------------------------------------- > > 4 files changed, 224 insertions(+), 223 deletions(-) > > > > diff --git a/server/dcc.c b/server/dcc.c > > index 5e35708..2fb0af6 100644 > > --- a/server/dcc.c > > +++ b/server/dcc.c > > @@ -18,6 +18,97 @@ > > #include "dcc.h" > > #include "display-channel.h" > > > > +static SurfaceCreateItem *surface_create_item_new(RedChannel* channel, > > + uint32_t surface_id, > > uint32_t width, > > + uint32_t height, > > uint32_t format, uint32_t flags) > > +{ > > + SurfaceCreateItem *create; > > + > > + create = spice_malloc(sizeof(SurfaceCreateItem)); > > + > > + create->surface_create.surface_id = surface_id; > > + create->surface_create.width = width; > > + create->surface_create.height = height; > > + create->surface_create.flags = flags; > > + create->surface_create.format = format; > > + > > + red_channel_pipe_item_init(channel, > > + &create->pipe_item, > > PIPE_ITEM_TYPE_CREATE_SURFACE); > > + return create; > > +} > > + > > +void dcc_create_surface(DisplayChannelClient *dcc, int surface_id) > > +{ > > + DisplayChannel *display; > > + RedSurface *surface; > > + SurfaceCreateItem *create; > > + uint32_t flags; > > + > > + if (!dcc) { > > + return; > > + } > > + > > + display = DCC_TO_DC(dcc); > > + flags = is_primary_surface(DCC_TO_DC(dcc), surface_id) ? > > SPICE_SURFACE_FLAGS_PRIMARY : 0; > > + > > + /* don't send redundant create surface commands to client */ > > + if (!dcc || display->common.during_target_migrate || > > + dcc->surface_client_created[surface_id]) { > > + return; > > + } > > + surface = &display->surfaces[surface_id]; > > + create = surface_create_item_new(RED_CHANNEL_CLIENT(dcc)->channel, > > + surface_id, surface->context.width, > > surface->context.height, > > + surface->context.format, flags); > > + dcc->surface_client_created[surface_id] = TRUE; > > + red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), > > &create->pipe_item); > > +} > > + > > +void dcc_push_surface_image(DisplayChannelClient *dcc, int surface_id) > > +{ > > + DisplayChannel *display; > > + SpiceRect area; > > + RedSurface *surface; > > + > > + if (!dcc) { > > + return; > > + } > > + > > + display = DCC_TO_DC(dcc); > > + surface = &display->surfaces[surface_id]; > > + if (!surface->context.canvas) { > > + return; > > + } > > + area.top = area.left = 0; > > + area.right = surface->context.width; > > + area.bottom = surface->context.height; > > + > > + /* not allowing lossy compression because probably, especially if it > > is a primary surface, > > + it combines both "picture-like" areas with areas that are more > > "artificial"*/ > > + dcc_add_surface_area_image(dcc, surface_id, &area, NULL, FALSE); > > + red_channel_client_push(RED_CHANNEL_CLIENT(dcc)); > > +} > > + > > +static void dcc_init_stream_agents(DisplayChannelClient *dcc) > > +{ > > + int i; > > + DisplayChannel *display = DCC_TO_DC(dcc); > > + RedChannel *channel = RED_CHANNEL_CLIENT(dcc)->channel; > > + > > + for (i = 0; i < NUM_STREAMS; i++) { > > + StreamAgent *agent = &dcc->stream_agents[i]; > > + agent->stream = &display->streams_buf[i]; > > + region_init(&agent->vis_region); > > + region_init(&agent->clip); > > + red_channel_pipe_item_init(channel, &agent->create_item, > > PIPE_ITEM_TYPE_STREAM_CREATE); > > + red_channel_pipe_item_init(channel, &agent->destroy_item, > > PIPE_ITEM_TYPE_STREAM_DESTROY); > > + } > > + dcc->use_mjpeg_encoder_rate_control = > > + red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(dcc), > > SPICE_DISPLAY_CAP_STREAM_REPORT); > > +} > > + > > +#define DISPLAY_FREE_LIST_DEFAULT_SIZE 128 > > + > > DisplayChannelClient *dcc_new(DisplayChannel *display, > > RedClient *client, RedsStream *stream, > > int mig_target, > > @@ -36,6 +127,7 @@ DisplayChannelClient *dcc_new(DisplayChannel *display, > > common_caps, num_common_caps, > > caps, num_caps); > > spice_return_val_if_fail(dcc, NULL); > > + spice_info("New display (client %p) dcc %p stream %p", client, dcc, > > stream); > > > > ring_init(&dcc->palette_cache_lru); > > dcc->palette_cache_available = CLIENT_PALETTE_CACHE_SIZE; > > @@ -45,11 +137,89 @@ DisplayChannelClient *dcc_new(DisplayChannel *display, > > // todo: tune quality according to bandwidth > > dcc->jpeg_quality = 85; > > > > + size_t stream_buf_size; > > + stream_buf_size = 32*1024; > > + dcc->send_data.stream_outbuf = spice_malloc(stream_buf_size); > > + dcc->send_data.stream_outbuf_size = stream_buf_size; > > + dcc->send_data.free_list.res = > > + spice_malloc(sizeof(SpiceResourceList) + > > + DISPLAY_FREE_LIST_DEFAULT_SIZE * > > sizeof(SpiceResourceID)); > > Could be better indented. > > > + dcc->send_data.free_list.res_size = DISPLAY_FREE_LIST_DEFAULT_SIZE; > > + > > + dcc_init_stream_agents(dcc); > > + > > dcc_encoders_init(dcc); > > > > return dcc; > > } > > > > +static void dcc_create_all_streams(DisplayChannelClient *dcc) > > +{ > > + Ring *ring = &DCC_TO_DC(dcc)->streams; > > + RingItem *item = ring; > > + > > + while ((item = ring_next(ring, item))) { > > + Stream *stream = SPICE_CONTAINEROF(item, Stream, link); > > + dcc_create_stream(dcc, stream); > > + } > > +} > > + > > +/* TODO: this function is evil^Wsynchronous, fix */ > > +static int display_channel_client_wait_for_init(DisplayChannelClient *dcc) > > +{ > > + dcc->expect_init = TRUE; > > + uint64_t end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT; > > + for (;;) { > > + red_channel_client_receive(RED_CHANNEL_CLIENT(dcc)); > > + if (!red_channel_client_is_connected(RED_CHANNEL_CLIENT(dcc))) { > > + break; > > + } > > + if (dcc->pixmap_cache && dcc->glz_dict) { > > + dcc->pixmap_cache_generation = dcc->pixmap_cache->generation; > > + /* TODO: move common.id? if it's used for a per client > > structure.. */ > > + spice_info("creating encoder with id == %d", dcc->common.id); > > + dcc->glz = glz_encoder_create(dcc->common.id, > > dcc->glz_dict->dict, &dcc->glz_data.usr); > > + if (!dcc->glz) { > > + spice_critical("create global lz failed"); > > + } > > + return TRUE; > > + } > > + if (red_get_monotonic_time() > end_time) { > > + spice_warning("timeout"); > > + red_channel_client_disconnect(RED_CHANNEL_CLIENT(dcc)); > > + break; > > + } > > + usleep(DISPLAY_CLIENT_RETRY_INTERVAL); > > + } > > + return FALSE; > > +} > > + > > +void dcc_start(DisplayChannelClient *dcc) > > +{ > > + DisplayChannel *display = DCC_TO_DC(dcc); > > + RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc); > > + > > + red_channel_client_push_set_ack(RED_CHANNEL_CLIENT(dcc)); > > + > > + if (red_channel_client_waits_for_migrate_data(rcc)) > > + return; > > + > > + if (!display_channel_client_wait_for_init(dcc)) > > + return; > > + > > + red_channel_client_ack_zero_messages_window(RED_CHANNEL_CLIENT(dcc)); > > + if (display->surfaces[0].context.canvas) { > > + display_channel_current_flush(display, 0); > > + red_channel_client_pipe_add_type(rcc, > > PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE); > > + dcc_create_surface(dcc, 0); > > + dcc_push_surface_image(dcc, 0); > > + dcc_push_monitors_config(dcc); > > + red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_MARK); > > + dcc_create_all_streams(dcc); > > + } > > +} > > + > > + > > void dcc_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent) > > { > > StreamClipItem *item = stream_clip_item_new(dcc, agent); > > diff --git a/server/dcc.h b/server/dcc.h > > index b66f730..94eaab3 100644 > > --- a/server/dcc.h > > +++ b/server/dcc.h > > @@ -30,6 +30,10 @@ > > #define PALETTE_CACHE_HASH_KEY(id) ((id) & PALETTE_CACHE_HASH_MASK) > > #define CLIENT_PALETTE_CACHE_SIZE 128 > > > > +#define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano > > +#define DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT 10000000000ULL //nano, 10 sec > > +#define DISPLAY_CLIENT_RETRY_INTERVAL 10000 //micro > > + > > /* Each drawable can refer to at most 3 images: src, brush and mask */ > > #define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3 > > > > @@ -110,6 +114,25 @@ struct DisplayChannelClient { > > 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; > > + PipeItem pipe_item; > > +} SurfaceCreateItem; > > + > > +typedef struct ImageItem { > > + PipeItem link; > > + int refs; > > + SpicePoint pos; > > + int width; > > + int height; > > + int stride; > > + int top_down; > > + int surface_id; > > + int image_format; > > + uint32_t image_flags; > > + int can_lossy; > > + uint8_t data[0]; > > +} ImageItem; > > > > DisplayChannelClient* dcc_new > > (DisplayChannel *display, > > RedClient > > *client, > > @@ -122,6 +145,7 @@ DisplayChannelClient* dcc_new > > (DisplayCha > > SpiceImageCompression > > image_compression, > > spice_wan_compression_t > > jpeg_state, > > spice_wan_compression_t > > zlib_glz_state); > > +void dcc_start > > (DisplayChannelClient *dcc); > > void dcc_push_monitors_config > > (DisplayChannelClient *dcc); > > void dcc_destroy_surface > > (DisplayChannelClient *dcc, > > uint32_t > > surface_id); > > @@ -129,5 +153,14 @@ void dcc_stream_agent_clip > > (DisplayCha > > StreamAgent > > *agent); > > void dcc_create_stream > > (DisplayChannelClient *dcc, > > 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); > > > > #endif /* DCC_H_ */ > > diff --git a/server/display-channel.h b/server/display-channel.h > > index ee107e8..ae55114 100644 > > --- a/server/display-channel.h > > +++ b/server/display-channel.h > > @@ -252,11 +252,6 @@ typedef struct SurfaceDestroyItem { > > PipeItem pipe_item; > > } SurfaceDestroyItem; > > > > -typedef struct SurfaceCreateItem { > > - SpiceMsgSurfaceCreate surface_create; > > - PipeItem pipe_item; > > -} SurfaceCreateItem; > > - > > > > void display_channel_set_stream_video > > (DisplayChannel *display, > > int > > stream_video); > > @@ -270,6 +265,8 @@ bool > > display_channel_surface_has_canvas > > (DisplayCha > > uint32_t > > surface_id); > > int display_channel_add_drawable > > (DisplayChannel *display, > > Drawable > > *drawable); > > +void display_channel_current_flush > > (DisplayChannel *display, > > + int > > surface_id); > > > > static inline int is_equal_path(SpicePath *path1, SpicePath *path2) > > { > > diff --git a/server/red_worker.c b/server/red_worker.c > > index f06e23b..a7baf0e 100644 > > --- a/server/red_worker.c > > +++ b/server/red_worker.c > > @@ -119,21 +119,6 @@ struct SpiceWatch { > > #define WIDE_CLIENT_ACK_WINDOW 40 > > #define NARROW_CLIENT_ACK_WINDOW 20 > > > > -typedef struct ImageItem { > > - PipeItem link; > > - int refs; > > - SpicePoint pos; > > - int width; > > - int height; > > - int stride; > > - int top_down; > > - int surface_id; > > - int image_format; > > - uint32_t image_flags; > > - int can_lossy; > > - uint8_t data[0]; > > -} ImageItem; > > - > > pthread_mutex_t glz_dictionary_list_lock = PTHREAD_MUTEX_INITIALIZER; > > Ring glz_dictionary_list = {&glz_dictionary_list, &glz_dictionary_list}; > > > > @@ -199,7 +184,6 @@ typedef struct BitmapData { > > static inline int validate_surface(DisplayChannel *display, uint32_t > > surface_id); > > > > static void red_draw_qxl_drawable(DisplayChannel *display, Drawable > > *drawable); > > -static void red_current_flush(DisplayChannel *display, int surface_id); > > static void red_draw_drawable(DisplayChannel *display, Drawable *item); > > static void red_update_area(DisplayChannel *display, const SpiceRect > > *area, int surface_id); > > static void red_update_area_till(DisplayChannel *display, const SpiceRect > > *area, int surface_id, > > @@ -211,8 +195,6 @@ static void > > display_channel_push_release(DisplayChannelClient *dcc, uint8_t type > > uint64_t* sync_data); > > static int > > red_display_free_some_independent_glz_drawables(DisplayChannelClient > > *dcc); > > static void dcc_free_glz_drawable(DisplayChannelClient *dcc, > > RedGlzDrawable *drawable); > > -static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc, > > int surface_id, > > - SpiceRect *area, PipeItem > > *pos, int can_lossy); > > static void > > display_channel_client_release_item_before_push(DisplayChannelClient > > *dcc, > > PipeItem > > *item); > > static void > > display_channel_client_release_item_after_push(DisplayChannelClient *dcc, > > @@ -369,8 +351,6 @@ static inline int validate_surface(DisplayChannel > > *display, uint32_t surface_id) > > return 1; > > } > > > > -static inline void red_create_surface_item(DisplayChannelClient *dcc, int > > surface_id); > > -static void red_push_surface_image(DisplayChannelClient *dcc, int > > surface_id); > > > > static inline void red_handle_drawable_surfaces_client_synced( > > DisplayChannelClient *dcc, Drawable *drawable) > > @@ -386,9 +366,9 @@ static inline void > > red_handle_drawable_surfaces_client_synced( > > if (dcc->surface_client_created[surface_id] == TRUE) { > > continue; > > } > > - red_create_surface_item(dcc, surface_id); > > - red_current_flush(display, surface_id); > > - red_push_surface_image(dcc, surface_id); > > + dcc_create_surface(dcc, surface_id); > > + display_channel_current_flush(display, surface_id); > > + dcc_push_surface_image(dcc, surface_id); > > } > > } > > > > @@ -396,9 +376,9 @@ static inline void > > red_handle_drawable_surfaces_client_synced( > > return; > > } > > > > - red_create_surface_item(dcc, drawable->surface_id); > > - red_current_flush(display, drawable->surface_id); > > - red_push_surface_image(dcc, drawable->surface_id); > > + dcc_create_surface(dcc, drawable->surface_id); > > + display_channel_current_flush(display, drawable->surface_id); > > + dcc_push_surface_image(dcc, drawable->surface_id); > > } > > > > static int display_is_connected(RedWorker *worker) > > @@ -985,7 +965,7 @@ static void > > dcc_detach_stream_gracefully(DisplayChannelClient *dcc, > > } else { > > red_update_area(DCC_TO_DC(dcc), &upgrade_area, 0); > > } > > - red_add_surface_area_image(dcc, 0, &upgrade_area, NULL, FALSE); > > + dcc_add_surface_area_image(dcc, 0, &upgrade_area, NULL, FALSE); > > } > > clear_vis_region: > > region_clear(&agent->vis_region); > > @@ -1065,35 +1045,6 @@ static void > > display_channel_streams_timeout(DisplayChannel *display) > > } > > } > > > > -static void dcc_create_all_streams(DisplayChannelClient *dcc) > > -{ > > - Ring *ring = &DCC_TO_DC(dcc)->streams; > > - RingItem *item = ring; > > - > > - while ((item = ring_next(ring, item))) { > > - Stream *stream = SPICE_CONTAINEROF(item, Stream, link); > > - dcc_create_stream(dcc, stream); > > - } > > -} > > - > > -static void dcc_init_stream_agents(DisplayChannelClient *dcc) > > -{ > > - int i; > > - DisplayChannel *display = DCC_TO_DC(dcc); > > - RedChannel *channel = RED_CHANNEL_CLIENT(dcc)->channel; > > - > > - for (i = 0; i < NUM_STREAMS; i++) { > > - StreamAgent *agent = &dcc->stream_agents[i]; > > - agent->stream = &display->streams_buf[i]; > > - region_init(&agent->vis_region); > > - region_init(&agent->clip); > > - red_channel_pipe_item_init(channel, &agent->create_item, > > PIPE_ITEM_TYPE_STREAM_CREATE); > > - red_channel_pipe_item_init(channel, &agent->destroy_item, > > PIPE_ITEM_TYPE_STREAM_DESTROY); > > - } > > - dcc->use_mjpeg_encoder_rate_control = > > - red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(dcc), > > SPICE_DISPLAY_CAP_STREAM_REPORT); > > -} > > - > > static void dcc_destroy_stream_agents(DisplayChannelClient *dcc) > > { > > int i; > > @@ -1999,7 +1950,7 @@ static void red_free_some(RedWorker *worker) > > } > > } > > > > -static void red_current_flush(DisplayChannel *display, int surface_id) > > +void display_channel_current_flush(DisplayChannel *display, int > > surface_id) > > { > > while (!ring_is_empty(&display->surfaces[surface_id].current_list)) { > > free_one_drawable(display, FALSE); > > @@ -2008,8 +1959,8 @@ static void red_current_flush(DisplayChannel > > *display, int surface_id) > > } > > > > // adding the pipe item after pos. If pos == NULL, adding to head. > > -static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc, > > int surface_id, > > - SpiceRect *area, PipeItem > > *pos, int can_lossy) > > +ImageItem *dcc_add_surface_area_image(DisplayChannelClient *dcc, int > > surface_id, > > + SpiceRect *area, PipeItem *pos, int > > can_lossy) > > { > > DisplayChannel *display = DCC_TO_DC(dcc); > > RedChannel *channel = RED_CHANNEL(display); > > @@ -2071,31 +2022,6 @@ static ImageItem > > *red_add_surface_area_image(DisplayChannelClient *dcc, int surf > > return item; > > } > > > > -static void red_push_surface_image(DisplayChannelClient *dcc, int > > surface_id) > > -{ > > - DisplayChannel *display; > > - SpiceRect area; > > - RedSurface *surface; > > - > > - if (!dcc) { > > - return; > > - } > > - > > - display = DCC_TO_DC(dcc); > > - surface = &display->surfaces[surface_id]; > > - if (!surface->context.canvas) { > > - return; > > - } > > - area.top = area.left = 0; > > - area.right = surface->context.width; > > - area.bottom = surface->context.height; > > - > > - /* not allowing lossy compression because probably, especially if it > > is a primary surface, > > - it combines both "picture-like" areas with areas that are more > > "artificial"*/ > > - red_add_surface_area_image(dcc, surface_id, &area, NULL, FALSE); > > - red_channel_client_push(RED_CHANNEL_CLIENT(dcc)); > > -} > > - > > static void fill_base(SpiceMarshaller *base_marshaller, Drawable > > *drawable) > > { > > SpiceMsgDisplayBase base; > > @@ -3506,7 +3432,7 @@ static void > > red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient > > continue; > > } > > > > - image = red_add_surface_area_image(dcc, > > drawable->red_drawable->surface_id, > > + image = dcc_add_surface_area_image(dcc, > > drawable->red_drawable->surface_id, > > &drawable->red_drawable->bbox, > > pipe_item, TRUE); > > resent_surface_ids[num_resent] = > > drawable->red_drawable->surface_id; > > resent_areas[num_resent] = drawable->red_drawable->bbox; > > @@ -3562,7 +3488,7 @@ static void > > red_add_lossless_drawable_dependencies(RedChannelClient *rcc, > > // the surfaces areas will be sent as DRAW_COPY commands, that > > // will be executed before the current drawable > > for (i = 0; i < num_deps; i++) { > > - red_add_surface_area_image(dcc, deps_surfaces_ids[i], > > deps_areas[i], > > + dcc_add_surface_area_image(dcc, deps_surfaces_ids[i], > > deps_areas[i], > > red_pipe_get_tail(dcc), FALSE); > > > > } > > @@ -3583,7 +3509,7 @@ static void > > red_add_lossless_drawable_dependencies(RedChannelClient *rcc, > > &drawable->bbox); > > } > > > > - red_add_surface_area_image(dcc, drawable->surface_id, > > &drawable->bbox, > > + dcc_add_surface_area_image(dcc, drawable->surface_id, > > &drawable->bbox, > > red_pipe_get_tail(dcc), TRUE); > > } > > } > > @@ -5579,60 +5505,13 @@ static inline void > > *create_canvas_for_surface(DisplayChannel *display, RedSurfac > > return NULL; > > } > > > > -static SurfaceCreateItem *get_surface_create_item( > > - RedChannel* channel, > > - uint32_t surface_id, uint32_t width, > > - uint32_t height, uint32_t format, uint32_t flags) > > -{ > > - SurfaceCreateItem *create; > > - > > - create = spice_malloc(sizeof(SurfaceCreateItem)); > > - > > - create->surface_create.surface_id = surface_id; > > - create->surface_create.width = width; > > - create->surface_create.height = height; > > - create->surface_create.flags = flags; > > - create->surface_create.format = format; > > - > > - red_channel_pipe_item_init(channel, > > - &create->pipe_item, PIPE_ITEM_TYPE_CREATE_SURFACE); > > - return create; > > -} > > - > > -static inline void red_create_surface_item(DisplayChannelClient *dcc, int > > surface_id) > > -{ > > - DisplayChannel *display; > > - RedSurface *surface; > > - SurfaceCreateItem *create; > > - uint32_t flags; > > - > > - if (!dcc) { > > - return; > > - } > > - > > - display = DCC_TO_DC(dcc); > > - flags = is_primary_surface(DCC_TO_DC(dcc), surface_id) ? > > SPICE_SURFACE_FLAGS_PRIMARY : 0; > > - > > - /* don't send redundant create surface commands to client */ > > - if (display->common.during_target_migrate || > > - dcc->surface_client_created[surface_id]) { > > - return; > > - } > > - surface = &display->surfaces[surface_id]; > > - create = get_surface_create_item(RED_CHANNEL_CLIENT(dcc)->channel, > > - surface_id, surface->context.width, surface->context.height, > > - surface->context.format, flags); > > - dcc->surface_client_created[surface_id] = TRUE; > > - red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), > > &create->pipe_item); > > -} > > - > > static void red_worker_create_surface_item(DisplayChannel *display, int > > surface_id) > > { > > DisplayChannelClient *dcc; > > RingItem *item, *next; > > > > FOREACH_DCC(display, item, next, dcc) { > > - red_create_surface_item(dcc, surface_id); > > + dcc_create_surface(dcc, surface_id); > > } > > } > > > > @@ -5643,7 +5522,7 @@ static void > > red_worker_push_surface_image(DisplayChannel *display, int surface_i > > RingItem *item, *next; > > > > FOREACH_DCC(display, item, next, dcc) { > > - red_push_surface_image(dcc, surface_id); > > + dcc_push_surface_image(dcc, surface_id); > > } > > } > > > > @@ -5808,70 +5687,6 @@ static inline void flush_all_qxl_commands(RedWorker > > *worker) > > flush_cursor_commands(worker); > > } > > > > -static void push_new_primary_surface(DisplayChannelClient *dcc) > > -{ > > - RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc); > > - > > - red_channel_client_pipe_add_type(rcc, > > PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE); > > - red_create_surface_item(dcc, 0); > > - red_channel_client_push(rcc); > > -} > > - > > -/* TODO: this function is evil^Wsynchronous, fix */ > > -static int display_channel_client_wait_for_init(DisplayChannelClient *dcc) > > -{ > > - dcc->expect_init = TRUE; > > - uint64_t end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT; > > - for (;;) { > > - red_channel_client_receive(RED_CHANNEL_CLIENT(dcc)); > > - if (!red_channel_client_is_connected(RED_CHANNEL_CLIENT(dcc))) { > > - break; > > - } > > - if (dcc->pixmap_cache && dcc->glz_dict) { > > - dcc->pixmap_cache_generation = dcc->pixmap_cache->generation; > > - /* TODO: move common.id? if it's used for a per client > > structure.. */ > > - spice_info("creating encoder with id == %d", dcc->common.id); > > - dcc->glz = glz_encoder_create(dcc->common.id, > > dcc->glz_dict->dict, &dcc->glz_data.usr); > > - if (!dcc->glz) { > > - spice_critical("create global lz failed"); > > - } > > - return TRUE; > > - } > > - if (red_get_monotonic_time() > end_time) { > > - spice_warning("timeout"); > > - red_channel_client_disconnect(RED_CHANNEL_CLIENT(dcc)); > > - break; > > - } > > - usleep(DISPLAY_CLIENT_RETRY_INTERVAL); > > - } > > - return FALSE; > > -} > > - > > -static void on_new_display_channel_client(DisplayChannelClient *dcc) > > -{ > > - DisplayChannel *display = DCC_TO_DC(dcc); > > - RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc); > > - > > - red_channel_client_push_set_ack(RED_CHANNEL_CLIENT(dcc)); > > - > > - if (red_channel_client_waits_for_migrate_data(rcc)) { > > - return; > > - } > > - > > - if (!display_channel_client_wait_for_init(dcc)) { > > - return; > > - } > > - red_channel_client_ack_zero_messages_window(RED_CHANNEL_CLIENT(dcc)); > > - if (display->surfaces[0].context.canvas) { > > - red_current_flush(display, 0); > > - push_new_primary_surface(dcc); > > - red_push_surface_image(dcc, 0); > > - dcc_push_monitors_config(dcc); > > - red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_MARK); > > - dcc_create_all_streams(dcc); > > - } > > -} > > - > > static GlzSharedDictionary *_red_find_glz_dictionary(RedClient *client, > > uint8_t dict_id) > > { > > RingItem *now; > > @@ -6712,12 +6527,9 @@ static void handle_new_display_channel(RedWorker > > *worker, RedClient *client, Red > > { > > DisplayChannel *display_channel; > > DisplayChannelClient *dcc; > > - size_t stream_buf_size; > > > > - if (!worker->display_channel) { > > - spice_warning("Display channel was not created"); > > - return; > > - } > > + spice_return_if_fail(worker->display_channel); > > + > > display_channel = worker->display_channel; > > spice_info("add display channel client"); > > dcc = dcc_new(display_channel, client, stream, migrate, > > @@ -6726,14 +6538,6 @@ static void handle_new_display_channel(RedWorker > > *worker, RedClient *client, Red > > if (!dcc) { > > return; > > } > > - spice_info("New display (client %p) dcc %p stream %p", client, dcc, > > stream); > > - stream_buf_size = 32*1024; > > - dcc->send_data.stream_outbuf = spice_malloc(stream_buf_size); > > - dcc->send_data.stream_outbuf_size = stream_buf_size; > > - dcc->send_data.free_list.res = > > - spice_malloc(sizeof(SpiceResourceList) + > > - DISPLAY_FREE_LIST_DEFAULT_SIZE * > > sizeof(SpiceResourceID)); > > - dcc->send_data.free_list.res_size = DISPLAY_FREE_LIST_DEFAULT_SIZE; > > > > if (dcc->jpeg_state == SPICE_WAN_COMPRESSION_AUTO) { > > display_channel->enable_jpeg = dcc->common.is_low_bandwidth; > > @@ -6747,14 +6551,11 @@ static void handle_new_display_channel(RedWorker > > *worker, RedClient *client, Red > > display_channel->enable_zlib_glz_wrap = (dcc->zlib_glz_state == > > SPICE_WAN_COMPRESSION_ALWAYS); > > } > > - > > spice_info("jpeg %s", display_channel->enable_jpeg ? "enabled" : > > "disabled"); > > spice_info("zlib-over-glz %s", display_channel->enable_zlib_glz_wrap ? > > "enabled" : "disabled"); > > > > guest_set_client_capabilities(worker); > > - > > - dcc_init_stream_agents(dcc); > > - on_new_display_channel_client(dcc); > > + dcc_start(dcc); > > } > > > > static void red_connect_cursor(RedWorker *worker, RedClient *client, > > RedsStream *stream, > > @@ -7071,7 +6872,7 @@ static void flush_all_surfaces(DisplayChannel > > *display) > > > > for (x = 0; x < NUM_SURFACES; ++x) { > > if (display->surfaces[x].context.canvas) { > > - red_current_flush(display, x); > > + display_channel_current_flush(display, x); > > } > > } > > } > > -- > > 2.4.3 > > > > _______________________________________________ > > Spice-devel mailing list > > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > > http://lists.freedesktop.org/mailman/listinfo/spice-devel > > Seems good. ACK. > Merged Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel