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