diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-08-10 18:46:12 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-08-10 18:46:12 -0400 |
commit | aa4db0e285127b5fd5e26dd5dc4f6d13eff8bd0f (patch) | |
tree | a92f180e7182234de2f18bc65a6d76849a88389b | |
parent | d5191bc030e42f7e2128d35184d523011c5acca5 (diff) |
Support for forcing pixman images to opaque
-rw-r--r-- | common/canvas_base.c | 35 | ||||
-rw-r--r-- | common/canvas_base.h | 2 | ||||
-rw-r--r-- | common/sw_canvas.c | 25 | ||||
m--------- | spice-protocol | 0 | ||||
-rw-r--r-- | spice.proto | 10 |
5 files changed, 58 insertions, 14 deletions
diff --git a/common/canvas_base.c b/common/canvas_base.c index dc16629..0ec8526 100644 --- a/common/canvas_base.c +++ b/common/canvas_base.c @@ -1275,13 +1275,25 @@ static void canvas_touch_image(CanvasBase *canvas, SpiceImage *image) static pixman_image_t* canvas_get_image_from_self(SpiceCanvas *canvas, int x, int y, - int32_t width, int32_t height) + int32_t width, int32_t height, + int force_opaque) { CanvasBase *canvas_base = (CanvasBase *)canvas; pixman_image_t *surface; uint8_t *dest; int dest_stride; SpiceRect area; + pixman_format_code_t format; + + format = spice_surface_format_to_pixman (canvas_base->format); + if (force_opaque) + { + /* Set alpha bits of the format to 0 */ + format = (pixman_format_code_t)(((uint32_t)format) & ~(0xf << 12)); + + spice_return_val_if_fail ( + pixman_format_supported_destination (format), NULL); + } surface = pixman_image_create_bits(spice_surface_format_to_pixman (canvas_base->format), width, height, NULL, 0); @@ -1923,7 +1935,7 @@ static void canvas_mask_pixman(CanvasBase *canvas, surface_canvas = canvas_get_surface_mask(canvas, mask->bitmap); if (surface_canvas) { needs_invert = mask->flags & SPICE_MASK_FLAGS_INVERS; - image = surface_canvas->ops->get_image(surface_canvas); + image = surface_canvas->ops->get_image(surface_canvas, FALSE); } else { needs_invert = FALSE; image = canvas_get_mask(canvas, @@ -3178,10 +3190,10 @@ static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, width = bbox->right - bbox->left; heigth = bbox->bottom - bbox->top; - d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, heigth); + d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, heigth, FALSE); surface_canvas = canvas_get_surface(canvas, rop3->src_bitmap); if (surface_canvas) { - s = surface_canvas->ops->get_image(surface_canvas); + s = surface_canvas->ops->get_image(surface_canvas, FALSE); } else { s = canvas_get_image(canvas, rop3->src_bitmap, FALSE); } @@ -3208,7 +3220,7 @@ static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, _surface_canvas = canvas_get_surface(canvas, rop3->brush.u.pattern.pat); if (_surface_canvas) { - p = _surface_canvas->ops->get_image(_surface_canvas); + p = _surface_canvas->ops->get_image(_surface_canvas, FALSE); } else { p = canvas_get_image(canvas, rop3->brush.u.pattern.pat, FALSE); } @@ -3278,12 +3290,14 @@ static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox, height = bbox->bottom - bbox->top; /* Dest */ - d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, height); + d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, height, + (composite->flags & SPICE_COMPOSITE_DEST_OPAQUE)); /* Src */ surface_canvas = canvas_get_surface(canvas, composite->src_bitmap); if (surface_canvas) { - s = surface_canvas->ops->get_image(surface_canvas); + s = surface_canvas->ops->get_image(surface_canvas, + (composite->flags & SPICE_COMPOSITE_SOURCE_OPAQUE)); } else { s = canvas_get_image(canvas, composite->src_bitmap, FALSE); } @@ -3306,7 +3320,7 @@ static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox, surface_canvas = canvas_get_surface(canvas, composite->mask_bitmap); if (surface_canvas) { - m = surface_canvas->ops->get_image(surface_canvas); + m = surface_canvas->ops->get_image(surface_canvas, FALSE); } else { m = canvas_get_image(canvas, composite->mask_bitmap, FALSE); } @@ -3325,11 +3339,12 @@ static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox, pixman_image_composite32 (op, s, m, d, composite->src_origin.x, composite->src_origin.y, - composite->mask_origin.y, composite->mask_origin.y, + composite->mask_origin.x, composite->mask_origin.y, 0, 0, width, height); pixman_image_unref(s); - pixman_image_unref(m); + if (m) + pixman_image_unref(m); spice_canvas->ops->blit_image(spice_canvas, &dest_region, d, bbox->left, diff --git a/common/canvas_base.h b/common/canvas_base.h index 4a4b083..637cdc1 100644 --- a/common/canvas_base.h +++ b/common/canvas_base.h @@ -307,7 +307,7 @@ typedef struct { void (*copy_region)(SpiceCanvas *canvas, pixman_region32_t *dest_region, int dx, int dy); - pixman_image_t *(*get_image)(SpiceCanvas *canvas); + pixman_image_t *(*get_image)(SpiceCanvas *canvas, int force_opaque); } SpiceCanvasOps; void spice_canvas_set_usr_data(SpiceCanvas *canvas, void *data, spice_destroy_fn_t destroy_fn); diff --git a/common/sw_canvas.c b/common/sw_canvas.c index 4b10383..5a00033 100644 --- a/common/sw_canvas.c +++ b/common/sw_canvas.c @@ -85,11 +85,32 @@ static pixman_image_t *canvas_get_pixman_brush(SwCanvas *canvas, return NULL; } -static pixman_image_t *get_image(SpiceCanvas *canvas) +static pixman_image_t *get_image(SpiceCanvas *canvas, int force_opaque) { SwCanvas *sw_canvas = (SwCanvas *)canvas; + pixman_format_code_t format; - pixman_image_ref(sw_canvas->image); + spice_pixman_image_get_format (sw_canvas->image, &format); + if (force_opaque && PIXMAN_FORMAT_A (format) != 0) + { + uint32_t *data; + int stride; + int width, height; + + /* Remove alpha bits from format */ + format = (pixman_format_code_t)(((uint32_t)format) & ~(0xf << 12)); + + data = pixman_image_get_data (sw_canvas->image); + stride = pixman_image_get_stride (sw_canvas->image); + width = pixman_image_get_width (sw_canvas->image); + height = pixman_image_get_height (sw_canvas->image); + + return pixman_image_create_bits (format, width, height, data, stride); + } + else + { + pixman_image_ref(sw_canvas->image); + } return sw_canvas->image; } diff --git a/spice-protocol b/spice-protocol -Subproject 243390b431f7f4180afe15d5905030baba12056 +Subproject 1c264e85d13d7c2822053f6d27930f5b7d384b8 diff --git a/spice.proto b/spice.proto index 30d32d1..519e337 100644 --- a/spice.proto +++ b/spice.proto @@ -72,7 +72,15 @@ flags32 composite_flags { HAS_MASK, HAS_SRC_TRANSFORM, - HAS_MASK_TRANSFORM + HAS_MASK_TRANSFORM, + + /* These are used to override the formats given in the images. For + * example, if the mask image has format a8r8g8b8, but MASK_OPAQUE + * is set, the image should be treated as if it were x8r8g8b8 + */ + SOURCE_OPAQUE, + MASK_OPAQUE, + DEST_OPAQUE, } @prefix(SPICE_COMPOSITE_); enum32 notify_severity { |