pixman: add generic 565 scanline fetcher
[openembedded.git] / recipes / xorg-lib / pixman-0.18.0 / 565-scanline.patch
blob8461a46a122cf595e52c60c70b1f5c2401ad781d
1 From deef1daf5896062f47fa61b94e1e77c7c0041820 Mon Sep 17 00:00:00 2001
2 From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
3 Date: Fri, 04 Dec 2009 16:49:19 +0000
4 Subject: A copy-paste version of 16bpp bilinear scanline fetcher
6 ---
7 diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
8 index 3d78ff0..1656975 100644
9 --- a/pixman/pixman-bits-image.c
10 +++ b/pixman/pixman-bits-image.c
11 @@ -535,6 +535,212 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
12 *buffer++ = 0;
15 +static void
16 +bits_image_fetch_bilinear_no_repeat_0565 (pixman_image_t * ima,
17 + int offset,
18 + int line,
19 + int width,
20 + uint32_t * buffer,
21 + const uint32_t * mask,
22 + uint32_t mask_bits)
24 + bits_image_t *bits = &ima->bits;
25 + pixman_fixed_t x_top, x_bottom, x;
26 + pixman_fixed_t ux_top, ux_bottom, ux;
27 + pixman_vector_t v;
28 + uint32_t top_mask, bottom_mask;
29 + uint16_t *top_row;
30 + uint16_t *bottom_row;
31 + uint32_t *end;
32 + uint16_t zero[2] = { 0, 0 };
33 + int y, y1, y2;
34 + int disty;
35 + int mask_inc;
36 + int w;
38 + /* reference point is the center of the pixel */
39 + v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
40 + v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
41 + v.vector[2] = pixman_fixed_1;
43 + if (!pixman_transform_point_3d (bits->common.transform, &v))
44 + return;
46 + ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
47 + x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
49 + y = v.vector[1] - pixman_fixed_1/2;
50 + disty = (y >> 8) & 0xff;
52 + /* Load the pointers to the first and second lines from the source
53 + * image that bilinear code must read.
54 + *
55 + * The main trick in this code is about the check if any line are
56 + * outside of the image;
57 + *
58 + * When I realize that a line (any one) is outside, I change
59 + * the pointer to a dummy area with zeros. Once I change this, I
60 + * must be sure the pointer will not change, so I set the
61 + * variables to each pointer increments inside the loop.
62 + */
63 + y1 = pixman_fixed_to_int (y);
64 + y2 = y1 + 1;
66 + if (y1 < 0 || y1 >= bits->height)
67 + {
68 + top_row = zero;
69 + x_top = 0;
70 + ux_top = 0;
71 + }
72 + else
73 + {
74 + top_row = bits->bits + y1 * bits->rowstride;
75 + x_top = x;
76 + ux_top = ux;
77 + }
79 + if (y2 < 0 || y2 >= bits->height)
80 + {
81 + bottom_row = zero;
82 + x_bottom = 0;
83 + ux_bottom = 0;
84 + }
85 + else
86 + {
87 + bottom_row = bits->bits + y2 * bits->rowstride;
88 + x_bottom = x;
89 + ux_bottom = ux;
90 + }
92 + /* Instead of checking whether the operation uses the mast in
93 + * each loop iteration, verify this only once and prepare the
94 + * variables to make the code smaller inside the loop.
95 + */
96 + if (!mask)
97 + {
98 + mask_inc = 0;
99 + mask_bits = 1;
100 + mask = &mask_bits;
102 + else
104 + /* If have a mask, prepare the variables to check it */
105 + mask_inc = 1;
108 + /* If both are zero, then the whole thing is zero */
109 + if (top_row == zero && bottom_row == zero)
111 + memset (buffer, 0, width * sizeof (uint32_t));
112 + return;
114 + else
116 + if (top_row == zero)
118 + top_mask = 0;
119 + bottom_mask = 0xff000000;
121 + else if (bottom_row == zero)
123 + top_mask = 0xff000000;
124 + bottom_mask = 0;
126 + else
128 + top_mask = 0xff000000;
129 + bottom_mask = 0xff000000;
133 + end = buffer + width;
135 + /* Zero fill to the left of the image */
136 + while (buffer < end && x < pixman_fixed_minus_1)
138 + *buffer++ = 0;
139 + x += ux;
140 + x_top += ux_top;
141 + x_bottom += ux_bottom;
142 + mask += mask_inc;
145 + /* Left edge
146 + */
147 + while (buffer < end && x < 0)
149 + uint32_t tr, br;
150 + int32_t distx;
152 + tr = CONVERT_0565_TO_0888 (top_row[pixman_fixed_to_int (x_top) + 1]) | top_mask;
153 + br = CONVERT_0565_TO_0888 (bottom_row[pixman_fixed_to_int (x_bottom) + 1]) | bottom_mask;
155 + distx = (x >> 8) & 0xff;
157 + *buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
159 + x += ux;
160 + x_top += ux_top;
161 + x_bottom += ux_bottom;
162 + mask += mask_inc;
165 + /* Main part */
166 + w = pixman_int_to_fixed (bits->width - 1);
168 + while (buffer < end && x < w)
170 + if (*mask)
172 + uint32_t tl, tr, bl, br;
173 + int32_t distx;
175 + tl = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top)]) | top_mask;
176 + tr = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top) + 1]) | top_mask;
177 + bl = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom)]) | bottom_mask;
178 + br = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom) + 1]) | bottom_mask;
180 + distx = (x >> 8) & 0xff;
182 + *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
185 + buffer++;
186 + x += ux;
187 + x_top += ux_top;
188 + x_bottom += ux_bottom;
189 + mask += mask_inc;
192 + /* Right Edge */
193 + w = pixman_int_to_fixed (bits->width);
194 + while (buffer < end && x < w)
196 + if (*mask)
198 + uint32_t tl, bl;
199 + int32_t distx;
201 + tl = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top)]) | top_mask;
202 + bl = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom)]) | bottom_mask;
204 + distx = (x >> 8) & 0xff;
206 + *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
209 + buffer++;
210 + x += ux;
211 + x_top += ux_top;
212 + x_bottom += ux_bottom;
213 + mask += mask_inc;
216 + /* Zero fill to the left of the image */
217 + while (buffer < end)
218 + *buffer++ = 0;
221 static force_inline uint32_t
222 bits_image_fetch_pixel_convolution (bits_image_t *image,
223 pixman_fixed_t x,
224 @@ -917,14 +1123,26 @@ bits_image_property_changed (pixman_image_t *image)
225 (bits->common.filter == PIXMAN_FILTER_BILINEAR ||
226 bits->common.filter == PIXMAN_FILTER_GOOD ||
227 bits->common.filter == PIXMAN_FILTER_BEST) &&
228 - bits->common.repeat == PIXMAN_REPEAT_NONE &&
229 - (bits->format == PIXMAN_a8r8g8b8 ||
230 - bits->format == PIXMAN_x8r8g8b8))
231 + bits->common.repeat == PIXMAN_REPEAT_NONE)
233 image->common.get_scanline_64 =
234 _pixman_image_get_scanline_generic_64;
235 - image->common.get_scanline_32 =
236 - bits_image_fetch_bilinear_no_repeat_8888;
238 + if (bits->format == PIXMAN_a8r8g8b8 || bits->format == PIXMAN_x8r8g8b8)
240 + image->common.get_scanline_32 =
241 + bits_image_fetch_bilinear_no_repeat_8888;
243 + else if (bits->format == PIXMAN_r5g6b5)
245 + image->common.get_scanline_32 =
246 + bits_image_fetch_bilinear_no_repeat_0565;
248 + else
250 + image->common.get_scanline_32 =
251 + bits_image_fetch_transformed;
254 else
257 cgit v0.8.3-6-g21f6