[Spice-devel] [PATCH 06/16] worker: move DisplayChannel/DisplayChannelClient functions together

Frediano Ziglio fziglio at redhat.com
Wed Nov 11 02:06:36 PST 2015


> 
> ACK
> 

Merged (yesterday)

Frediano

> 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