summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-04-23 15:24:03 +0200
committerAlexander Larsson <alexl@redhat.com>2010-04-23 16:41:47 +0200
commitc2f38a68ba4004cdf6eb9eba875d6f8f53fa1fb8 (patch)
tree4a613cc83c34af28263b1d39d1e495f8dfe698ec /server
parent810caf0e779bf280370221018bee6a0d4d63160b (diff)
downloadspice-c2f38a68ba4004cdf6eb9eba875d6f8f53fa1fb8.tar.gz
spice-c2f38a68ba4004cdf6eb9eba875d6f8f53fa1fb8.tar.xz
spice-c2f38a68ba4004cdf6eb9eba875d6f8f53fa1fb8.zip
If we have alpha in a 32bit rgb surface, ensure we send that
If we don't then alpha is lost which is problematic if the surface is later used as with alpha_blend and SRC_SURFACE_HAS_ALPHA.
Diffstat (limited to 'server')
-rw-r--r--server/red_worker.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/server/red_worker.c b/server/red_worker.c
index 98ead52c..042f59eb 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -3581,6 +3581,25 @@ static int surface_format_to_image_type(uint32_t surface_format)
return 0;
}
+static int rgb32_data_has_alpha(int width, int height, size_t stride,
+ uint8_t *data)
+{
+ uint32_t *line, *end;
+
+ while (height-- > 0) {
+ line = (uint32_t *)data;
+ end = line + width;
+ data += stride;
+ while (line != end) {
+ if ((*line & 0xff000000) != 0) {
+ return 1;
+ }
+ line++;
+ }
+ }
+ return 0;
+}
+
static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
{
QXLImage *image;
@@ -3623,6 +3642,11 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
red_get_area(worker, drawable->surface_id,
&drawable->qxl_drawable->self_bitmap_area, dest, dest_stride, TRUE);
+ if (image->bitmap.format == SPICE_BITMAP_FMT_32BIT &&
+ rgb32_data_has_alpha(width, height, dest_stride, dest)) {
+ image->bitmap.format = SPICE_BITMAP_FMT_RGBA;
+ }
+
drawable->self_bitmap = (uint8_t *)image;
return TRUE;
}
@@ -4941,6 +4965,12 @@ static void red_add_surface_image(RedWorker *worker, int surface_id)
area.right = surface->context.width;
area.bottom = surface->context.height;
canvas->ops->read_bits(canvas, item->data, stride, &area);
+
+ if (item->image_format == SPICE_BITMAP_FMT_32BIT &&
+ rgb32_data_has_alpha(item->width, item->height, item->stride, item->data)) {
+ item->image_format = SPICE_BITMAP_FMT_RGBA;
+ }
+
red_pipe_add_image_item(worker, item);
release_image_item(item);
display_channel_push(worker);