зеркало из https://github.com/mozilla/gecko-dev.git
Back out 0c1f34eb5b93 and 0f987ac28e8c (bug 683243) for Android R2 bustage
This commit is contained in:
Родитель
d11a1a1fec
Коммит
c6b792f900
|
@ -198,10 +198,6 @@ 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.
|
||||
|
|
|
@ -81,7 +81,6 @@ CSRCS = \
|
|||
pixman-access-accessors.c \
|
||||
pixman-bits-image.c \
|
||||
pixman.c \
|
||||
pixman-combine16.c \
|
||||
pixman-combine32.c \
|
||||
pixman-combine64.c \
|
||||
pixman-conical-gradient.c \
|
||||
|
|
|
@ -938,44 +938,6 @@ store_scanline_x2b10g10r10 (bits_image_t * image,
|
|||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -1087,12 +1049,10 @@ fetch_pixel_generic_lossy_32 (bits_image_t *image,
|
|||
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;
|
||||
|
@ -1100,24 +1060,11 @@ typedef struct
|
|||
#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[] =
|
||||
{
|
||||
|
@ -1137,8 +1084,8 @@ static const format_info_t accessors[] =
|
|||
FORMAT_INFO (b8g8r8),
|
||||
|
||||
/* 16bpp formats */
|
||||
FORMAT_INFO16 (r5g6b5),
|
||||
FORMAT_INFO16 (b5g6r5),
|
||||
FORMAT_INFO (r5g6b5),
|
||||
FORMAT_INFO (b5g6r5),
|
||||
|
||||
FORMAT_INFO (a1r5g5b5),
|
||||
FORMAT_INFO (x1r5g5b5),
|
||||
|
@ -1190,33 +1137,33 @@ static const format_info_t accessors[] =
|
|||
/* 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 },
|
||||
|
||||
|
@ -1232,12 +1179,10 @@ setup_accessors (bits_image_t *image)
|
|||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -1252,21 +1252,6 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
|||
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 *
|
||||
|
@ -1346,20 +1331,6 @@ dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
|
|||
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)
|
||||
{
|
||||
|
@ -1409,20 +1380,7 @@ dest_write_back_wide (pixman_iter_t *iter)
|
|||
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))
|
||||
|
@ -1433,7 +1391,7 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
|||
{
|
||||
iter->get_scanline = dest_get_scanline_narrow;
|
||||
}
|
||||
|
||||
|
||||
iter->write_back = dest_write_back_narrow;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -111,7 +111,6 @@ general_composite_rect (pixman_implementation_t *imp,
|
|||
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;
|
||||
|
||||
|
@ -128,20 +127,6 @@ general_composite_rect (pixman_implementation_t *imp,
|
|||
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);
|
||||
|
@ -155,7 +140,7 @@ general_composite_rect (pixman_implementation_t *imp,
|
|||
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,
|
||||
|
@ -184,10 +169,10 @@ general_composite_rect (pixman_implementation_t *imp,
|
|||
/* 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;
|
||||
|
@ -254,7 +239,6 @@ _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);
|
||||
|
||||
|
|
|
@ -456,10 +456,6 @@ compute_image_info (pixman_image_t *image)
|
|||
|
||||
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:
|
||||
|
|
|
@ -106,7 +106,6 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
|
|||
|
||||
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;
|
||||
|
@ -120,8 +119,7 @@ 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;
|
||||
|
||||
|
@ -133,14 +131,10 @@ _pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
|
|||
(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);
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#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,
|
||||
|
@ -224,163 +222,6 @@ linear_get_scanline_narrow (pixman_iter_t *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;
|
||||
|
||||
_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)
|
||||
{
|
||||
|
@ -394,13 +235,10 @@ linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
|
|||
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);
|
||||
|
@ -409,9 +247,7 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
|||
}
|
||||
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;
|
||||
|
|
|
@ -157,8 +157,6 @@ struct bits_image
|
|||
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;
|
||||
|
@ -167,8 +165,6 @@ struct bits_image
|
|||
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;
|
||||
|
@ -211,14 +207,7 @@ typedef enum
|
|||
*/
|
||||
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
|
||||
|
@ -445,7 +434,6 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
|
|||
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);
|
||||
|
||||
|
@ -476,7 +464,6 @@ struct pixman_implementation_t
|
|||
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
|
||||
|
@ -492,8 +479,7 @@ 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,
|
||||
|
@ -632,7 +618,6 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
|
|||
#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 | \
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#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,
|
||||
|
@ -402,262 +400,6 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
|||
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)
|
||||
{
|
||||
|
@ -671,15 +413,12 @@ radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
|
|||
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,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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++;
|
||||
|
|
@ -61,15 +61,15 @@ fuzzy-if(azureSkia,1,7860) fuzzy-if(azureQuartz,1,1926) fails-if(Android) == rad
|
|||
== 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
|
||||
|
|
|
@ -40,7 +40,7 @@ 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
|
||||
|
|
|
@ -178,7 +178,7 @@ fails == inline-in-xul-basic-01.xul pass.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
|
||||
|
|
Загрузка…
Ссылка в новой задаче