[Spice-devel] [PATCH] worker: move dcc_add_surface_area_image
Jonathon Jongsma
jjongsma at redhat.com
Fri Nov 20 07:48:45 PST 2015
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
On Fri, 2015-11-20 at 13:47 +0000, Frediano Ziglio 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 | 50 ++++++++++++++++++++++
> server/utils.h | 3 ++
> 5 files changed, 119 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..a8301e0 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_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_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..66df86f
> --- /dev/null
> +++ b/server/utils.c
> @@ -0,0 +1,50 @@
> +/*
> + 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/
> >.
> +*/
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#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..54c6100 100644
> --- a/server/utils.h
> +++ b/server/utils.h
> @@ -32,4 +32,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_ */
More information about the Spice-devel
mailing list