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 | diff --git a/gfx/cairo/libpixman/src/pixman-dither.h b/gfx/cairo/libpixman/src/pixman-dither.h |
michael@0 | 2 | new file mode 100644 |
michael@0 | 3 | --- /dev/null |
michael@0 | 4 | +++ b/gfx/cairo/libpixman/src/pixman-dither.h |
michael@0 | 5 | @@ -0,0 +1,51 @@ |
michael@0 | 6 | +#define R16_BITS 5 |
michael@0 | 7 | +#define G16_BITS 6 |
michael@0 | 8 | +#define B16_BITS 5 |
michael@0 | 9 | + |
michael@0 | 10 | +#define R16_SHIFT (B16_BITS + G16_BITS) |
michael@0 | 11 | +#define G16_SHIFT (B16_BITS) |
michael@0 | 12 | +#define B16_SHIFT 0 |
michael@0 | 13 | + |
michael@0 | 14 | +#define MASK 0xff |
michael@0 | 15 | +#define ONE_HALF 0x80 |
michael@0 | 16 | + |
michael@0 | 17 | +#define A_SHIFT 8 * 3 |
michael@0 | 18 | +#define R_SHIFT 8 * 2 |
michael@0 | 19 | +#define G_SHIFT 8 |
michael@0 | 20 | +#define A_MASK 0xff000000 |
michael@0 | 21 | +#define R_MASK 0xff0000 |
michael@0 | 22 | +#define G_MASK 0xff00 |
michael@0 | 23 | + |
michael@0 | 24 | +#define RB_MASK 0xff00ff |
michael@0 | 25 | +#define AG_MASK 0xff00ff00 |
michael@0 | 26 | +#define RB_ONE_HALF 0x800080 |
michael@0 | 27 | +#define RB_MASK_PLUS_ONE 0x10000100 |
michael@0 | 28 | + |
michael@0 | 29 | +#define ALPHA_8(x) ((x) >> A_SHIFT) |
michael@0 | 30 | +#define RED_8(x) (((x) >> R_SHIFT) & MASK) |
michael@0 | 31 | +#define GREEN_8(x) (((x) >> G_SHIFT) & MASK) |
michael@0 | 32 | +#define BLUE_8(x) ((x) & MASK) |
michael@0 | 33 | + |
michael@0 | 34 | +// This uses the same dithering technique that Skia does. |
michael@0 | 35 | +// It is essentially preturbing the lower bit based on the |
michael@0 | 36 | +// high bit |
michael@0 | 37 | +static inline uint16_t dither_32_to_16(uint32_t c) |
michael@0 | 38 | +{ |
michael@0 | 39 | + uint8_t b = BLUE_8(c); |
michael@0 | 40 | + uint8_t g = GREEN_8(c); |
michael@0 | 41 | + uint8_t r = RED_8(c); |
michael@0 | 42 | + r = ((r << 1) - ((r >> (8 - R16_BITS) << (8 - R16_BITS)) | (r >> R16_BITS))) >> (8 - R16_BITS); |
michael@0 | 43 | + g = ((g << 1) - ((g >> (8 - G16_BITS) << (8 - G16_BITS)) | (g >> G16_BITS))) >> (8 - G16_BITS); |
michael@0 | 44 | + b = ((b << 1) - ((b >> (8 - B16_BITS) << (8 - B16_BITS)) | (b >> B16_BITS))) >> (8 - B16_BITS); |
michael@0 | 45 | + return ((r << R16_SHIFT) | (g << G16_SHIFT) | (b << B16_SHIFT)); |
michael@0 | 46 | +} |
michael@0 | 47 | + |
michael@0 | 48 | +static inline uint16_t dither_8888_to_0565(uint32_t color, pixman_bool_t toggle) |
michael@0 | 49 | +{ |
michael@0 | 50 | + // alternate between a preturbed truncation and a regular truncation |
michael@0 | 51 | + if (toggle) { |
michael@0 | 52 | + return dither_32_to_16(color); |
michael@0 | 53 | + } else { |
michael@0 | 54 | + return CONVERT_8888_TO_0565(color); |
michael@0 | 55 | + } |
michael@0 | 56 | +} |
michael@0 | 57 | diff --git a/gfx/cairo/libpixman/src/pixman-linear-gradient.c b/gfx/cairo/libpixman/src/pixman-linear-gradient.c |
michael@0 | 58 | --- a/gfx/cairo/libpixman/src/pixman-linear-gradient.c |
michael@0 | 59 | +++ b/gfx/cairo/libpixman/src/pixman-linear-gradient.c |
michael@0 | 60 | @@ -26,16 +26,18 @@ |
michael@0 | 61 | */ |
michael@0 | 62 | |
michael@0 | 63 | #ifdef HAVE_CONFIG_H |
michael@0 | 64 | #include <config.h> |
michael@0 | 65 | #endif |
michael@0 | 66 | #include <stdlib.h> |
michael@0 | 67 | #include "pixman-private.h" |
michael@0 | 68 | |
michael@0 | 69 | +#include "pixman-dither.h" |
michael@0 | 70 | + |
michael@0 | 71 | static pixman_bool_t |
michael@0 | 72 | linear_gradient_is_horizontal (pixman_image_t *image, |
michael@0 | 73 | int x, |
michael@0 | 74 | int y, |
michael@0 | 75 | int width, |
michael@0 | 76 | int height) |
michael@0 | 77 | { |
michael@0 | 78 | linear_gradient_t *linear = (linear_gradient_t *)image; |
michael@0 | 79 | @@ -222,25 +224,28 @@ linear_get_scanline_narrow (pixman_iter_ |
michael@0 | 80 | return iter->buffer; |
michael@0 | 81 | } |
michael@0 | 82 | |
michael@0 | 83 | static uint16_t convert_8888_to_0565(uint32_t color) |
michael@0 | 84 | { |
michael@0 | 85 | return CONVERT_8888_TO_0565(color); |
michael@0 | 86 | } |
michael@0 | 87 | |
michael@0 | 88 | + |
michael@0 | 89 | + |
michael@0 | 90 | static uint32_t * |
michael@0 | 91 | linear_get_scanline_16 (pixman_iter_t *iter, |
michael@0 | 92 | const uint32_t *mask) |
michael@0 | 93 | { |
michael@0 | 94 | pixman_image_t *image = iter->image; |
michael@0 | 95 | int x = iter->x; |
michael@0 | 96 | int y = iter->y; |
michael@0 | 97 | int width = iter->width; |
michael@0 | 98 | uint16_t * buffer = (uint16_t*)iter->buffer; |
michael@0 | 99 | + pixman_bool_t toggle = ((x ^ y) & 1); |
michael@0 | 100 | |
michael@0 | 101 | pixman_vector_t v, unit; |
michael@0 | 102 | pixman_fixed_32_32_t l; |
michael@0 | 103 | pixman_fixed_48_16_t dx, dy; |
michael@0 | 104 | gradient_t *gradient = (gradient_t *)image; |
michael@0 | 105 | linear_gradient_t *linear = (linear_gradient_t *)image; |
michael@0 | 106 | uint16_t *end = buffer + width; |
michael@0 | 107 | pixman_gradient_walker_t walker; |
michael@0 | 108 | @@ -294,34 +299,47 @@ linear_get_scanline_16 (pixman_iter_t * |
michael@0 | 109 | t = ((dx * v.vector[0] + dy * v.vector[1]) - |
michael@0 | 110 | (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; |
michael@0 | 111 | inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; |
michael@0 | 112 | } |
michael@0 | 113 | next_inc = 0; |
michael@0 | 114 | |
michael@0 | 115 | if (((pixman_fixed_32_32_t )(inc * width)) == 0) |
michael@0 | 116 | { |
michael@0 | 117 | - register uint16_t color; |
michael@0 | 118 | + register uint32_t color; |
michael@0 | 119 | + uint16_t dither_diff; |
michael@0 | 120 | + uint16_t color16; |
michael@0 | 121 | + uint16_t color16b; |
michael@0 | 122 | |
michael@0 | 123 | - color = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); |
michael@0 | 124 | - while (buffer < end) |
michael@0 | 125 | - *buffer++ = color; |
michael@0 | 126 | + color = _pixman_gradient_walker_pixel (&walker, t); |
michael@0 | 127 | + color16 = dither_8888_to_0565(color, toggle); |
michael@0 | 128 | + color16b = dither_8888_to_0565(color, toggle^1); |
michael@0 | 129 | + // compute the difference |
michael@0 | 130 | + dither_diff = color16 ^ color16b; |
michael@0 | 131 | + while (buffer < end) { |
michael@0 | 132 | + *buffer++ = color16; |
michael@0 | 133 | + // use dither_diff to toggle between color16 and color16b |
michael@0 | 134 | + color16 ^= dither_diff; |
michael@0 | 135 | + toggle ^= 1; |
michael@0 | 136 | + } |
michael@0 | 137 | } |
michael@0 | 138 | else |
michael@0 | 139 | { |
michael@0 | 140 | int i; |
michael@0 | 141 | |
michael@0 | 142 | i = 0; |
michael@0 | 143 | while (buffer < end) |
michael@0 | 144 | { |
michael@0 | 145 | if (!mask || *mask++) |
michael@0 | 146 | { |
michael@0 | 147 | - *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, |
michael@0 | 148 | - t + next_inc)); |
michael@0 | 149 | + *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, |
michael@0 | 150 | + t + next_inc), |
michael@0 | 151 | + toggle); |
michael@0 | 152 | } |
michael@0 | 153 | + toggle ^= 1; |
michael@0 | 154 | i++; |
michael@0 | 155 | next_inc = inc * i; |
michael@0 | 156 | buffer++; |
michael@0 | 157 | } |
michael@0 | 158 | } |
michael@0 | 159 | } |
michael@0 | 160 | else |
michael@0 | 161 | { |
michael@0 | 162 | @@ -340,18 +358,20 @@ linear_get_scanline_16 (pixman_iter_t * |
michael@0 | 163 | |
michael@0 | 164 | invden = pixman_fixed_1 * (double) pixman_fixed_1 / |
michael@0 | 165 | (l * (double) v.vector[2]); |
michael@0 | 166 | v2 = v.vector[2] * (1. / pixman_fixed_1); |
michael@0 | 167 | t = ((dx * v.vector[0] + dy * v.vector[1]) - |
michael@0 | 168 | (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | - *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); |
michael@0 | 172 | + *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t), |
michael@0 | 173 | + toggle); |
michael@0 | 174 | } |
michael@0 | 175 | + toggle ^= 1; |
michael@0 | 176 | |
michael@0 | 177 | ++buffer; |
michael@0 | 178 | |
michael@0 | 179 | v.vector[0] += unit.vector[0]; |
michael@0 | 180 | v.vector[1] += unit.vector[1]; |
michael@0 | 181 | v.vector[2] += unit.vector[2]; |
michael@0 | 182 | } |
michael@0 | 183 | } |
michael@0 | 184 | @@ -369,17 +389,18 @@ linear_get_scanline_wide (pixman_iter_t |
michael@0 | 185 | pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); |
michael@0 | 186 | |
michael@0 | 187 | return buffer; |
michael@0 | 188 | } |
michael@0 | 189 | |
michael@0 | 190 | void |
michael@0 | 191 | _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) |
michael@0 | 192 | { |
michael@0 | 193 | - if (linear_gradient_is_horizontal ( |
michael@0 | 194 | + // XXX: we can't use this optimization when dithering |
michael@0 | 195 | + if (0 && linear_gradient_is_horizontal ( |
michael@0 | 196 | iter->image, iter->x, iter->y, iter->width, iter->height)) |
michael@0 | 197 | { |
michael@0 | 198 | if (iter->flags & ITER_16) |
michael@0 | 199 | linear_get_scanline_16 (iter, NULL); |
michael@0 | 200 | else if (iter->flags & ITER_NARROW) |
michael@0 | 201 | linear_get_scanline_narrow (iter, NULL); |
michael@0 | 202 | else |
michael@0 | 203 | linear_get_scanline_wide (iter, NULL); |
michael@0 | 204 | diff --git a/gfx/cairo/libpixman/src/pixman-radial-gradient.c b/gfx/cairo/libpixman/src/pixman-radial-gradient.c |
michael@0 | 205 | --- a/gfx/cairo/libpixman/src/pixman-radial-gradient.c |
michael@0 | 206 | +++ b/gfx/cairo/libpixman/src/pixman-radial-gradient.c |
michael@0 | 207 | @@ -29,16 +29,18 @@ |
michael@0 | 208 | |
michael@0 | 209 | #ifdef HAVE_CONFIG_H |
michael@0 | 210 | #include <config.h> |
michael@0 | 211 | #endif |
michael@0 | 212 | #include <stdlib.h> |
michael@0 | 213 | #include <math.h> |
michael@0 | 214 | #include "pixman-private.h" |
michael@0 | 215 | |
michael@0 | 216 | +#include "pixman-dither.h" |
michael@0 | 217 | + |
michael@0 | 218 | static inline pixman_fixed_32_32_t |
michael@0 | 219 | dot (pixman_fixed_48_16_t x1, |
michael@0 | 220 | pixman_fixed_48_16_t y1, |
michael@0 | 221 | pixman_fixed_48_16_t z1, |
michael@0 | 222 | pixman_fixed_48_16_t x2, |
michael@0 | 223 | pixman_fixed_48_16_t y2, |
michael@0 | 224 | pixman_fixed_48_16_t z2) |
michael@0 | 225 | { |
michael@0 | 226 | @@ -489,16 +491,17 @@ radial_get_scanline_16 (pixman_iter_t *i |
michael@0 | 227 | * <=> for every p, the radiuses associated with the two t solutions |
michael@0 | 228 | * have opposite sign |
michael@0 | 229 | */ |
michael@0 | 230 | pixman_image_t *image = iter->image; |
michael@0 | 231 | int x = iter->x; |
michael@0 | 232 | int y = iter->y; |
michael@0 | 233 | int width = iter->width; |
michael@0 | 234 | uint16_t *buffer = iter->buffer; |
michael@0 | 235 | + pixman_bool_t toggle = ((x ^ y) & 1); |
michael@0 | 236 | |
michael@0 | 237 | gradient_t *gradient = (gradient_t *)image; |
michael@0 | 238 | radial_gradient_t *radial = (radial_gradient_t *)image; |
michael@0 | 239 | uint16_t *end = buffer + width; |
michael@0 | 240 | pixman_gradient_walker_t walker; |
michael@0 | 241 | pixman_vector_t v, unit; |
michael@0 | 242 | |
michael@0 | 243 | /* reference point is the center of the pixel */ |
michael@0 | 244 | @@ -575,25 +578,27 @@ radial_get_scanline_16 (pixman_iter_t *i |
michael@0 | 245 | unit.vector[0], unit.vector[1], 0); |
michael@0 | 246 | ddc = 2 * dot (unit.vector[0], unit.vector[1], 0, |
michael@0 | 247 | unit.vector[0], unit.vector[1], 0); |
michael@0 | 248 | |
michael@0 | 249 | while (buffer < end) |
michael@0 | 250 | { |
michael@0 | 251 | if (!mask || *mask++) |
michael@0 | 252 | { |
michael@0 | 253 | - *buffer = convert_8888_to_0565( |
michael@0 | 254 | + *buffer = dither_8888_to_0565( |
michael@0 | 255 | radial_compute_color (radial->a, b, c, |
michael@0 | 256 | radial->inva, |
michael@0 | 257 | radial->delta.radius, |
michael@0 | 258 | radial->mindr, |
michael@0 | 259 | &walker, |
michael@0 | 260 | - image->common.repeat)); |
michael@0 | 261 | + image->common.repeat), |
michael@0 | 262 | + toggle); |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | + toggle ^= 1; |
michael@0 | 266 | b += db; |
michael@0 | 267 | c += dc; |
michael@0 | 268 | dc += ddc; |
michael@0 | 269 | ++buffer; |
michael@0 | 270 | } |
michael@0 | 271 | } |
michael@0 | 272 | else |
michael@0 | 273 | { |
michael@0 | 274 | @@ -621,31 +626,33 @@ radial_get_scanline_16 (pixman_iter_t *i |
michael@0 | 275 | radial->delta.x, radial->delta.y, |
michael@0 | 276 | radial->delta.radius); |
michael@0 | 277 | /* / pixman_fixed_1 / pixman_fixed_1 */ |
michael@0 | 278 | |
michael@0 | 279 | c = fdot (pdx, pdy, -radial->c1.radius, |
michael@0 | 280 | pdx, pdy, radial->c1.radius); |
michael@0 | 281 | /* / pixman_fixed_1 / pixman_fixed_1 */ |
michael@0 | 282 | |
michael@0 | 283 | - *buffer = convert_8888_to_0565 ( |
michael@0 | 284 | + *buffer = dither_8888_to_0565 ( |
michael@0 | 285 | radial_compute_color (radial->a, b, c, |
michael@0 | 286 | radial->inva, |
michael@0 | 287 | radial->delta.radius, |
michael@0 | 288 | radial->mindr, |
michael@0 | 289 | &walker, |
michael@0 | 290 | - image->common.repeat)); |
michael@0 | 291 | + image->common.repeat), |
michael@0 | 292 | + toggle); |
michael@0 | 293 | } |
michael@0 | 294 | else |
michael@0 | 295 | { |
michael@0 | 296 | *buffer = 0; |
michael@0 | 297 | } |
michael@0 | 298 | } |
michael@0 | 299 | |
michael@0 | 300 | ++buffer; |
michael@0 | 301 | + toggle ^= 1; |
michael@0 | 302 | |
michael@0 | 303 | v.vector[0] += unit.vector[0]; |
michael@0 | 304 | v.vector[1] += unit.vector[1]; |
michael@0 | 305 | v.vector[2] += unit.vector[2]; |
michael@0 | 306 | } |
michael@0 | 307 | } |
michael@0 | 308 | |
michael@0 | 309 | iter->y++; |
michael@0 | 310 |