[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