diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-04-23 15:24:03 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-04-23 16:41:47 +0200 |
commit | c2f38a68ba4004cdf6eb9eba875d6f8f53fa1fb8 (patch) | |
tree | 4a613cc83c34af28263b1d39d1e495f8dfe698ec /server/red_worker.c | |
parent | 810caf0e779bf280370221018bee6a0d4d63160b (diff) | |
download | spice-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/red_worker.c')
-rw-r--r-- | server/red_worker.c | 30 |
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); |