diff options
-rw-r--r-- | pixman/pixman-arm-neon.c | 41 | ||||
-rw-r--r-- | pixman/pixman-arm-simd.c | 41 | ||||
-rw-r--r-- | pixman/pixman-fast-path.c | 208 | ||||
-rw-r--r-- | pixman/pixman-general.c | 26 | ||||
-rw-r--r-- | pixman/pixman-implementation.c | 53 | ||||
-rw-r--r-- | pixman/pixman-mmx.c | 34 | ||||
-rw-r--r-- | pixman/pixman-private.h | 124 | ||||
-rw-r--r-- | pixman/pixman-sse2.c | 58 | ||||
-rw-r--r-- | pixman/pixman-utils.c | 531 | ||||
-rw-r--r-- | pixman/pixman-vmx.c | 7 | ||||
-rw-r--r-- | pixman/pixman.c | 635 |
11 files changed, 750 insertions, 1008 deletions
diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c index 26f7267c..557301e3 100644 --- a/pixman/pixman-arm-neon.c +++ b/pixman/pixman-arm-neon.c @@ -383,7 +383,7 @@ pixman_blt_neon (uint32_t *src_bits, } } -static const pixman_fast_path_t arm_neon_fast_path_array[] = +static const pixman_fast_path_t arm_neon_fast_paths[] = { PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, neon_composite_src_0565_0565), PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, neon_composite_src_0565_0565), @@ -435,41 +435,6 @@ static const pixman_fast_path_t arm_neon_fast_path_array[] = { PIXMAN_OP_NONE }, }; -const pixman_fast_path_t *const arm_neon_fast_paths = arm_neon_fast_path_array; - -static void -arm_neon_composite (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - if (_pixman_run_fast_path (arm_neon_fast_paths, imp, - op, src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height)) - { - return; - } - - _pixman_implementation_composite (imp->delegate, op, - src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height); -} - static pixman_bool_t arm_neon_blt (pixman_implementation_t *imp, uint32_t * src_bits, @@ -551,12 +516,12 @@ pixman_implementation_t * _pixman_implementation_create_arm_neon (void) { pixman_implementation_t *general = _pixman_implementation_create_fast_path (); - pixman_implementation_t *imp = _pixman_implementation_create (general); + pixman_implementation_t *imp = + _pixman_implementation_create (general, arm_neon_fast_paths); imp->combine_32[PIXMAN_OP_OVER] = neon_combine_over_u; imp->combine_32[PIXMAN_OP_ADD] = neon_combine_add_u; - imp->composite = arm_neon_composite; imp->blt = arm_neon_blt; imp->fill = arm_neon_fill; diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c index dd8dc5c0..09a28883 100644 --- a/pixman/pixman-arm-simd.c +++ b/pixman/pixman-arm-simd.c @@ -419,7 +419,7 @@ arm_composite_over_n_8_8888 (pixman_implementation_t * impl, } } -static const pixman_fast_path_t arm_simd_fast_path_array[] = +static const pixman_fast_path_t arm_simd_fast_paths[] = { PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, arm_composite_over_8888_8888), PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, arm_composite_over_8888_8888), @@ -438,48 +438,11 @@ static const pixman_fast_path_t arm_simd_fast_path_array[] = { PIXMAN_OP_NONE }, }; -const pixman_fast_path_t *const arm_simd_fast_paths = arm_simd_fast_path_array; - -static void -arm_simd_composite (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - if (_pixman_run_fast_path (arm_simd_fast_paths, imp, - op, src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height)) - { - return; - } - - _pixman_implementation_composite (imp->delegate, op, - src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height); -} - pixman_implementation_t * _pixman_implementation_create_arm_simd (void) { pixman_implementation_t *general = _pixman_implementation_create_fast_path (); - pixman_implementation_t *imp = _pixman_implementation_create (general); - - imp->composite = arm_simd_composite; + pixman_implementation_t *imp = _pixman_implementation_create (general, arm_simd_fast_paths); return imp; } diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 170e9d69..4d26b0fa 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1033,7 +1033,7 @@ fast_composite_add_n_8_8 (pixman_implementation_t *imp, #define UPDATE_BITMASK(n) ((n) << 1) #endif -#define TEST_BIT(p, n) \ +#define TEST_BIT(p, n) \ (*((p) + ((n) >> 5)) & CREATE_BITMASK ((n) & 31)) #define SET_BIT(p, n) \ do { *((p) + ((n) >> 5)) |= CREATE_BITMASK ((n) & 31); } while (0); @@ -1345,64 +1345,6 @@ fast_composite_src_8888_x888 (pixman_implementation_t *imp, } } -static const pixman_fast_path_t c_fast_paths[] = -{ - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, fast_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, fast_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r8g8b8, fast_composite_over_n_8_0888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b8g8r8, fast_composite_over_n_8_0888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8r8g8b8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8r8g8b8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8b8g8r8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8b8g8r8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, r5g6b5, fast_composite_over_n_1_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, b5g6r5, fast_composite_over_n_1_0565), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, fast_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, fast_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, fast_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, fast_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, fast_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, fast_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, fast_composite_add_8000_8000), - PIXMAN_STD_FAST_PATH (ADD, a1, null, a1, fast_composite_add_1000_1000), - PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, fast_composite_add_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, fast_composite_add_n_8_8), - PIXMAN_STD_FAST_PATH (SRC, solid, null, a8r8g8b8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, a8b8g8r8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, fast_composite_src_8888_x888), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, fast_composite_src_8888_x888), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, fast_composite_src_8888_x888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, fast_composite_src_8888_x888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, fast_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, fast_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, fast_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, fast_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (IN, a8, null, a8, fast_composite_in_8_8), - PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, fast_composite_in_n_8_8), - - { PIXMAN_OP_NONE }, -}; - static force_inline pixman_bool_t repeat (pixman_repeat_t repeat, int *c, int size) { @@ -1591,67 +1533,98 @@ fast_composite_scaled_nearest (pixman_implementation_t *imp, } } -static void -fast_path_composite (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) +static const pixman_fast_path_t c_fast_paths[] = { - if (src->type == BITS - && src->common.transform - && !mask - && (op == PIXMAN_OP_SRC || op == PIXMAN_OP_OVER) - && !src->common.alpha_map && !dest->common.alpha_map - && (src->common.filter == PIXMAN_FILTER_NEAREST) - && (dest->bits.format == PIXMAN_a8r8g8b8 || dest->bits.format == PIXMAN_x8r8g8b8) - && (src->bits.format == PIXMAN_a8r8g8b8 || src->bits.format == PIXMAN_x8r8g8b8) - && !src->bits.read_func && !src->bits.write_func - && !dest->bits.read_func && !dest->bits.write_func) - { - /* ensure that the transform matrix only has a scale */ - if (src->common.transform->matrix[0][1] == 0 && - src->common.transform->matrix[1][0] == 0 && - src->common.transform->matrix[2][0] == 0 && - src->common.transform->matrix[2][1] == 0 && - src->common.transform->matrix[2][2] == pixman_fixed_1) - { - _pixman_walk_composite_region (imp, op, - src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height, - fast_composite_scaled_nearest); - return; - } - } + PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, fast_composite_over_n_8_0565), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, fast_composite_over_n_8_0565), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, r8g8b8, fast_composite_over_n_8_0888), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, b8g8r8, fast_composite_over_n_8_0888), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, fast_composite_over_n_8_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, fast_composite_over_n_8_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, fast_composite_over_n_8_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, fast_composite_over_n_8_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8r8g8b8, fast_composite_over_n_1_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8r8g8b8, fast_composite_over_n_1_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8b8g8r8, fast_composite_over_n_1_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8b8g8r8, fast_composite_over_n_1_8888), + PIXMAN_STD_FAST_PATH (OVER, solid, a1, r5g6b5, fast_composite_over_n_1_0565), + PIXMAN_STD_FAST_PATH (OVER, solid, a1, b5g6r5, fast_composite_over_n_1_0565), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, fast_composite_over_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, fast_composite_over_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, fast_composite_over_n_8888_0565_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, fast_composite_over_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, fast_composite_over_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, fast_composite_over_n_8888_0565_ca), + PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, fast_composite_over_x888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, fast_composite_over_x888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, fast_composite_over_x888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, fast_composite_over_x888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, fast_composite_over_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, fast_composite_over_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, fast_composite_over_8888_0565), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, fast_composite_over_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, fast_composite_over_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, fast_composite_over_8888_0565), + PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, fast_composite_add_8888_8888), + PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, fast_composite_add_8888_8888), + PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, fast_composite_add_8000_8000), + PIXMAN_STD_FAST_PATH (ADD, a1, null, a1, fast_composite_add_1000_1000), + PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, fast_composite_add_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, fast_composite_add_n_8_8), + PIXMAN_STD_FAST_PATH (SRC, solid, null, a8r8g8b8, fast_composite_solid_fill), + PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill), + PIXMAN_STD_FAST_PATH (SRC, solid, null, a8b8g8r8, fast_composite_solid_fill), + PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, fast_composite_solid_fill), + PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill), + PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill), + PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, fast_composite_src_8888_x888), + PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, fast_composite_src_8888_x888), + PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, fast_composite_src_8888_x888), + PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, fast_composite_src_8888_x888), + PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, fast_composite_src_x888_0565), + PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, fast_composite_src_x888_0565), + PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, fast_composite_src_x888_0565), + PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, fast_composite_src_x888_0565), + PIXMAN_STD_FAST_PATH (IN, a8, null, a8, fast_composite_in_8_8), + PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, fast_composite_in_n_8_8), - if (_pixman_run_fast_path (c_fast_paths, imp, - op, src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height)) - { - return; +#define SCALED_NEAREST_FLAGS \ + (FAST_PATH_SCALE_TRANSFORM | \ + FAST_PATH_NO_ALPHA_MAP | \ + FAST_PATH_NEAREST_FILTER | \ + FAST_PATH_NO_ACCESSORS | \ + FAST_PATH_NO_WIDE_FORMAT) + +#define NEAREST_FAST_PATH(op,s,d) \ + { PIXMAN_OP_ ## op, \ + PIXMAN_ ## s, SCALED_NEAREST_FLAGS, \ + PIXMAN_null, 0, \ + PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ + fast_composite_scaled_nearest, \ } - _pixman_implementation_composite (imp->delegate, op, - src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height); -} + NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8), + NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8), + NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8), + NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8), + + NEAREST_FAST_PATH (SRC, x8r8g8b8, a8r8g8b8), + NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8), + NEAREST_FAST_PATH (SRC, x8b8g8r8, a8b8g8r8), + NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8), + + NEAREST_FAST_PATH (OVER, x8r8g8b8, x8r8g8b8), + NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8), + NEAREST_FAST_PATH (OVER, x8b8g8r8, x8b8g8r8), + NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8), + + NEAREST_FAST_PATH (OVER, x8r8g8b8, a8r8g8b8), + NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8), + NEAREST_FAST_PATH (OVER, x8b8g8r8, a8b8g8r8), + NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8), + + { PIXMAN_OP_NONE }, +}; static void pixman_fill8 (uint32_t *bits, @@ -1764,9 +1737,8 @@ pixman_implementation_t * _pixman_implementation_create_fast_path (void) { pixman_implementation_t *general = _pixman_implementation_create_general (); - pixman_implementation_t *imp = _pixman_implementation_create (general); + pixman_implementation_t *imp = _pixman_implementation_create (general, c_fast_paths); - imp->composite = fast_path_composite; imp->fill = fast_path_fill; return imp; diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index c96a3f97..bddf79aa 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -264,26 +264,11 @@ general_composite_rect (pixman_implementation_t *imp, free (scanline_buffer); } -static void -general_composite (pixman_implementation_t * imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) +static const pixman_fast_path_t general_fast_path[] = { - _pixman_walk_composite_region (imp, op, src, mask, dest, src_x, src_y, - mask_x, mask_y, dest_x, dest_y, - width, height, - general_composite_rect); -} + { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect }, + { PIXMAN_OP_NONE } +}; static pixman_bool_t general_blt (pixman_implementation_t *imp, @@ -322,12 +307,11 @@ general_fill (pixman_implementation_t *imp, pixman_implementation_t * _pixman_implementation_create_general (void) { - pixman_implementation_t *imp = _pixman_implementation_create (NULL); + pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); _pixman_setup_combiner_functions_32 (imp); _pixman_setup_combiner_functions_64 (imp); - imp->composite = general_composite; imp->blt = general_blt; imp->fill = general_fill; diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c index 6488332b..bc3749ef 100644 --- a/pixman/pixman-implementation.c +++ b/pixman/pixman-implementation.c @@ -28,30 +28,6 @@ #include "pixman-private.h" static void -delegate_composite (pixman_implementation_t * imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - _pixman_implementation_composite (imp->delegate, - op, - src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height); -} - -static void delegate_combine_32 (pixman_implementation_t * imp, pixman_op_t op, uint32_t * dest, @@ -136,7 +112,8 @@ delegate_fill (pixman_implementation_t *imp, } pixman_implementation_t * -_pixman_implementation_create (pixman_implementation_t *delegate) +_pixman_implementation_create (pixman_implementation_t *delegate, + const pixman_fast_path_t *fast_paths) { pixman_implementation_t *imp = malloc (sizeof (pixman_implementation_t)); pixman_implementation_t *d; @@ -145,6 +122,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate) if (!imp) return NULL; + assert (fast_paths); + /* Make sure the whole delegate chain has the right toplevel */ imp->delegate = delegate; for (d = imp; d != NULL; d = d->delegate) @@ -152,7 +131,6 @@ _pixman_implementation_create (pixman_implementation_t *delegate) /* Fill out function pointers with ones that just delegate */ - imp->composite = delegate_composite; imp->blt = delegate_blt; imp->fill = delegate_fill; @@ -164,6 +142,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate) imp->combine_64_ca[i] = delegate_combine_64_ca; } + imp->fast_paths = fast_paths; + return imp; } @@ -211,27 +191,6 @@ _pixman_implementation_combine_64_ca (pixman_implementation_t * imp, (*imp->combine_64_ca[op]) (imp, op, dest, src, mask, width); } -void -_pixman_implementation_composite (pixman_implementation_t * imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - (*imp->composite) (imp, op, - src, mask, dest, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, - width, height); -} - pixman_bool_t _pixman_implementation_blt (pixman_implementation_t * imp, uint32_t * src_bits, diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c index a4affa57..e084e7ff 100644 --- a/pixman/pixman-mmx.c +++ b/pixman/pixman-mmx.c @@ -3288,37 +3288,6 @@ static const pixman_fast_path_t mmx_fast_paths[] = { PIXMAN_OP_NONE }, }; -static void -mmx_composite (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - if (_pixman_run_fast_path (mmx_fast_paths, imp, - op, src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height)) - { - return; - } - - _pixman_implementation_composite (imp->delegate, - op, src, mask, dest, src_x, src_y, - mask_x, mask_y, dest_x, dest_y, - width, height); -} - static pixman_bool_t mmx_blt (pixman_implementation_t *imp, uint32_t * src_bits, @@ -3372,7 +3341,7 @@ pixman_implementation_t * _pixman_implementation_create_mmx (void) { pixman_implementation_t *general = _pixman_implementation_create_fast_path (); - pixman_implementation_t *imp = _pixman_implementation_create (general); + pixman_implementation_t *imp = _pixman_implementation_create (general, mmx_fast_paths); imp->combine_32[PIXMAN_OP_OVER] = mmx_combine_over_u; imp->combine_32[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_u; @@ -3398,7 +3367,6 @@ _pixman_implementation_create_mmx (void) imp->combine_32_ca[PIXMAN_OP_XOR] = mmx_combine_xor_ca; imp->combine_32_ca[PIXMAN_OP_ADD] = mmx_combine_add_ca; - imp->composite = mmx_composite; imp->blt = mmx_blt; imp->fill = mmx_fill; diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 4b5af087..048d030e 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -372,7 +372,6 @@ pixman_rasterize_edges_accessors (pixman_image_t *image, /* * Implementations */ - typedef struct pixman_implementation_t pixman_implementation_t; typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp, @@ -428,23 +427,36 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp, void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp); -struct pixman_implementation_t +typedef struct { - pixman_implementation_t *toplevel; - pixman_implementation_t *delegate; + pixman_op_t op; + pixman_format_code_t src_format; + uint32_t src_flags; + pixman_format_code_t mask_format; + uint32_t mask_flags; + pixman_format_code_t dest_format; + uint32_t dest_flags; + pixman_composite_func_t func; +} pixman_fast_path_t; - pixman_composite_func_t composite; - pixman_blt_func_t blt; - pixman_fill_func_t fill; +struct pixman_implementation_t +{ + pixman_implementation_t * toplevel; + pixman_implementation_t * delegate; + const pixman_fast_path_t * fast_paths; + + pixman_blt_func_t blt; + pixman_fill_func_t fill; - pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS]; - pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS]; - pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS]; - pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS]; + pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS]; + pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS]; + pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS]; + pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS]; }; pixman_implementation_t * -_pixman_implementation_create (pixman_implementation_t *delegate); +_pixman_implementation_create (pixman_implementation_t *delegate, + const pixman_fast_path_t *fast_paths); void _pixman_implementation_combine_32 (pixman_implementation_t *imp, @@ -474,20 +486,6 @@ _pixman_implementation_combine_64_ca (pixman_implementation_t *imp, const uint64_t * src, const uint64_t * mask, int width); -void -_pixman_implementation_composite (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height); pixman_bool_t _pixman_implementation_blt (pixman_implementation_t *imp, @@ -564,17 +562,22 @@ _pixman_choose_implementation (void); #define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0) #define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0) #define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0) - -#define FAST_PATH_ID_TRANSFORM (1 << 0) -#define FAST_PATH_NO_ALPHA_MAP (1 << 1) -#define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2) -#define FAST_PATH_NO_PAD_REPEAT (1 << 3) -#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4) -#define FAST_PATH_NO_ACCESSORS (1 << 5) -#define FAST_PATH_NO_WIDE_FORMAT (1 << 6) -#define FAST_PATH_reserved (1 << 7) -#define FAST_PATH_COMPONENT_ALPHA (1 << 8) -#define FAST_PATH_UNIFIED_ALPHA (1 << 9) +#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0) + +#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1) + +#define FAST_PATH_ID_TRANSFORM (1 << 0) +#define FAST_PATH_NO_ALPHA_MAP (1 << 1) +#define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2) +#define FAST_PATH_NO_PAD_REPEAT (1 << 3) +#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4) +#define FAST_PATH_NO_ACCESSORS (1 << 5) +#define FAST_PATH_NO_WIDE_FORMAT (1 << 6) +#define FAST_PATH_COVERS_CLIP (1 << 7) +#define FAST_PATH_COMPONENT_ALPHA (1 << 8) +#define FAST_PATH_UNIFIED_ALPHA (1 << 9) +#define FAST_PATH_SCALE_TRANSFORM (1 << 10) +#define FAST_PATH_NEAREST_FILTER (1 << 11) #define _FAST_PATH_STANDARD_FLAGS \ (FAST_PATH_ID_TRANSFORM | \ @@ -583,7 +586,8 @@ _pixman_choose_implementation (void); FAST_PATH_NO_PAD_REPEAT | \ FAST_PATH_NO_REFLECT_REPEAT | \ FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_NO_WIDE_FORMAT) + FAST_PATH_NO_WIDE_FORMAT | \ + FAST_PATH_COVERS_CLIP) #define FAST_PATH_STD_SRC_FLAGS \ _FAST_PATH_STANDARD_FLAGS @@ -597,18 +601,6 @@ _pixman_choose_implementation (void); (FAST_PATH_NO_ACCESSORS | \ FAST_PATH_NO_WIDE_FORMAT) -typedef struct -{ - pixman_op_t op; - pixman_format_code_t src_format; - uint32_t src_flags; - pixman_format_code_t mask_format; - uint32_t mask_flags; - pixman_format_code_t dest_format; - uint32_t dest_flags; - pixman_composite_func_t func; -} pixman_fast_path_t; - #define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \ PIXMAN_OP_ ## op, \ PIXMAN_ ## src, \ @@ -649,38 +641,6 @@ pixman_bool_t pixman_addition_overflows_int (unsigned int a, unsigned int b); /* Compositing utilities */ -pixman_bool_t -_pixman_run_fast_path (const pixman_fast_path_t *paths, - pixman_implementation_t * imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height); - -void -_pixman_walk_composite_region (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dst_image, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height, - pixman_composite_func_t composite_rect); - void pixman_expand (uint64_t * dst, const uint32_t * src, diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index f69de0b3..946e7ba3 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -5842,61 +5842,6 @@ static const pixman_fast_path_t sse2_fast_paths[] = { PIXMAN_OP_NONE }, }; -/* - * Work around GCC bug causing crashes in Mozilla with SSE2 - * - * When using -msse, gcc generates movdqa instructions assuming that - * the stack is 16 byte aligned. Unfortunately some applications, such - * as Mozilla and Mono, end up aligning the stack to 4 bytes, which - * causes the movdqa instructions to fail. - * - * The __force_align_arg_pointer__ makes gcc generate a prologue that - * realigns the stack pointer to 16 bytes. - * - * On x86-64 this is not necessary because the standard ABI already - * calls for a 16 byte aligned stack. - * - * See https://bugs.freedesktop.org/show_bug.cgi?id=15693 - */ -#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif -static void -sse2_composite (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - if (_pixman_run_fast_path (sse2_fast_paths, imp, - op, src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height)) - { - return; - } - - _pixman_implementation_composite (imp->delegate, op, - src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height); -} - -#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif static pixman_bool_t sse2_blt (pixman_implementation_t *imp, uint32_t * src_bits, @@ -5960,7 +5905,7 @@ _pixman_implementation_create_sse2 (void) #else pixman_implementation_t *fallback = _pixman_implementation_create_fast_path (); #endif - pixman_implementation_t *imp = _pixman_implementation_create (fallback); + pixman_implementation_t *imp = _pixman_implementation_create (fallback, sse2_fast_paths); /* SSE2 constants */ mask_565_r = create_mask_2x32_128 (0x00f80000, 0x00f80000); @@ -6018,7 +5963,6 @@ _pixman_implementation_create_sse2 (void) imp->combine_32_ca[PIXMAN_OP_XOR] = sse2_combine_xor_ca; imp->combine_32_ca[PIXMAN_OP_ADD] = sse2_combine_add_ca; - imp->composite = sse2_composite; imp->blt = sse2_blt; imp->fill = sse2_fill; diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index ec54c2d9..3ef88b75 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -30,208 +30,6 @@ #include "pixman-private.h" -/* - * Computing composite region - */ -static inline pixman_bool_t -clip_general_image (pixman_region32_t * region, - pixman_region32_t * clip, - int dx, - int dy) -{ - if (pixman_region32_n_rects (region) == 1 && - pixman_region32_n_rects (clip) == 1) - { - pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL); - pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL); - int v; - - if (rbox->x1 < (v = cbox->x1 + dx)) - rbox->x1 = v; - if (rbox->x2 > (v = cbox->x2 + dx)) - rbox->x2 = v; - if (rbox->y1 < (v = cbox->y1 + dy)) - rbox->y1 = v; - if (rbox->y2 > (v = cbox->y2 + dy)) - rbox->y2 = v; - if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2) - { - pixman_region32_init (region); - return FALSE; - } - } - else if (!pixman_region32_not_empty (clip)) - { - return FALSE; - } - else - { - if (dx || dy) - pixman_region32_translate (region, -dx, -dy); - - if (!pixman_region32_intersect (region, region, clip)) - return FALSE; - - if (dx || dy) - pixman_region32_translate (region, dx, dy); - } - - return pixman_region32_not_empty (region); -} - -static inline pixman_bool_t -clip_source_image (pixman_region32_t * region, - pixman_image_t * image, - int dx, - int dy) -{ - /* Source clips are ignored, unless they are explicitly turned on - * and the clip in question was set by an X client. (Because if - * the clip was not set by a client, then it is a hierarchy - * clip and those should always be ignored for sources). - */ - if (!image->common.clip_sources || !image->common.client_clip) - return TRUE; - - return clip_general_image (region, - &image->common.clip_region, - dx, dy); -} - -/* - * returns FALSE if the final region is empty. Indistinguishable from - * an allocation failure, but rendering ignores those anyways. - */ -static pixman_bool_t -pixman_compute_composite_region32 (pixman_region32_t * region, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dst_image, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - region->extents.x1 = dest_x; - region->extents.x2 = dest_x + width; - region->extents.y1 = dest_y; - region->extents.y2 = dest_y + height; - - region->extents.x1 = MAX (region->extents.x1, 0); - region->extents.y1 = MAX (region->extents.y1, 0); - region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width); - region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height); - - region->data = 0; - - /* Check for empty operation */ - if (region->extents.x1 >= region->extents.x2 || - region->extents.y1 >= region->extents.y2) - { - pixman_region32_init (region); - return FALSE; - } - - if (dst_image->common.have_clip_region) - { - if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0)) - { - pixman_region32_fini (region); - return FALSE; - } - } - - if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region) - { - if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region, - -dst_image->common.alpha_origin_x, - -dst_image->common.alpha_origin_y)) - { - pixman_region32_fini (region); - return FALSE; - } - } - - /* clip against src */ - if (src_image->common.have_clip_region) - { - if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y)) - { - pixman_region32_fini (region); - return FALSE; - } - } - if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region) - { - if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map, - dest_x - (src_x - src_image->common.alpha_origin_x), - dest_y - (src_y - src_image->common.alpha_origin_y))) - { - pixman_region32_fini (region); - return FALSE; - } - } - /* clip against mask */ - if (mask_image && mask_image->common.have_clip_region) - { - if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y)) - { - pixman_region32_fini (region); - return FALSE; - } - if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region) - { - if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map, - dest_x - (mask_x - mask_image->common.alpha_origin_x), - dest_y - (mask_y - mask_image->common.alpha_origin_y))) - { - pixman_region32_fini (region); - return FALSE; - } - } - } - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_compute_composite_region (pixman_region16_t * region, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dst_image, - int16_t src_x, - int16_t src_y, - int16_t mask_x, - int16_t mask_y, - int16_t dest_x, - int16_t dest_y, - uint16_t width, - uint16_t height) -{ - pixman_region32_t r32; - pixman_bool_t retval; - - pixman_region32_init (&r32); - - retval = pixman_compute_composite_region32 ( - &r32, src_image, mask_image, dst_image, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, - width, height); - - if (retval) - { - if (!pixman_region16_copy_from_region32 (region, &r32)) - retval = FALSE; - } - - pixman_region32_fini (&r32); - return retval; -} - pixman_bool_t pixman_multiply_overflows_int (unsigned int a, unsigned int b) @@ -369,335 +167,6 @@ pixman_contract (uint32_t * dst, } } -static void -walk_region_internal (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dst_image, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height, - pixman_bool_t src_repeat, - pixman_bool_t mask_repeat, - pixman_region32_t * region, - pixman_composite_func_t composite_rect) -{ - int n; - const pixman_box32_t *pbox; - int w, h, w_this, h_this; - int x_msk, y_msk, x_src, y_src, x_dst, y_dst; - - pbox = pixman_region32_rectangles (region, &n); - while (n--) - { - h = pbox->y2 - pbox->y1; - y_src = pbox->y1 - dest_y + src_y; - y_msk = pbox->y1 - dest_y + mask_y; - y_dst = pbox->y1; - - while (h) - { - h_this = h; - w = pbox->x2 - pbox->x1; - x_src = pbox->x1 - dest_x + src_x; - x_msk = pbox->x1 - dest_x + mask_x; - x_dst = pbox->x1; - - if (mask_repeat) - { - y_msk = MOD (y_msk, mask_image->bits.height); - if (h_this > mask_image->bits.height - y_msk) - h_this = mask_image->bits.height - y_msk; - } - - if (src_repeat) - { - y_src = MOD (y_src, src_image->bits.height); - if (h_this > src_image->bits.height - y_src) - h_this = src_image->bits.height - y_src; - } - - while (w) - { - w_this = w; - - if (mask_repeat) - { - x_msk = MOD (x_msk, mask_image->bits.width); - if (w_this > mask_image->bits.width - x_msk) - w_this = mask_image->bits.width - x_msk; - } - - if (src_repeat) - { - x_src = MOD (x_src, src_image->bits.width); - if (w_this > src_image->bits.width - x_src) - w_this = src_image->bits.width - x_src; - } - - (*composite_rect) (imp, op, - src_image, mask_image, dst_image, - x_src, y_src, x_msk, y_msk, x_dst, y_dst, - w_this, h_this); - w -= w_this; - - x_src += w_this; - x_msk += w_this; - x_dst += w_this; - } - - h -= h_this; - y_src += h_this; - y_msk += h_this; - y_dst += h_this; - } - - pbox++; - } -} - -void -_pixman_walk_composite_region (pixman_implementation_t *imp, - pixman_op_t op, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dst_image, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height, - pixman_composite_func_t composite_rect) -{ - pixman_region32_t region; - - pixman_region32_init (®ion); - - if (pixman_compute_composite_region32 ( - ®ion, src_image, mask_image, dst_image, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, - width, height)) - { - walk_region_internal (imp, op, - src_image, mask_image, dst_image, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, - width, height, FALSE, FALSE, - ®ion, - composite_rect); - - pixman_region32_fini (®ion); - } -} - -static void -get_image_info (pixman_image_t *image, - pixman_format_code_t *code, - uint32_t *flags) -{ - *flags = 0; - - if (!image) - { - *code = PIXMAN_null; - } - else - { - if (!image->common.transform) - *flags |= FAST_PATH_ID_TRANSFORM; - - if (!image->common.alpha_map) - *flags |= FAST_PATH_NO_ALPHA_MAP; - - if (image->common.filter != PIXMAN_FILTER_CONVOLUTION) - *flags |= FAST_PATH_NO_CONVOLUTION_FILTER; - - if (image->common.repeat != PIXMAN_REPEAT_PAD) - *flags |= FAST_PATH_NO_PAD_REPEAT; - - if (image->common.repeat != PIXMAN_REPEAT_REFLECT) - *flags |= FAST_PATH_NO_REFLECT_REPEAT; - - *flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NO_WIDE_FORMAT); - if (image->type == BITS) - { - if (image->bits.read_func || image->bits.write_func) - *flags &= ~FAST_PATH_NO_ACCESSORS; - - if (PIXMAN_FORMAT_IS_WIDE (image->bits.format)) - *flags &= ~FAST_PATH_NO_WIDE_FORMAT; - } - - if (image->common.component_alpha) - *flags |= FAST_PATH_COMPONENT_ALPHA; - else - *flags |= FAST_PATH_UNIFIED_ALPHA; - - if (_pixman_image_is_solid (image)) - *code = PIXMAN_solid; - else if (image->common.type == BITS) - *code = image->bits.format; - else - *code = PIXMAN_unknown; - } -} - -static force_inline pixman_bool_t -image_covers (pixman_image_t *image, - pixman_box32_t *extents, - int x, - int y) -{ - if (image->common.type == BITS && - image->common.repeat == PIXMAN_REPEAT_NONE) - { - if (x > extents->x1 || y > extents->y1 || - x + image->bits.width < extents->x2 || - y + image->bits.height < extents->y2) - { - return FALSE; - } - } - - return TRUE; -} - -static force_inline pixman_bool_t -sources_cover (pixman_image_t *src, - pixman_image_t *mask, - pixman_box32_t *extents, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dest_x, - int dest_y) -{ - if (!image_covers (src, extents, dest_x - src_x, dest_y - src_y)) - return FALSE; - - if (!mask) - return TRUE; - - if (!image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y)) - return FALSE; - - return TRUE; -} - -pixman_bool_t -_pixman_run_fast_path (const pixman_fast_path_t *paths, - pixman_implementation_t * imp, - pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - pixman_format_code_t src_format, mask_format, dest_format; - uint32_t src_flags, mask_flags, dest_flags; - pixman_composite_func_t func; - const pixman_fast_path_t *info; - pixman_bool_t result; - - get_image_info (src, &src_format, &src_flags); - get_image_info (mask, &mask_format, &mask_flags); - get_image_info (dest, &dest_format, &dest_flags); - - /* Check for pixbufs */ - if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) && - (src->type == BITS && src->bits.bits == mask->bits.bits) && - (src->common.repeat == mask->common.repeat) && - (src_x == mask_x && src_y == mask_y)) - { - if (src_format == PIXMAN_x8b8g8r8) - src_format = mask_format = PIXMAN_pixbuf; - else if (src_format == PIXMAN_x8r8g8b8) - src_format = mask_format = PIXMAN_rpixbuf; - } - - func = NULL; - for (info = paths; info->op != PIXMAN_OP_NONE; ++info) - { - if (info->op == op && - (info->src_format == src_format) && - (info->src_flags & src_flags) == info->src_flags && - (info->mask_format == mask_format) && - (info->mask_flags & mask_flags) == info->mask_flags && - (info->dest_format == dest_format) && - (info->dest_flags & dest_flags) == info->dest_flags) - { - func = info->func; - break; - } - } - - result = FALSE; - - if (func) - { - pixman_region32_t region; - pixman_region32_init (®ion); - - if (pixman_compute_composite_region32 ( - ®ion, src, mask, dest, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) - { - pixman_box32_t *extents = pixman_region32_extents (®ion); - - if (sources_cover ( - src, mask, extents, - src_x, src_y, mask_x, mask_y, dest_x, dest_y)) - { - pixman_bool_t src_repeat, mask_repeat; - - src_repeat = - src->type == BITS && - src_flags & FAST_PATH_ID_TRANSFORM && - src->common.repeat == PIXMAN_REPEAT_NORMAL && - src_format != PIXMAN_solid; - - mask_repeat = - mask && - mask->type == BITS && - mask_flags & FAST_PATH_ID_TRANSFORM && - mask->common.repeat == PIXMAN_REPEAT_NORMAL && - mask_format != PIXMAN_solid; - - walk_region_internal (imp, op, - src, mask, dest, - src_x, src_y, mask_x, mask_y, - dest_x, dest_y, - width, height, - src_repeat, mask_repeat, - ®ion, - func); - - result = TRUE; - } - - pixman_region32_fini (®ion); - } - } - - return result; -} - #define N_TMP_BOXES (16) pixman_bool_t diff --git a/pixman/pixman-vmx.c b/pixman/pixman-vmx.c index 06325a7c..e811cf73 100644 --- a/pixman/pixman-vmx.c +++ b/pixman/pixman-vmx.c @@ -1607,11 +1607,16 @@ vmx_combine_add_ca (pixman_implementation_t *imp, } } +static const pixman_fast_path_t vmx_fast_paths[] = +{ + { PIXMAN_OP_NONE }, +}; + pixman_implementation_t * _pixman_implementation_create_vmx (void) { pixman_implementation_t *fast = _pixman_implementation_create_fast_path (); - pixman_implementation_t *imp = _pixman_implementation_create (fast); + pixman_implementation_t *imp = _pixman_implementation_create (fast, vmx_fast_paths); /* Set up function pointers */ diff --git a/pixman/pixman.c b/pixman/pixman.c index 9ab875d7..6a260ed4 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -117,43 +117,554 @@ apply_workaround (pixman_image_t *image, int * save_dx, int * save_dy) { - /* Some X servers generate images that point to the - * wrong place in memory, but then set the clip region - * to point to the right place. Because of an old bug - * in pixman, this would actually work. - * - * Here we try and undo the damage + if (image && image->common.need_workaround) + { + /* Some X servers generate images that point to the + * wrong place in memory, but then set the clip region + * to point to the right place. Because of an old bug + * in pixman, this would actually work. + * + * Here we try and undo the damage + */ + int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8; + pixman_box32_t *extents; + uint8_t *t; + int dx, dy; + + extents = pixman_region32_extents (&(image->common.clip_region)); + dx = extents->x1; + dy = extents->y1; + + *save_bits = image->bits.bits; + + *x -= dx; + *y -= dy; + pixman_region32_translate (&(image->common.clip_region), -dx, -dy); + + t = (uint8_t *)image->bits.bits; + t += dy * image->bits.rowstride * 4 + dx * bpp; + image->bits.bits = (uint32_t *)t; + + *save_dx = dx; + *save_dy = dy; + } +} + +static void +unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy) +{ + if (image && image->common.need_workaround) + { + image->bits.bits = bits; + pixman_region32_translate (&image->common.clip_region, dx, dy); + } +} + +/* + * Computing composite region + */ +static inline pixman_bool_t +clip_general_image (pixman_region32_t * region, + pixman_region32_t * clip, + int dx, + int dy) +{ + if (pixman_region32_n_rects (region) == 1 && + pixman_region32_n_rects (clip) == 1) + { + pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL); + pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL); + int v; + + if (rbox->x1 < (v = cbox->x1 + dx)) + rbox->x1 = v; + if (rbox->x2 > (v = cbox->x2 + dx)) + rbox->x2 = v; + if (rbox->y1 < (v = cbox->y1 + dy)) + rbox->y1 = v; + if (rbox->y2 > (v = cbox->y2 + dy)) + rbox->y2 = v; + if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2) + { + pixman_region32_init (region); + return FALSE; + } + } + else if (!pixman_region32_not_empty (clip)) + { + return FALSE; + } + else + { + if (dx || dy) + pixman_region32_translate (region, -dx, -dy); + + if (!pixman_region32_intersect (region, region, clip)) + return FALSE; + + if (dx || dy) + pixman_region32_translate (region, dx, dy); + } + + return pixman_region32_not_empty (region); +} + +static inline pixman_bool_t +clip_source_image (pixman_region32_t * region, + pixman_image_t * image, + int dx, + int dy) +{ + /* Source clips are ignored, unless they are explicitly turned on + * and the clip in question was set by an X client. (Because if + * the clip was not set by a client, then it is a hierarchy + * clip and those should always be ignored for sources). */ - int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8; - pixman_box32_t *extents; - uint8_t *t; - int dx, dy; + if (!image->common.clip_sources || !image->common.client_clip) + return TRUE; + + return clip_general_image (region, + &image->common.clip_region, + dx, dy); +} + +/* + * returns FALSE if the final region is empty. Indistinguishable from + * an allocation failure, but rendering ignores those anyways. + */ +static pixman_bool_t +pixman_compute_composite_region32 (pixman_region32_t * region, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + region->extents.x1 = dest_x; + region->extents.x2 = dest_x + width; + region->extents.y1 = dest_y; + region->extents.y2 = dest_y + height; - extents = pixman_region32_extents (&(image->common.clip_region)); - dx = extents->x1; - dy = extents->y1; + region->extents.x1 = MAX (region->extents.x1, 0); + region->extents.y1 = MAX (region->extents.y1, 0); + region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width); + region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height); - *save_bits = image->bits.bits; + region->data = 0; - *x -= dx; - *y -= dy; - pixman_region32_translate (&(image->common.clip_region), -dx, -dy); + /* Check for empty operation */ + if (region->extents.x1 >= region->extents.x2 || + region->extents.y1 >= region->extents.y2) + { + pixman_region32_init (region); + return FALSE; + } + + if (dst_image->common.have_clip_region) + { + if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0)) + { + pixman_region32_fini (region); + return FALSE; + } + } + + if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region) + { + if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region, + -dst_image->common.alpha_origin_x, + -dst_image->common.alpha_origin_y)) + { + pixman_region32_fini (region); + return FALSE; + } + } + + /* clip against src */ + if (src_image->common.have_clip_region) + { + if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y)) + { + pixman_region32_fini (region); + return FALSE; + } + } + if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region) + { + if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map, + dest_x - (src_x - src_image->common.alpha_origin_x), + dest_y - (src_y - src_image->common.alpha_origin_y))) + { + pixman_region32_fini (region); + return FALSE; + } + } + /* clip against mask */ + if (mask_image && mask_image->common.have_clip_region) + { + if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y)) + { + pixman_region32_fini (region); + return FALSE; + } + if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region) + { + if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map, + dest_x - (mask_x - mask_image->common.alpha_origin_x), + dest_y - (mask_y - mask_image->common.alpha_origin_y))) + { + pixman_region32_fini (region); + return FALSE; + } + } + } - t = (uint8_t *)image->bits.bits; - t += dy * image->bits.rowstride * 4 + dx * bpp; - image->bits.bits = (uint32_t *)t; + return TRUE; +} - *save_dx = dx; - *save_dy = dy; +static void +walk_region_internal (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height, + pixman_bool_t src_repeat, + pixman_bool_t mask_repeat, + pixman_region32_t * region, + pixman_composite_func_t composite_rect) +{ + int w, h, w_this, h_this; + int x_msk, y_msk, x_src, y_src, x_dst, y_dst; + int src_dy = src_y - dest_y; + int src_dx = src_x - dest_x; + int mask_dy = mask_y - dest_y; + int mask_dx = mask_x - dest_x; + const pixman_box32_t *pbox; + int n; + + pbox = pixman_region32_rectangles (region, &n); + + /* Fast path for non-repeating sources */ + if (!src_repeat && !mask_repeat) + { + while (n--) + { + (*composite_rect) (imp, op, + src_image, mask_image, dst_image, + pbox->x1 + src_dx, + pbox->y1 + src_dy, + pbox->x1 + mask_dx, + pbox->y1 + mask_dy, + pbox->x1, + pbox->y1, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + + pbox++; + } + + return; + } + + while (n--) + { + h = pbox->y2 - pbox->y1; + y_src = pbox->y1 + src_dy; + y_msk = pbox->y1 + mask_dy; + y_dst = pbox->y1; + + while (h) + { + h_this = h; + w = pbox->x2 - pbox->x1; + x_src = pbox->x1 + src_dx; + x_msk = pbox->x1 + mask_dx; + x_dst = pbox->x1; + + if (mask_repeat) + { + y_msk = MOD (y_msk, mask_image->bits.height); + if (h_this > mask_image->bits.height - y_msk) + h_this = mask_image->bits.height - y_msk; + } + + if (src_repeat) + { + y_src = MOD (y_src, src_image->bits.height); + if (h_this > src_image->bits.height - y_src) + h_this = src_image->bits.height - y_src; + } + + while (w) + { + w_this = w; + + if (mask_repeat) + { + x_msk = MOD (x_msk, mask_image->bits.width); + if (w_this > mask_image->bits.width - x_msk) + w_this = mask_image->bits.width - x_msk; + } + + if (src_repeat) + { + x_src = MOD (x_src, src_image->bits.width); + if (w_this > src_image->bits.width - x_src) + w_this = src_image->bits.width - x_src; + } + + (*composite_rect) (imp, op, + src_image, mask_image, dst_image, + x_src, y_src, x_msk, y_msk, x_dst, y_dst, + w_this, h_this); + w -= w_this; + + x_src += w_this; + x_msk += w_this; + x_dst += w_this; + } + + h -= h_this; + y_src += h_this; + y_msk += h_this; + y_dst += h_this; + } + + pbox++; + } } static void -unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy) +get_image_info (pixman_image_t *image, + pixman_format_code_t *code, + uint32_t *flags) +{ + *flags = 0; + + if (!image->common.transform) + { + *flags |= FAST_PATH_ID_TRANSFORM; + } + else + { + if (image->common.transform->matrix[0][1] == 0 && + image->common.transform->matrix[1][0] == 0 && + image->common.transform->matrix[2][0] == 0 && + image->common.transform->matrix[2][1] == 0 && + image->common.transform->matrix[2][2] == pixman_fixed_1) + { + *flags |= FAST_PATH_SCALE_TRANSFORM; + } + } + + if (!image->common.alpha_map) + *flags |= FAST_PATH_NO_ALPHA_MAP; + + if (image->common.filter != PIXMAN_FILTER_CONVOLUTION) + { + *flags |= FAST_PATH_NO_CONVOLUTION_FILTER; + + if (image->common.filter == PIXMAN_FILTER_NEAREST) + *flags |= FAST_PATH_NEAREST_FILTER; + } + + if (image->common.repeat != PIXMAN_REPEAT_PAD) + *flags |= FAST_PATH_NO_PAD_REPEAT; + + if (image->common.repeat != PIXMAN_REPEAT_REFLECT) + *flags |= FAST_PATH_NO_REFLECT_REPEAT; + + *flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NO_WIDE_FORMAT); + if (image->type == BITS) + { + if (image->bits.read_func || image->bits.write_func) + *flags &= ~FAST_PATH_NO_ACCESSORS; + + if (PIXMAN_FORMAT_IS_WIDE (image->bits.format)) + *flags &= ~FAST_PATH_NO_WIDE_FORMAT; + } + + if (image->common.component_alpha) + *flags |= FAST_PATH_COMPONENT_ALPHA; + else + *flags |= FAST_PATH_UNIFIED_ALPHA; + + if (_pixman_image_is_solid (image)) + *code = PIXMAN_solid; + else if (image->common.type == BITS) + *code = image->bits.format; + else + *code = PIXMAN_unknown; +} + +static force_inline pixman_bool_t +image_covers (pixman_image_t *image, + pixman_box32_t *extents, + int x, + int y) { - image->bits.bits = bits; - pixman_region32_translate (&image->common.clip_region, dx, dy); + if (image->common.type == BITS && + image->common.repeat == PIXMAN_REPEAT_NONE) + { + if (x > extents->x1 || y > extents->y1 || + x + image->bits.width < extents->x2 || + y + image->bits.height < extents->y2) + { + return FALSE; + } + } + + return TRUE; +} + +static void +do_composite (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t *src, + pixman_image_t *mask, + pixman_image_t *dest, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dest_x, + int dest_y, + int width, + int height) +{ + pixman_format_code_t src_format, mask_format, dest_format; + uint32_t src_flags, mask_flags, dest_flags; + pixman_bool_t src_repeat, mask_repeat; + pixman_region32_t region; + pixman_box32_t *extents; + + get_image_info (src, &src_format, &src_flags); + if (mask) + { + get_image_info (mask, &mask_format, &mask_flags); + } + else + { + mask_format = PIXMAN_null; + mask_flags = 0; + } + get_image_info (dest, &dest_format, &dest_flags); + + /* Check for pixbufs */ + if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) && + (src->type == BITS && src->bits.bits == mask->bits.bits) && + (src->common.repeat == mask->common.repeat) && + (src_x == mask_x && src_y == mask_y)) + { + if (src_format == PIXMAN_x8b8g8r8) + src_format = mask_format = PIXMAN_pixbuf; + else if (src_format == PIXMAN_x8r8g8b8) + src_format = mask_format = PIXMAN_rpixbuf; + } + + src_repeat = + src->type == BITS && + src_flags & FAST_PATH_ID_TRANSFORM && + src->common.repeat == PIXMAN_REPEAT_NORMAL && + src_format != PIXMAN_solid; + + mask_repeat = + mask && + mask->type == BITS && + mask_flags & FAST_PATH_ID_TRANSFORM && + mask->common.repeat == PIXMAN_REPEAT_NORMAL && + mask_format != PIXMAN_solid; + + pixman_region32_init (®ion); + + if (!pixman_compute_composite_region32 ( + ®ion, src, mask, dest, + src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) + { + return; + } + + extents = pixman_region32_extents (®ion); + + if (image_covers (src, extents, dest_x - src_x, dest_y - src_y)) + src_flags |= FAST_PATH_COVERS_CLIP; + + if (mask && image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y)) + mask_flags |= FAST_PATH_COVERS_CLIP; + + while (imp) + { + const pixman_fast_path_t *info; + + for (info = imp->fast_paths; info->op != PIXMAN_OP_NONE; ++info) + { + if ((info->op == op || info->op == PIXMAN_OP_any) && + /* src */ + ((info->src_format == src_format) || + (info->src_format == PIXMAN_any)) && + (info->src_flags & src_flags) == info->src_flags && + /* mask */ + ((info->mask_format == mask_format) || + (info->mask_format == PIXMAN_any)) && + (info->mask_flags & mask_flags) == info->mask_flags && + /* dest */ + ((info->dest_format == dest_format) || + (info->dest_format == PIXMAN_any)) && + (info->dest_flags & dest_flags) == info->dest_flags) + { + walk_region_internal (imp, op, + src, mask, dest, + src_x, src_y, mask_x, mask_y, + dest_x, dest_y, + width, height, + src_repeat, mask_repeat, + ®ion, + info->func); + + goto done; + } + } + + imp = imp->delegate; + } + +done: + pixman_region32_fini (®ion); } +/* + * Work around GCC bug causing crashes in Mozilla with SSE2 + * + * When using -msse, gcc generates movdqa instructions assuming that + * the stack is 16 byte aligned. Unfortunately some applications, such + * as Mozilla and Mono, end up aligning the stack to 4 bytes, which + * causes the movdqa instructions to fail. + * + * The __force_align_arg_pointer__ makes gcc generate a prologue that + * realigns the stack pointer to 16 bytes. + * + * On x86-64 this is not necessary because the standard ABI already + * calls for a 16 byte aligned stack. + * + * See https://bugs.freedesktop.org/show_bug.cgi?id=15693 + */ +#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) +__attribute__((__force_align_arg_pointer__)) +#endif PIXMAN_EXPORT void pixman_image_composite (pixman_op_t op, pixman_image_t * src, @@ -192,6 +703,7 @@ pixman_image_composite32 (pixman_op_t op, int mask_dx, mask_dy; uint32_t *dest_bits; int dest_dx, dest_dy; + pixman_bool_t need_workaround; _pixman_image_validate (src); if (mask) @@ -214,26 +726,34 @@ pixman_image_composite32 (pixman_op_t op, if (!imp) imp = _pixman_choose_implementation (); - if (src->common.need_workaround) + need_workaround = + (src->common.need_workaround) || + (mask && mask->common.need_workaround) || + (dest->common.need_workaround); + + if (need_workaround) + { apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy); - if (mask && mask->common.need_workaround) apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy); - if (dest->common.need_workaround) apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy); + } - _pixman_implementation_composite (imp, op, - src, mask, dest, - src_x, src_y, - mask_x, mask_y, - dest_x, dest_y, - width, height); - - if (src->common.need_workaround) - unapply_workaround (src, src_bits, src_dx, src_dy); - if (mask && mask->common.need_workaround) - unapply_workaround (mask, mask_bits, mask_dx, mask_dy); - if (dest->common.need_workaround) - unapply_workaround (dest, dest_bits, dest_dx, dest_dy); + do_composite (imp, op, + src, mask, dest, + src_x, src_y, + mask_x, mask_y, + dest_x, dest_y, + width, height); + + if (need_workaround) + { + if (src->common.need_workaround) + unapply_workaround (src, src_bits, src_dx, src_dy); + if (mask && mask->common.need_workaround) + unapply_workaround (mask, mask_bits, mask_dx, mask_dy); + if (dest->common.need_workaround) + unapply_workaround (dest, dest_bits, dest_dx, dest_dy); + } } PIXMAN_EXPORT pixman_bool_t @@ -598,3 +1118,36 @@ pixman_format_supported_destination (pixman_format_code_t format) return pixman_format_supported_source (format); } +PIXMAN_EXPORT pixman_bool_t +pixman_compute_composite_region (pixman_region16_t * region, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int16_t src_x, + int16_t src_y, + int16_t mask_x, + int16_t mask_y, + int16_t dest_x, + int16_t dest_y, + uint16_t width, + uint16_t height) +{ + pixman_region32_t r32; + pixman_bool_t retval; + + pixman_region32_init (&r32); + + retval = pixman_compute_composite_region32 ( + &r32, src_image, mask_image, dst_image, + src_x, src_y, mask_x, mask_y, dest_x, dest_y, + width, height); + + if (retval) + { + if (!pixman_region16_copy_from_region32 (region, &r32)) + retval = FALSE; + } + + pixman_region32_fini (&r32); + return retval; +} |