[Spice-devel] [PATCH 05/18] worker: move dcc_start()

Frediano Ziglio fziglio at redhat.com
Thu Nov 19 04:45:27 PST 2015


> On Wed, Nov 18, 2015 at 5:17 PM, Frediano Ziglio <fziglio at redhat.com> wrote:
> > From: Marc-André Lureau <marcandre.lureau at gmail.com>
> >
> > Author:    Marc-André Lureau <marcandre.lureau at gmail.com>
> > ---
> >  server/dcc.c             | 170 +++++++++++++++++++++++++++++++++
> >  server/dcc.h             |  33 +++++++
> >  server/display-channel.h |   7 +-
> >  server/red_worker.c      | 237
> >  ++++-------------------------------------------
> >  4 files changed, 224 insertions(+), 223 deletions(-)
> >
> > diff --git a/server/dcc.c b/server/dcc.c
> > index 5e35708..2fb0af6 100644
> > --- a/server/dcc.c
> > +++ b/server/dcc.c
> > @@ -18,6 +18,97 @@
> >  #include "dcc.h"
> >  #include "display-channel.h"
> >
> > +static SurfaceCreateItem *surface_create_item_new(RedChannel* channel,
> > +                                                  uint32_t surface_id,
> > uint32_t width,
> > +                                                  uint32_t height,
> > uint32_t format, uint32_t flags)
> > +{
> > +    SurfaceCreateItem *create;
> > +
> > +    create = spice_malloc(sizeof(SurfaceCreateItem));
> > +
> > +    create->surface_create.surface_id = surface_id;
> > +    create->surface_create.width = width;
> > +    create->surface_create.height = height;
> > +    create->surface_create.flags = flags;
> > +    create->surface_create.format = format;
> > +
> > +    red_channel_pipe_item_init(channel,
> > +                               &create->pipe_item,
> > PIPE_ITEM_TYPE_CREATE_SURFACE);
> > +    return create;
> > +}
> > +
> > +void dcc_create_surface(DisplayChannelClient *dcc, int surface_id)
> > +{
> > +    DisplayChannel *display;
> > +    RedSurface *surface;
> > +    SurfaceCreateItem *create;
> > +    uint32_t flags;
> > +
> > +    if (!dcc) {
> > +        return;
> > +    }
> > +
> > +    display = DCC_TO_DC(dcc);
> > +    flags = is_primary_surface(DCC_TO_DC(dcc), surface_id) ?
> > SPICE_SURFACE_FLAGS_PRIMARY : 0;
> > +
> > +    /* don't send redundant create surface commands to client */
> > +    if (!dcc || display->common.during_target_migrate ||
> > +        dcc->surface_client_created[surface_id]) {
> > +        return;
> > +    }
> > +    surface = &display->surfaces[surface_id];
> > +    create = surface_create_item_new(RED_CHANNEL_CLIENT(dcc)->channel,
> > +                                     surface_id, surface->context.width,
> > surface->context.height,
> > +                                     surface->context.format, flags);
> > +    dcc->surface_client_created[surface_id] = TRUE;
> > +    red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc),
> > &create->pipe_item);
> > +}
> > +
> > +void dcc_push_surface_image(DisplayChannelClient *dcc, int surface_id)
> > +{
> > +    DisplayChannel *display;
> > +    SpiceRect area;
> > +    RedSurface *surface;
> > +
> > +    if (!dcc) {
> > +        return;
> > +    }
> > +
> > +    display = DCC_TO_DC(dcc);
> > +    surface = &display->surfaces[surface_id];
> > +    if (!surface->context.canvas) {
> > +        return;
> > +    }
> > +    area.top = area.left = 0;
> > +    area.right = surface->context.width;
> > +    area.bottom = surface->context.height;
> > +
> > +    /* not allowing lossy compression because probably, especially if it
> > is a primary surface,
> > +       it combines both "picture-like" areas with areas that are more
> > "artificial"*/
> > +    dcc_add_surface_area_image(dcc, surface_id, &area, NULL, FALSE);
> > +    red_channel_client_push(RED_CHANNEL_CLIENT(dcc));
> > +}
> > +
> > +static void dcc_init_stream_agents(DisplayChannelClient *dcc)
> > +{
> > +    int i;
> > +    DisplayChannel *display = DCC_TO_DC(dcc);
> > +    RedChannel *channel = RED_CHANNEL_CLIENT(dcc)->channel;
> > +
> > +    for (i = 0; i < NUM_STREAMS; i++) {
> > +        StreamAgent *agent = &dcc->stream_agents[i];
> > +        agent->stream = &display->streams_buf[i];
> > +        region_init(&agent->vis_region);
> > +        region_init(&agent->clip);
> > +        red_channel_pipe_item_init(channel, &agent->create_item,
> > PIPE_ITEM_TYPE_STREAM_CREATE);
> > +        red_channel_pipe_item_init(channel, &agent->destroy_item,
> > PIPE_ITEM_TYPE_STREAM_DESTROY);
> > +    }
> > +    dcc->use_mjpeg_encoder_rate_control =
> > +        red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(dcc),
> > SPICE_DISPLAY_CAP_STREAM_REPORT);
> > +}
> > +
> > +#define DISPLAY_FREE_LIST_DEFAULT_SIZE 128
> > +
> >  DisplayChannelClient *dcc_new(DisplayChannel *display,
> >                                RedClient *client, RedsStream *stream,
> >                                int mig_target,
> > @@ -36,6 +127,7 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
> >          common_caps, num_common_caps,
> >          caps, num_caps);
> >      spice_return_val_if_fail(dcc, NULL);
> > +    spice_info("New display (client %p) dcc %p stream %p", client, dcc,
> > stream);
> >
> >      ring_init(&dcc->palette_cache_lru);
> >      dcc->palette_cache_available = CLIENT_PALETTE_CACHE_SIZE;
> > @@ -45,11 +137,89 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
> >      // todo: tune quality according to bandwidth
> >      dcc->jpeg_quality = 85;
> >
> > +    size_t stream_buf_size;
> > +    stream_buf_size = 32*1024;
> > +    dcc->send_data.stream_outbuf = spice_malloc(stream_buf_size);
> > +    dcc->send_data.stream_outbuf_size = stream_buf_size;
> > +    dcc->send_data.free_list.res =
> > +        spice_malloc(sizeof(SpiceResourceList) +
> > +                     DISPLAY_FREE_LIST_DEFAULT_SIZE *
> > sizeof(SpiceResourceID));
> 
> Could be better indented.
> 
> > +    dcc->send_data.free_list.res_size = DISPLAY_FREE_LIST_DEFAULT_SIZE;
> > +
> > +    dcc_init_stream_agents(dcc);
> > +
> >      dcc_encoders_init(dcc);
> >
> >      return dcc;
> >  }
> >
> > +static void dcc_create_all_streams(DisplayChannelClient *dcc)
> > +{
> > +    Ring *ring = &DCC_TO_DC(dcc)->streams;
> > +    RingItem *item = ring;
> > +
> > +    while ((item = ring_next(ring, item))) {
> > +        Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
> > +        dcc_create_stream(dcc, stream);
> > +    }
> > +}
> > +
> > +/* TODO: this function is evil^Wsynchronous, fix */
> > +static int display_channel_client_wait_for_init(DisplayChannelClient *dcc)
> > +{
> > +    dcc->expect_init = TRUE;
> > +    uint64_t end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT;
> > +    for (;;) {
> > +        red_channel_client_receive(RED_CHANNEL_CLIENT(dcc));
> > +        if (!red_channel_client_is_connected(RED_CHANNEL_CLIENT(dcc))) {
> > +            break;
> > +        }
> > +        if (dcc->pixmap_cache && dcc->glz_dict) {
> > +            dcc->pixmap_cache_generation = dcc->pixmap_cache->generation;
> > +            /* TODO: move common.id? if it's used for a per client
> > structure.. */
> > +            spice_info("creating encoder with id == %d", dcc->common.id);
> > +            dcc->glz = glz_encoder_create(dcc->common.id,
> > dcc->glz_dict->dict, &dcc->glz_data.usr);
> > +            if (!dcc->glz) {
> > +                spice_critical("create global lz failed");
> > +            }
> > +            return TRUE;
> > +        }
> > +        if (red_get_monotonic_time() > end_time) {
> > +            spice_warning("timeout");
> > +            red_channel_client_disconnect(RED_CHANNEL_CLIENT(dcc));
> > +            break;
> > +        }
> > +        usleep(DISPLAY_CLIENT_RETRY_INTERVAL);
> > +    }
> > +    return FALSE;
> > +}
> > +
> > +void dcc_start(DisplayChannelClient *dcc)
> > +{
> > +    DisplayChannel *display = DCC_TO_DC(dcc);
> > +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
> > +
> > +    red_channel_client_push_set_ack(RED_CHANNEL_CLIENT(dcc));
> > +
> > +    if (red_channel_client_waits_for_migrate_data(rcc))
> > +        return;
> > +
> > +    if (!display_channel_client_wait_for_init(dcc))
> > +        return;
> > +
> > +    red_channel_client_ack_zero_messages_window(RED_CHANNEL_CLIENT(dcc));
> > +    if (display->surfaces[0].context.canvas) {
> > +        display_channel_current_flush(display, 0);
> > +        red_channel_client_pipe_add_type(rcc,
> > PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
> > +        dcc_create_surface(dcc, 0);
> > +        dcc_push_surface_image(dcc, 0);
> > +        dcc_push_monitors_config(dcc);
> > +        red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_MARK);
> > +        dcc_create_all_streams(dcc);
> > +    }
> > +}
> > +
> > +
> >  void dcc_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent)
> >  {
> >      StreamClipItem *item = stream_clip_item_new(dcc, agent);
> > diff --git a/server/dcc.h b/server/dcc.h
> > index b66f730..94eaab3 100644
> > --- a/server/dcc.h
> > +++ b/server/dcc.h
> > @@ -30,6 +30,10 @@
> >  #define PALETTE_CACHE_HASH_KEY(id) ((id) & PALETTE_CACHE_HASH_MASK)
> >  #define CLIENT_PALETTE_CACHE_SIZE 128
> >
> > +#define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano
> > +#define DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT 10000000000ULL //nano, 10 sec
> > +#define DISPLAY_CLIENT_RETRY_INTERVAL 10000 //micro
> > +
> >  /* Each drawable can refer to at most 3 images: src, brush and mask */
> >  #define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3
> >
> > @@ -110,6 +114,25 @@ struct DisplayChannelClient {
> >       SPICE_CONTAINEROF((dcc)->common.base.channel, DisplayChannel,
> >       common.base)
> >  #define RCC_TO_DCC(rcc) SPICE_CONTAINEROF((rcc), DisplayChannelClient,
> >  common.base)
> >
> > +typedef struct SurfaceCreateItem {
> > +    SpiceMsgSurfaceCreate surface_create;
> > +    PipeItem pipe_item;
> > +} SurfaceCreateItem;
> > +
> > +typedef struct ImageItem {
> > +    PipeItem link;
> > +    int refs;
> > +    SpicePoint pos;
> > +    int width;
> > +    int height;
> > +    int stride;
> > +    int top_down;
> > +    int surface_id;
> > +    int image_format;
> > +    uint32_t image_flags;
> > +    int can_lossy;
> > +    uint8_t data[0];
> > +} ImageItem;
> >
> >  DisplayChannelClient*      dcc_new
> >  (DisplayChannel *display,
> >                                                                        RedClient
> >                                                                        *client,
> > @@ -122,6 +145,7 @@ DisplayChannelClient*      dcc_new
> > (DisplayCha
> >                                                                        SpiceImageCompression
> >                                                                        image_compression,
> >                                                                        spice_wan_compression_t
> >                                                                        jpeg_state,
> >                                                                        spice_wan_compression_t
> >                                                                        zlib_glz_state);
> > +void                       dcc_start
> > (DisplayChannelClient *dcc);
> >  void                       dcc_push_monitors_config
> >  (DisplayChannelClient *dcc);
> >  void                       dcc_destroy_surface
> >  (DisplayChannelClient *dcc,
> >                                                                        uint32_t
> >                                                                        surface_id);
> > @@ -129,5 +153,14 @@ void                       dcc_stream_agent_clip
> > (DisplayCha
> >                                                                        StreamAgent
> >                                                                        *agent);
> >  void                       dcc_create_stream
> >  (DisplayChannelClient *dcc,
> >                                                                        Stream
> >                                                                        *stream);
> > +void                       dcc_create_surface
> > (DisplayChannelClient *dcc,
> > +                                                                      int
> > surface_id);
> > +void                       dcc_push_surface_image
> > (DisplayChannelClient *dcc,
> > +                                                                      int
> > surface_id);
> > +ImageItem *                dcc_add_surface_area_image
> > (DisplayChannelClient *dcc,
> > +                                                                      int
> > surface_id,
> > +
> > SpiceRect
> > *area,
> > +
> > PipeItem
> > *pos,
> > +                                                                      int
> > can_lossy);
> >
> >  #endif /* DCC_H_ */
> > diff --git a/server/display-channel.h b/server/display-channel.h
> > index ee107e8..ae55114 100644
> > --- a/server/display-channel.h
> > +++ b/server/display-channel.h
> > @@ -252,11 +252,6 @@ typedef struct SurfaceDestroyItem {
> >      PipeItem pipe_item;
> >  } SurfaceDestroyItem;
> >
> > -typedef struct SurfaceCreateItem {
> > -    SpiceMsgSurfaceCreate surface_create;
> > -    PipeItem pipe_item;
> > -} SurfaceCreateItem;
> > -
> >
> >  void                       display_channel_set_stream_video
> >  (DisplayChannel *display,
> >                                                                        int
> >                                                                        stream_video);
> > @@ -270,6 +265,8 @@ bool
> > display_channel_surface_has_canvas
> > (DisplayCha
> >                                                                        uint32_t
> >                                                                        surface_id);
> >  int                        display_channel_add_drawable
> >  (DisplayChannel *display,
> >                                                                        Drawable
> >                                                                        *drawable);
> > +void                       display_channel_current_flush
> > (DisplayChannel *display,
> > +                                                                      int
> > surface_id);
> >
> >  static inline int is_equal_path(SpicePath *path1, SpicePath *path2)
> >  {
> > diff --git a/server/red_worker.c b/server/red_worker.c
> > index f06e23b..a7baf0e 100644
> > --- a/server/red_worker.c
> > +++ b/server/red_worker.c
> > @@ -119,21 +119,6 @@ struct SpiceWatch {
> >  #define WIDE_CLIENT_ACK_WINDOW 40
> >  #define NARROW_CLIENT_ACK_WINDOW 20
> >
> > -typedef struct ImageItem {
> > -    PipeItem link;
> > -    int refs;
> > -    SpicePoint pos;
> > -    int width;
> > -    int height;
> > -    int stride;
> > -    int top_down;
> > -    int surface_id;
> > -    int image_format;
> > -    uint32_t image_flags;
> > -    int can_lossy;
> > -    uint8_t data[0];
> > -} ImageItem;
> > -
> >  pthread_mutex_t glz_dictionary_list_lock = PTHREAD_MUTEX_INITIALIZER;
> >  Ring glz_dictionary_list = {&glz_dictionary_list, &glz_dictionary_list};
> >
> > @@ -199,7 +184,6 @@ typedef struct BitmapData {
> >  static inline int validate_surface(DisplayChannel *display, uint32_t
> >  surface_id);
> >
> >  static void red_draw_qxl_drawable(DisplayChannel *display, Drawable
> >  *drawable);
> > -static void red_current_flush(DisplayChannel *display, int surface_id);
> >  static void red_draw_drawable(DisplayChannel *display, Drawable *item);
> >  static void red_update_area(DisplayChannel *display, const SpiceRect
> >  *area, int surface_id);
> >  static void red_update_area_till(DisplayChannel *display, const SpiceRect
> >  *area, int surface_id,
> > @@ -211,8 +195,6 @@ static void
> > display_channel_push_release(DisplayChannelClient *dcc, uint8_t type
> >                                           uint64_t* sync_data);
> >  static int
> >  red_display_free_some_independent_glz_drawables(DisplayChannelClient
> >  *dcc);
> >  static void dcc_free_glz_drawable(DisplayChannelClient *dcc,
> >  RedGlzDrawable *drawable);
> > -static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc,
> > int surface_id,
> > -                                             SpiceRect *area, PipeItem
> > *pos, int can_lossy);
> >  static void
> >  display_channel_client_release_item_before_push(DisplayChannelClient
> >  *dcc,
> >                                                              PipeItem
> >                                                              *item);
> >  static void
> >  display_channel_client_release_item_after_push(DisplayChannelClient *dcc,
> > @@ -369,8 +351,6 @@ static inline int validate_surface(DisplayChannel
> > *display, uint32_t surface_id)
> >      return 1;
> >  }
> >
> > -static inline void red_create_surface_item(DisplayChannelClient *dcc, int
> > surface_id);
> > -static void red_push_surface_image(DisplayChannelClient *dcc, int
> > surface_id);
> >
> >  static inline void red_handle_drawable_surfaces_client_synced(
> >                          DisplayChannelClient *dcc, Drawable *drawable)
> > @@ -386,9 +366,9 @@ static inline void
> > red_handle_drawable_surfaces_client_synced(
> >              if (dcc->surface_client_created[surface_id] == TRUE) {
> >                  continue;
> >              }
> > -            red_create_surface_item(dcc, surface_id);
> > -            red_current_flush(display, surface_id);
> > -            red_push_surface_image(dcc, surface_id);
> > +            dcc_create_surface(dcc, surface_id);
> > +            display_channel_current_flush(display, surface_id);
> > +            dcc_push_surface_image(dcc, surface_id);
> >          }
> >      }
> >
> > @@ -396,9 +376,9 @@ static inline void
> > red_handle_drawable_surfaces_client_synced(
> >          return;
> >      }
> >
> > -    red_create_surface_item(dcc, drawable->surface_id);
> > -    red_current_flush(display, drawable->surface_id);
> > -    red_push_surface_image(dcc, drawable->surface_id);
> > +    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)
> > @@ -985,7 +965,7 @@ static void
> > dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
> >          } else {
> >              red_update_area(DCC_TO_DC(dcc), &upgrade_area, 0);
> >          }
> > -        red_add_surface_area_image(dcc, 0, &upgrade_area, NULL, FALSE);
> > +        dcc_add_surface_area_image(dcc, 0, &upgrade_area, NULL, FALSE);
> >      }
> >  clear_vis_region:
> >      region_clear(&agent->vis_region);
> > @@ -1065,35 +1045,6 @@ static void
> > display_channel_streams_timeout(DisplayChannel *display)
> >      }
> >  }
> >
> > -static void dcc_create_all_streams(DisplayChannelClient *dcc)
> > -{
> > -    Ring *ring = &DCC_TO_DC(dcc)->streams;
> > -    RingItem *item = ring;
> > -
> > -    while ((item = ring_next(ring, item))) {
> > -        Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
> > -        dcc_create_stream(dcc, stream);
> > -    }
> > -}
> > -
> > -static void dcc_init_stream_agents(DisplayChannelClient *dcc)
> > -{
> > -    int i;
> > -    DisplayChannel *display = DCC_TO_DC(dcc);
> > -    RedChannel *channel = RED_CHANNEL_CLIENT(dcc)->channel;
> > -
> > -    for (i = 0; i < NUM_STREAMS; i++) {
> > -        StreamAgent *agent = &dcc->stream_agents[i];
> > -        agent->stream = &display->streams_buf[i];
> > -        region_init(&agent->vis_region);
> > -        region_init(&agent->clip);
> > -        red_channel_pipe_item_init(channel, &agent->create_item,
> > PIPE_ITEM_TYPE_STREAM_CREATE);
> > -        red_channel_pipe_item_init(channel, &agent->destroy_item,
> > PIPE_ITEM_TYPE_STREAM_DESTROY);
> > -    }
> > -    dcc->use_mjpeg_encoder_rate_control =
> > -        red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(dcc),
> > SPICE_DISPLAY_CAP_STREAM_REPORT);
> > -}
> > -
> >  static void dcc_destroy_stream_agents(DisplayChannelClient *dcc)
> >  {
> >      int i;
> > @@ -1999,7 +1950,7 @@ static void red_free_some(RedWorker *worker)
> >      }
> >  }
> >
> > -static void red_current_flush(DisplayChannel *display, int surface_id)
> > +void display_channel_current_flush(DisplayChannel *display, int
> > surface_id)
> >  {
> >      while (!ring_is_empty(&display->surfaces[surface_id].current_list)) {
> >          free_one_drawable(display, FALSE);
> > @@ -2008,8 +1959,8 @@ static void red_current_flush(DisplayChannel
> > *display, int surface_id)
> >  }
> >
> >  // adding the pipe item after pos. If pos == NULL, adding to head.
> > -static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc,
> > int surface_id,
> > -                                             SpiceRect *area, PipeItem
> > *pos, int can_lossy)
> > +ImageItem *dcc_add_surface_area_image(DisplayChannelClient *dcc, int
> > surface_id,
> > +                                      SpiceRect *area, PipeItem *pos, int
> > can_lossy)
> >  {
> >      DisplayChannel *display = DCC_TO_DC(dcc);
> >      RedChannel *channel = RED_CHANNEL(display);
> > @@ -2071,31 +2022,6 @@ static ImageItem
> > *red_add_surface_area_image(DisplayChannelClient *dcc, int surf
> >      return item;
> >  }
> >
> > -static void red_push_surface_image(DisplayChannelClient *dcc, int
> > surface_id)
> > -{
> > -    DisplayChannel *display;
> > -    SpiceRect area;
> > -    RedSurface *surface;
> > -
> > -    if (!dcc) {
> > -        return;
> > -    }
> > -
> > -    display = DCC_TO_DC(dcc);
> > -    surface = &display->surfaces[surface_id];
> > -    if (!surface->context.canvas) {
> > -        return;
> > -    }
> > -    area.top = area.left = 0;
> > -    area.right = surface->context.width;
> > -    area.bottom = surface->context.height;
> > -
> > -    /* not allowing lossy compression because probably, especially if it
> > is a primary surface,
> > -       it combines both "picture-like" areas with areas that are more
> > "artificial"*/
> > -    red_add_surface_area_image(dcc, surface_id, &area, NULL, FALSE);
> > -    red_channel_client_push(RED_CHANNEL_CLIENT(dcc));
> > -}
> > -
> >  static void fill_base(SpiceMarshaller *base_marshaller, Drawable
> >  *drawable)
> >  {
> >      SpiceMsgDisplayBase base;
> > @@ -3506,7 +3432,7 @@ static void
> > red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient
> >              continue;
> >          }
> >
> > -        image = red_add_surface_area_image(dcc,
> > drawable->red_drawable->surface_id,
> > +        image = dcc_add_surface_area_image(dcc,
> > drawable->red_drawable->surface_id,
> >                                             &drawable->red_drawable->bbox,
> >                                             pipe_item, TRUE);
> >          resent_surface_ids[num_resent] =
> >          drawable->red_drawable->surface_id;
> >          resent_areas[num_resent] = drawable->red_drawable->bbox;
> > @@ -3562,7 +3488,7 @@ static void
> > red_add_lossless_drawable_dependencies(RedChannelClient *rcc,
> >          // 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++) {
> > -            red_add_surface_area_image(dcc, deps_surfaces_ids[i],
> > deps_areas[i],
> > +            dcc_add_surface_area_image(dcc, deps_surfaces_ids[i],
> > deps_areas[i],
> >                                         red_pipe_get_tail(dcc), FALSE);
> >
> >          }
> > @@ -3583,7 +3509,7 @@ static void
> > red_add_lossless_drawable_dependencies(RedChannelClient *rcc,
> >                                                              &drawable->bbox);
> >          }
> >
> > -        red_add_surface_area_image(dcc, drawable->surface_id,
> > &drawable->bbox,
> > +        dcc_add_surface_area_image(dcc, drawable->surface_id,
> > &drawable->bbox,
> >                                     red_pipe_get_tail(dcc), TRUE);
> >      }
> >  }
> > @@ -5579,60 +5505,13 @@ static inline void
> > *create_canvas_for_surface(DisplayChannel *display, RedSurfac
> >      return NULL;
> >  }
> >
> > -static SurfaceCreateItem *get_surface_create_item(
> > -    RedChannel* channel,
> > -    uint32_t surface_id, uint32_t width,
> > -    uint32_t height, uint32_t format, uint32_t flags)
> > -{
> > -    SurfaceCreateItem *create;
> > -
> > -    create = spice_malloc(sizeof(SurfaceCreateItem));
> > -
> > -    create->surface_create.surface_id = surface_id;
> > -    create->surface_create.width = width;
> > -    create->surface_create.height = height;
> > -    create->surface_create.flags = flags;
> > -    create->surface_create.format = format;
> > -
> > -    red_channel_pipe_item_init(channel,
> > -            &create->pipe_item, PIPE_ITEM_TYPE_CREATE_SURFACE);
> > -    return create;
> > -}
> > -
> > -static inline void red_create_surface_item(DisplayChannelClient *dcc, int
> > surface_id)
> > -{
> > -    DisplayChannel *display;
> > -    RedSurface *surface;
> > -    SurfaceCreateItem *create;
> > -    uint32_t flags;
> > -
> > -    if (!dcc) {
> > -        return;
> > -    }
> > -
> > -    display = DCC_TO_DC(dcc);
> > -    flags = is_primary_surface(DCC_TO_DC(dcc), surface_id) ?
> > SPICE_SURFACE_FLAGS_PRIMARY : 0;
> > -
> > -    /* don't send redundant create surface commands to client */
> > -    if (display->common.during_target_migrate ||
> > -        dcc->surface_client_created[surface_id]) {
> > -        return;
> > -    }
> > -    surface = &display->surfaces[surface_id];
> > -    create = get_surface_create_item(RED_CHANNEL_CLIENT(dcc)->channel,
> > -            surface_id, surface->context.width, surface->context.height,
> > -                                     surface->context.format, flags);
> > -    dcc->surface_client_created[surface_id] = TRUE;
> > -    red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc),
> > &create->pipe_item);
> > -}
> > -
> >  static void red_worker_create_surface_item(DisplayChannel *display, int
> >  surface_id)
> >  {
> >      DisplayChannelClient *dcc;
> >      RingItem *item, *next;
> >
> >      FOREACH_DCC(display, item, next, dcc) {
> > -        red_create_surface_item(dcc, surface_id);
> > +        dcc_create_surface(dcc, surface_id);
> >      }
> >  }
> >
> > @@ -5643,7 +5522,7 @@ static void
> > red_worker_push_surface_image(DisplayChannel *display, int surface_i
> >      RingItem *item, *next;
> >
> >      FOREACH_DCC(display, item, next, dcc) {
> > -        red_push_surface_image(dcc, surface_id);
> > +        dcc_push_surface_image(dcc, surface_id);
> >      }
> >  }
> >
> > @@ -5808,70 +5687,6 @@ static inline void flush_all_qxl_commands(RedWorker
> > *worker)
> >      flush_cursor_commands(worker);
> >  }
> >
> > -static void push_new_primary_surface(DisplayChannelClient *dcc)
> > -{
> > -    RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
> > -
> > -    red_channel_client_pipe_add_type(rcc,
> > PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
> > -    red_create_surface_item(dcc, 0);
> > -    red_channel_client_push(rcc);
> > -}
> > -
> > -/* TODO: this function is evil^Wsynchronous, fix */
> > -static int display_channel_client_wait_for_init(DisplayChannelClient *dcc)
> > -{
> > -    dcc->expect_init = TRUE;
> > -    uint64_t end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT;
> > -    for (;;) {
> > -        red_channel_client_receive(RED_CHANNEL_CLIENT(dcc));
> > -        if (!red_channel_client_is_connected(RED_CHANNEL_CLIENT(dcc))) {
> > -            break;
> > -        }
> > -        if (dcc->pixmap_cache && dcc->glz_dict) {
> > -            dcc->pixmap_cache_generation = dcc->pixmap_cache->generation;
> > -            /* TODO: move common.id? if it's used for a per client
> > structure.. */
> > -            spice_info("creating encoder with id == %d", dcc->common.id);
> > -            dcc->glz = glz_encoder_create(dcc->common.id,
> > dcc->glz_dict->dict, &dcc->glz_data.usr);
> > -            if (!dcc->glz) {
> > -                spice_critical("create global lz failed");
> > -            }
> > -            return TRUE;
> > -        }
> > -        if (red_get_monotonic_time() > end_time) {
> > -            spice_warning("timeout");
> > -            red_channel_client_disconnect(RED_CHANNEL_CLIENT(dcc));
> > -            break;
> > -        }
> > -        usleep(DISPLAY_CLIENT_RETRY_INTERVAL);
> > -    }
> > -    return FALSE;
> > -}
> > -
> > -static void on_new_display_channel_client(DisplayChannelClient *dcc)
> > -{
> > -    DisplayChannel *display = DCC_TO_DC(dcc);
> > -    RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
> > -
> > -    red_channel_client_push_set_ack(RED_CHANNEL_CLIENT(dcc));
> > -
> > -    if (red_channel_client_waits_for_migrate_data(rcc)) {
> > -        return;
> > -    }
> > -
> > -    if (!display_channel_client_wait_for_init(dcc)) {
> > -        return;
> > -    }
> > -    red_channel_client_ack_zero_messages_window(RED_CHANNEL_CLIENT(dcc));
> > -    if (display->surfaces[0].context.canvas) {
> > -        red_current_flush(display, 0);
> > -        push_new_primary_surface(dcc);
> > -        red_push_surface_image(dcc, 0);
> > -        dcc_push_monitors_config(dcc);
> > -        red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_MARK);
> > -        dcc_create_all_streams(dcc);
> > -    }
> > -}
> > -
> >  static GlzSharedDictionary *_red_find_glz_dictionary(RedClient *client,
> >  uint8_t dict_id)
> >  {
> >      RingItem *now;
> > @@ -6712,12 +6527,9 @@ static void handle_new_display_channel(RedWorker
> > *worker, RedClient *client, Red
> >  {
> >      DisplayChannel *display_channel;
> >      DisplayChannelClient *dcc;
> > -    size_t stream_buf_size;
> >
> > -    if (!worker->display_channel) {
> > -        spice_warning("Display channel was not created");
> > -        return;
> > -    }
> > +    spice_return_if_fail(worker->display_channel);
> > +
> >      display_channel = worker->display_channel;
> >      spice_info("add display channel client");
> >      dcc = dcc_new(display_channel, client, stream, migrate,
> > @@ -6726,14 +6538,6 @@ static void handle_new_display_channel(RedWorker
> > *worker, RedClient *client, Red
> >      if (!dcc) {
> >          return;
> >      }
> > -    spice_info("New display (client %p) dcc %p stream %p", client, dcc,
> > stream);
> > -    stream_buf_size = 32*1024;
> > -    dcc->send_data.stream_outbuf = spice_malloc(stream_buf_size);
> > -    dcc->send_data.stream_outbuf_size = stream_buf_size;
> > -    dcc->send_data.free_list.res =
> > -        spice_malloc(sizeof(SpiceResourceList) +
> > -                     DISPLAY_FREE_LIST_DEFAULT_SIZE *
> > sizeof(SpiceResourceID));
> > -    dcc->send_data.free_list.res_size = DISPLAY_FREE_LIST_DEFAULT_SIZE;
> >
> >      if (dcc->jpeg_state == SPICE_WAN_COMPRESSION_AUTO) {
> >          display_channel->enable_jpeg = dcc->common.is_low_bandwidth;
> > @@ -6747,14 +6551,11 @@ static void handle_new_display_channel(RedWorker
> > *worker, RedClient *client, Red
> >          display_channel->enable_zlib_glz_wrap = (dcc->zlib_glz_state ==
> >                                                   SPICE_WAN_COMPRESSION_ALWAYS);
> >      }
> > -
> >      spice_info("jpeg %s", display_channel->enable_jpeg ? "enabled" :
> >      "disabled");
> >      spice_info("zlib-over-glz %s", display_channel->enable_zlib_glz_wrap ?
> >      "enabled" : "disabled");
> >
> >      guest_set_client_capabilities(worker);
> > -
> > -    dcc_init_stream_agents(dcc);
> > -    on_new_display_channel_client(dcc);
> > +    dcc_start(dcc);
> >  }
> >
> >  static void red_connect_cursor(RedWorker *worker, RedClient *client,
> >  RedsStream *stream,
> > @@ -7071,7 +6872,7 @@ static void flush_all_surfaces(DisplayChannel
> > *display)
> >
> >      for (x = 0; x < NUM_SURFACES; ++x) {
> >          if (display->surfaces[x].context.canvas) {
> > -            red_current_flush(display, x);
> > +            display_channel_current_flush(display, x);
> >          }
> >      }
> >  }
> > --
> > 2.4.3
> >
> > _______________________________________________
> > Spice-devel mailing list
> > Spice-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/spice-devel
> 
> Seems good. ACK.
> 
Merged

Frediano


More information about the Spice-devel mailing list