diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-09-25 18:31:39 +0200 |
---|---|---|
committer | Fabiano Fidêncio <fidencio@redhat.com> | 2015-02-23 23:00:39 +0100 |
commit | 1e206fa0bd76d8113cadc54a89e5e820cf979310 (patch) | |
tree | 46eef4425b490108cc1d9942c6f7862cfe43fef5 /server | |
parent | 7f7f94fa383bdc44b6fa5ce088725a886f83d966 (diff) | |
download | spice-1e206fa0bd76d8113cadc54a89e5e820cf979310.tar.gz spice-1e206fa0bd76d8113cadc54a89e5e820cf979310.tar.xz spice-1e206fa0bd76d8113cadc54a89e5e820cf979310.zip |
worker: move dcc_add_drawable*
Diffstat (limited to 'server')
-rw-r--r-- | server/dcc.c | 82 | ||||
-rw-r--r-- | server/dcc.h | 17 | ||||
-rw-r--r-- | server/display_channel.c | 63 | ||||
-rw-r--r-- | server/display_channel.h | 19 | ||||
-rw-r--r-- | server/red_worker.c | 144 |
5 files changed, 156 insertions, 169 deletions
diff --git a/server/dcc.c b/server/dcc.c index 539bcd50..dd175e8b 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -61,6 +61,88 @@ void dcc_push_surface_image(DisplayChannelClient *dcc, int surface_id) red_channel_client_push(RED_CHANNEL_CLIENT(dcc)); } +static void add_drawable_surface_images(DisplayChannelClient *dcc, Drawable *drawable) +{ + DisplayChannel *display = DCC_TO_DC(dcc); + int x; + + for (x = 0; x < 3; ++x) { + int surface_id; + + surface_id = drawable->surface_deps[x]; + if (surface_id != -1) { + if (dcc->surface_client_created[surface_id] == TRUE) { + continue; + } + dcc_create_surface(dcc, surface_id); + display_channel_current_flush(display, surface_id); + dcc_push_surface_image(dcc, surface_id); + } + } + + if (dcc->surface_client_created[drawable->surface_id] == TRUE) { + return; + } + + dcc_create_surface(dcc, drawable->surface_id); + display_channel_current_flush(display, drawable->surface_id); + dcc_push_surface_image(dcc, drawable->surface_id); +} + +DrawablePipeItem *drawable_pipe_item_ref(DrawablePipeItem *dpi) +{ + dpi->refs++; + return dpi; +} + +void drawable_pipe_item_unref(DrawablePipeItem *dpi) +{ + DisplayChannel *display = DCC_TO_DC(dpi->dcc); + + if (--dpi->refs) + return; + + spice_return_if_fail(!ring_item_is_linked(&dpi->dpi_pipe_item.link)); + spice_return_if_fail(!ring_item_is_linked(&dpi->base)); + display_channel_drawable_unref(display, dpi->drawable); + free(dpi); +} + +static DrawablePipeItem *drawable_pipe_item_new(DisplayChannelClient *dcc, Drawable *drawable) +{ + DrawablePipeItem *dpi; + + dpi = spice_malloc0(sizeof(*dpi)); + dpi->drawable = drawable; + dpi->dcc = dcc; + ring_item_init(&dpi->base); + ring_add(&drawable->pipes, &dpi->base); + red_channel_pipe_item_init(RED_CHANNEL_CLIENT(dcc)->channel, + &dpi->dpi_pipe_item, PIPE_ITEM_TYPE_DRAW); + dpi->refs++; + drawable->refs++; + return dpi; +} + +void dcc_add_drawable(DisplayChannelClient *dcc, Drawable *drawable, bool to_tail) +{ + DrawablePipeItem *dpi = drawable_pipe_item_new(dcc, drawable); + + add_drawable_surface_images(dcc, drawable); + if (to_tail) + red_channel_client_pipe_add_tail(RED_CHANNEL_CLIENT(dcc), &dpi->dpi_pipe_item); + else + red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &dpi->dpi_pipe_item); +} + +void dcc_add_drawable_after(DisplayChannelClient *dcc, Drawable *drawable, PipeItem *pos) +{ + DrawablePipeItem *dpi = drawable_pipe_item_new(dcc, drawable); + + add_drawable_surface_images(dcc, drawable); + red_channel_client_pipe_add_after(RED_CHANNEL_CLIENT(dcc), &dpi->dpi_pipe_item, pos); +} + static void dcc_init_stream_agents(DisplayChannelClient *dcc) { int i; diff --git a/server/dcc.h b/server/dcc.h index e2a99e54..d478be47 100644 --- a/server/dcc.h +++ b/server/dcc.h @@ -119,6 +119,17 @@ typedef struct ImageItem { uint8_t data[0]; } ImageItem; +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 */ + Drawable *drawable; + DisplayChannelClient *dcc; + uint8_t refs; +} DrawablePipeItem; + +void drawable_pipe_item_unref (DrawablePipeItem *dpi); +DrawablePipeItem* drawable_pipe_item_ref (DrawablePipeItem *dpi); + DisplayChannelClient* dcc_new (DisplayChannel *display, RedClient *client, RedsStream *stream, @@ -153,6 +164,12 @@ void dcc_palette_cache_palette (DisplayCha uint8_t *flags); int dcc_pixmap_cache_add (DisplayChannelClient *dcc, uint64_t id, uint32_t size, int lossy); +void dcc_add_drawable (DisplayChannelClient *dcc, + Drawable *drawable, + bool to_tail); +void dcc_add_drawable_after (DisplayChannelClient *dcc, + Drawable *drawable, + PipeItem *pos); typedef struct compress_send_data_t { void* comp_buf; diff --git a/server/display_channel.c b/server/display_channel.c index 83385bf5..8ee8e6d5 100644 --- a/server/display_channel.c +++ b/server/display_channel.c @@ -337,6 +337,50 @@ static void streams_update_visible_region(DisplayChannel *display, Drawable *dra } } +static void pipes_add_drawable(DisplayChannel *display, Drawable *drawable) +{ + DisplayChannelClient *dcc; + RingItem *dcc_ring_item, *next; + + spice_warn_if(!ring_is_empty(&drawable->pipes)); + FOREACH_DCC(display, dcc_ring_item, next, dcc) { + dcc_add_drawable(dcc, drawable, FALSE); + } +} + +static void pipes_add_drawable_after(DisplayChannel *display, + Drawable *drawable, Drawable *pos_after) +{ + DrawablePipeItem *dpi_pos_after; + RingItem *dpi_link, *dpi_next; + DisplayChannelClient *dcc; + int num_other_linked = 0; + + DRAWABLE_FOREACH_DPI_SAFE(pos_after, dpi_link, dpi_next, dpi_pos_after) { + num_other_linked++; + dcc_add_drawable_after(dpi_pos_after->dcc, drawable, &dpi_pos_after->dpi_pipe_item); + } + if (num_other_linked == 0) { + pipes_add_drawable(display, drawable); + return; + } + if (num_other_linked != display->common.base.clients_num) { + RingItem *item, *next; + spice_debug("TODO: not O(n^2)"); + FOREACH_DCC(display, item, next, dcc) { + int sent = 0; + DRAWABLE_FOREACH_DPI_SAFE(pos_after, dpi_link, dpi_next, dpi_pos_after) { + if (dpi_pos_after->dcc == dcc) { + sent = 1; + break; + } + } + if (!sent) { + dcc_add_drawable(dcc, drawable, FALSE); + } + } + } +} static void current_add_drawable(DisplayChannel *display, Drawable *drawable, RingItem *pos) @@ -378,9 +422,9 @@ static int current_add_equal(DisplayChannel *display, DrawItem *item, TreeItem * other_drawable->refs++; current_remove_drawable(display, other_drawable); if (add_after) { - red_pipes_add_drawable_after(display, drawable, other_drawable); + pipes_add_drawable_after(display, drawable, other_drawable); } else { - red_pipes_add_drawable(display, drawable); + pipes_add_drawable(display, drawable); } red_pipes_remove_drawable(other_drawable); display_channel_drawable_unref(display, other_drawable); @@ -408,7 +452,7 @@ static int current_add_equal(DisplayChannel *display, DrawItem *item, TreeItem * common.base.channel_link); dpi = SPICE_CONTAINEROF(dpi_ring_item, DrawablePipeItem, base); while (worker_ring_item && (!dpi || dcc != dpi->dcc)) { - dcc_add_drawable(dcc, drawable); + dcc_add_drawable(dcc, drawable, FALSE); worker_ring_item = ring_next(&RED_CHANNEL(display)->clients, worker_ring_item); dcc = SPICE_CONTAINEROF(worker_ring_item, DisplayChannelClient, @@ -435,7 +479,7 @@ static int current_add_equal(DisplayChannel *display, DrawItem *item, TreeItem * current_add_drawable(display, drawable, &other->siblings_link); red_pipes_remove_drawable(other_drawable); current_remove_drawable(display, other_drawable); - red_pipes_add_drawable(display, drawable); + pipes_add_drawable(display, drawable); return TRUE; } break; @@ -792,20 +836,21 @@ void display_channel_print_stats(DisplayChannel *display) #endif } -int display_channel_add_drawable(DisplayChannel *display, Drawable *drawable) +void display_channel_add_drawable(DisplayChannel *display, Drawable *drawable) { - int ret = FALSE, surface_id = drawable->surface_id; + int success = FALSE, surface_id = drawable->surface_id; RedDrawable *red_drawable = drawable->red_drawable; Ring *ring = &display->surfaces[surface_id].current; if (has_shadow(red_drawable)) { - ret = current_add_with_shadow(display, ring, drawable); + success = current_add_with_shadow(display, ring, drawable); } else { drawable->streamable = drawable_can_stream(display, drawable); - ret = current_add(display, ring, drawable); + success = current_add(display, ring, drawable); } - return ret; + if (success) + pipes_add_drawable(display, drawable); } int display_channel_wait_for_migrate_data(DisplayChannel *display) diff --git a/server/display_channel.h b/server/display_channel.h index 1f2fa93f..f1a3e59e 100644 --- a/server/display_channel.h +++ b/server/display_channel.h @@ -99,19 +99,6 @@ enum { PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT, }; -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 */ - Drawable *drawable; - DisplayChannelClient *dcc; - uint8_t refs; -} DrawablePipeItem; - -DrawablePipeItem* drawable_pipe_item_new (DisplayChannelClient *dcc, - Drawable *drawable); -void drawable_pipe_item_unref (DrawablePipeItem *dpi); -DrawablePipeItem* drawable_pipe_item_ref (DrawablePipeItem *dpi); - typedef struct MonitorsConfig { int refs; int count; @@ -268,7 +255,7 @@ void display_channel_set_surface_release_info (DisplayCha QXLReleaseInfo *info, uint32_t group_id); void display_channel_show_tree (DisplayChannel *display); -int display_channel_add_drawable (DisplayChannel *display, +void display_channel_add_drawable (DisplayChannel *display, Drawable *drawable); void display_channel_current_flush (DisplayChannel *display, int surface_id); @@ -392,12 +379,8 @@ static inline void region_add_clip_rects(QRegion *rgn, SpiceClipRects *data) } } -void red_pipes_add_drawable(DisplayChannel *display, Drawable *drawable); void current_remove_drawable(DisplayChannel *display, Drawable *item); -void red_pipes_add_drawable_after(DisplayChannel *display, - Drawable *drawable, Drawable *pos_after); void red_pipes_remove_drawable(Drawable *drawable); -void dcc_add_drawable(DisplayChannelClient *dcc, Drawable *drawable); void current_remove(DisplayChannel *display, TreeItem *item); void detach_streams_behind(DisplayChannel *display, QRegion *region, Drawable *drawable); diff --git a/server/red_worker.c b/server/red_worker.c index 14b0fb31..8a0df075 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -181,44 +181,6 @@ GMainContext* red_worker_get_context(RedWorker *worker) return worker->main_context; } -/* fixme: move to display channel */ -DrawablePipeItem *drawable_pipe_item_new(DisplayChannelClient *dcc, - Drawable *drawable) -{ - DrawablePipeItem *dpi; - - dpi = spice_malloc0(sizeof(*dpi)); - dpi->drawable = drawable; - dpi->dcc = dcc; - ring_item_init(&dpi->base); - ring_add(&drawable->pipes, &dpi->base); - red_channel_pipe_item_init(RED_CHANNEL_CLIENT(dcc)->channel, - &dpi->dpi_pipe_item, PIPE_ITEM_TYPE_DRAW); - dpi->refs++; - drawable->refs++; - return dpi; -} - -DrawablePipeItem *drawable_pipe_item_ref(DrawablePipeItem *dpi) -{ - dpi->refs++; - return dpi; -} - -void drawable_pipe_item_unref(DrawablePipeItem *dpi) -{ - DisplayChannel *display = DCC_TO_DC(dpi->dcc); - - if (--dpi->refs) { - return; - } - - spice_return_if_fail(!ring_item_is_linked(&dpi->dpi_pipe_item.link)); - spice_return_if_fail(!ring_item_is_linked(&dpi->base)); - display_channel_drawable_unref(display, dpi->drawable); - free(dpi); -} - QXLInstance* red_worker_get_qxl(RedWorker *worker) { spice_return_val_if_fail(worker != NULL, NULL); @@ -242,35 +204,6 @@ static inline int validate_surface(DisplayChannel *display, uint32_t surface_id) } -static inline void red_handle_drawable_surfaces_client_synced( - DisplayChannelClient *dcc, Drawable *drawable) -{ - DisplayChannel *display = DCC_TO_DC(dcc); - int x; - - for (x = 0; x < 3; ++x) { - int surface_id; - - surface_id = drawable->surface_deps[x]; - if (surface_id != -1) { - if (dcc->surface_client_created[surface_id] == TRUE) { - continue; - } - dcc_create_surface(dcc, surface_id); - display_channel_current_flush(display, surface_id); - dcc_push_surface_image(dcc, surface_id); - } - } - - if (dcc->surface_client_created[drawable->surface_id] == TRUE) { - return; - } - - 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) { return worker->display_channel && @@ -283,76 +216,6 @@ static int cursor_is_connected(RedWorker *worker) red_channel_is_connected(RED_CHANNEL(worker->cursor_channel)); } -void dcc_add_drawable(DisplayChannelClient *dcc, Drawable *drawable) -{ - DrawablePipeItem *dpi; - - red_handle_drawable_surfaces_client_synced(dcc, drawable); - dpi = drawable_pipe_item_new(dcc, drawable); - red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &dpi->dpi_pipe_item); -} - -void red_pipes_add_drawable(DisplayChannel *display, Drawable *drawable) -{ - DisplayChannelClient *dcc; - RingItem *dcc_ring_item, *next; - - spice_warn_if(!ring_is_empty(&drawable->pipes)); - FOREACH_DCC(display, dcc_ring_item, next, dcc) { - dcc_add_drawable(dcc, drawable); - } -} - -static void dcc_add_drawable_to_tail(DisplayChannelClient *dcc, Drawable *drawable) -{ - DrawablePipeItem *dpi; - - if (!dcc) { - return; - } - red_handle_drawable_surfaces_client_synced(dcc, drawable); - dpi = drawable_pipe_item_new(dcc, drawable); - red_channel_client_pipe_add_tail(RED_CHANNEL_CLIENT(dcc), &dpi->dpi_pipe_item); -} - -void red_pipes_add_drawable_after(DisplayChannel *display, - Drawable *drawable, Drawable *pos_after) -{ - DrawablePipeItem *dpi, *dpi_pos_after; - RingItem *dpi_link, *dpi_next; - DisplayChannelClient *dcc; - int num_other_linked = 0; - - DRAWABLE_FOREACH_DPI_SAFE(pos_after, dpi_link, dpi_next, dpi_pos_after) { - num_other_linked++; - dcc = dpi_pos_after->dcc; - red_handle_drawable_surfaces_client_synced(dcc, drawable); - dpi = drawable_pipe_item_new(dcc, drawable); - red_channel_client_pipe_add_after(RED_CHANNEL_CLIENT(dcc), &dpi->dpi_pipe_item, - &dpi_pos_after->dpi_pipe_item); - } - if (num_other_linked == 0) { - red_pipes_add_drawable(display, drawable); - return; - } - if (num_other_linked != display->common.base.clients_num) { - RingItem *item, *next; - spice_debug("TODO: not O(n^2)"); - FOREACH_DCC(display, item, next, dcc) { - int sent = 0; - DRAWABLE_FOREACH_DPI_SAFE(pos_after, dpi_link, dpi_next, dpi_pos_after) { - if (dpi_pos_after->dcc == dcc) { - sent = 1; - break; - } - } - if (!sent) { - dcc_add_drawable(dcc, drawable); - } - } - } -} - static inline PipeItem *red_pipe_get_tail(DisplayChannelClient *dcc) { if (!dcc) { @@ -1379,10 +1242,7 @@ static gboolean red_process_draw(RedWorker *worker, QXLCommandExt *ext_cmd) goto end; } - if (display_channel_add_drawable(worker->display_channel, drawable)) { - red_pipes_add_drawable(worker->display_channel, drawable); - } - + display_channel_add_drawable(worker->display_channel, drawable); success = TRUE; end: @@ -2685,7 +2545,7 @@ static void red_add_lossless_drawable_dependencies(RedChannelClient *rcc, if (!sync_rendered) { // pushing the pipe item back to the pipe - dcc_add_drawable_to_tail(dcc, item); + dcc_add_drawable(dcc, item, TRUE); // 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++) { |