author | Phil Ringnalda <philringnalda@gmail.com> |
Thu, 12 Jul 2012 22:27:34 -0700 | |
changeset 99156 | 8919db908bedec55d668a9dd298ce511ad964be7 |
parent 99155 | 6dcd9fe905dfff204b256372e1db6c5c2ac2df17 |
child 99157 | 1e5dd8c5cc38c23789363779522acc6bdb38a4b8 |
push id | 23105 |
push user | emorley@mozilla.com |
push date | Fri, 13 Jul 2012 12:23:43 +0000 |
treeherder | mozilla-central@a2d40b91eea9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 683243 |
milestone | 16.0a1 |
backs out | 0c1f34eb5b9304e636789e4a23819cf2a8ca69d5 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/cairo/README +++ b/gfx/cairo/README @@ -193,15 +193,11 @@ NOTE: we previously supported ARM assemb pixman-export.patch: use cairo_public for PIXMAN_EXPORT to make sure pixman symbols are not exported in libxul pixman-limits.patch: include limits.h for SIZE_MAX pixman-lowres-interp.patch: Use lower quality interpolation for more speed. pixman-bilinear-fastpath.patch: Bilinear fast paths for non-neon -pixman-16-bit-pipeline.patch: 16 bit pipeline for dithering - -pixman-dither.patch: Add dithering of 16 bit gradients - ==== disable printing patch ==== disable-printing.patch: allows us to use NS_PRINTING to disable printing.
--- a/gfx/cairo/libpixman/src/Makefile.in +++ b/gfx/cairo/libpixman/src/Makefile.in @@ -76,17 +76,16 @@ endif endif CSRCS = \ pixman-access.c \ pixman-access-accessors.c \ pixman-bits-image.c \ pixman.c \ - pixman-combine16.c \ pixman-combine32.c \ pixman-combine64.c \ pixman-conical-gradient.c \ pixman-cpu.c \ pixman-edge.c \ pixman-edge-accessors.c \ pixman-fast-path.c \ pixman-general.c \
--- a/gfx/cairo/libpixman/src/pixman-access.c +++ b/gfx/cairo/libpixman/src/pixman-access.c @@ -933,54 +933,16 @@ store_scanline_x2b10g10r10 (bits_image_t { WRITE (image, pixel++, ((values[i] >> 38) & 0x3ff) | ((values[i] >> 12) & 0xffc00) | ((values[i] << 14) & 0x3ff00000)); } } -static void -store_scanline_16 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *v) -{ - uint16_t *bits = (uint16_t*)(image->bits + image->rowstride * y); - uint16_t *values = (uint16_t *)v; - uint16_t *pixel = bits + x; - int i; - - for (i = 0; i < width; ++i) - { - WRITE (image, pixel++, values[i]); - } -} - -static void -fetch_scanline_16 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * b, - const uint32_t *mask) -{ - const uint16_t *bits = (uint16_t*)(image->bits.bits + y * image->bits.rowstride); - const uint16_t *pixel = bits + x; - int i; - uint16_t *buffer = (uint16_t *)b; - - for (i = 0; i < width; ++i) - { - *buffer++ = READ (image, pixel++); - } -} - - /* * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit * store proc. Despite the type, this function expects a uint64_t buffer. */ static void store_scanline_generic_64 (bits_image_t * image, int x, int y, @@ -1082,47 +1044,32 @@ fetch_pixel_generic_lossy_32 (bits_image pixman_contract (&result, &pixel64, 1); return result; } typedef struct { pixman_format_code_t format; - fetch_scanline_t fetch_scanline_16; fetch_scanline_t fetch_scanline_32; fetch_scanline_t fetch_scanline_64; fetch_pixel_32_t fetch_pixel_32; fetch_pixel_64_t fetch_pixel_64; - store_scanline_t store_scanline_16; store_scanline_t store_scanline_32; store_scanline_t store_scanline_64; } format_info_t; #define FORMAT_INFO(format) \ { \ PIXMAN_ ## format, \ - NULL, \ fetch_scanline_ ## format, \ fetch_scanline_generic_64, \ fetch_pixel_ ## format, fetch_pixel_generic_64, \ - NULL, \ store_scanline_ ## format, store_scanline_generic_64 \ } -#define FORMAT_INFO16(format) \ - { \ - PIXMAN_ ## format, \ - fetch_scanline_16, \ - fetch_scanline_ ## format, \ - fetch_scanline_generic_64, \ - fetch_pixel_ ## format, fetch_pixel_generic_64, \ - store_scanline_16, \ - store_scanline_ ## format, store_scanline_generic_64 \ - } - static const format_info_t accessors[] = { /* 32 bpp formats */ FORMAT_INFO (a8r8g8b8), FORMAT_INFO (x8r8g8b8), FORMAT_INFO (a8b8g8r8), FORMAT_INFO (x8b8g8r8), @@ -1132,18 +1079,18 @@ static const format_info_t accessors[] = FORMAT_INFO (r8g8b8x8), FORMAT_INFO (x14r6g6b6), /* 24bpp formats */ FORMAT_INFO (r8g8b8), FORMAT_INFO (b8g8r8), /* 16bpp formats */ - FORMAT_INFO16 (r5g6b5), - FORMAT_INFO16 (b5g6r5), + FORMAT_INFO (r5g6b5), + FORMAT_INFO (b5g6r5), FORMAT_INFO (a1r5g5b5), FORMAT_INFO (x1r5g5b5), FORMAT_INFO (a1b5g5r5), FORMAT_INFO (x1b5g5r5), FORMAT_INFO (a4r4g4b4), FORMAT_INFO (x4r4g4b4), FORMAT_INFO (a4b4g4r4), @@ -1185,64 +1132,62 @@ static const format_info_t accessors[] = /* 1bpp formats */ FORMAT_INFO (a1), FORMAT_INFO (g1), /* Wide formats */ { PIXMAN_a2r10g10b10, - NULL, NULL, fetch_scanline_a2r10g10b10, + NULL, fetch_scanline_a2r10g10b10, fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10, NULL, store_scanline_a2r10g10b10 }, { PIXMAN_x2r10g10b10, - NULL, NULL, fetch_scanline_x2r10g10b10, + NULL, fetch_scanline_x2r10g10b10, fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10, NULL, store_scanline_x2r10g10b10 }, { PIXMAN_a2b10g10r10, - NULL, NULL, fetch_scanline_a2b10g10r10, + NULL, fetch_scanline_a2b10g10r10, fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10, NULL, store_scanline_a2b10g10r10 }, { PIXMAN_x2b10g10r10, - NULL, NULL, fetch_scanline_x2b10g10r10, + NULL, fetch_scanline_x2b10g10r10, fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10, NULL, store_scanline_x2b10g10r10 }, /* YUV formats */ { PIXMAN_yuy2, - NULL, fetch_scanline_yuy2, fetch_scanline_generic_64, + fetch_scanline_yuy2, fetch_scanline_generic_64, fetch_pixel_yuy2, fetch_pixel_generic_64, NULL, NULL }, { PIXMAN_yv12, - NULL, fetch_scanline_yv12, fetch_scanline_generic_64, + fetch_scanline_yv12, fetch_scanline_generic_64, fetch_pixel_yv12, fetch_pixel_generic_64, NULL, NULL }, { PIXMAN_null }, }; static void setup_accessors (bits_image_t *image) { const format_info_t *info = accessors; while (info->format != PIXMAN_null) { if (info->format == image->format) { - image->fetch_scanline_16 = info->fetch_scanline_16; image->fetch_scanline_32 = info->fetch_scanline_32; image->fetch_scanline_64 = info->fetch_scanline_64; image->fetch_pixel_32 = info->fetch_pixel_32; image->fetch_pixel_64 = info->fetch_pixel_64; - image->store_scanline_16 = info->store_scanline_16; image->store_scanline_32 = info->store_scanline_32; image->store_scanline_64 = info->store_scanline_64; return; } info++; }
--- a/gfx/cairo/libpixman/src/pixman-bits-image.c +++ b/gfx/cairo/libpixman/src/pixman-bits-image.c @@ -1247,31 +1247,16 @@ src_get_scanline_wide (pixman_iter_t *it void _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) { if (iter->flags & ITER_NARROW) iter->get_scanline = src_get_scanline_narrow; else iter->get_scanline = src_get_scanline_wide; - -} - -static uint32_t * -dest_get_scanline_16 (pixman_iter_t *iter, const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - image->bits.fetch_scanline_16 (image, x, y, width, buffer, mask); - - return iter->buffer; } static uint32_t * dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) { pixman_image_t *image = iter->image; int x = iter->x; int y = iter->y; @@ -1342,30 +1327,16 @@ dest_get_scanline_wide (pixman_iter_t *i free (alpha); } } return iter->buffer; } static void -dest_write_back_16 (pixman_iter_t *iter) -{ - bits_image_t * image = &iter->image->bits; - int x = iter->x; - int y = iter->y; - int width = iter->width; - const uint32_t *buffer = iter->buffer; - - image->store_scanline_16 (image, x, y, width, buffer); - - iter->y++; -} - -static void dest_write_back_narrow (pixman_iter_t *iter) { bits_image_t * image = &iter->image->bits; int x = iter->x; int y = iter->y; int width = iter->width; const uint32_t *buffer = iter->buffer; @@ -1404,41 +1375,28 @@ dest_write_back_wide (pixman_iter_t *ite } iter->y++; } void _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) { - if (iter->flags & ITER_16) - { - if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == - (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) - { - iter->get_scanline = _pixman_iter_get_scanline_noop; - } - else - { - iter->get_scanline = dest_get_scanline_16; - } - iter->write_back = dest_write_back_16; - } - else if (iter->flags & ITER_NARROW) + if (iter->flags & ITER_NARROW) { if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) { iter->get_scanline = _pixman_iter_get_scanline_noop; } else { iter->get_scanline = dest_get_scanline_narrow; } - + iter->write_back = dest_write_back_narrow; } else { iter->get_scanline = dest_get_scanline_wide; iter->write_back = dest_write_back_wide; } }
deleted file mode 100644 --- a/gfx/cairo/libpixman/src/pixman-combine16.c +++ /dev/null @@ -1,124 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <string.h> - -#include "pixman-private.h" - -#include "pixman-combine32.h" - -static force_inline uint32_t -combine_mask (const uint32_t src, const uint32_t mask) -{ - uint32_t s, m; - - m = mask >> A_SHIFT; - - if (!m) - return 0; - s = src; - - UN8x4_MUL_UN8 (s, m); - - return s; -} - -static inline uint32_t convert_0565_to_8888(uint16_t color) -{ - return CONVERT_0565_TO_8888(color); -} - -static inline uint16_t convert_8888_to_0565(uint32_t color) -{ - return CONVERT_8888_TO_0565(color); -} - -static void -combine_src_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - if (!mask) - memcpy (dest, src, width * sizeof (uint16_t)); - else - { - uint16_t *d = (uint16_t*)dest; - uint16_t *src16 = (uint16_t*)src; - for (i = 0; i < width; ++i) - { - if ((*mask & 0xff000000) == 0xff000000) { - // it's likely worth special casing - // fully opaque because it avoids - // the cost of conversion as well the multiplication - *(d + i) = *src16; - } else { - // the mask is still 32bits - uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); - *(d + i) = convert_8888_to_0565(s); - } - mask++; - src16++; - } - } - -} - -static void -combine_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - if (!mask) - memcpy (dest, src, width * sizeof (uint16_t)); - else - { - uint16_t *d = (uint16_t*)dest; - uint16_t *src16 = (uint16_t*)src; - for (i = 0; i < width; ++i) - { - if ((*mask & 0xff000000) == 0xff000000) { - // it's likely worth special casing - // fully opaque because it avoids - // the cost of conversion as well the multiplication - *(d + i) = *src16; - } else if ((*mask & 0xff000000) == 0x00000000) { - // keep the dest the same - } else { - // the mask is still 32bits - uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); - uint32_t ia = ALPHA_8 (~s); - uint32_t d32 = convert_0565_to_8888(*(d + i)); - UN8x4_MUL_UN8_ADD_UN8x4 (d32, ia, s); - *(d + i) = convert_8888_to_0565(d32); - } - mask++; - src16++; - } - } - -} - - -void -_pixman_setup_combiner_functions_16 (pixman_implementation_t *imp) -{ - int i; - for (i = 0; i < PIXMAN_N_OPERATORS; i++) { - imp->combine_16[i] = NULL; - } - imp->combine_16[PIXMAN_OP_SRC] = combine_src_u; - imp->combine_16[PIXMAN_OP_OVER] = combine_over_u; -} -
deleted file mode 100644 --- a/gfx/cairo/libpixman/src/pixman-dither.h +++ /dev/null @@ -1,51 +0,0 @@ -#define R16_BITS 5 -#define G16_BITS 6 -#define B16_BITS 5 - -#define R16_SHIFT (B16_BITS + G16_BITS) -#define G16_SHIFT (B16_BITS) -#define B16_SHIFT 0 - -#define MASK 0xff -#define ONE_HALF 0x80 - -#define A_SHIFT 8 * 3 -#define R_SHIFT 8 * 2 -#define G_SHIFT 8 -#define A_MASK 0xff000000 -#define R_MASK 0xff0000 -#define G_MASK 0xff00 - -#define RB_MASK 0xff00ff -#define AG_MASK 0xff00ff00 -#define RB_ONE_HALF 0x800080 -#define RB_MASK_PLUS_ONE 0x10000100 - -#define ALPHA_8(x) ((x) >> A_SHIFT) -#define RED_8(x) (((x) >> R_SHIFT) & MASK) -#define GREEN_8(x) (((x) >> G_SHIFT) & MASK) -#define BLUE_8(x) ((x) & MASK) - -// This uses the same dithering technique that Skia does. -// It is essentially preturbing the lower bit based on the -// high bit -static inline uint16_t dither_32_to_16(uint32_t c) -{ - uint8_t b = BLUE_8(c); - uint8_t g = GREEN_8(c); - uint8_t r = RED_8(c); - r = ((r << 1) - ((r >> (8 - R16_BITS) << (8 - R16_BITS)) | (r >> R16_BITS))) >> (8 - R16_BITS); - g = ((g << 1) - ((g >> (8 - G16_BITS) << (8 - G16_BITS)) | (g >> G16_BITS))) >> (8 - G16_BITS); - b = ((b << 1) - ((b >> (8 - B16_BITS) << (8 - B16_BITS)) | (b >> B16_BITS))) >> (8 - B16_BITS); - return ((r << R16_SHIFT) | (g << G16_SHIFT) | (b << B16_SHIFT)); -} - -static inline uint16_t dither_8888_to_0565(uint32_t color, pixman_bool_t toggle) -{ - // alternate between a preturbed truncation and a regular truncation - if (toggle) { - return dither_32_to_16(color); - } else { - return CONVERT_8888_TO_0565(color); - } -}
--- a/gfx/cairo/libpixman/src/pixman-general.c +++ b/gfx/cairo/libpixman/src/pixman-general.c @@ -106,61 +106,46 @@ general_composite_rect (pixman_implemen PIXMAN_COMPOSITE_ARGS (info); uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8]; uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer; uint8_t *src_buffer, *mask_buffer, *dest_buffer; pixman_iter_t src_iter, mask_iter, dest_iter; pixman_combine_32_func_t compose; pixman_bool_t component_alpha; iter_flags_t narrow, src_flags; - iter_flags_t rgb16; int Bpp; int i; if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) && (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) && (dest_image->common.flags & FAST_PATH_NARROW_FORMAT)) { narrow = ITER_NARROW; Bpp = 4; } else { narrow = 0; Bpp = 8; } - // XXX: This special casing is bad. Ideally, we'd keep the general code general perhaps - // by having it deal more specifically with different intermediate formats - if ( - (dest_image->common.flags & FAST_PATH_16_FORMAT && (src_image->type == LINEAR || src_image->type == RADIAL)) && - ( op == PIXMAN_OP_SRC || - (op == PIXMAN_OP_OVER && (src_image->common.flags & FAST_PATH_IS_OPAQUE)) - ) - ) { - rgb16 = ITER_16; - } else { - rgb16 = 0; - } - - if (width * Bpp > SCANLINE_BUFFER_LENGTH) { scanline_buffer = pixman_malloc_abc (width, 3, Bpp); if (!scanline_buffer) return; } src_buffer = scanline_buffer; mask_buffer = src_buffer + width * Bpp; dest_buffer = mask_buffer + width * Bpp; /* src iter */ - src_flags = narrow | op_flags[op].src | rgb16; + src_flags = narrow | op_flags[op].src; _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image, src_x, src_y, width, height, src_buffer, src_flags); /* mask iter */ if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) @@ -179,20 +164,20 @@ general_composite_rect (pixman_implemen _pixman_implementation_src_iter_init ( imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height, mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB)); /* dest iter */ _pixman_implementation_dest_iter_init ( imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height, - dest_buffer, narrow | op_flags[op].dst | rgb16); + dest_buffer, narrow | op_flags[op].dst); compose = _pixman_implementation_lookup_combiner ( - imp->toplevel, op, component_alpha, narrow, !!rgb16); + imp->toplevel, op, component_alpha, narrow); if (!compose) return; for (i = 0; i < height; ++i) { uint32_t *s, *m, *d; @@ -249,17 +234,16 @@ general_fill (pixman_implementation_t *i return FALSE; } pixman_implementation_t * _pixman_implementation_create_general (void) { pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); - _pixman_setup_combiner_functions_16 (imp); _pixman_setup_combiner_functions_32 (imp); _pixman_setup_combiner_functions_64 (imp); imp->blt = general_blt; imp->fill = general_fill; imp->src_iter_init = general_src_iter_init; imp->dest_iter_init = general_dest_iter_init;
--- a/gfx/cairo/libpixman/src/pixman-image.c +++ b/gfx/cairo/libpixman/src/pixman-image.c @@ -451,20 +451,16 @@ compute_image_info (pixman_image_t *imag flags |= FAST_PATH_IS_OPAQUE; } 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_NARROW_FORMAT; - - if (image->bits.format == PIXMAN_r5g6b5) - flags |= FAST_PATH_16_FORMAT; - break; case RADIAL: code = PIXMAN_unknown; /* * As explained in pixman-radial-gradient.c, every point of * the plane has a valid associated radius (and thus will be
--- a/gfx/cairo/libpixman/src/pixman-implementation.c +++ b/gfx/cairo/libpixman/src/pixman-implementation.c @@ -101,51 +101,45 @@ pixman_implementation_t * imp->fill = delegate_fill; imp->src_iter_init = delegate_src_iter_init; imp->dest_iter_init = delegate_dest_iter_init; imp->fast_paths = fast_paths; for (i = 0; i < PIXMAN_N_OPERATORS; ++i) { - imp->combine_16[i] = NULL; imp->combine_32[i] = NULL; imp->combine_64[i] = NULL; imp->combine_32_ca[i] = NULL; imp->combine_64_ca[i] = NULL; } return imp; } pixman_combine_32_func_t _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, pixman_op_t op, pixman_bool_t component_alpha, - pixman_bool_t narrow, - pixman_bool_t rgb16) + pixman_bool_t narrow) { pixman_combine_32_func_t f; do { pixman_combine_32_func_t (*combiners[]) = { (pixman_combine_32_func_t *)imp->combine_64, (pixman_combine_32_func_t *)imp->combine_64_ca, imp->combine_32, imp->combine_32_ca, - (pixman_combine_32_func_t *)imp->combine_16, - NULL, }; - if (rgb16) { - f = combiners[4][op]; - } else { - f = combiners[component_alpha + (narrow << 1)][op]; - } + + f = combiners[component_alpha | (narrow << 1)][op]; + imp = imp->delegate; } while (!f); return f; } pixman_bool_t
--- a/gfx/cairo/libpixman/src/pixman-linear-gradient.c +++ b/gfx/cairo/libpixman/src/pixman-linear-gradient.c @@ -26,18 +26,16 @@ */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdlib.h> #include "pixman-private.h" -#include "pixman-dither.h" - static pixman_bool_t linear_gradient_is_horizontal (pixman_image_t *image, int x, int y, int width, int height) { linear_gradient_t *linear = (linear_gradient_t *)image; @@ -219,204 +217,42 @@ linear_get_scanline_narrow (pixman_iter_ } } iter->y++; return iter->buffer; } -static uint16_t convert_8888_to_0565(uint32_t color) -{ - return CONVERT_8888_TO_0565(color); -} - - - -static uint32_t * -linear_get_scanline_16 (pixman_iter_t *iter, - const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint16_t * buffer = (uint16_t*)iter->buffer; - pixman_bool_t toggle = ((x ^ y) & 1); - - pixman_vector_t v, unit; - pixman_fixed_32_32_t l; - pixman_fixed_48_16_t dx, dy; - gradient_t *gradient = (gradient_t *)image; - linear_gradient_t *linear = (linear_gradient_t *)image; - uint16_t *end = buffer + width; - pixman_gradient_walker_t walker; - - _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (image->common.transform) - { - if (!pixman_transform_point_3d (image->common.transform, &v)) - return iter->buffer; - - unit.vector[0] = image->common.transform->matrix[0][0]; - unit.vector[1] = image->common.transform->matrix[1][0]; - unit.vector[2] = image->common.transform->matrix[2][0]; - } - else - { - unit.vector[0] = pixman_fixed_1; - unit.vector[1] = 0; - unit.vector[2] = 0; - } - - dx = linear->p2.x - linear->p1.x; - dy = linear->p2.y - linear->p1.y; - - l = dx * dx + dy * dy; - - if (l == 0 || unit.vector[2] == 0) - { - /* affine transformation only */ - pixman_fixed_32_32_t t, next_inc; - double inc; - - if (l == 0 || v.vector[2] == 0) - { - t = 0; - inc = 0; - } - else - { - double invden, v2; - - invden = pixman_fixed_1 * (double) pixman_fixed_1 / - (l * (double) v.vector[2]); - v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; - } - next_inc = 0; - - if (((pixman_fixed_32_32_t )(inc * width)) == 0) - { - register uint32_t color; - uint16_t dither_diff; - uint16_t color16; - uint16_t color16b; - - color = _pixman_gradient_walker_pixel (&walker, t); - color16 = dither_8888_to_0565(color, toggle); - color16b = dither_8888_to_0565(color, toggle^1); - // compute the difference - dither_diff = color16 ^ color16b; - while (buffer < end) { - *buffer++ = color16; - // use dither_diff to toggle between color16 and color16b - color16 ^= dither_diff; - toggle ^= 1; - } - } - else - { - int i; - - i = 0; - while (buffer < end) - { - if (!mask || *mask++) - { - *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, - t + next_inc), - toggle); - } - toggle ^= 1; - i++; - next_inc = inc * i; - buffer++; - } - } - } - else - { - /* projective transformation */ - double t; - - t = 0; - - while (buffer < end) - { - if (!mask || *mask++) - { - if (v.vector[2] != 0) - { - double invden, v2; - - invden = pixman_fixed_1 * (double) pixman_fixed_1 / - (l * (double) v.vector[2]); - v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - } - - *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t), - toggle); - } - toggle ^= 1; - - ++buffer; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } - - iter->y++; - - return iter->buffer; -} - static uint32_t * linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { uint32_t *buffer = linear_get_scanline_narrow (iter, NULL); pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); return buffer; } void _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) { - // XXX: we can't use this optimization when dithering - if (0 && linear_gradient_is_horizontal ( + if (linear_gradient_is_horizontal ( iter->image, iter->x, iter->y, iter->width, iter->height)) { - if (iter->flags & ITER_16) - linear_get_scanline_16 (iter, NULL); - else if (iter->flags & ITER_NARROW) + if (iter->flags & ITER_NARROW) linear_get_scanline_narrow (iter, NULL); else linear_get_scanline_wide (iter, NULL); iter->get_scanline = _pixman_iter_get_scanline_noop; } else { - if (iter->flags & ITER_16) - iter->get_scanline = linear_get_scanline_16; - else if (iter->flags & ITER_NARROW) + if (iter->flags & ITER_NARROW) iter->get_scanline = linear_get_scanline_narrow; else iter->get_scanline = linear_get_scanline_wide; } } PIXMAN_EXPORT pixman_image_t * pixman_image_create_linear_gradient (pixman_point_fixed_t * p1,
--- a/gfx/cairo/libpixman/src/pixman-private.h +++ b/gfx/cairo/libpixman/src/pixman-private.h @@ -152,28 +152,24 @@ struct bits_image int height; uint32_t * bits; uint32_t * free_me; int rowstride; /* in number of uint32_t's */ fetch_scanline_t get_scanline_32; fetch_scanline_t get_scanline_64; - fetch_scanline_t fetch_scanline_16; - fetch_scanline_t fetch_scanline_32; fetch_pixel_32_t fetch_pixel_32; store_scanline_t store_scanline_32; fetch_scanline_t fetch_scanline_64; fetch_pixel_64_t fetch_pixel_64; store_scanline_t store_scanline_64; - store_scanline_t store_scanline_16; - /* Used for indirect access to the bits */ pixman_read_memory_func_t read_func; pixman_write_memory_func_t write_func; }; union pixman_image { image_type_t type; @@ -206,24 +202,17 @@ typedef enum * destination. * * When he destination is xRGB, this is useful knowledge, because then * we can treat it as if it were ARGB, which means in some cases we can * avoid copying it to a temporary buffer. */ ITER_LOCALIZED_ALPHA = (1 << 1), ITER_IGNORE_ALPHA = (1 << 2), - ITER_IGNORE_RGB = (1 << 3), - - /* With the addition of ITER_16 we now have two flags that to represent - * 3 pipelines. This means that there can be an invalid state when - * both ITER_NARROW and ITER_16 are set. In this case - * ITER_16 overrides NARROW and we should use the 16 bit pipeline. - * Note: ITER_16 still has a 32 bit mask, which is a bit weird. */ - ITER_16 = (1 << 4) + ITER_IGNORE_RGB = (1 << 3) } iter_flags_t; struct pixman_iter_t { /* These are initialized by _pixman_implementation_{src,dest}_init */ pixman_image_t * image; uint32_t * buffer; int x, y; @@ -440,17 +429,16 @@ typedef pixman_bool_t (*pixman_fill_func int x, int y, int width, int height, uint32_t xor); typedef void (*pixman_iter_init_func_t) (pixman_implementation_t *imp, pixman_iter_t *iter); -void _pixman_setup_combiner_functions_16 (pixman_implementation_t *imp); void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp); typedef struct { pixman_op_t op; pixman_format_code_t src_format; uint32_t src_flags; @@ -471,34 +459,32 @@ struct pixman_implementation_t pixman_fill_func_t fill; pixman_iter_init_func_t src_iter_init; pixman_iter_init_func_t dest_iter_init; 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_64_func_t combine_16[PIXMAN_N_OPERATORS]; }; uint32_t _pixman_image_get_solid (pixman_implementation_t *imp, pixman_image_t * image, pixman_format_code_t format); pixman_implementation_t * _pixman_implementation_create (pixman_implementation_t *delegate, const pixman_fast_path_t *fast_paths); pixman_combine_32_func_t _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, pixman_op_t op, pixman_bool_t component_alpha, - pixman_bool_t wide, - pixman_bool_t rgb16); + pixman_bool_t wide); pixman_bool_t _pixman_implementation_blt (pixman_implementation_t *imp, uint32_t * src_bits, uint32_t * dst_bits, int src_stride, int dst_stride, int src_bpp, @@ -627,17 +613,16 @@ uint32_t * #define FAST_PATH_Y_UNIT_ZERO (1 << 18) #define FAST_PATH_BILINEAR_FILTER (1 << 19) #define FAST_PATH_ROTATE_90_TRANSFORM (1 << 20) #define FAST_PATH_ROTATE_180_TRANSFORM (1 << 21) #define FAST_PATH_ROTATE_270_TRANSFORM (1 << 22) #define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST (1 << 23) #define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR (1 << 24) #define FAST_PATH_BITS_IMAGE (1 << 25) -#define FAST_PATH_16_FORMAT (1 << 26) #define FAST_PATH_PAD_REPEAT \ (FAST_PATH_NO_NONE_REPEAT | \ FAST_PATH_NO_NORMAL_REPEAT | \ FAST_PATH_NO_REFLECT_REPEAT) #define FAST_PATH_NORMAL_REPEAT \ (FAST_PATH_NO_NONE_REPEAT | \
--- a/gfx/cairo/libpixman/src/pixman-radial-gradient.c +++ b/gfx/cairo/libpixman/src/pixman-radial-gradient.c @@ -29,18 +29,16 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdlib.h> #include <math.h> #include "pixman-private.h" -#include "pixman-dither.h" - static inline pixman_fixed_32_32_t dot (pixman_fixed_48_16_t x1, pixman_fixed_48_16_t y1, pixman_fixed_48_16_t z1, pixman_fixed_48_16_t x2, pixman_fixed_48_16_t y2, pixman_fixed_48_16_t z2) { @@ -397,294 +395,35 @@ radial_get_scanline_narrow (pixman_iter_ v.vector[2] += unit.vector[2]; } } iter->y++; return iter->buffer; } -static uint16_t convert_8888_to_0565(uint32_t color) -{ - return CONVERT_8888_TO_0565(color); -} - -static uint32_t * -radial_get_scanline_16 (pixman_iter_t *iter, const uint32_t *mask) -{ - /* - * Implementation of radial gradients following the PDF specification. - * See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference - * Manual (PDF 32000-1:2008 at the time of this writing). - * - * In the radial gradient problem we are given two circles (c₁,r₁) and - * (c₂,r₂) that define the gradient itself. - * - * Mathematically the gradient can be defined as the family of circles - * - * ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂) - * - * excluding those circles whose radius would be < 0. When a point - * belongs to more than one circle, the one with a bigger t is the only - * one that contributes to its color. When a point does not belong - * to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0). - * Further limitations on the range of values for t are imposed when - * the gradient is not repeated, namely t must belong to [0,1]. - * - * The graphical result is the same as drawing the valid (radius > 0) - * circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient - * is not repeated) using SOURCE operator composition. - * - * It looks like a cone pointing towards the viewer if the ending circle - * is smaller than the starting one, a cone pointing inside the page if - * the starting circle is the smaller one and like a cylinder if they - * have the same radius. - * - * What we actually do is, given the point whose color we are interested - * in, compute the t values for that point, solving for t in: - * - * length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂ - * - * Let's rewrite it in a simpler way, by defining some auxiliary - * variables: - * - * cd = c₂ - c₁ - * pd = p - c₁ - * dr = r₂ - r₁ - * length(t·cd - pd) = r₁ + t·dr - * - * which actually means - * - * hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr - * - * or - * - * ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr. - * - * If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes: - * - * (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)² - * - * where we can actually expand the squares and solve for t: - * - * t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² = - * = r₁² + 2·r₁·t·dr + t²·dr² - * - * (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t + - * (pdx² + pdy² - r₁²) = 0 - * - * A = cdx² + cdy² - dr² - * B = pdx·cdx + pdy·cdy + r₁·dr - * C = pdx² + pdy² - r₁² - * At² - 2Bt + C = 0 - * - * The solutions (unless the equation degenerates because of A = 0) are: - * - * t = (B ± ⎷(B² - A·C)) / A - * - * The solution we are going to prefer is the bigger one, unless the - * radius associated to it is negative (or it falls outside the valid t - * range). - * - * Additional observations (useful for optimizations): - * A does not depend on p - * - * A < 0 <=> one of the two circles completely contains the other one - * <=> for every p, the radiuses associated with the two t solutions - * have opposite sign - */ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint16_t *buffer = iter->buffer; - pixman_bool_t toggle = ((x ^ y) & 1); - - gradient_t *gradient = (gradient_t *)image; - radial_gradient_t *radial = (radial_gradient_t *)image; - uint16_t *end = buffer + width; - pixman_gradient_walker_t walker; - pixman_vector_t v, unit; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); - - if (image->common.transform) - { - if (!pixman_transform_point_3d (image->common.transform, &v)) - return iter->buffer; - - unit.vector[0] = image->common.transform->matrix[0][0]; - unit.vector[1] = image->common.transform->matrix[1][0]; - unit.vector[2] = image->common.transform->matrix[2][0]; - } - else - { - unit.vector[0] = pixman_fixed_1; - unit.vector[1] = 0; - unit.vector[2] = 0; - } - - if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1) - { - /* - * Given: - * - * t = (B ± ⎷(B² - A·C)) / A - * - * where - * - * A = cdx² + cdy² - dr² - * B = pdx·cdx + pdy·cdy + r₁·dr - * C = pdx² + pdy² - r₁² - * det = B² - A·C - * - * Since we have an affine transformation, we know that (pdx, pdy) - * increase linearly with each pixel, - * - * pdx = pdx₀ + n·ux, - * pdy = pdy₀ + n·uy, - * - * we can then express B, C and det through multiple differentiation. - */ - pixman_fixed_32_32_t b, db, c, dc, ddc; - - /* warning: this computation may overflow */ - v.vector[0] -= radial->c1.x; - v.vector[1] -= radial->c1.y; - - /* - * B and C are computed and updated exactly. - * If fdot was used instead of dot, in the worst case it would - * lose 11 bits of precision in each of the multiplication and - * summing up would zero out all the bit that were preserved, - * thus making the result 0 instead of the correct one. - * This would mean a worst case of unbound relative error or - * about 2^10 absolute error - */ - b = dot (v.vector[0], v.vector[1], radial->c1.radius, - radial->delta.x, radial->delta.y, radial->delta.radius); - db = dot (unit.vector[0], unit.vector[1], 0, - radial->delta.x, radial->delta.y, 0); - - c = dot (v.vector[0], v.vector[1], - -((pixman_fixed_48_16_t) radial->c1.radius), - v.vector[0], v.vector[1], radial->c1.radius); - dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0], - 2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1], - 0, - unit.vector[0], unit.vector[1], 0); - ddc = 2 * dot (unit.vector[0], unit.vector[1], 0, - unit.vector[0], unit.vector[1], 0); - - while (buffer < end) - { - if (!mask || *mask++) - { - *buffer = dither_8888_to_0565( - radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, - image->common.repeat), - toggle); - } - - toggle ^= 1; - b += db; - c += dc; - dc += ddc; - ++buffer; - } - } - else - { - /* projective */ - /* Warning: - * error propagation guarantees are much looser than in the affine case - */ - while (buffer < end) - { - if (!mask || *mask++) - { - if (v.vector[2] != 0) - { - double pdx, pdy, invv2, b, c; - - invv2 = 1. * pixman_fixed_1 / v.vector[2]; - - pdx = v.vector[0] * invv2 - radial->c1.x; - /* / pixman_fixed_1 */ - - pdy = v.vector[1] * invv2 - radial->c1.y; - /* / pixman_fixed_1 */ - - b = fdot (pdx, pdy, radial->c1.radius, - radial->delta.x, radial->delta.y, - radial->delta.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - - c = fdot (pdx, pdy, -radial->c1.radius, - pdx, pdy, radial->c1.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - - *buffer = dither_8888_to_0565 ( - radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, - image->common.repeat), - toggle); - } - else - { - *buffer = 0; - } - } - - ++buffer; - toggle ^= 1; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } - - iter->y++; - return iter->buffer; -} static uint32_t * radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); return buffer; } void _pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) { - if (iter->flags & ITER_16) - iter->get_scanline = radial_get_scanline_16; - else if (iter->flags & ITER_NARROW) + if (iter->flags & ITER_NARROW) iter->get_scanline = radial_get_scanline_narrow; else iter->get_scanline = radial_get_scanline_wide; } - PIXMAN_EXPORT pixman_image_t * pixman_image_create_radial_gradient (pixman_point_fixed_t * inner, pixman_point_fixed_t * outer, pixman_fixed_t inner_radius, pixman_fixed_t outer_radius, const pixman_gradient_stop_t *stops, int n_stops) {
deleted file mode 100644 --- a/gfx/cairo/pixman-16-bit-pipeline.patch +++ /dev/null @@ -1,1242 +0,0 @@ -diff --git a/gfx/cairo/libpixman/src/pixman-access.c b/gfx/cairo/libpixman/src/pixman-access.c ---- a/gfx/cairo/libpixman/src/pixman-access.c -+++ b/gfx/cairo/libpixman/src/pixman-access.c -@@ -933,16 +933,54 @@ store_scanline_x2b10g10r10 (bits_image_t - { - WRITE (image, pixel++, - ((values[i] >> 38) & 0x3ff) | - ((values[i] >> 12) & 0xffc00) | - ((values[i] << 14) & 0x3ff00000)); - } - } - -+static void -+store_scanline_16 (bits_image_t * image, -+ int x, -+ int y, -+ int width, -+ const uint32_t *v) -+{ -+ uint16_t *bits = (uint16_t*)(image->bits + image->rowstride * y); -+ uint16_t *values = (uint16_t *)v; -+ uint16_t *pixel = bits + x; -+ int i; -+ -+ for (i = 0; i < width; ++i) -+ { -+ WRITE (image, pixel++, values[i]); -+ } -+} -+ -+static void -+fetch_scanline_16 (pixman_image_t *image, -+ int x, -+ int y, -+ int width, -+ uint32_t * b, -+ const uint32_t *mask) -+{ -+ const uint16_t *bits = (uint16_t*)(image->bits.bits + y * image->bits.rowstride); -+ const uint16_t *pixel = bits + x; -+ int i; -+ uint16_t *buffer = (uint16_t *)b; -+ -+ for (i = 0; i < width; ++i) -+ { -+ *buffer++ = READ (image, pixel++); -+ } -+} -+ -+ - /* - * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit - * store proc. Despite the type, this function expects a uint64_t buffer. - */ - static void - store_scanline_generic_64 (bits_image_t * image, - int x, - int y, -@@ -1044,32 +1082,47 @@ fetch_pixel_generic_lossy_32 (bits_image - pixman_contract (&result, &pixel64, 1); - - return result; - } - - typedef struct - { - pixman_format_code_t format; -+ fetch_scanline_t fetch_scanline_16; - fetch_scanline_t fetch_scanline_32; - fetch_scanline_t fetch_scanline_64; - fetch_pixel_32_t fetch_pixel_32; - fetch_pixel_64_t fetch_pixel_64; -+ store_scanline_t store_scanline_16; - store_scanline_t store_scanline_32; - store_scanline_t store_scanline_64; - } format_info_t; - - #define FORMAT_INFO(format) \ - { \ - PIXMAN_ ## format, \ -+ NULL, \ - fetch_scanline_ ## format, \ - fetch_scanline_generic_64, \ - fetch_pixel_ ## format, fetch_pixel_generic_64, \ -+ NULL, \ - store_scanline_ ## format, store_scanline_generic_64 \ - } -+#define FORMAT_INFO16(format) \ -+ { \ -+ PIXMAN_ ## format, \ -+ fetch_scanline_16, \ -+ fetch_scanline_ ## format, \ -+ fetch_scanline_generic_64, \ -+ fetch_pixel_ ## format, fetch_pixel_generic_64, \ -+ store_scanline_16, \ -+ store_scanline_ ## format, store_scanline_generic_64 \ -+ } -+ - - static const format_info_t accessors[] = - { - /* 32 bpp formats */ - FORMAT_INFO (a8r8g8b8), - FORMAT_INFO (x8r8g8b8), - FORMAT_INFO (a8b8g8r8), - FORMAT_INFO (x8b8g8r8), -@@ -1079,18 +1132,18 @@ static const format_info_t accessors[] = - FORMAT_INFO (r8g8b8x8), - FORMAT_INFO (x14r6g6b6), - - /* 24bpp formats */ - FORMAT_INFO (r8g8b8), - FORMAT_INFO (b8g8r8), - - /* 16bpp formats */ -- FORMAT_INFO (r5g6b5), -- FORMAT_INFO (b5g6r5), -+ FORMAT_INFO16 (r5g6b5), -+ FORMAT_INFO16 (b5g6r5), - - FORMAT_INFO (a1r5g5b5), - FORMAT_INFO (x1r5g5b5), - FORMAT_INFO (a1b5g5r5), - FORMAT_INFO (x1b5g5r5), - FORMAT_INFO (a4r4g4b4), - FORMAT_INFO (x4r4g4b4), - FORMAT_INFO (a4b4g4r4), -@@ -1132,62 +1185,64 @@ static const format_info_t accessors[] = - - /* 1bpp formats */ - FORMAT_INFO (a1), - FORMAT_INFO (g1), - - /* Wide formats */ - - { PIXMAN_a2r10g10b10, -- NULL, fetch_scanline_a2r10g10b10, -+ NULL, NULL, fetch_scanline_a2r10g10b10, - fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10, - NULL, store_scanline_a2r10g10b10 }, - - { PIXMAN_x2r10g10b10, -- NULL, fetch_scanline_x2r10g10b10, -+ NULL, NULL, fetch_scanline_x2r10g10b10, - fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10, - NULL, store_scanline_x2r10g10b10 }, - - { PIXMAN_a2b10g10r10, -- NULL, fetch_scanline_a2b10g10r10, -+ NULL, NULL, fetch_scanline_a2b10g10r10, - fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10, - NULL, store_scanline_a2b10g10r10 }, - - { PIXMAN_x2b10g10r10, -- NULL, fetch_scanline_x2b10g10r10, -+ NULL, NULL, fetch_scanline_x2b10g10r10, - fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10, - NULL, store_scanline_x2b10g10r10 }, - - /* YUV formats */ - { PIXMAN_yuy2, -- fetch_scanline_yuy2, fetch_scanline_generic_64, -+ NULL, fetch_scanline_yuy2, fetch_scanline_generic_64, - fetch_pixel_yuy2, fetch_pixel_generic_64, - NULL, NULL }, - - { PIXMAN_yv12, -- fetch_scanline_yv12, fetch_scanline_generic_64, -+ NULL, fetch_scanline_yv12, fetch_scanline_generic_64, - fetch_pixel_yv12, fetch_pixel_generic_64, - NULL, NULL }, - - { PIXMAN_null }, - }; - - static void - setup_accessors (bits_image_t *image) - { - const format_info_t *info = accessors; - - while (info->format != PIXMAN_null) - { - if (info->format == image->format) - { -+ image->fetch_scanline_16 = info->fetch_scanline_16; - image->fetch_scanline_32 = info->fetch_scanline_32; - image->fetch_scanline_64 = info->fetch_scanline_64; - image->fetch_pixel_32 = info->fetch_pixel_32; - image->fetch_pixel_64 = info->fetch_pixel_64; -+ image->store_scanline_16 = info->store_scanline_16; - image->store_scanline_32 = info->store_scanline_32; - image->store_scanline_64 = info->store_scanline_64; - - return; - } - - info++; - } -diff --git a/gfx/cairo/libpixman/src/pixman-bits-image.c b/gfx/cairo/libpixman/src/pixman-bits-image.c ---- a/gfx/cairo/libpixman/src/pixman-bits-image.c -+++ b/gfx/cairo/libpixman/src/pixman-bits-image.c -@@ -1247,16 +1247,31 @@ src_get_scanline_wide (pixman_iter_t *it - - void - _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) - { - if (iter->flags & ITER_NARROW) - iter->get_scanline = src_get_scanline_narrow; - else - iter->get_scanline = src_get_scanline_wide; -+ -+} -+ -+static uint32_t * -+dest_get_scanline_16 (pixman_iter_t *iter, const uint32_t *mask) -+{ -+ pixman_image_t *image = iter->image; -+ int x = iter->x; -+ int y = iter->y; -+ int width = iter->width; -+ uint32_t * buffer = iter->buffer; -+ -+ image->bits.fetch_scanline_16 (image, x, y, width, buffer, mask); -+ -+ return iter->buffer; - } - - static uint32_t * - dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) - { - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; -@@ -1327,16 +1342,30 @@ dest_get_scanline_wide (pixman_iter_t *i - free (alpha); - } - } - - return iter->buffer; - } - - static void -+dest_write_back_16 (pixman_iter_t *iter) -+{ -+ bits_image_t * image = &iter->image->bits; -+ int x = iter->x; -+ int y = iter->y; -+ int width = iter->width; -+ const uint32_t *buffer = iter->buffer; -+ -+ image->store_scanline_16 (image, x, y, width, buffer); -+ -+ iter->y++; -+} -+ -+static void - dest_write_back_narrow (pixman_iter_t *iter) - { - bits_image_t * image = &iter->image->bits; - int x = iter->x; - int y = iter->y; - int width = iter->width; - const uint32_t *buffer = iter->buffer; - -@@ -1375,28 +1404,41 @@ dest_write_back_wide (pixman_iter_t *ite - } - - iter->y++; - } - - void - _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) - { -- if (iter->flags & ITER_NARROW) -+ if (iter->flags & ITER_16) -+ { -+ if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == -+ (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) -+ { -+ iter->get_scanline = _pixman_iter_get_scanline_noop; -+ } -+ else -+ { -+ iter->get_scanline = dest_get_scanline_16; -+ } -+ iter->write_back = dest_write_back_16; -+ } -+ else if (iter->flags & ITER_NARROW) - { - if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == - (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) - { - iter->get_scanline = _pixman_iter_get_scanline_noop; - } - else - { - iter->get_scanline = dest_get_scanline_narrow; - } -- -+ - iter->write_back = dest_write_back_narrow; - } - else - { - iter->get_scanline = dest_get_scanline_wide; - iter->write_back = dest_write_back_wide; - } - } -diff --git a/gfx/cairo/libpixman/src/pixman-combine16.c b/gfx/cairo/libpixman/src/pixman-combine16.c -new file mode 100644 ---- /dev/null -+++ b/gfx/cairo/libpixman/src/pixman-combine16.c -@@ -0,0 +1,124 @@ -+#ifdef HAVE_CONFIG_H -+#include <config.h> -+#endif -+ -+#include <math.h> -+#include <string.h> -+ -+#include "pixman-private.h" -+ -+#include "pixman-combine32.h" -+ -+static force_inline uint32_t -+combine_mask (const uint32_t src, const uint32_t mask) -+{ -+ uint32_t s, m; -+ -+ m = mask >> A_SHIFT; -+ -+ if (!m) -+ return 0; -+ s = src; -+ -+ UN8x4_MUL_UN8 (s, m); -+ -+ return s; -+} -+ -+static inline uint32_t convert_0565_to_8888(uint16_t color) -+{ -+ return CONVERT_0565_TO_8888(color); -+} -+ -+static inline uint16_t convert_8888_to_0565(uint32_t color) -+{ -+ return CONVERT_8888_TO_0565(color); -+} -+ -+static void -+combine_src_u (pixman_implementation_t *imp, -+ pixman_op_t op, -+ uint32_t * dest, -+ const uint32_t * src, -+ const uint32_t * mask, -+ int width) -+{ -+ int i; -+ -+ if (!mask) -+ memcpy (dest, src, width * sizeof (uint16_t)); -+ else -+ { -+ uint16_t *d = (uint16_t*)dest; -+ uint16_t *src16 = (uint16_t*)src; -+ for (i = 0; i < width; ++i) -+ { -+ if ((*mask & 0xff000000) == 0xff000000) { -+ // it's likely worth special casing -+ // fully opaque because it avoids -+ // the cost of conversion as well the multiplication -+ *(d + i) = *src16; -+ } else { -+ // the mask is still 32bits -+ uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); -+ *(d + i) = convert_8888_to_0565(s); -+ } -+ mask++; -+ src16++; -+ } -+ } -+ -+} -+ -+static void -+combine_over_u (pixman_implementation_t *imp, -+ pixman_op_t op, -+ uint32_t * dest, -+ const uint32_t * src, -+ const uint32_t * mask, -+ int width) -+{ -+ int i; -+ -+ if (!mask) -+ memcpy (dest, src, width * sizeof (uint16_t)); -+ else -+ { -+ uint16_t *d = (uint16_t*)dest; -+ uint16_t *src16 = (uint16_t*)src; -+ for (i = 0; i < width; ++i) -+ { -+ if ((*mask & 0xff000000) == 0xff000000) { -+ // it's likely worth special casing -+ // fully opaque because it avoids -+ // the cost of conversion as well the multiplication -+ *(d + i) = *src16; -+ } else if ((*mask & 0xff000000) == 0x00000000) { -+ // keep the dest the same -+ } else { -+ // the mask is still 32bits -+ uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); -+ uint32_t ia = ALPHA_8 (~s); -+ uint32_t d32 = convert_0565_to_8888(*(d + i)); -+ UN8x4_MUL_UN8_ADD_UN8x4 (d32, ia, s); -+ *(d + i) = convert_8888_to_0565(d32); -+ } -+ mask++; -+ src16++; -+ } -+ } -+ -+} -+ -+ -+void -+_pixman_setup_combiner_functions_16 (pixman_implementation_t *imp) -+{ -+ int i; -+ for (i = 0; i < PIXMAN_N_OPERATORS; i++) { -+ imp->combine_16[i] = NULL; -+ } -+ imp->combine_16[PIXMAN_OP_SRC] = combine_src_u; -+ imp->combine_16[PIXMAN_OP_OVER] = combine_over_u; -+} -+ -diff --git a/gfx/cairo/libpixman/src/pixman-general.c b/gfx/cairo/libpixman/src/pixman-general.c ---- a/gfx/cairo/libpixman/src/pixman-general.c -+++ b/gfx/cairo/libpixman/src/pixman-general.c -@@ -106,46 +106,61 @@ general_composite_rect (pixman_implemen - PIXMAN_COMPOSITE_ARGS (info); - uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8]; - uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer; - uint8_t *src_buffer, *mask_buffer, *dest_buffer; - pixman_iter_t src_iter, mask_iter, dest_iter; - pixman_combine_32_func_t compose; - pixman_bool_t component_alpha; - iter_flags_t narrow, src_flags; -+ iter_flags_t rgb16; - int Bpp; - int i; - - if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) && - (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) && - (dest_image->common.flags & FAST_PATH_NARROW_FORMAT)) - { - narrow = ITER_NARROW; - Bpp = 4; - } - else - { - narrow = 0; - Bpp = 8; - } - -+ // XXX: This special casing is bad. Ideally, we'd keep the general code general perhaps -+ // by having it deal more specifically with different intermediate formats -+ if ( -+ (dest_image->common.flags & FAST_PATH_16_FORMAT && (src_image->type == LINEAR || src_image->type == RADIAL)) && -+ ( op == PIXMAN_OP_SRC || -+ (op == PIXMAN_OP_OVER && (src_image->common.flags & FAST_PATH_IS_OPAQUE)) -+ ) -+ ) { -+ rgb16 = ITER_16; -+ } else { -+ rgb16 = 0; -+ } -+ -+ - if (width * Bpp > SCANLINE_BUFFER_LENGTH) - { - scanline_buffer = pixman_malloc_abc (width, 3, Bpp); - - if (!scanline_buffer) - return; - } - - src_buffer = scanline_buffer; - mask_buffer = src_buffer + width * Bpp; - dest_buffer = mask_buffer + width * Bpp; - - /* src iter */ -- src_flags = narrow | op_flags[op].src; -+ src_flags = narrow | op_flags[op].src | rgb16; - - _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image, - src_x, src_y, width, height, - src_buffer, src_flags); - - /* mask iter */ - if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == - (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) -@@ -164,20 +179,20 @@ general_composite_rect (pixman_implemen - - _pixman_implementation_src_iter_init ( - imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height, - mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB)); - - /* dest iter */ - _pixman_implementation_dest_iter_init ( - imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height, -- dest_buffer, narrow | op_flags[op].dst); -+ dest_buffer, narrow | op_flags[op].dst | rgb16); - - compose = _pixman_implementation_lookup_combiner ( -- imp->toplevel, op, component_alpha, narrow); -+ imp->toplevel, op, component_alpha, narrow, !!rgb16); - - if (!compose) - return; - - for (i = 0; i < height; ++i) - { - uint32_t *s, *m, *d; - -@@ -234,16 +249,17 @@ general_fill (pixman_implementation_t *i - return FALSE; - } - - pixman_implementation_t * - _pixman_implementation_create_general (void) - { - pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); - -+ _pixman_setup_combiner_functions_16 (imp); - _pixman_setup_combiner_functions_32 (imp); - _pixman_setup_combiner_functions_64 (imp); - - imp->blt = general_blt; - imp->fill = general_fill; - imp->src_iter_init = general_src_iter_init; - imp->dest_iter_init = general_dest_iter_init; - -diff --git a/gfx/cairo/libpixman/src/pixman-image.c b/gfx/cairo/libpixman/src/pixman-image.c ---- a/gfx/cairo/libpixman/src/pixman-image.c -+++ b/gfx/cairo/libpixman/src/pixman-image.c -@@ -451,16 +451,20 @@ compute_image_info (pixman_image_t *imag - flags |= FAST_PATH_IS_OPAQUE; - } - - 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_NARROW_FORMAT; -+ -+ if (image->bits.format == PIXMAN_r5g6b5) -+ flags |= FAST_PATH_16_FORMAT; -+ - break; - - case RADIAL: - code = PIXMAN_unknown; - - /* - * As explained in pixman-radial-gradient.c, every point of - * the plane has a valid associated radius (and thus will be -diff --git a/gfx/cairo/libpixman/src/pixman-implementation.c b/gfx/cairo/libpixman/src/pixman-implementation.c ---- a/gfx/cairo/libpixman/src/pixman-implementation.c -+++ b/gfx/cairo/libpixman/src/pixman-implementation.c -@@ -101,45 +101,51 @@ pixman_implementation_t * - imp->fill = delegate_fill; - imp->src_iter_init = delegate_src_iter_init; - imp->dest_iter_init = delegate_dest_iter_init; - - imp->fast_paths = fast_paths; - - for (i = 0; i < PIXMAN_N_OPERATORS; ++i) - { -+ imp->combine_16[i] = NULL; - imp->combine_32[i] = NULL; - imp->combine_64[i] = NULL; - imp->combine_32_ca[i] = NULL; - imp->combine_64_ca[i] = NULL; - } - - return imp; - } - - pixman_combine_32_func_t - _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, - pixman_op_t op, - pixman_bool_t component_alpha, -- pixman_bool_t narrow) -+ pixman_bool_t narrow, -+ pixman_bool_t rgb16) - { - pixman_combine_32_func_t f; - - do - { - pixman_combine_32_func_t (*combiners[]) = - { - (pixman_combine_32_func_t *)imp->combine_64, - (pixman_combine_32_func_t *)imp->combine_64_ca, - imp->combine_32, - imp->combine_32_ca, -+ (pixman_combine_32_func_t *)imp->combine_16, -+ NULL, - }; -- -- f = combiners[component_alpha | (narrow << 1)][op]; -- -+ if (rgb16) { -+ f = combiners[4][op]; -+ } else { -+ f = combiners[component_alpha + (narrow << 1)][op]; -+ } - imp = imp->delegate; - } - while (!f); - - return f; - } - - pixman_bool_t -diff --git a/gfx/cairo/libpixman/src/pixman-linear-gradient.c b/gfx/cairo/libpixman/src/pixman-linear-gradient.c ---- a/gfx/cairo/libpixman/src/pixman-linear-gradient.c -+++ b/gfx/cairo/libpixman/src/pixman-linear-gradient.c -@@ -217,42 +217,185 @@ linear_get_scanline_narrow (pixman_iter_ - } - } - - iter->y++; - - return iter->buffer; - } - -+static uint16_t convert_8888_to_0565(uint32_t color) -+{ -+ return CONVERT_8888_TO_0565(color); -+} -+ -+static uint32_t * -+linear_get_scanline_16 (pixman_iter_t *iter, -+ const uint32_t *mask) -+{ -+ pixman_image_t *image = iter->image; -+ int x = iter->x; -+ int y = iter->y; -+ int width = iter->width; -+ uint16_t * buffer = (uint16_t*)iter->buffer; -+ -+ pixman_vector_t v, unit; -+ pixman_fixed_32_32_t l; -+ pixman_fixed_48_16_t dx, dy; -+ gradient_t *gradient = (gradient_t *)image; -+ linear_gradient_t *linear = (linear_gradient_t *)image; -+ uint16_t *end = buffer + width; -+ pixman_gradient_walker_t walker; -+ -+ _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); -+ -+ /* reference point is the center of the pixel */ -+ v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; -+ v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; -+ v.vector[2] = pixman_fixed_1; -+ -+ if (image->common.transform) -+ { -+ if (!pixman_transform_point_3d (image->common.transform, &v)) -+ return iter->buffer; -+ -+ unit.vector[0] = image->common.transform->matrix[0][0]; -+ unit.vector[1] = image->common.transform->matrix[1][0]; -+ unit.vector[2] = image->common.transform->matrix[2][0]; -+ } -+ else -+ { -+ unit.vector[0] = pixman_fixed_1; -+ unit.vector[1] = 0; -+ unit.vector[2] = 0; -+ } -+ -+ dx = linear->p2.x - linear->p1.x; -+ dy = linear->p2.y - linear->p1.y; -+ -+ l = dx * dx + dy * dy; -+ -+ if (l == 0 || unit.vector[2] == 0) -+ { -+ /* affine transformation only */ -+ pixman_fixed_32_32_t t, next_inc; -+ double inc; -+ -+ if (l == 0 || v.vector[2] == 0) -+ { -+ t = 0; -+ inc = 0; -+ } -+ else -+ { -+ double invden, v2; -+ -+ invden = pixman_fixed_1 * (double) pixman_fixed_1 / -+ (l * (double) v.vector[2]); -+ v2 = v.vector[2] * (1. / pixman_fixed_1); -+ t = ((dx * v.vector[0] + dy * v.vector[1]) - -+ (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; -+ inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; -+ } -+ next_inc = 0; -+ -+ if (((pixman_fixed_32_32_t )(inc * width)) == 0) -+ { -+ register uint16_t color; -+ -+ color = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); -+ while (buffer < end) -+ *buffer++ = color; -+ } -+ else -+ { -+ int i; -+ -+ i = 0; -+ while (buffer < end) -+ { -+ if (!mask || *mask++) -+ { -+ *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, -+ t + next_inc)); -+ } -+ i++; -+ next_inc = inc * i; -+ buffer++; -+ } -+ } -+ } -+ else -+ { -+ /* projective transformation */ -+ double t; -+ -+ t = 0; -+ -+ while (buffer < end) -+ { -+ if (!mask || *mask++) -+ { -+ if (v.vector[2] != 0) -+ { -+ double invden, v2; -+ -+ invden = pixman_fixed_1 * (double) pixman_fixed_1 / -+ (l * (double) v.vector[2]); -+ v2 = v.vector[2] * (1. / pixman_fixed_1); -+ t = ((dx * v.vector[0] + dy * v.vector[1]) - -+ (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; -+ } -+ -+ *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); -+ } -+ -+ ++buffer; -+ -+ v.vector[0] += unit.vector[0]; -+ v.vector[1] += unit.vector[1]; -+ v.vector[2] += unit.vector[2]; -+ } -+ } -+ -+ iter->y++; -+ -+ return iter->buffer; -+} -+ - static uint32_t * - linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) - { - uint32_t *buffer = linear_get_scanline_narrow (iter, NULL); - - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; - } - - void - _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) - { - if (linear_gradient_is_horizontal ( - iter->image, iter->x, iter->y, iter->width, iter->height)) - { -- if (iter->flags & ITER_NARROW) -+ if (iter->flags & ITER_16) -+ linear_get_scanline_16 (iter, NULL); -+ else if (iter->flags & ITER_NARROW) - linear_get_scanline_narrow (iter, NULL); - else - linear_get_scanline_wide (iter, NULL); - - iter->get_scanline = _pixman_iter_get_scanline_noop; - } - else - { -- if (iter->flags & ITER_NARROW) -+ if (iter->flags & ITER_16) -+ iter->get_scanline = linear_get_scanline_16; -+ else if (iter->flags & ITER_NARROW) - iter->get_scanline = linear_get_scanline_narrow; - else - iter->get_scanline = linear_get_scanline_wide; - } - } - - PIXMAN_EXPORT pixman_image_t * - pixman_image_create_linear_gradient (pixman_point_fixed_t * p1, -diff --git a/gfx/cairo/libpixman/src/pixman-private.h b/gfx/cairo/libpixman/src/pixman-private.h ---- a/gfx/cairo/libpixman/src/pixman-private.h -+++ b/gfx/cairo/libpixman/src/pixman-private.h -@@ -152,24 +152,28 @@ struct bits_image - int height; - uint32_t * bits; - uint32_t * free_me; - int rowstride; /* in number of uint32_t's */ - - fetch_scanline_t get_scanline_32; - fetch_scanline_t get_scanline_64; - -+ fetch_scanline_t fetch_scanline_16; -+ - fetch_scanline_t fetch_scanline_32; - fetch_pixel_32_t fetch_pixel_32; - store_scanline_t store_scanline_32; - - fetch_scanline_t fetch_scanline_64; - fetch_pixel_64_t fetch_pixel_64; - store_scanline_t store_scanline_64; - -+ store_scanline_t store_scanline_16; -+ - /* Used for indirect access to the bits */ - pixman_read_memory_func_t read_func; - pixman_write_memory_func_t write_func; - }; - - union pixman_image - { - image_type_t type; -@@ -202,17 +206,24 @@ typedef enum - * destination. - * - * When he destination is xRGB, this is useful knowledge, because then - * we can treat it as if it were ARGB, which means in some cases we can - * avoid copying it to a temporary buffer. - */ - ITER_LOCALIZED_ALPHA = (1 << 1), - ITER_IGNORE_ALPHA = (1 << 2), -- ITER_IGNORE_RGB = (1 << 3) -+ ITER_IGNORE_RGB = (1 << 3), -+ -+ /* With the addition of ITER_16 we now have two flags that to represent -+ * 3 pipelines. This means that there can be an invalid state when -+ * both ITER_NARROW and ITER_16 are set. In this case -+ * ITER_16 overrides NARROW and we should use the 16 bit pipeline. -+ * Note: ITER_16 still has a 32 bit mask, which is a bit weird. */ -+ ITER_16 = (1 << 4) - } iter_flags_t; - - struct pixman_iter_t - { - /* These are initialized by _pixman_implementation_{src,dest}_init */ - pixman_image_t * image; - uint32_t * buffer; - int x, y; -@@ -429,16 +440,17 @@ typedef pixman_bool_t (*pixman_fill_func - int x, - int y, - int width, - int height, - uint32_t xor); - typedef void (*pixman_iter_init_func_t) (pixman_implementation_t *imp, - pixman_iter_t *iter); - -+void _pixman_setup_combiner_functions_16 (pixman_implementation_t *imp); - void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); - void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp); - - typedef struct - { - pixman_op_t op; - pixman_format_code_t src_format; - uint32_t src_flags; -@@ -459,32 +471,34 @@ struct pixman_implementation_t - pixman_fill_func_t fill; - pixman_iter_init_func_t src_iter_init; - pixman_iter_init_func_t dest_iter_init; - - 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_64_func_t combine_16[PIXMAN_N_OPERATORS]; - }; - - uint32_t - _pixman_image_get_solid (pixman_implementation_t *imp, - pixman_image_t * image, - pixman_format_code_t format); - - pixman_implementation_t * - _pixman_implementation_create (pixman_implementation_t *delegate, - const pixman_fast_path_t *fast_paths); - - pixman_combine_32_func_t - _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, - pixman_op_t op, - pixman_bool_t component_alpha, -- pixman_bool_t wide); -+ pixman_bool_t wide, -+ pixman_bool_t rgb16); - - pixman_bool_t - _pixman_implementation_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, -@@ -613,16 +627,17 @@ uint32_t * - #define FAST_PATH_Y_UNIT_ZERO (1 << 18) - #define FAST_PATH_BILINEAR_FILTER (1 << 19) - #define FAST_PATH_ROTATE_90_TRANSFORM (1 << 20) - #define FAST_PATH_ROTATE_180_TRANSFORM (1 << 21) - #define FAST_PATH_ROTATE_270_TRANSFORM (1 << 22) - #define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST (1 << 23) - #define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR (1 << 24) - #define FAST_PATH_BITS_IMAGE (1 << 25) -+#define FAST_PATH_16_FORMAT (1 << 26) - - #define FAST_PATH_PAD_REPEAT \ - (FAST_PATH_NO_NONE_REPEAT | \ - FAST_PATH_NO_NORMAL_REPEAT | \ - FAST_PATH_NO_REFLECT_REPEAT) - - #define FAST_PATH_NORMAL_REPEAT \ - (FAST_PATH_NO_NONE_REPEAT | \ -diff --git a/gfx/cairo/libpixman/src/pixman-radial-gradient.c b/gfx/cairo/libpixman/src/pixman-radial-gradient.c ---- a/gfx/cairo/libpixman/src/pixman-radial-gradient.c -+++ b/gfx/cairo/libpixman/src/pixman-radial-gradient.c -@@ -395,35 +395,289 @@ radial_get_scanline_narrow (pixman_iter_ - v.vector[2] += unit.vector[2]; - } - } - - iter->y++; - return iter->buffer; - } - -+static uint16_t convert_8888_to_0565(uint32_t color) -+{ -+ return CONVERT_8888_TO_0565(color); -+} -+ -+static uint32_t * -+radial_get_scanline_16 (pixman_iter_t *iter, const uint32_t *mask) -+{ -+ /* -+ * Implementation of radial gradients following the PDF specification. -+ * See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference -+ * Manual (PDF 32000-1:2008 at the time of this writing). -+ * -+ * In the radial gradient problem we are given two circles (c₁,r₁) and -+ * (c₂,r₂) that define the gradient itself. -+ * -+ * Mathematically the gradient can be defined as the family of circles -+ * -+ * ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂) -+ * -+ * excluding those circles whose radius would be < 0. When a point -+ * belongs to more than one circle, the one with a bigger t is the only -+ * one that contributes to its color. When a point does not belong -+ * to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0). -+ * Further limitations on the range of values for t are imposed when -+ * the gradient is not repeated, namely t must belong to [0,1]. -+ * -+ * The graphical result is the same as drawing the valid (radius > 0) -+ * circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient -+ * is not repeated) using SOURCE operator composition. -+ * -+ * It looks like a cone pointing towards the viewer if the ending circle -+ * is smaller than the starting one, a cone pointing inside the page if -+ * the starting circle is the smaller one and like a cylinder if they -+ * have the same radius. -+ * -+ * What we actually do is, given the point whose color we are interested -+ * in, compute the t values for that point, solving for t in: -+ * -+ * length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂ -+ * -+ * Let's rewrite it in a simpler way, by defining some auxiliary -+ * variables: -+ * -+ * cd = c₂ - c₁ -+ * pd = p - c₁ -+ * dr = r₂ - r₁ -+ * length(t·cd - pd) = r₁ + t·dr -+ * -+ * which actually means -+ * -+ * hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr -+ * -+ * or -+ * -+ * ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr. -+ * -+ * If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes: -+ * -+ * (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)² -+ * -+ * where we can actually expand the squares and solve for t: -+ * -+ * t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² = -+ * = r₁² + 2·r₁·t·dr + t²·dr² -+ * -+ * (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t + -+ * (pdx² + pdy² - r₁²) = 0 -+ * -+ * A = cdx² + cdy² - dr² -+ * B = pdx·cdx + pdy·cdy + r₁·dr -+ * C = pdx² + pdy² - r₁² -+ * At² - 2Bt + C = 0 -+ * -+ * The solutions (unless the equation degenerates because of A = 0) are: -+ * -+ * t = (B ± ⎷(B² - A·C)) / A -+ * -+ * The solution we are going to prefer is the bigger one, unless the -+ * radius associated to it is negative (or it falls outside the valid t -+ * range). -+ * -+ * Additional observations (useful for optimizations): -+ * A does not depend on p -+ * -+ * A < 0 <=> one of the two circles completely contains the other one -+ * <=> for every p, the radiuses associated with the two t solutions -+ * have opposite sign -+ */ -+ pixman_image_t *image = iter->image; -+ int x = iter->x; -+ int y = iter->y; -+ int width = iter->width; -+ uint16_t *buffer = iter->buffer; -+ -+ gradient_t *gradient = (gradient_t *)image; -+ radial_gradient_t *radial = (radial_gradient_t *)image; -+ uint16_t *end = buffer + width; -+ pixman_gradient_walker_t walker; -+ pixman_vector_t v, unit; -+ -+ /* reference point is the center of the pixel */ -+ v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; -+ v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; -+ v.vector[2] = pixman_fixed_1; -+ -+ _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); -+ -+ if (image->common.transform) -+ { -+ if (!pixman_transform_point_3d (image->common.transform, &v)) -+ return iter->buffer; -+ -+ unit.vector[0] = image->common.transform->matrix[0][0]; -+ unit.vector[1] = image->common.transform->matrix[1][0]; -+ unit.vector[2] = image->common.transform->matrix[2][0]; -+ } -+ else -+ { -+ unit.vector[0] = pixman_fixed_1; -+ unit.vector[1] = 0; -+ unit.vector[2] = 0; -+ } -+ -+ if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1) -+ { -+ /* -+ * Given: -+ * -+ * t = (B ± ⎷(B² - A·C)) / A -+ * -+ * where -+ * -+ * A = cdx² + cdy² - dr² -+ * B = pdx·cdx + pdy·cdy + r₁·dr -+ * C = pdx² + pdy² - r₁² -+ * det = B² - A·C -+ * -+ * Since we have an affine transformation, we know that (pdx, pdy) -+ * increase linearly with each pixel, -+ * -+ * pdx = pdx₀ + n·ux, -+ * pdy = pdy₀ + n·uy, -+ * -+ * we can then express B, C and det through multiple differentiation. -+ */ -+ pixman_fixed_32_32_t b, db, c, dc, ddc; -+ -+ /* warning: this computation may overflow */ -+ v.vector[0] -= radial->c1.x; -+ v.vector[1] -= radial->c1.y; -+ -+ /* -+ * B and C are computed and updated exactly. -+ * If fdot was used instead of dot, in the worst case it would -+ * lose 11 bits of precision in each of the multiplication and -+ * summing up would zero out all the bit that were preserved, -+ * thus making the result 0 instead of the correct one. -+ * This would mean a worst case of unbound relative error or -+ * about 2^10 absolute error -+ */ -+ b = dot (v.vector[0], v.vector[1], radial->c1.radius, -+ radial->delta.x, radial->delta.y, radial->delta.radius); -+ db = dot (unit.vector[0], unit.vector[1], 0, -+ radial->delta.x, radial->delta.y, 0); -+ -+ c = dot (v.vector[0], v.vector[1], -+ -((pixman_fixed_48_16_t) radial->c1.radius), -+ v.vector[0], v.vector[1], radial->c1.radius); -+ dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0], -+ 2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1], -+ 0, -+ unit.vector[0], unit.vector[1], 0); -+ ddc = 2 * dot (unit.vector[0], unit.vector[1], 0, -+ unit.vector[0], unit.vector[1], 0); -+ -+ while (buffer < end) -+ { -+ if (!mask || *mask++) -+ { -+ *buffer = convert_8888_to_0565( -+ radial_compute_color (radial->a, b, c, -+ radial->inva, -+ radial->delta.radius, -+ radial->mindr, -+ &walker, -+ image->common.repeat)); -+ } -+ -+ b += db; -+ c += dc; -+ dc += ddc; -+ ++buffer; -+ } -+ } -+ else -+ { -+ /* projective */ -+ /* Warning: -+ * error propagation guarantees are much looser than in the affine case -+ */ -+ while (buffer < end) -+ { -+ if (!mask || *mask++) -+ { -+ if (v.vector[2] != 0) -+ { -+ double pdx, pdy, invv2, b, c; -+ -+ invv2 = 1. * pixman_fixed_1 / v.vector[2]; -+ -+ pdx = v.vector[0] * invv2 - radial->c1.x; -+ /* / pixman_fixed_1 */ -+ -+ pdy = v.vector[1] * invv2 - radial->c1.y; -+ /* / pixman_fixed_1 */ -+ -+ b = fdot (pdx, pdy, radial->c1.radius, -+ radial->delta.x, radial->delta.y, -+ radial->delta.radius); -+ /* / pixman_fixed_1 / pixman_fixed_1 */ -+ -+ c = fdot (pdx, pdy, -radial->c1.radius, -+ pdx, pdy, radial->c1.radius); -+ /* / pixman_fixed_1 / pixman_fixed_1 */ -+ -+ *buffer = convert_8888_to_0565 ( -+ radial_compute_color (radial->a, b, c, -+ radial->inva, -+ radial->delta.radius, -+ radial->mindr, -+ &walker, -+ image->common.repeat)); -+ } -+ else -+ { -+ *buffer = 0; -+ } -+ } -+ -+ ++buffer; -+ -+ v.vector[0] += unit.vector[0]; -+ v.vector[1] += unit.vector[1]; -+ v.vector[2] += unit.vector[2]; -+ } -+ } -+ -+ iter->y++; -+ return iter->buffer; -+} - static uint32_t * - radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) - { - uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); - - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; - } - - void - _pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) - { -- if (iter->flags & ITER_NARROW) -+ if (iter->flags & ITER_16) -+ iter->get_scanline = radial_get_scanline_16; -+ else if (iter->flags & ITER_NARROW) - iter->get_scanline = radial_get_scanline_narrow; - else - iter->get_scanline = radial_get_scanline_wide; - } - -+ - PIXMAN_EXPORT pixman_image_t * - pixman_image_create_radial_gradient (pixman_point_fixed_t * inner, - pixman_point_fixed_t * outer, - pixman_fixed_t inner_radius, - pixman_fixed_t outer_radius, - const pixman_gradient_stop_t *stops, - int n_stops) - {
deleted file mode 100644 --- a/gfx/cairo/pixman-dither.patch +++ /dev/null @@ -1,310 +0,0 @@ -diff --git a/gfx/cairo/libpixman/src/pixman-dither.h b/gfx/cairo/libpixman/src/pixman-dither.h -new file mode 100644 ---- /dev/null -+++ b/gfx/cairo/libpixman/src/pixman-dither.h -@@ -0,0 +1,51 @@ -+#define R16_BITS 5 -+#define G16_BITS 6 -+#define B16_BITS 5 -+ -+#define R16_SHIFT (B16_BITS + G16_BITS) -+#define G16_SHIFT (B16_BITS) -+#define B16_SHIFT 0 -+ -+#define MASK 0xff -+#define ONE_HALF 0x80 -+ -+#define A_SHIFT 8 * 3 -+#define R_SHIFT 8 * 2 -+#define G_SHIFT 8 -+#define A_MASK 0xff000000 -+#define R_MASK 0xff0000 -+#define G_MASK 0xff00 -+ -+#define RB_MASK 0xff00ff -+#define AG_MASK 0xff00ff00 -+#define RB_ONE_HALF 0x800080 -+#define RB_MASK_PLUS_ONE 0x10000100 -+ -+#define ALPHA_8(x) ((x) >> A_SHIFT) -+#define RED_8(x) (((x) >> R_SHIFT) & MASK) -+#define GREEN_8(x) (((x) >> G_SHIFT) & MASK) -+#define BLUE_8(x) ((x) & MASK) -+ -+// This uses the same dithering technique that Skia does. -+// It is essentially preturbing the lower bit based on the -+// high bit -+static inline uint16_t dither_32_to_16(uint32_t c) -+{ -+ uint8_t b = BLUE_8(c); -+ uint8_t g = GREEN_8(c); -+ uint8_t r = RED_8(c); -+ r = ((r << 1) - ((r >> (8 - R16_BITS) << (8 - R16_BITS)) | (r >> R16_BITS))) >> (8 - R16_BITS); -+ g = ((g << 1) - ((g >> (8 - G16_BITS) << (8 - G16_BITS)) | (g >> G16_BITS))) >> (8 - G16_BITS); -+ b = ((b << 1) - ((b >> (8 - B16_BITS) << (8 - B16_BITS)) | (b >> B16_BITS))) >> (8 - B16_BITS); -+ return ((r << R16_SHIFT) | (g << G16_SHIFT) | (b << B16_SHIFT)); -+} -+ -+static inline uint16_t dither_8888_to_0565(uint32_t color, pixman_bool_t toggle) -+{ -+ // alternate between a preturbed truncation and a regular truncation -+ if (toggle) { -+ return dither_32_to_16(color); -+ } else { -+ return CONVERT_8888_TO_0565(color); -+ } -+} -diff --git a/gfx/cairo/libpixman/src/pixman-linear-gradient.c b/gfx/cairo/libpixman/src/pixman-linear-gradient.c ---- a/gfx/cairo/libpixman/src/pixman-linear-gradient.c -+++ b/gfx/cairo/libpixman/src/pixman-linear-gradient.c -@@ -26,16 +26,18 @@ - */ - - #ifdef HAVE_CONFIG_H - #include <config.h> - #endif - #include <stdlib.h> - #include "pixman-private.h" - -+#include "pixman-dither.h" -+ - static pixman_bool_t - linear_gradient_is_horizontal (pixman_image_t *image, - int x, - int y, - int width, - int height) - { - linear_gradient_t *linear = (linear_gradient_t *)image; -@@ -222,25 +224,28 @@ linear_get_scanline_narrow (pixman_iter_ - return iter->buffer; - } - - static uint16_t convert_8888_to_0565(uint32_t color) - { - return CONVERT_8888_TO_0565(color); - } - -+ -+ - static uint32_t * - linear_get_scanline_16 (pixman_iter_t *iter, - const uint32_t *mask) - { - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint16_t * buffer = (uint16_t*)iter->buffer; -+ pixman_bool_t toggle = ((x ^ y) & 1); - - pixman_vector_t v, unit; - pixman_fixed_32_32_t l; - pixman_fixed_48_16_t dx, dy; - gradient_t *gradient = (gradient_t *)image; - linear_gradient_t *linear = (linear_gradient_t *)image; - uint16_t *end = buffer + width; - pixman_gradient_walker_t walker; -@@ -294,34 +299,47 @@ linear_get_scanline_16 (pixman_iter_t * - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; - } - next_inc = 0; - - if (((pixman_fixed_32_32_t )(inc * width)) == 0) - { -- register uint16_t color; -+ register uint32_t color; -+ uint16_t dither_diff; -+ uint16_t color16; -+ uint16_t color16b; - -- color = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); -- while (buffer < end) -- *buffer++ = color; -+ color = _pixman_gradient_walker_pixel (&walker, t); -+ color16 = dither_8888_to_0565(color, toggle); -+ color16b = dither_8888_to_0565(color, toggle^1); -+ // compute the difference -+ dither_diff = color16 ^ color16b; -+ while (buffer < end) { -+ *buffer++ = color16; -+ // use dither_diff to toggle between color16 and color16b -+ color16 ^= dither_diff; -+ toggle ^= 1; -+ } - } - else - { - int i; - - i = 0; - while (buffer < end) - { - if (!mask || *mask++) - { -- *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, -- t + next_inc)); -+ *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, -+ t + next_inc), -+ toggle); - } -+ toggle ^= 1; - i++; - next_inc = inc * i; - buffer++; - } - } - } - else - { -@@ -340,18 +358,20 @@ linear_get_scanline_16 (pixman_iter_t * - - invden = pixman_fixed_1 * (double) pixman_fixed_1 / - (l * (double) v.vector[2]); - v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - } - -- *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); -+ *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t), -+ toggle); - } -+ toggle ^= 1; - - ++buffer; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } -@@ -369,17 +389,18 @@ linear_get_scanline_wide (pixman_iter_t - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; - } - - void - _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) - { -- if (linear_gradient_is_horizontal ( -+ // XXX: we can't use this optimization when dithering -+ if (0 && linear_gradient_is_horizontal ( - iter->image, iter->x, iter->y, iter->width, iter->height)) - { - if (iter->flags & ITER_16) - linear_get_scanline_16 (iter, NULL); - else if (iter->flags & ITER_NARROW) - linear_get_scanline_narrow (iter, NULL); - else - linear_get_scanline_wide (iter, NULL); -diff --git a/gfx/cairo/libpixman/src/pixman-radial-gradient.c b/gfx/cairo/libpixman/src/pixman-radial-gradient.c ---- a/gfx/cairo/libpixman/src/pixman-radial-gradient.c -+++ b/gfx/cairo/libpixman/src/pixman-radial-gradient.c -@@ -29,16 +29,18 @@ - - #ifdef HAVE_CONFIG_H - #include <config.h> - #endif - #include <stdlib.h> - #include <math.h> - #include "pixman-private.h" - -+#include "pixman-dither.h" -+ - static inline pixman_fixed_32_32_t - dot (pixman_fixed_48_16_t x1, - pixman_fixed_48_16_t y1, - pixman_fixed_48_16_t z1, - pixman_fixed_48_16_t x2, - pixman_fixed_48_16_t y2, - pixman_fixed_48_16_t z2) - { -@@ -489,16 +491,17 @@ radial_get_scanline_16 (pixman_iter_t *i - * <=> for every p, the radiuses associated with the two t solutions - * have opposite sign - */ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint16_t *buffer = iter->buffer; -+ pixman_bool_t toggle = ((x ^ y) & 1); - - gradient_t *gradient = (gradient_t *)image; - radial_gradient_t *radial = (radial_gradient_t *)image; - uint16_t *end = buffer + width; - pixman_gradient_walker_t walker; - pixman_vector_t v, unit; - - /* reference point is the center of the pixel */ -@@ -575,25 +578,27 @@ radial_get_scanline_16 (pixman_iter_t *i - unit.vector[0], unit.vector[1], 0); - ddc = 2 * dot (unit.vector[0], unit.vector[1], 0, - unit.vector[0], unit.vector[1], 0); - - while (buffer < end) - { - if (!mask || *mask++) - { -- *buffer = convert_8888_to_0565( -+ *buffer = dither_8888_to_0565( - radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, -- image->common.repeat)); -+ image->common.repeat), -+ toggle); - } - -+ toggle ^= 1; - b += db; - c += dc; - dc += ddc; - ++buffer; - } - } - else - { -@@ -621,31 +626,33 @@ radial_get_scanline_16 (pixman_iter_t *i - radial->delta.x, radial->delta.y, - radial->delta.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - - c = fdot (pdx, pdy, -radial->c1.radius, - pdx, pdy, radial->c1.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - -- *buffer = convert_8888_to_0565 ( -+ *buffer = dither_8888_to_0565 ( - radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, -- image->common.repeat)); -+ image->common.repeat), -+ toggle); - } - else - { - *buffer = 0; - } - } - - ++buffer; -+ toggle ^= 1; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } - - iter->y++; -
--- a/layout/reftests/css-gradients/reftest.list +++ b/layout/reftests/css-gradients/reftest.list @@ -56,25 +56,25 @@ fuzzy-if(azureSkia,1,7860) fuzzy-if(azur fuzzy-if(azureSkia,1,7860) fuzzy-if(azureQuartz,1,1926) fails-if(Android) == radial-2d.html radial-2-ref.html fuzzy-if(azureSkia,1,7860) fuzzy-if(azureQuartz,1,1926) fails-if(Android) == radial-2e.html radial-2-ref.html fuzzy-if(azureSkia,1,7860) fuzzy-if(azureQuartz,1,1926) fails-if(Android) == radial-2f.html radial-2-ref.html == radial-position-1a.html radial-position-1-ref.html == radial-position-1b.html radial-position-1-ref.html == radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html == radial-shape-closest-corner-1c.html radial-shape-closest-corner-1-ref.html -fuzzy-if(Android,9,3880) == radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html -fuzzy-if(Android,9,3880) == radial-shape-closest-side-1b.html radial-shape-closest-side-1-ref.html -fuzzy-if(Android,9,3880) == radial-shape-closest-side-1c.html radial-shape-closest-side-1-ref.html +== radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html +== radial-shape-closest-side-1b.html radial-shape-closest-side-1-ref.html +== radial-shape-closest-side-1c.html radial-shape-closest-side-1-ref.html == radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html fails-if(cocoaWidget&&/x86-/.test(xulRuntime.XPCOMABI)||gtk2Widget&&/x86_64-/.test(xulRuntime.XPCOMABI)) == radial-shape-farthest-corner-1b.html radial-shape-farthest-corner-1-ref.html == radial-shape-farthest-corner-1c.html radial-shape-farthest-corner-1-ref.html -fuzzy-if(Android,9,13314) == radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html -fuzzy-if(Android,9,13314) == radial-shape-farthest-side-1b.html radial-shape-farthest-side-1-ref.html -fuzzy-if(Android,9,13314) == radial-shape-farthest-side-1c.html radial-shape-farthest-side-1-ref.html +== radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html +== radial-shape-farthest-side-1b.html radial-shape-farthest-side-1-ref.html +== radial-shape-farthest-side-1c.html radial-shape-farthest-side-1-ref.html == radial-size-1a.html radial-size-1-ref.html == radial-size-1b.html radial-size-1-ref.html == radial-zero-length-1a.html radial-zero-length-1-ref.html == radial-zero-length-1b.html radial-zero-length-1-ref.html == radial-zero-length-1c.html radial-zero-length-1-ref.html == radial-zero-length-1d.html radial-zero-length-1-ref.html == radial-zero-length-1e.html radial-zero-length-1-ref.html == radial-zero-length-1f.html radial-zero-length-1-ref.html
--- a/layout/reftests/image-element/reftest.list +++ b/layout/reftests/image-element/reftest.list @@ -35,12 +35,12 @@ random-if(d2d) == element-paint-transfor random-if(!cocoaWidget) == gradient-html-03.html gradient-html-03-ref.svg == gradient-html-04.html gradient-html-04-ref.html == gradient-html-05.html gradient-html-05-ref.html random-if(!cocoaWidget) == gradient-html-06a.html gradient-html-06b.html random-if(!cocoaWidget) == gradient-html-06b.html gradient-html-06c.html == gradient-html-06c.html gradient-html-06d.html == gradient-html-06d.html gradient-html-06e.html random-if(!cocoaWidget) == gradient-html-07a.html gradient-html-07b.html -fuzzy-if(Android,9,23112) == gradient-html-07b.html gradient-html-07c.html +== gradient-html-07b.html gradient-html-07c.html == pattern-html-01.html pattern-html-01-ref.svg == pattern-html-02.html pattern-html-02-ref.svg == referenced-from-binding-01.html referenced-from-binding-01-ref.html
--- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -173,17 +173,17 @@ fails == inline-in-xul-basic-01.xul pass == mask-basic-01.svg pass.svg == mask-basic-02.svg mask-basic-02-ref.svg == mask-extref-dataURI-01.svg pass.svg == mask-containing-masked-content-01.svg pass.svg == mask-transformed-01.svg mask-transformed-01-ref.svg == nested-viewBox-01.svg pass.svg == nesting-invalid-01.svg nesting-invalid-01-ref.svg == non-scaling-stroke-01.svg non-scaling-stroke-01-ref.svg -fuzzy-if(Android,9,61) == non-scaling-stroke-02.svg non-scaling-stroke-02-ref.svg +fuzzy-if(Android,9,38) == non-scaling-stroke-02.svg non-scaling-stroke-02-ref.svg == objectBoundingBox-and-clipPath.svg pass.svg # Bug 588684 random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-01.svg objectBoundingBox-and-fePointLight-01-ref.svg random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-02.svg objectBoundingBox-and-fePointLight-02-ref.svg == objectBoundingBox-and-mask.svg pass.svg == objectBoundingBox-and-mask-02.svg pass.svg == objectBoundingBox-and-pattern-01a.svg objectBoundingBox-and-pattern-01-ref.svg == objectBoundingBox-and-pattern-01b.svg objectBoundingBox-and-pattern-01-ref.svg