[Spice-devel] [PATCH 06/18] worker: move dcc_add_surface_area_image

Fabiano Fidêncio fabiano at fidencio.org
Fri Nov 20 04:39:51 PST 2015


On Fri, Nov 20, 2015 at 12: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/Makefile.am  |   1 +
>  server/dcc.c        |  62 +++++++++++++++++++++++++++
>  server/red_worker.c | 121 ++--------------------------------------------------
>  server/utils.c      |  46 ++++++++++++++++++++
>  server/utils.h      |   4 ++
>  5 files changed, 116 insertions(+), 118 deletions(-)
>  create mode 100644 server/utils.c
>
> diff --git a/server/Makefile.am b/server/Makefile.am
> index 669664a..64d0e7d 100644
> --- a/server/Makefile.am
> +++ b/server/Makefile.am
> @@ -135,6 +135,7 @@ libspice_server_la_SOURCES =                        \
>         tree.c                          \
>         spice-bitmap-utils.h                    \
>         spice-bitmap-utils.c                    \
> +       utils.c                                 \
>         utils.h                                 \
>         stream.c                                        \
>         stream.h                                        \
> diff --git a/server/dcc.c b/server/dcc.c
> index a17fa7d..b59029d 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -68,6 +68,68 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id)
>      red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &create->pipe_item);
>  }
>
> +// adding the pipe item after pos. If pos == NULL, adding to head.
> +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);
> +    RedSurface *surface = &display->surfaces[surface_id];
> +    SpiceCanvas *canvas = surface->context.canvas;
> +    ImageItem *item;
> +    int stride;
> +    int width;
> +    int height;
> +    int bpp;
> +    int all_set;
> +
> +    spice_return_val_if_fail(area, NULL);
> +
> +    width = area->right - area->left;
> +    height = area->bottom - area->top;
> +    bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
> +    stride = width * bpp;
> +
> +    item = (ImageItem *)spice_malloc_n_m(height, stride, sizeof(ImageItem));
> +
> +    red_channel_pipe_item_init(channel, &item->link, PIPE_ITEM_TYPE_IMAGE);
> +
> +    item->refs = 1;
> +    item->surface_id = surface_id;
> +    item->image_format =
> +        spice_bitmap_from_surface_type(surface->context.format);
> +    item->image_flags = 0;
> +    item->pos.x = area->left;
> +    item->pos.y = area->top;
> +    item->width = width;
> +    item->height = height;
> +    item->stride = stride;
> +    item->top_down = surface->context.top_down;
> +    item->can_lossy = can_lossy;
> +
> +    canvas->ops->read_bits(canvas, item->data, stride, area);
> +
> +    /* For 32bit non-primary surfaces we need to keep any non-zero
> +       high bytes as the surface may be used as source to an alpha_blend */
> +    if (!is_primary_surface(display, surface_id) &&
> +        item->image_format == SPICE_BITMAP_FMT_32BIT &&
> +        rgb32_data_has_alpha(item->width, item->height, item->stride, item->data, &all_set)) {
> +        if (all_set) {
> +            item->image_flags |= SPICE_IMAGE_FLAGS_HIGH_BITS_SET;
> +        } else {
> +            item->image_format = SPICE_BITMAP_FMT_RGBA;
> +        }
> +    }
> +
> +    if (pos) {
> +        red_channel_client_pipe_add_after(RED_CHANNEL_CLIENT(dcc), &item->link, pos);
> +    } else {
> +        red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &item->link);
> +    }
> +
> +    return item;
> +}
> +
>  void dcc_push_surface_image(DisplayChannelClient *dcc, int surface_id)
>  {
>      DisplayChannel *display;
> diff --git a/server/red_worker.c b/server/red_worker.c
> index 377eb36..09ebc0d 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -226,12 +226,8 @@ static int cursor_is_connected(RedWorker *worker)
>          red_channel_is_connected(RED_CHANNEL(worker->cursor_channel));
>  }
>
> -static inline PipeItem *red_pipe_get_tail(DisplayChannelClient *dcc)
> +static PipeItem *dcc_get_tail(DisplayChannelClient *dcc)
>  {
> -    if (!dcc) {
> -        return NULL;
> -    }
> -
>      return (PipeItem*)ring_get_tail(&RED_CHANNEL_CLIENT(dcc)->pipe);
>  }
>
> @@ -249,25 +245,6 @@ void red_pipes_remove_drawable(Drawable *drawable)
>      }
>  }
>
> -static inline void red_pipe_add_image_item(DisplayChannelClient *dcc, ImageItem *item)
> -{
> -    if (!dcc) {
> -        return;
> -    }
> -    item->refs++;
> -    red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &item->link);
> -}
> -
> -static inline void red_pipe_add_image_item_after(DisplayChannelClient *dcc, ImageItem *item,
> -                                                 PipeItem *pos)
> -{
> -    if (!dcc) {
> -        return;
> -    }
> -    item->refs++;
> -    red_channel_client_pipe_add_after(RED_CHANNEL_CLIENT(dcc), &item->link, pos);
> -}
> -
>  static void release_image_item(ImageItem *item)
>  {
>      if (!--item->refs) {
> @@ -811,34 +788,6 @@ static void red_get_area(DisplayChannel *display, int surface_id, const SpiceRec
>      canvas->ops->read_bits(canvas, dest, dest_stride, area);
>  }
>
> -static int rgb32_data_has_alpha(int width, int height, size_t stride,
> -                                uint8_t *data, int *all_set_out)
> -{
> -    uint32_t *line, *end, alpha;
> -    int has_alpha;
> -
> -    has_alpha = FALSE;
> -    while (height-- > 0) {
> -        line = (uint32_t *)data;
> -        end = line + width;
> -        data += stride;
> -        while (line != end) {
> -            alpha = *line & 0xff000000U;
> -            if (alpha != 0) {
> -                has_alpha = TRUE;
> -                if (alpha != 0xff000000U) {
> -                    *all_set_out = FALSE;
> -                    return TRUE;
> -                }
> -            }
> -            line++;
> -        }
> -    }
> -
> -    *all_set_out = has_alpha;
> -    return has_alpha;
> -}
> -
>  static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
>  {
>      DisplayChannel *display = worker->display_channel;
> @@ -1677,70 +1626,6 @@ void display_channel_current_flush(DisplayChannel *display, int surface_id)
>      current_remove_all(display, surface_id);
>  }
>
> -// adding the pipe item after pos. If pos == NULL, adding to head.
> -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);
> -    RedSurface *surface = &display->surfaces[surface_id];
> -    SpiceCanvas *canvas = surface->context.canvas;
> -    ImageItem *item;
> -    int stride;
> -    int width;
> -    int height;
> -    int bpp;
> -    int all_set;
> -
> -    spice_assert(area);
> -
> -    width = area->right - area->left;
> -    height = area->bottom - area->top;
> -    bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
> -    stride = width * bpp;
> -
> -    item = (ImageItem *)spice_malloc_n_m(height, stride, sizeof(ImageItem));
> -
> -    red_channel_pipe_item_init(channel, &item->link, PIPE_ITEM_TYPE_IMAGE);
> -
> -    item->refs = 1;
> -    item->surface_id = surface_id;
> -    item->image_format =
> -        spice_bitmap_from_surface_type(surface->context.format);
> -    item->image_flags = 0;
> -    item->pos.x = area->left;
> -    item->pos.y = area->top;
> -    item->width = width;
> -    item->height = height;
> -    item->stride = stride;
> -    item->top_down = surface->context.top_down;
> -    item->can_lossy = can_lossy;
> -
> -    canvas->ops->read_bits(canvas, item->data, stride, area);
> -
> -    /* For 32bit non-primary surfaces we need to keep any non-zero
> -       high bytes as the surface may be used as source to an alpha_blend */
> -    if (!is_primary_surface(display, surface_id) &&
> -        item->image_format == SPICE_BITMAP_FMT_32BIT &&
> -        rgb32_data_has_alpha(item->width, item->height, item->stride, item->data, &all_set)) {
> -        if (all_set) {
> -            item->image_flags |= SPICE_IMAGE_FLAGS_HIGH_BITS_SET;
> -        } else {
> -            item->image_format = SPICE_BITMAP_FMT_RGBA;
> -        }
> -    }
> -
> -    if (!pos) {
> -        red_pipe_add_image_item(dcc, item);
> -    } else {
> -        red_pipe_add_image_item_after(dcc, item, pos);
> -    }
> -
> -    release_image_item(item);
> -
> -    return item;
> -}
> -
>  static void fill_base(SpiceMarshaller *base_marshaller, Drawable *drawable)
>  {
>      SpiceMsgDisplayBase base;
> @@ -2376,7 +2261,7 @@ static void red_add_lossless_drawable_dependencies(RedChannelClient *rcc,
>          // will be executed before the current drawable
>          for (i = 0; i < num_deps; i++) {
>              dcc_add_surface_area_image(dcc, deps_surfaces_ids[i], deps_areas[i],
> -                                       red_pipe_get_tail(dcc), FALSE);
> +                                       dcc_get_tail(dcc), FALSE);
>
>          }
>      } else {
> @@ -2397,7 +2282,7 @@ static void red_add_lossless_drawable_dependencies(RedChannelClient *rcc,
>          }
>
>          dcc_add_surface_area_image(dcc, drawable->surface_id, &drawable->bbox,
> -                                   red_pipe_get_tail(dcc), TRUE);
> +                                   dcc_get_tail(dcc), TRUE);
>      }
>  }
>
> diff --git a/server/utils.c b/server/utils.c
> new file mode 100644
> index 0000000..6840118
> --- /dev/null
> +++ b/server/utils.c
> @@ -0,0 +1,46 @@
> +/*
> +   Copyright (C) 2009-2015 Red Hat, Inc.
> +
> +   This library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   This library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with this library; if not, see <http://www.gnu.org/licenses/>.
> +*/

Missing config.h, which breaks make syntax-check.

> +#include <glib.h>
> +#include "utils.h"
> +
> +int rgb32_data_has_alpha(int width, int height, size_t stride,
> +                         uint8_t *data, int *all_set_out)
> +{
> +    uint32_t *line, *end, alpha;
> +    int has_alpha;
> +
> +    has_alpha = FALSE;
> +    while (height-- > 0) {
> +        line = (uint32_t *)data;
> +        end = line + width;
> +        data += stride;
> +        while (line != end) {
> +            alpha = *line & 0xff000000U;
> +            if (alpha != 0) {
> +                has_alpha = TRUE;
> +                if (alpha != 0xff000000U) {
> +                    *all_set_out = FALSE;
> +                    return TRUE;
> +                }
> +            }
> +            line++;
> +        }
> +    }
> +
> +    *all_set_out = has_alpha;
> +    return has_alpha;
> +}
> diff --git a/server/utils.h b/server/utils.h
> index cae03d4..db4242d 100644
> --- a/server/utils.h
> +++ b/server/utils.h
> @@ -18,6 +18,7 @@
>  #ifndef UTILS_H_
>  # define UTILS_H_
>
> +#include <stdint.h>
>  #include <time.h>
>  #include <stdint.h>
>
> @@ -32,4 +33,7 @@ static inline red_time_t red_get_monotonic_time(void)
>      return (red_time_t) time.tv_sec * (1000 * 1000 * 1000) + time.tv_nsec;
>  }
>
> +int rgb32_data_has_alpha(int width, int height, size_t stride,
> +                         uint8_t *data, int *all_set_out);
> +
>  #endif /* UTILS_H_ */
> --
> 2.4.3
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel



-- 
Fabiano Fidêncio


More information about the Spice-devel mailing list