From 0e224d04fbd9a05a3289b19c32e9a8fd4afca086 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Tue, 17 Sep 2013 16:29:44 +0200 Subject: worker: move dcc_start() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Author: Marc-André Lureau Acked-by: Fabiano Fidêncio --- server/red_worker.c | 237 +++++----------------------------------------------- 1 file changed, 19 insertions(+), 218 deletions(-) (limited to 'server/red_worker.c') diff --git a/server/red_worker.c b/server/red_worker.c index 76698548..a6e6b6a5 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; @@ -3501,7 +3427,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; @@ -3557,7 +3483,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); } @@ -3578,7 +3504,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); } } @@ -5574,60 +5500,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); } } @@ -5638,7 +5517,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); } } @@ -5803,70 +5682,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; @@ -6707,12 +6522,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, @@ -6721,14 +6533,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; @@ -6742,14 +6546,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, @@ -7066,7 +6867,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); } } } -- cgit