[Spice-devel] [PATCH 06/16] worker: move DisplayChannel/DisplayChannelClient functions together
Jonathon Jongsma
jjongsma at redhat.com
Tue Nov 10 07:54:00 PST 2015
ACK
On Tue, 2015-11-10 at 14:16 +0000, Frediano Ziglio wrote:
> From: Marc-André Lureau <marcandre.lureau at gmail.com>
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
> server/red_worker.c | 327 ++++++++++++++++++++++++++----------------
> ----------
> 1 file changed, 164 insertions(+), 163 deletions(-)
>
> diff --git a/server/red_worker.c b/server/red_worker.c
> index 816938c..1284e44 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -516,6 +516,138 @@ static void
> display_channel_client_release_item_after_push(DisplayChannelClient
> SAFE_FOREACH(link, next, drawable, &(drawable)->glz_ring, glz,
> LINK_TO_GLZ(link))
>
>
> +static inline int get_stream_id(RedWorker *worker, Stream *stream)
> +{
> + return (int)(stream - worker->streams_buf);
> +}
> +
> +static inline void red_free_stream(RedWorker *worker, Stream
> *stream)
> +{
> + stream->next = worker->free_streams;
> + worker->free_streams = stream;
> +}
> +
> +static void red_release_stream(RedWorker *worker, Stream *stream)
> +{
> + if (!--stream->refs) {
> + spice_assert(!ring_item_is_linked(&stream->link));
> + red_free_stream(worker, stream);
> + worker->stream_count--;
> + }
> +}
> +
> +static void red_display_release_stream(RedWorker *worker,
> StreamAgent *agent)
> +{
> + spice_assert(agent->stream);
> + red_release_stream(worker, agent->stream);
> +}
> +
> +static void red_display_release_stream_clip(RedWorker *worker,
> StreamClipItem *item)
> +{
> + if (!--item->refs) {
> + red_display_release_stream(worker, item->stream_agent);
> + free(item->rects);
> + free(item);
> + }
> +}
> +
> +static void dcc_push_stream_agent_clip(DisplayChannelClient* dcc,
> StreamAgent *agent)
> +{
> + StreamClipItem *item = stream_clip_item_new(dcc, agent);
> + int n_rects;
> +
> + if (!item) {
> + spice_critical("alloc failed");
> + }
> + item->clip_type = SPICE_CLIP_TYPE_RECTS;
> +
> + n_rects = pixman_region32_n_rects(&agent->clip);
> +
> + item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect),
> sizeof(SpiceClipRects));
> + item->rects->num_rects = n_rects;
> + region_ret_rects(&agent->clip, item->rects->rects, n_rects);
> + red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), (PipeItem
> *)item);
> +}
> +
> +
> +static void red_attach_stream(RedWorker *worker, Drawable *drawable,
> Stream *stream)
> +{
> + DisplayChannelClient *dcc;
> + RingItem *item, *next;
> +
> + spice_assert(!drawable->stream && !stream->current);
> + spice_assert(drawable && stream);
> + stream->current = drawable;
> + drawable->stream = stream;
> + stream->last_time = drawable->creation_time;
> +
> + uint64_t duration = drawable->creation_time - stream
> ->input_fps_start_time;
> + if (duration >= RED_STREAM_INPUT_FPS_TIMEOUT) {
> + /* Round to the nearest integer, for instance 24 for 23.976
> */
> + stream->input_fps = ((uint64_t)stream->num_input_frames *
> 1000 * 1000 * 1000 + duration / 2) / duration;
> + spice_debug("input-fps=%u", stream->input_fps);
> + stream->num_input_frames = 0;
> + stream->input_fps_start_time = drawable->creation_time;
> + } else {
> + stream->num_input_frames++;
> + }
> +
> + FOREACH_DCC(worker->display_channel, item, next, dcc) {
> + StreamAgent *agent;
> + QRegion clip_in_draw_dest;
> +
> + agent = &dcc->stream_agents[get_stream_id(worker, stream)];
> + region_or(&agent->vis_region, &drawable
> ->tree_item.base.rgn);
> +
> + region_init(&clip_in_draw_dest);
> + region_add(&clip_in_draw_dest, &drawable->red_drawable
> ->bbox);
> + region_and(&clip_in_draw_dest, &agent->clip);
> +
> + if (!region_is_equal(&clip_in_draw_dest, &drawable
> ->tree_item.base.rgn)) {
> + region_remove(&agent->clip, &drawable->red_drawable
> ->bbox);
> + region_or(&agent->clip, &drawable->tree_item.base.rgn);
> + dcc_push_stream_agent_clip(dcc, agent);
> + }
> +#ifdef STREAM_STATS
> + agent->stats.num_input_frames++;
> +#endif
> + }
> +}
> +
> +static void red_stop_stream(RedWorker *worker, Stream *stream)
> +{
> + DisplayChannelClient *dcc;
> + RingItem *item, *next;
> +
> + spice_assert(ring_item_is_linked(&stream->link));
> + spice_assert(!stream->current);
> + spice_debug("stream %d", get_stream_id(worker, stream));
> + FOREACH_DCC(worker->display_channel, item, next, dcc) {
> + StreamAgent *stream_agent;
> +
> + stream_agent = &dcc->stream_agents[get_stream_id(worker,
> stream)];
> + region_clear(&stream_agent->vis_region);
> + region_clear(&stream_agent->clip);
> + spice_assert(!pipe_item_is_linked(&stream_agent
> ->destroy_item));
> + if (stream_agent->mjpeg_encoder && dcc
> ->use_mjpeg_encoder_rate_control) {
> + uint64_t stream_bit_rate =
> mjpeg_encoder_get_bit_rate(stream_agent->mjpeg_encoder);
> +
> + if (stream_bit_rate > dcc->streams_max_bit_rate) {
> + spice_debug("old max-bit-rate=%.2f new=%.2f",
> + dcc->streams_max_bit_rate / 8.0 / 1024.0 / 1024.0,
> + stream_bit_rate / 8.0 / 1024.0 / 1024.0);
> + dcc->streams_max_bit_rate = stream_bit_rate;
> + }
> + }
> + stream->refs++;
> + red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc),
> &stream_agent->destroy_item);
> + stream_agent_stats_print(stream_agent);
> + }
> + worker->streams_size_total -= stream->width * stream->height;
> + ring_remove(&stream->link);
> + red_release_stream(worker, stream);
> +}
> +
> /* fixme: move to display channel */
> DrawablePipeItem *drawable_pipe_item_new(DisplayChannelClient *dcc,
> Drawable *drawable)
> @@ -880,6 +1012,25 @@ static inline void
> red_destroy_surface_item(RedWorker *worker,
> red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &destroy
> ->pipe_item);
> }
>
> +static void red_reset_stream_trace(RedWorker *worker)
> +{
> + Ring *ring = &worker->streams;
> + RingItem *item = ring_get_head(ring);
> +
> + while (item) {
> + Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
> + item = ring_next(ring, item);
> + if (!stream->current) {
> + red_stop_stream(worker, stream);
> + } else {
> + spice_info("attached stream");
> + }
> + }
> +
> + worker->next_item_trace = 0;
> + memset(worker->items_trace, 0, sizeof(worker->items_trace));
> +}
> +
> static void red_surface_unref(RedWorker *worker, uint32_t
> surface_id)
> {
> RedSurface *surface = &worker->surfaces[surface_id];
> @@ -1504,21 +1655,6 @@ static int is_same_drawable(RedWorker *worker,
> Drawable *d1, Drawable *d2)
> }
> }
>
> -static inline void red_free_stream(RedWorker *worker, Stream
> *stream)
> -{
> - stream->next = worker->free_streams;
> - worker->free_streams = stream;
> -}
> -
> -static void red_release_stream(RedWorker *worker, Stream *stream)
> -{
> - if (!--stream->refs) {
> - spice_assert(!ring_item_is_linked(&stream->link));
> - red_free_stream(worker, stream);
> - worker->stream_count--;
> - }
> -}
> -
> static inline void red_detach_stream(RedWorker *worker, Stream
> *stream, int detach_sized)
> {
> spice_assert(stream->current && stream->current->stream);
> @@ -1530,116 +1666,6 @@ static inline void
> red_detach_stream(RedWorker *worker, Stream *stream, int deta
> stream->current = NULL;
> }
>
> -static void dcc_push_stream_agent_clip(DisplayChannelClient* dcc,
> StreamAgent *agent)
> -{
> - StreamClipItem *item = stream_clip_item_new(dcc, agent);
> - int n_rects;
> -
> - if (!item) {
> - spice_critical("alloc failed");
> - }
> - item->clip_type = SPICE_CLIP_TYPE_RECTS;
> -
> - n_rects = pixman_region32_n_rects(&agent->clip);
> -
> - item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect),
> sizeof(SpiceClipRects));
> - item->rects->num_rects = n_rects;
> - region_ret_rects(&agent->clip, item->rects->rects, n_rects);
> - red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), (PipeItem
> *)item);
> -}
> -
> -static void red_display_release_stream_clip(RedWorker *worker,
> StreamClipItem *item)
> -{
> - if (!--item->refs) {
> - red_display_release_stream(worker, item->stream_agent);
> - free(item->rects);
> - free(item);
> - }
> -}
> -
> -static inline int get_stream_id(RedWorker *worker, Stream *stream)
> -{
> - return (int)(stream - worker->streams_buf);
> -}
> -
> -static void red_attach_stream(RedWorker *worker, Drawable *drawable,
> Stream *stream)
> -{
> - DisplayChannelClient *dcc;
> - RingItem *item, *next;
> -
> - spice_assert(!drawable->stream && !stream->current);
> - spice_assert(drawable && stream);
> - stream->current = drawable;
> - drawable->stream = stream;
> - stream->last_time = drawable->creation_time;
> -
> - uint64_t duration = drawable->creation_time - stream
> ->input_fps_start_time;
> - if (duration >= RED_STREAM_INPUT_FPS_TIMEOUT) {
> - /* Round to the nearest integer, for instance 24 for 23.976
> */
> - stream->input_fps = ((uint64_t)stream->num_input_frames *
> 1000 * 1000 * 1000 + duration / 2) / duration;
> - spice_debug("input-fps=%u", stream->input_fps);
> - stream->num_input_frames = 0;
> - stream->input_fps_start_time = drawable->creation_time;
> - } else {
> - stream->num_input_frames++;
> - }
> -
> - FOREACH_DCC(worker->display_channel, item, next, dcc) {
> - StreamAgent *agent;
> - QRegion clip_in_draw_dest;
> -
> - agent = &dcc->stream_agents[get_stream_id(worker, stream)];
> - region_or(&agent->vis_region, &drawable
> ->tree_item.base.rgn);
> -
> - region_init(&clip_in_draw_dest);
> - region_add(&clip_in_draw_dest, &drawable->red_drawable
> ->bbox);
> - region_and(&clip_in_draw_dest, &agent->clip);
> -
> - if (!region_is_equal(&clip_in_draw_dest, &drawable
> ->tree_item.base.rgn)) {
> - region_remove(&agent->clip, &drawable->red_drawable
> ->bbox);
> - region_or(&agent->clip, &drawable->tree_item.base.rgn);
> - dcc_push_stream_agent_clip(dcc, agent);
> - }
> -#ifdef STREAM_STATS
> - agent->stats.num_input_frames++;
> -#endif
> - }
> -}
> -
> -static void red_stop_stream(RedWorker *worker, Stream *stream)
> -{
> - DisplayChannelClient *dcc;
> - RingItem *item, *next;
> -
> - spice_assert(ring_item_is_linked(&stream->link));
> - spice_assert(!stream->current);
> - spice_debug("stream %d", get_stream_id(worker, stream));
> - FOREACH_DCC(worker->display_channel, item, next, dcc) {
> - StreamAgent *stream_agent;
> -
> - stream_agent = &dcc->stream_agents[get_stream_id(worker,
> stream)];
> - region_clear(&stream_agent->vis_region);
> - region_clear(&stream_agent->clip);
> - spice_assert(!pipe_item_is_linked(&stream_agent
> ->destroy_item));
> - if (stream_agent->mjpeg_encoder && dcc
> ->use_mjpeg_encoder_rate_control) {
> - uint64_t stream_bit_rate =
> mjpeg_encoder_get_bit_rate(stream_agent->mjpeg_encoder);
> -
> - if (stream_bit_rate > dcc->streams_max_bit_rate) {
> - spice_debug("old max-bit-rate=%.2f new=%.2f",
> - dcc->streams_max_bit_rate / 8.0 / 1024.0 / 1024.0,
> - stream_bit_rate / 8.0 / 1024.0 / 1024.0);
> - dcc->streams_max_bit_rate = stream_bit_rate;
> - }
> - }
> - stream->refs++;
> - red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc),
> &stream_agent->destroy_item);
> - stream_agent_stats_print(stream_agent);
> - }
> - worker->streams_size_total -= stream->width * stream->height;
> - ring_remove(&stream->link);
> - red_release_stream(worker, stream);
> -}
> -
> static int red_display_drawable_is_in_pipe(DisplayChannelClient
> *dcc, Drawable *drawable)
> {
> DrawablePipeItem *dpi;
> @@ -1860,12 +1886,6 @@ static inline void
> red_handle_streams_timout(RedWorker *worker)
> }
> }
>
> -static void red_display_release_stream(RedWorker *worker,
> StreamAgent *agent)
> -{
> - spice_assert(agent->stream);
> - red_release_stream(worker, agent->stream);
> -}
> -
> static inline Stream *red_alloc_stream(RedWorker *worker)
> {
> Stream *stream;
> @@ -2136,19 +2156,6 @@ static void
> dcc_destroy_stream_agents(DisplayChannelClient *dcc)
> }
> }
>
> -static void red_init_streams(RedWorker *worker)
> -{
> - int i;
> -
> - ring_init(&worker->streams);
> - worker->free_streams = NULL;
> - for (i = 0; i < NUM_STREAMS; i++) {
> - Stream *stream = &worker->streams_buf[i];
> - ring_item_init(&stream->link);
> - red_free_stream(worker, stream);
> - }
> -}
> -
> static inline int __red_is_next_stream_frame(RedWorker *worker,
> const Drawable
> *candidate,
> const int
> other_src_width,
> @@ -2569,25 +2576,6 @@ static inline void
> red_use_stream_trace(RedWorker *worker, Drawable *drawable)
> }
> }
>
> -static void red_reset_stream_trace(RedWorker *worker)
> -{
> - Ring *ring = &worker->streams;
> - RingItem *item = ring_get_head(ring);
> -
> - while (item) {
> - Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
> - item = ring_next(ring, item);
> - if (!stream->current) {
> - red_stop_stream(worker, stream);
> - } else {
> - spice_info("attached stream");
> - }
> - }
> -
> - worker->next_item_trace = 0;
> - memset(worker->items_trace, 0, sizeof(worker->items_trace));
> -}
> -
> static inline int red_current_add(RedWorker *worker, Ring *ring,
> Drawable *drawable)
> {
> DrawItem *item = &drawable->tree_item;
> @@ -8858,6 +8846,19 @@ static void
> display_channel_release_item(RedChannelClient *rcc, PipeItem *item,
> }
> }
>
> +static void red_init_streams(RedWorker *worker)
> +{
> + int i;
> +
> + ring_init(&worker->streams);
> + worker->free_streams = NULL;
> + for (i = 0; i < NUM_STREAMS; i++) {
> + Stream *stream = &worker->streams_buf[i];
> + ring_item_init(&stream->link);
> + red_free_stream(worker, stream);
> + }
> +}
> +
> static void display_channel_create(RedWorker *worker, int migrate)
> {
> DisplayChannel *display_channel;
More information about the Spice-devel
mailing list