diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-07-10 07:02:00 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-07-10 07:02:00 -0400 |
commit | d5191bc030e42f7e2128d35184d523011c5acca5 (patch) | |
tree | 6cce814ae1571266422835b010338ebe8397ff5a | |
parent | 38f86f4e3587edd71f656c10705fd64a15d08f8a (diff) |
work-in-progress
-rw-r--r-- | common/canvas_base.c | 67 | ||||
-rw-r--r-- | common/draw.h | 7 | ||||
-rw-r--r-- | spice.proto | 50 |
3 files changed, 89 insertions, 35 deletions
diff --git a/common/canvas_base.c b/common/canvas_base.c index 24e69b4..dc16629 100644 --- a/common/canvas_base.c +++ b/common/canvas_base.c @@ -3246,6 +3246,12 @@ static void transform_to_pixman_transform(SpiceTransform *transform, p->matrix[2][2] = pixman_fixed_1; } +#define MASK(lo, hi) \ + (((1U << (hi)) - 1) - (((1U << (lo))) - 1)) + +#define EXTRACT(v, lo, hi) \ + ((v & MASK(lo, hi)) >> lo) + static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceComposite *composite) { @@ -3255,9 +3261,11 @@ static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox, pixman_image_t *d; pixman_image_t *s; pixman_image_t *m; + pixman_repeat_t src_repeat; + pixman_filter_t src_filter; + pixman_op_t op; pixman_transform_t transform; - int width; - int heigth; + int width, height; pixman_region32_init_rect(&dest_region, bbox->left, bbox->top, @@ -3267,23 +3275,35 @@ static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox, canvas_clip_pixman(canvas, &dest_region, clip); width = bbox->right - bbox->left; - heigth = bbox->bottom - bbox->top; + height = bbox->bottom - bbox->top; - d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, heigth); + /* Dest */ + d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, height); + + /* Src */ surface_canvas = canvas_get_surface(canvas, composite->src_bitmap); if (surface_canvas) { s = surface_canvas->ops->get_image(surface_canvas); } else { s = canvas_get_image(canvas, composite->src_bitmap, FALSE); } + if (composite->flags & SPICE_COMPOSITE_HAS_SRC_TRANSFORM) + { + transform_to_pixman_transform (&composite->src_transform, &transform); + pixman_image_set_transform (s, &transform); + } + src_filter = (pixman_filter_t) EXTRACT (composite->flags, 8, 11); + src_repeat = (pixman_repeat_t) EXTRACT (composite->flags, 14, 16); + pixman_image_set_filter (s, src_filter, NULL, 0); + pixman_image_set_repeat (s, src_repeat); - transform_to_pixman_transform (&composite->src_transform, &transform); - pixman_image_set_transform (s, &transform); - pixman_image_set_repeat (s, (pixman_repeat_t)composite->src_repeat); - pixman_image_set_filter (s, (pixman_filter_t)composite->src_filter, NULL, 0); - + /* Mask */ m = NULL; - if (composite->mask_bitmap) { + if (composite->flags & SPICE_COMPOSITE_HAS_MASK) { + pixman_filter_t mask_filter = (pixman_filter_t) EXTRACT (composite->flags, 11, 14); + pixman_repeat_t mask_repeat = (pixman_repeat_t) EXTRACT (composite->flags, 16, 18); + pixman_bool_t component_alpha = EXTRACT (composite->flags, 18, 19); + surface_canvas = canvas_get_surface(canvas, composite->mask_bitmap); if (surface_canvas) { m = surface_canvas->ops->get_image(surface_canvas); @@ -3291,15 +3311,30 @@ static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox, m = canvas_get_image(canvas, composite->mask_bitmap, FALSE); } - transform_to_pixman_transform (&composite->mask_transform, &transform); - pixman_image_set_transform (m, &transform); - pixman_image_set_repeat (m, (pixman_repeat_t)composite->mask_repeat); - pixman_image_set_filter (m, (pixman_filter_t)composite->mask_filter, NULL, 0); - pixman_image_set_component_alpha (m, (pixman_bool_t)composite->component_alpha); + if (composite->flags & SPICE_COMPOSITE_HAS_MASK_TRANSFORM) { + transform_to_pixman_transform (&composite->mask_transform, &transform); + pixman_image_set_transform (m, &transform); + } + + pixman_image_set_repeat (m, mask_repeat); + pixman_image_set_filter (m, mask_filter, NULL, 0); + pixman_image_set_component_alpha (m, component_alpha); } - + + op = (pixman_op_t) EXTRACT (composite->flags, 0, 8); + + pixman_image_composite32 (op, s, m, d, + composite->src_origin.x, composite->src_origin.y, + composite->mask_origin.y, composite->mask_origin.y, + 0, 0, width, height); + pixman_image_unref(s); pixman_image_unref(m); + + spice_canvas->ops->blit_image(spice_canvas, &dest_region, d, + bbox->left, + bbox->top); + pixman_image_unref(d); pixman_region32_fini(&dest_region); diff --git a/common/draw.h b/common/draw.h index 5ab60c4..3704358 100644 --- a/common/draw.h +++ b/common/draw.h @@ -234,12 +234,7 @@ typedef struct SpiceTransform { } SpiceTransform; typedef struct SpiceComposite { - uint8_t op; - uint8_t src_filter; - uint8_t mask_filter; - uint8_t src_repeat; - uint8_t mask_repeat; - uint8_t component_alpha; + uint32_t flags; SpiceImage *src_bitmap; SpiceImage *mask_bitmap; SpiceTransform src_transform; diff --git a/spice.proto b/spice.proto index fa4c37b..30d32d1 100644 --- a/spice.proto +++ b/spice.proto @@ -61,6 +61,20 @@ flags32 migrate_flags { NEED_DATA_TRANSFER } @prefix(SPICE_MIGRATE_); +flags32 composite_flags { + OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7, + SRC_FILTER0, SRC_FILTER1, SRC_FILTER2, + MASK_FILTER0, MASK_FITLER1, MASK_FILTER2, + + SRC_REPEAT0, SRC_REPEAT1, + MASK_REPEAT0, MASK_REPEAT1, + COMPONENT_ALPHA, + + HAS_MASK, + HAS_SRC_TRANSFORM, + HAS_MASK_TRANSFORM +} @prefix(SPICE_COMPOSITE_); + enum32 notify_severity { INFO, WARN, @@ -331,7 +345,7 @@ enum8 bitmap_fmt { 24BIT /* 3 byte, brg */, 32BIT /* 4 byte, xrgb in little endian format */, RGBA /* 4 byte, argb in little endian format */, - A8 /* 1 byte, alpha */ + 8BIT_A /* 1 byte, alpha */ }; flags8 bitmap_flags { @@ -745,18 +759,6 @@ channel DisplayChannel : BaseChannel { } draw_rop3; message { - DisplayBase base; - struct Composite { - Image *src_bitmap; - Image *mask_bitmap; - Transform *src_transform; - Transform *mask_transform; - Point16 src_origin; - Point16 mask_origin; - } data; - } draw_composite; - - message { DisplayBase base; struct Stroke { Path *path @marshall @nonnull; @@ -820,6 +822,28 @@ channel DisplayChannel : BaseChannel { uint8 data[data_size] @end @nomarshal; } stream_data_sized; + message { + DisplayBase base; + struct Composite { + composite_flags flags; + Image *src_bitmap; + switch (flags) { + case HAS_MASK: + Image *mask_bitmap; + } a @anon; + switch (flags) { + case HAS_SRC_TRANSFORM: + Transform src_transform; + } b @anon; + switch (flags) { + case HAS_MASK_TRANSFORM: + Transform mask_transform; + } c @anon; + Point16 src_origin; + Point16 mask_origin; + } data; + } draw_composite; + client: message { uint8 pixmap_cache_id; |