зеркало из https://github.com/mozilla/gecko-dev.git
243 строки
6.2 KiB
Diff
243 строки
6.2 KiB
Diff
From
|
|
https://cgit.freedesktop.org/cairo/commit/?id=71e8a4c23019b01aa43b334fcb2784c70daae9b5
|
|
https://bugs.freedesktop.org/show_bug.cgi?id=34177
|
|
|
|
diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c
|
|
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
|
|
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
|
|
@@ -870,17 +870,17 @@ static cairo_bool_t
|
|
*ty = _pixman_nearest_sample (*ty);
|
|
} else {
|
|
if (*tx != floor (*tx) || *ty != floor (*ty))
|
|
return FALSE;
|
|
}
|
|
return fabs (*tx) < PIXMAN_MAX_INT && fabs (*ty) < PIXMAN_MAX_INT;
|
|
}
|
|
|
|
-#if HAS_ATOMIC_OPS
|
|
+#if PIXMAN_HAS_ATOMIC_OPS
|
|
static pixman_image_t *__pixman_transparent_image;
|
|
static pixman_image_t *__pixman_black_image;
|
|
static pixman_image_t *__pixman_white_image;
|
|
|
|
static pixman_image_t *
|
|
_pixman_transparent_image (void)
|
|
{
|
|
pixman_image_t *image;
|
|
@@ -964,56 +964,59 @@ static pixman_image_t *
|
|
pixman_image_ref (image);
|
|
}
|
|
} else {
|
|
pixman_image_ref (image);
|
|
}
|
|
|
|
return image;
|
|
}
|
|
-#else
|
|
-static pixman_image_t *
|
|
-_pixman_transparent_image (void)
|
|
-{
|
|
- return _pixman_image_for_solid (&_cairo_pattern_clear);
|
|
-}
|
|
-static pixman_image_t *
|
|
-_pixman_black_image (void)
|
|
-{
|
|
- return _pixman_image_for_solid (&_cairo_pattern_black);
|
|
-}
|
|
-static pixman_image_t *
|
|
-_pixman_white_image (void)
|
|
-{
|
|
- return _pixman_image_for_solid (&_cairo_pattern_white);
|
|
-}
|
|
-#endif
|
|
|
|
static uint32_t
|
|
hars_petruska_f54_1_random (void)
|
|
{
|
|
#define rol(x,k) ((x << k) | (x >> (32-k)))
|
|
static uint32_t x;
|
|
return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849;
|
|
#undef rol
|
|
}
|
|
|
|
static struct {
|
|
cairo_color_t color;
|
|
pixman_image_t *image;
|
|
} cache[16];
|
|
static int n_cached;
|
|
|
|
+#else /* !PIXMAN_HAS_ATOMIC_OPS */
|
|
+static pixman_image_t *
|
|
+_pixman_transparent_image (void)
|
|
+{
|
|
+ return _pixman_image_for_solid (&_cairo_pattern_clear);
|
|
+}
|
|
+
|
|
+static pixman_image_t *
|
|
+_pixman_black_image (void)
|
|
+{
|
|
+ return _pixman_image_for_solid (&_cairo_pattern_black);
|
|
+}
|
|
+
|
|
+static pixman_image_t *
|
|
+_pixman_white_image (void)
|
|
+{
|
|
+ return _pixman_image_for_solid (&_cairo_pattern_white);
|
|
+}
|
|
+#endif /* !PIXMAN_HAS_ATOMIC_OPS */
|
|
+
|
|
void
|
|
_cairo_image_reset_static_data (void)
|
|
{
|
|
+#if PIXMAN_HAS_ATOMIC_OPS
|
|
while (n_cached)
|
|
pixman_image_unref (cache[--n_cached].image);
|
|
|
|
-#if HAS_ATOMIC_OPS
|
|
if (__pixman_transparent_image) {
|
|
pixman_image_unref (__pixman_transparent_image);
|
|
__pixman_transparent_image = NULL;
|
|
}
|
|
|
|
if (__pixman_black_image) {
|
|
pixman_image_unref (__pixman_black_image);
|
|
__pixman_black_image = NULL;
|
|
@@ -1026,19 +1029,20 @@ void
|
|
#endif
|
|
}
|
|
|
|
static pixman_image_t *
|
|
_pixman_image_for_solid (const cairo_solid_pattern_t *pattern)
|
|
{
|
|
pixman_color_t color;
|
|
pixman_image_t *image;
|
|
+
|
|
+#if PIXMAN_HAS_ATOMIC_OPS
|
|
int i;
|
|
|
|
-#if HAS_ATOMIC_OPS
|
|
if (pattern->color.alpha_short <= 0x00ff)
|
|
return _pixman_transparent_image ();
|
|
|
|
if (pattern->color.alpha_short >= 0xff00) {
|
|
if (pattern->color.red_short <= 0x00ff &&
|
|
pattern->color.green_short <= 0x00ff &&
|
|
pattern->color.blue_short <= 0x00ff)
|
|
{
|
|
@@ -1047,46 +1051,48 @@ static pixman_image_t *
|
|
|
|
if (pattern->color.red_short >= 0xff00 &&
|
|
pattern->color.green_short >= 0xff00 &&
|
|
pattern->color.blue_short >= 0xff00)
|
|
{
|
|
return _pixman_white_image ();
|
|
}
|
|
}
|
|
-#endif
|
|
|
|
CAIRO_MUTEX_LOCK (_cairo_image_solid_cache_mutex);
|
|
for (i = 0; i < n_cached; i++) {
|
|
if (_cairo_color_equal (&cache[i].color, &pattern->color)) {
|
|
image = pixman_image_ref (cache[i].image);
|
|
goto UNLOCK;
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
color.red = pattern->color.red_short;
|
|
color.green = pattern->color.green_short;
|
|
color.blue = pattern->color.blue_short;
|
|
color.alpha = pattern->color.alpha_short;
|
|
|
|
image = pixman_image_create_solid_fill (&color);
|
|
+#if PIXMAN_HAS_ATOMIC_OPS
|
|
if (image == NULL)
|
|
goto UNLOCK;
|
|
|
|
if (n_cached < ARRAY_LENGTH (cache)) {
|
|
i = n_cached++;
|
|
} else {
|
|
i = hars_petruska_f54_1_random () % ARRAY_LENGTH (cache);
|
|
pixman_image_unref (cache[i].image);
|
|
}
|
|
cache[i].image = pixman_image_ref (image);
|
|
cache[i].color = pattern->color;
|
|
|
|
UNLOCK:
|
|
CAIRO_MUTEX_UNLOCK (_cairo_image_solid_cache_mutex);
|
|
+#endif
|
|
return image;
|
|
}
|
|
|
|
static double
|
|
clamp (double val, double min, double max)
|
|
{
|
|
return val < min ? min : (val > max ? max : val);
|
|
}
|
|
@@ -1423,25 +1429,27 @@ static pixman_image_t *
|
|
return _pixman_transparent_image ();
|
|
}
|
|
else
|
|
{
|
|
return _pixel_to_solid (source, sample.x, sample.y);
|
|
}
|
|
}
|
|
|
|
+#if PIXMAN_HAS_ATOMIC_OPS
|
|
/* avoid allocating a 'pattern' image if we can reuse the original */
|
|
if (extend == CAIRO_EXTEND_NONE &&
|
|
_cairo_matrix_is_translation (&pattern->base.matrix) &&
|
|
_nearest_sample (filter, &tx, &ty))
|
|
{
|
|
*ix = tx;
|
|
*iy = ty;
|
|
return pixman_image_ref (source->pixman_image);
|
|
}
|
|
+#endif
|
|
|
|
pixman_image = pixman_image_create_bits (source->pixman_format,
|
|
source->width,
|
|
source->height,
|
|
(uint32_t *) source->data,
|
|
source->stride);
|
|
if (unlikely (pixman_image == NULL))
|
|
return NULL;
|
|
@@ -1466,31 +1474,36 @@ static pixman_image_t *
|
|
sub->extents.x + sample.x,
|
|
sub->extents.y + sample.y);
|
|
} else {
|
|
if (extend == CAIRO_EXTEND_NONE)
|
|
return _pixman_transparent_image ();
|
|
}
|
|
}
|
|
|
|
+#if PIXMAN_HAS_ATOMIC_OPS
|
|
if (is_contained &&
|
|
_cairo_matrix_is_translation (&pattern->base.matrix) &&
|
|
_nearest_sample (filter, &tx, &ty))
|
|
{
|
|
*ix = tx + sub->extents.x;
|
|
*iy = ty + sub->extents.y;
|
|
return pixman_image_ref (source->pixman_image);
|
|
}
|
|
+#endif
|
|
|
|
/* Avoid sub-byte offsets, force a copy in that case. */
|
|
if (PIXMAN_FORMAT_BPP (source->pixman_format) >= 8) {
|
|
+ void *data = source->data
|
|
+ + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8
|
|
+ + sub->extents.y * source->stride;
|
|
pixman_image = pixman_image_create_bits (source->pixman_format,
|
|
sub->extents.width,
|
|
sub->extents.height,
|
|
- (uint32_t *) (source->data + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8 + sub->extents.y * source->stride),
|
|
+ data,
|
|
source->stride);
|
|
if (unlikely (pixman_image == NULL))
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pixman_image == NULL) {
|