gfx/cairo/pixman-lowres-interp.patch

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 summary: Bug 689707. Use lower precision bilinear interpolation. r=joe
michael@0 2
michael@0 3 diff --git a/gfx/cairo/libpixman/src/pixman-bits-image.c b/gfx/cairo/libpixman/src/pixman-bits-image.c
michael@0 4 --- a/gfx/cairo/libpixman/src/pixman-bits-image.c
michael@0 5 +++ b/gfx/cairo/libpixman/src/pixman-bits-image.c
michael@0 6 @@ -124,18 +124,18 @@ bits_image_fetch_pixel_bilinear (bits_im
michael@0 7 int height = image->height;
michael@0 8 int x1, y1, x2, y2;
michael@0 9 uint32_t tl, tr, bl, br;
michael@0 10 int32_t distx, disty;
michael@0 11
michael@0 12 x1 = x - pixman_fixed_1 / 2;
michael@0 13 y1 = y - pixman_fixed_1 / 2;
michael@0 14
michael@0 15 - distx = (x1 >> 8) & 0xff;
michael@0 16 - disty = (y1 >> 8) & 0xff;
michael@0 17 + distx = interpolation_coord(x1);
michael@0 18 + disty = interpolation_coord(y1);
michael@0 19
michael@0 20 x1 = pixman_fixed_to_int (x1);
michael@0 21 y1 = pixman_fixed_to_int (y1);
michael@0 22 x2 = x1 + 1;
michael@0 23 y2 = y1 + 1;
michael@0 24
michael@0 25 if (repeat_mode != PIXMAN_REPEAT_NONE)
michael@0 26 {
michael@0 27 @@ -190,17 +190,17 @@ bits_image_fetch_bilinear_no_repeat_8888
michael@0 28
michael@0 29 if (!pixman_transform_point_3d (bits->common.transform, &v))
michael@0 30 return;
michael@0 31
michael@0 32 ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
michael@0 33 x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
michael@0 34
michael@0 35 y = v.vector[1] - pixman_fixed_1/2;
michael@0 36 - disty = (y >> 8) & 0xff;
michael@0 37 + disty = interpolation_coord(y);
michael@0 38
michael@0 39 /* Load the pointers to the first and second lines from the source
michael@0 40 * image that bilinear code must read.
michael@0 41 *
michael@0 42 * The main trick in this code is about the check if any line are
michael@0 43 * outside of the image;
michael@0 44 *
michael@0 45 * When I realize that a line (any one) is outside, I change
michael@0 46 @@ -299,17 +299,17 @@ bits_image_fetch_bilinear_no_repeat_8888
michael@0 47 while (buffer < end && x < 0)
michael@0 48 {
michael@0 49 uint32_t tr, br;
michael@0 50 int32_t distx;
michael@0 51
michael@0 52 tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask;
michael@0 53 br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
michael@0 54
michael@0 55 - distx = (x >> 8) & 0xff;
michael@0 56 + distx = interpolation_coord(x);
michael@0 57
michael@0 58 *buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
michael@0 59
michael@0 60 x += ux;
michael@0 61 x_top += ux_top;
michael@0 62 x_bottom += ux_bottom;
michael@0 63 mask += mask_inc;
michael@0 64 }
michael@0 65 @@ -324,17 +324,17 @@ bits_image_fetch_bilinear_no_repeat_8888
michael@0 66 uint32_t tl, tr, bl, br;
michael@0 67 int32_t distx;
michael@0 68
michael@0 69 tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
michael@0 70 tr = top_row [pixman_fixed_to_int (x_top) + 1] | top_mask;
michael@0 71 bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
michael@0 72 br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
michael@0 73
michael@0 74 - distx = (x >> 8) & 0xff;
michael@0 75 + distx = interpolation_coord(x);
michael@0 76
michael@0 77 *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
michael@0 78 }
michael@0 79
michael@0 80 buffer++;
michael@0 81 x += ux;
michael@0 82 x_top += ux_top;
michael@0 83 x_bottom += ux_bottom;
michael@0 84 @@ -348,17 +348,17 @@ bits_image_fetch_bilinear_no_repeat_8888
michael@0 85 if (*mask)
michael@0 86 {
michael@0 87 uint32_t tl, bl;
michael@0 88 int32_t distx;
michael@0 89
michael@0 90 tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
michael@0 91 bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
michael@0 92
michael@0 93 - distx = (x >> 8) & 0xff;
michael@0 94 + distx = interpolation_coord(x);
michael@0 95
michael@0 96 *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
michael@0 97 }
michael@0 98
michael@0 99 buffer++;
michael@0 100 x += ux;
michael@0 101 x_top += ux_top;
michael@0 102 x_bottom += ux_bottom;
michael@0 103 @@ -675,18 +675,18 @@ bits_image_fetch_bilinear_affine (pixman
michael@0 104 const uint8_t *row2;
michael@0 105
michael@0 106 if (mask && !mask[i])
michael@0 107 goto next;
michael@0 108
michael@0 109 x1 = x - pixman_fixed_1 / 2;
michael@0 110 y1 = y - pixman_fixed_1 / 2;
michael@0 111
michael@0 112 - distx = (x1 >> 8) & 0xff;
michael@0 113 - disty = (y1 >> 8) & 0xff;
michael@0 114 + distx = interpolation_coord(x1);
michael@0 115 + disty = interpolation_coord(y1);
michael@0 116
michael@0 117 y1 = pixman_fixed_to_int (y1);
michael@0 118 y2 = y1 + 1;
michael@0 119 x1 = pixman_fixed_to_int (x1);
michael@0 120 x2 = x1 + 1;
michael@0 121
michael@0 122 if (repeat_mode != PIXMAN_REPEAT_NONE)
michael@0 123 {
michael@0 124 diff --git a/gfx/cairo/libpixman/src/pixman-inlines.h b/gfx/cairo/libpixman/src/pixman-inlines.h
michael@0 125 --- a/gfx/cairo/libpixman/src/pixman-inlines.h
michael@0 126 +++ b/gfx/cairo/libpixman/src/pixman-inlines.h
michael@0 127 @@ -76,16 +76,31 @@ repeat (pixman_repeat_t repeat, int *c,
michael@0 128 {
michael@0 129 *c = MOD (*c, size * 2);
michael@0 130 if (*c >= size)
michael@0 131 *c = size * 2 - *c - 1;
michael@0 132 }
michael@0 133 return TRUE;
michael@0 134 }
michael@0 135
michael@0 136 +#ifdef MOZ_GFX_OPTIMIZE_MOBILE
michael@0 137 +#define LOW_QUALITY_INTERPOLATION
michael@0 138 +#endif
michael@0 139 +
michael@0 140 +static force_inline int32_t
michael@0 141 +interpolation_coord(pixman_fixed_t t)
michael@0 142 +{
michael@0 143 +#ifdef LOW_QUALITY_INTERPOLATION
michael@0 144 + return (t >> 12) & 0xf;
michael@0 145 +#else
michael@0 146 + return (t >> 8) & 0xff;
michael@0 147 +#endif
michael@0 148 +}
michael@0 149 +
michael@0 150 +
michael@0 151 #if SIZEOF_LONG > 4
michael@0 152
michael@0 153 static force_inline uint32_t
michael@0 154 bilinear_interpolation (uint32_t tl, uint32_t tr,
michael@0 155 uint32_t bl, uint32_t br,
michael@0 156 int distx, int disty)
michael@0 157 {
michael@0 158 uint64_t distxy, distxiy, distixy, distixiy;
michael@0 159 @@ -122,16 +137,44 @@ bilinear_interpolation (uint32_t tl, uin
michael@0 160 f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy;
michael@0 161 r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull);
michael@0 162
michael@0 163 return (uint32_t)(r >> 16);
michael@0 164 }
michael@0 165
michael@0 166 #else
michael@0 167
michael@0 168 +#ifdef LOW_QUALITY_INTERPOLATION
michael@0 169 +/* Based on Filter_32_opaque_portable from Skia */
michael@0 170 +static force_inline uint32_t
michael@0 171 +bilinear_interpolation(uint32_t a00, uint32_t a01,
michael@0 172 + uint32_t a10, uint32_t a11,
michael@0 173 + int x, int y)
michael@0 174 +{
michael@0 175 + int xy = x * y;
michael@0 176 + static const uint32_t mask = 0xff00ff;
michael@0 177 +
michael@0 178 + int scale = 256 - 16*y - 16*x + xy;
michael@0 179 + uint32_t lo = (a00 & mask) * scale;
michael@0 180 + uint32_t hi = ((a00 >> 8) & mask) * scale;
michael@0 181 +
michael@0 182 + scale = 16*x - xy;
michael@0 183 + lo += (a01 & mask) * scale;
michael@0 184 + hi += ((a01 >> 8) & mask) * scale;
michael@0 185 +
michael@0 186 + scale = 16*y - xy;
michael@0 187 + lo += (a10 & mask) * scale;
michael@0 188 + hi += ((a10 >> 8) & mask) * scale;
michael@0 189 +
michael@0 190 + lo += (a11 & mask) * xy;
michael@0 191 + hi += ((a11 >> 8) & mask) * xy;
michael@0 192 +
michael@0 193 + return ((lo >> 8) & mask) | (hi & ~mask);
michael@0 194 +}
michael@0 195 +#else
michael@0 196 static force_inline uint32_t
michael@0 197 bilinear_interpolation (uint32_t tl, uint32_t tr,
michael@0 198 uint32_t bl, uint32_t br,
michael@0 199 int distx, int disty)
michael@0 200 {
michael@0 201 int distxy, distxiy, distixy, distixiy;
michael@0 202 uint32_t f, r;
michael@0 203
michael@0 204 @@ -164,17 +207,17 @@ bilinear_interpolation (uint32_t tl, uin
michael@0 205
michael@0 206 /* Alpha */
michael@0 207 f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
michael@0 208 + (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy;
michael@0 209 r |= f & 0xff000000;
michael@0 210
michael@0 211 return r;
michael@0 212 }
michael@0 213 -
michael@0 214 +#endif
michael@0 215 #endif
michael@0 216
michael@0 217 /*
michael@0 218 * For each scanline fetched from source image with PAD repeat:
michael@0 219 * - calculate how many pixels need to be padded on the left side
michael@0 220 * - calculate how many pixels need to be padded on the right side
michael@0 221 * - update width to only count pixels which are fetched from the image
michael@0 222 * All this information is returned via 'width', 'left_pad', 'right_pad'

mercurial