Tue, 06 Jan 2015 21:39:09 +0100
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' |