> > ACK > Merged (yesterday) Frediano > On Tue, 2015-11-10 at 14:16 +0000, Frediano Ziglio wrote: > > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > > > Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> > > --- > > 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; > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel