summaryrefslogtreecommitdiff
path: root/gfx/cairo/no-pixman-image-reuse-across-threads.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/no-pixman-image-reuse-across-threads.patch')
-rw-r--r--gfx/cairo/no-pixman-image-reuse-across-threads.patch242
1 files changed, 242 insertions, 0 deletions
diff --git a/gfx/cairo/no-pixman-image-reuse-across-threads.patch b/gfx/cairo/no-pixman-image-reuse-across-threads.patch
new file mode 100644
index 0000000000..ccaf5a5e63
--- /dev/null
+++ b/gfx/cairo/no-pixman-image-reuse-across-threads.patch
@@ -0,0 +1,242 @@
+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) {