summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-08-10 18:46:12 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-08-10 18:46:12 -0400
commitaa4db0e285127b5fd5e26dd5dc4f6d13eff8bd0f (patch)
treea92f180e7182234de2f18bc65a6d76849a88389b
parentd5191bc030e42f7e2128d35184d523011c5acca5 (diff)
Support for forcing pixman images to opaque
-rw-r--r--common/canvas_base.c35
-rw-r--r--common/canvas_base.h2
-rw-r--r--common/sw_canvas.c25
m---------spice-protocol0
-rw-r--r--spice.proto10
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 {