[Spice-devel] [PATCH 06/18] worker: move dcc_add_surface_area_image
Frediano Ziglio
fziglio at redhat.com
Fri Nov 20 03:17:30 PST 2015
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/>.
+*/
+#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
More information about the Spice-devel
mailing list