gfx/cairo/pixman-lowres-interp.patch

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial