This is a DisplayChannelClient method, so it belongs in this source file. red_upgrade_item_free() was also moved, since it is only used by this function. Signed-off-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> --- server/dcc.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ server/dcc.h | 3 ++ server/video-stream.c | 81 -------------------------------------------------- server/video-stream.h | 3 -- 4 files changed, 85 insertions(+), 84 deletions(-) diff --git a/server/dcc.c b/server/dcc.c index fb5009e91..a0a3676a4 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -1457,3 +1457,85 @@ gboolean dcc_is_low_bandwidth(DisplayChannelClient *dcc) { return dcc->is_low_bandwidth; } + +static void red_upgrade_item_free(RedPipeItem *base) +{ + g_return_if_fail(base != NULL); + + RedUpgradeItem *item = SPICE_UPCAST(RedUpgradeItem, base); + + g_return_if_fail(item->base.refcount == 0); + + drawable_unref(item->drawable); + g_free(item->rects); + g_free(item); +} + +/* + * after dcc_detach_stream_gracefully is called for all the display channel clients, + * video_stream_detach_drawable should be called. See comment (1). + */ +void dcc_detach_stream_gracefully(DisplayChannelClient *dcc, + VideoStream *stream, + Drawable *update_area_limit) +{ + DisplayChannel *display = DCC_TO_DC(dcc); + int stream_id = display_channel_get_video_stream_id(display, stream); + VideoStreamAgent *agent = dcc_get_video_stream_agent(dcc, stream_id); + + /* stopping the client from playing older frames at once*/ + region_clear(&agent->clip); + dcc_video_stream_agent_clip(dcc, agent); + + if (region_is_empty(&agent->vis_region)) { + spice_debug("stream %d: vis region empty", stream_id); + return; + } + + if (stream->current && + region_contains(&stream->current->tree_item.base.rgn, &agent->vis_region)) { + RedChannelClient *rcc; + RedUpgradeItem *upgrade_item; + int n_rects; + + /* (1) The caller should detach the drawable from the stream. This will + * lead to sending the drawable losslessly, as an ordinary drawable. */ + if (dcc_drawable_is_in_pipe(dcc, stream->current)) { + spice_debug("stream %d: upgrade by linked drawable. box ==>", + stream_id); + rect_debug(&stream->current->red_drawable->bbox); + goto clear_vis_region; + } + spice_debug("stream %d: upgrade by drawable. box ==>", stream_id); + rect_debug(&stream->current->red_drawable->bbox); + rcc = RED_CHANNEL_CLIENT(dcc); + upgrade_item = g_new(RedUpgradeItem, 1); + red_pipe_item_init_full(&upgrade_item->base, RED_PIPE_ITEM_TYPE_UPGRADE, + red_upgrade_item_free); + upgrade_item->drawable = stream->current; + upgrade_item->drawable->refs++; + n_rects = pixman_region32_n_rects(&upgrade_item->drawable->tree_item.base.rgn); + upgrade_item->rects = g_malloc(sizeof(SpiceClipRects) + n_rects * sizeof(SpiceRect)); + upgrade_item->rects->num_rects = n_rects; + region_ret_rects(&upgrade_item->drawable->tree_item.base.rgn, + upgrade_item->rects->rects, n_rects); + red_channel_client_pipe_add(rcc, &upgrade_item->base); + + } else { + SpiceRect upgrade_area; + + region_extents(&agent->vis_region, &upgrade_area); + spice_debug("stream %d: upgrade by screenshot. has current %d. box ==>", + stream_id, stream->current != NULL); + rect_debug(&upgrade_area); + if (update_area_limit) { + display_channel_draw_until(DCC_TO_DC(dcc), &upgrade_area, 0, update_area_limit); + } else { + display_channel_draw(DCC_TO_DC(dcc), &upgrade_area, 0); + } + dcc_add_surface_area_image(dcc, 0, &upgrade_area, NULL, FALSE); + } +clear_vis_region: + region_clear(&agent->vis_region); +} + diff --git a/server/dcc.h b/server/dcc.h index ec7dc3ca9..18f01daaf 100644 --- a/server/dcc.h +++ b/server/dcc.h @@ -199,6 +199,9 @@ uint64_t dcc_get_max_stream_bit_rate(DisplayChannelClient *dcc); void dcc_set_max_stream_bit_rate(DisplayChannelClient *dcc, uint64_t rate); gboolean dcc_is_low_bandwidth(DisplayChannelClient *dcc); GArray *dcc_get_preferred_video_codecs_for_encoding(DisplayChannelClient *dcc); +void dcc_detach_stream_gracefully(DisplayChannelClient *dcc, + VideoStream *stream, + Drawable *update_area_limit); G_END_DECLS diff --git a/server/video-stream.c b/server/video-stream.c index 227824fa0..7bf1ef5af 100644 --- a/server/video-stream.c +++ b/server/video-stream.c @@ -396,87 +396,6 @@ void video_stream_agent_stop(VideoStreamAgent *agent) } } -static void red_upgrade_item_free(RedPipeItem *base) -{ - g_return_if_fail(base != NULL); - - RedUpgradeItem *item = SPICE_UPCAST(RedUpgradeItem, base); - - g_return_if_fail(item->base.refcount == 0); - - drawable_unref(item->drawable); - g_free(item->rects); - g_free(item); -} - -/* - * after dcc_detach_stream_gracefully is called for all the display channel clients, - * video_stream_detach_drawable should be called. See comment (1). - */ -void dcc_detach_stream_gracefully(DisplayChannelClient *dcc, - VideoStream *stream, - Drawable *update_area_limit) -{ - DisplayChannel *display = DCC_TO_DC(dcc); - int stream_id = display_channel_get_video_stream_id(display, stream); - VideoStreamAgent *agent = dcc_get_video_stream_agent(dcc, stream_id); - - /* stopping the client from playing older frames at once*/ - region_clear(&agent->clip); - dcc_video_stream_agent_clip(dcc, agent); - - if (region_is_empty(&agent->vis_region)) { - spice_debug("stream %d: vis region empty", stream_id); - return; - } - - if (stream->current && - region_contains(&stream->current->tree_item.base.rgn, &agent->vis_region)) { - RedChannelClient *rcc; - RedUpgradeItem *upgrade_item; - int n_rects; - - /* (1) The caller should detach the drawable from the stream. This will - * lead to sending the drawable losslessly, as an ordinary drawable. */ - if (dcc_drawable_is_in_pipe(dcc, stream->current)) { - spice_debug("stream %d: upgrade by linked drawable. box ==>", - stream_id); - rect_debug(&stream->current->red_drawable->bbox); - goto clear_vis_region; - } - spice_debug("stream %d: upgrade by drawable. box ==>", stream_id); - rect_debug(&stream->current->red_drawable->bbox); - rcc = RED_CHANNEL_CLIENT(dcc); - upgrade_item = g_new(RedUpgradeItem, 1); - red_pipe_item_init_full(&upgrade_item->base, RED_PIPE_ITEM_TYPE_UPGRADE, - red_upgrade_item_free); - upgrade_item->drawable = stream->current; - upgrade_item->drawable->refs++; - n_rects = pixman_region32_n_rects(&upgrade_item->drawable->tree_item.base.rgn); - upgrade_item->rects = g_malloc(sizeof(SpiceClipRects) + n_rects * sizeof(SpiceRect)); - upgrade_item->rects->num_rects = n_rects; - region_ret_rects(&upgrade_item->drawable->tree_item.base.rgn, - upgrade_item->rects->rects, n_rects); - red_channel_client_pipe_add(rcc, &upgrade_item->base); - - } else { - SpiceRect upgrade_area; - - region_extents(&agent->vis_region, &upgrade_area); - spice_debug("stream %d: upgrade by screenshot. has current %d. box ==>", - stream_id, stream->current != NULL); - rect_debug(&upgrade_area); - if (update_area_limit) { - display_channel_draw_until(DCC_TO_DC(dcc), &upgrade_area, 0, update_area_limit); - } else { - display_channel_draw(DCC_TO_DC(dcc), &upgrade_area, 0); - } - dcc_add_surface_area_image(dcc, 0, &upgrade_area, NULL, FALSE); - } -clear_vis_region: - region_clear(&agent->vis_region); -} - /* * region : a primary surface region. Streams that intersects with the given * region will be detached. diff --git a/server/video-stream.h b/server/video-stream.h index b1c50ea25..df95c0573 100644 --- a/server/video-stream.h +++ b/server/video-stream.h @@ -137,8 +137,5 @@ void video_stream_agent_unref(VideoStreamAgent *agent); void video_stream_agent_stop(VideoStreamAgent *agent); void video_stream_detach_drawable(VideoStream *stream); -void dcc_detach_stream_gracefully(DisplayChannelClient *dcc, - VideoStream *stream, - Drawable *update_area_limit); #endif /* VIDEO_STREAM_H_ */ -- 2.13.6 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel