Home | History | Annotate | Line # | Download | only in pixman
      1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
      2 /*
      3  * Copyright  2000 SuSE, Inc.
      4  * Copyright  2007 Red Hat, Inc.
      5  *
      6  * Permission to use, copy, modify, distribute, and sell this software and its
      7  * documentation for any purpose is hereby granted without fee, provided that
      8  * the above copyright notice appear in all copies and that both that
      9  * copyright notice and this permission notice appear in supporting
     10  * documentation, and that the name of SuSE not be used in advertising or
     11  * publicity pertaining to distribution of the software without specific,
     12  * written prior permission.  SuSE makes no representations about the
     13  * suitability of this software for any purpose.  It is provided "as is"
     14  * without express or implied warranty.
     15  *
     16  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
     18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     22  *
     23  * Author:  Keith Packard, SuSE, Inc.
     24  */
     25 
     26 #ifdef HAVE_CONFIG_H
     27 #include <pixman-config.h>
     28 #endif
     29 #include <string.h>
     30 #include <stdlib.h>
     31 #include "pixman-private.h"
     32 #include "pixman-combine32.h"
     33 #include "pixman-inlines.h"
     34 
     35 static force_inline uint32_t
     36 fetch_24 (uint8_t *a)
     37 {
     38     if (((uintptr_t)a) & 1)
     39     {
     40 #ifdef WORDS_BIGENDIAN
     41 	return (*a << 16) | (*(uint16_t *)(a + 1));
     42 #else
     43 	return *a | (*(uint16_t *)(a + 1) << 8);
     44 #endif
     45     }
     46     else
     47     {
     48 #ifdef WORDS_BIGENDIAN
     49 	return (*(uint16_t *)a << 8) | *(a + 2);
     50 #else
     51 	return *(uint16_t *)a | (*(a + 2) << 16);
     52 #endif
     53     }
     54 }
     55 
     56 static force_inline void
     57 store_24 (uint8_t *a,
     58           uint32_t v)
     59 {
     60     if (((uintptr_t)a) & 1)
     61     {
     62 #ifdef WORDS_BIGENDIAN
     63 	*a = (uint8_t) (v >> 16);
     64 	*(uint16_t *)(a + 1) = (uint16_t) (v);
     65 #else
     66 	*a = (uint8_t) (v);
     67 	*(uint16_t *)(a + 1) = (uint16_t) (v >> 8);
     68 #endif
     69     }
     70     else
     71     {
     72 #ifdef WORDS_BIGENDIAN
     73 	*(uint16_t *)a = (uint16_t)(v >> 8);
     74 	*(a + 2) = (uint8_t)v;
     75 #else
     76 	*(uint16_t *)a = (uint16_t)v;
     77 	*(a + 2) = (uint8_t)(v >> 16);
     78 #endif
     79     }
     80 }
     81 
     82 static force_inline uint32_t
     83 over (uint32_t src,
     84       uint32_t dest)
     85 {
     86     uint32_t a = ~src >> 24;
     87 
     88     UN8x4_MUL_UN8_ADD_UN8x4 (dest, a, src);
     89 
     90     return dest;
     91 }
     92 
     93 static force_inline uint32_t
     94 in (uint32_t x,
     95     uint8_t  y)
     96 {
     97     uint16_t a = y;
     98 
     99     UN8x4_MUL_UN8 (x, a);
    100 
    101     return x;
    102 }
    103 
    104 /*
    105  * Naming convention:
    106  *
    107  *  op_src_mask_dest
    108  */
    109 static void
    110 fast_composite_over_x888_8_8888 (pixman_implementation_t *imp,
    111                                  pixman_composite_info_t *info)
    112 {
    113     PIXMAN_COMPOSITE_ARGS (info);
    114     uint32_t    *src, *src_line;
    115     uint32_t    *dst, *dst_line;
    116     uint8_t     *mask, *mask_line;
    117     int src_stride, mask_stride, dst_stride;
    118     uint8_t m;
    119     uint32_t s, d;
    120     int32_t w;
    121 
    122     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
    123     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
    124     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
    125 
    126     while (height--)
    127     {
    128 	src = src_line;
    129 	src_line += src_stride;
    130 	dst = dst_line;
    131 	dst_line += dst_stride;
    132 	mask = mask_line;
    133 	mask_line += mask_stride;
    134 
    135 	w = width;
    136 	while (w--)
    137 	{
    138 	    m = *mask++;
    139 	    if (m)
    140 	    {
    141 		s = *src | 0xff000000;
    142 
    143 		if (m == 0xff)
    144 		{
    145 		    *dst = s;
    146 		}
    147 		else
    148 		{
    149 		    d = in (s, m);
    150 		    *dst = over (d, *dst);
    151 		}
    152 	    }
    153 	    src++;
    154 	    dst++;
    155 	}
    156     }
    157 }
    158 
    159 static void
    160 fast_composite_in_n_8_8 (pixman_implementation_t *imp,
    161                          pixman_composite_info_t *info)
    162 {
    163     PIXMAN_COMPOSITE_ARGS (info);
    164     uint32_t src, srca;
    165     uint8_t     *dst_line, *dst;
    166     uint8_t     *mask_line, *mask, m;
    167     int dst_stride, mask_stride;
    168     int32_t w;
    169     uint16_t t;
    170 
    171     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    172 
    173     srca = src >> 24;
    174 
    175     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
    176     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
    177 
    178     if (srca == 0xff)
    179     {
    180 	while (height--)
    181 	{
    182 	    dst = dst_line;
    183 	    dst_line += dst_stride;
    184 	    mask = mask_line;
    185 	    mask_line += mask_stride;
    186 	    w = width;
    187 
    188 	    while (w--)
    189 	    {
    190 		m = *mask++;
    191 
    192 		if (m == 0)
    193 		    *dst = 0;
    194 		else if (m != 0xff)
    195 		    *dst = MUL_UN8 (m, *dst, t);
    196 
    197 		dst++;
    198 	    }
    199 	}
    200     }
    201     else
    202     {
    203 	while (height--)
    204 	{
    205 	    dst = dst_line;
    206 	    dst_line += dst_stride;
    207 	    mask = mask_line;
    208 	    mask_line += mask_stride;
    209 	    w = width;
    210 
    211 	    while (w--)
    212 	    {
    213 		m = *mask++;
    214 		m = MUL_UN8 (m, srca, t);
    215 
    216 		if (m == 0)
    217 		    *dst = 0;
    218 		else if (m != 0xff)
    219 		    *dst = MUL_UN8 (m, *dst, t);
    220 
    221 		dst++;
    222 	    }
    223 	}
    224     }
    225 }
    226 
    227 static void
    228 fast_composite_in_8_8 (pixman_implementation_t *imp,
    229                        pixman_composite_info_t *info)
    230 {
    231     PIXMAN_COMPOSITE_ARGS (info);
    232     uint8_t     *dst_line, *dst;
    233     uint8_t     *src_line, *src;
    234     int dst_stride, src_stride;
    235     int32_t w;
    236     uint8_t s;
    237     uint16_t t;
    238 
    239     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
    240     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
    241 
    242     while (height--)
    243     {
    244 	dst = dst_line;
    245 	dst_line += dst_stride;
    246 	src = src_line;
    247 	src_line += src_stride;
    248 	w = width;
    249 
    250 	while (w--)
    251 	{
    252 	    s = *src++;
    253 
    254 	    if (s == 0)
    255 		*dst = 0;
    256 	    else if (s != 0xff)
    257 		*dst = MUL_UN8 (s, *dst, t);
    258 
    259 	    dst++;
    260 	}
    261     }
    262 }
    263 
    264 static void
    265 fast_composite_over_n_8_8888 (pixman_implementation_t *imp,
    266                               pixman_composite_info_t *info)
    267 {
    268     PIXMAN_COMPOSITE_ARGS (info);
    269     uint32_t src, srca;
    270     uint32_t    *dst_line, *dst, d;
    271     uint8_t     *mask_line, *mask, m;
    272     int dst_stride, mask_stride;
    273     int32_t w;
    274 
    275     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    276 
    277     srca = src >> 24;
    278     if (src == 0)
    279 	return;
    280 
    281     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
    282     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
    283 
    284     while (height--)
    285     {
    286 	dst = dst_line;
    287 	dst_line += dst_stride;
    288 	mask = mask_line;
    289 	mask_line += mask_stride;
    290 	w = width;
    291 
    292 	while (w--)
    293 	{
    294 	    m = *mask++;
    295 	    if (m == 0xff)
    296 	    {
    297 		if (srca == 0xff)
    298 		    *dst = src;
    299 		else
    300 		    *dst = over (src, *dst);
    301 	    }
    302 	    else if (m)
    303 	    {
    304 		d = in (src, m);
    305 		*dst = over (d, *dst);
    306 	    }
    307 	    dst++;
    308 	}
    309     }
    310 }
    311 
    312 static void
    313 fast_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
    314 				   pixman_composite_info_t *info)
    315 {
    316     PIXMAN_COMPOSITE_ARGS (info);
    317     uint32_t src, s;
    318     uint32_t    *dst_line, *dst, d;
    319     uint32_t    *mask_line, *mask, ma;
    320     int dst_stride, mask_stride;
    321     int32_t w;
    322 
    323     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    324 
    325     if (src == 0)
    326 	return;
    327 
    328     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
    329     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
    330 
    331     while (height--)
    332     {
    333 	dst = dst_line;
    334 	dst_line += dst_stride;
    335 	mask = mask_line;
    336 	mask_line += mask_stride;
    337 	w = width;
    338 
    339 	while (w--)
    340 	{
    341 	    ma = *mask++;
    342 
    343 	    if (ma)
    344 	    {
    345 		d = *dst;
    346 		s = src;
    347 
    348 		UN8x4_MUL_UN8x4_ADD_UN8x4 (s, ma, d);
    349 
    350 		*dst = s;
    351 	    }
    352 
    353 	    dst++;
    354 	}
    355     }
    356 }
    357 
    358 static void
    359 fast_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
    360                                     pixman_composite_info_t *info)
    361 {
    362     PIXMAN_COMPOSITE_ARGS (info);
    363     uint32_t src, srca, s;
    364     uint32_t    *dst_line, *dst, d;
    365     uint32_t    *mask_line, *mask, ma;
    366     int dst_stride, mask_stride;
    367     int32_t w;
    368 
    369     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    370 
    371     srca = src >> 24;
    372     if (src == 0)
    373 	return;
    374 
    375     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
    376     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
    377 
    378     while (height--)
    379     {
    380 	dst = dst_line;
    381 	dst_line += dst_stride;
    382 	mask = mask_line;
    383 	mask_line += mask_stride;
    384 	w = width;
    385 
    386 	while (w--)
    387 	{
    388 	    ma = *mask++;
    389 	    if (ma == 0xffffffff)
    390 	    {
    391 		if (srca == 0xff)
    392 		    *dst = src;
    393 		else
    394 		    *dst = over (src, *dst);
    395 	    }
    396 	    else if (ma)
    397 	    {
    398 		d = *dst;
    399 		s = src;
    400 
    401 		UN8x4_MUL_UN8x4 (s, ma);
    402 		UN8x4_MUL_UN8 (ma, srca);
    403 		ma = ~ma;
    404 		UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ma, s);
    405 
    406 		*dst = d;
    407 	    }
    408 
    409 	    dst++;
    410 	}
    411     }
    412 }
    413 
    414 static void
    415 fast_composite_over_n_8_0888 (pixman_implementation_t *imp,
    416                               pixman_composite_info_t *info)
    417 {
    418     PIXMAN_COMPOSITE_ARGS (info);
    419     uint32_t src, srca;
    420     uint8_t     *dst_line, *dst;
    421     uint32_t d;
    422     uint8_t     *mask_line, *mask, m;
    423     int dst_stride, mask_stride;
    424     int32_t w;
    425 
    426     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    427 
    428     srca = src >> 24;
    429     if (src == 0)
    430 	return;
    431 
    432     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 3);
    433     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
    434 
    435     while (height--)
    436     {
    437 	dst = dst_line;
    438 	dst_line += dst_stride;
    439 	mask = mask_line;
    440 	mask_line += mask_stride;
    441 	w = width;
    442 
    443 	while (w--)
    444 	{
    445 	    m = *mask++;
    446 	    if (m == 0xff)
    447 	    {
    448 		if (srca == 0xff)
    449 		{
    450 		    d = src;
    451 		}
    452 		else
    453 		{
    454 		    d = fetch_24 (dst);
    455 		    d = over (src, d);
    456 		}
    457 		store_24 (dst, d);
    458 	    }
    459 	    else if (m)
    460 	    {
    461 		d = over (in (src, m), fetch_24 (dst));
    462 		store_24 (dst, d);
    463 	    }
    464 	    dst += 3;
    465 	}
    466     }
    467 }
    468 
    469 static void
    470 fast_composite_over_n_8_0565 (pixman_implementation_t *imp,
    471                               pixman_composite_info_t *info)
    472 {
    473     PIXMAN_COMPOSITE_ARGS (info);
    474     uint32_t src, srca;
    475     uint16_t    *dst_line, *dst;
    476     uint32_t d;
    477     uint8_t     *mask_line, *mask, m;
    478     int dst_stride, mask_stride;
    479     int32_t w;
    480 
    481     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    482 
    483     srca = src >> 24;
    484     if (src == 0)
    485 	return;
    486 
    487     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
    488     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
    489 
    490     while (height--)
    491     {
    492 	dst = dst_line;
    493 	dst_line += dst_stride;
    494 	mask = mask_line;
    495 	mask_line += mask_stride;
    496 	w = width;
    497 
    498 	while (w--)
    499 	{
    500 	    m = *mask++;
    501 	    if (m == 0xff)
    502 	    {
    503 		if (srca == 0xff)
    504 		{
    505 		    d = src;
    506 		}
    507 		else
    508 		{
    509 		    d = *dst;
    510 		    d = over (src, convert_0565_to_0888 (d));
    511 		}
    512 		*dst = convert_8888_to_0565 (d);
    513 	    }
    514 	    else if (m)
    515 	    {
    516 		d = *dst;
    517 		d = over (in (src, m), convert_0565_to_0888 (d));
    518 		*dst = convert_8888_to_0565 (d);
    519 	    }
    520 	    dst++;
    521 	}
    522     }
    523 }
    524 
    525 static void
    526 fast_composite_over_n_8888_0565_ca (pixman_implementation_t *imp,
    527                                     pixman_composite_info_t *info)
    528 {
    529     PIXMAN_COMPOSITE_ARGS (info);
    530     uint32_t  src, srca, s;
    531     uint16_t  src16;
    532     uint16_t *dst_line, *dst;
    533     uint32_t  d;
    534     uint32_t *mask_line, *mask, ma;
    535     int dst_stride, mask_stride;
    536     int32_t w;
    537 
    538     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    539 
    540     srca = src >> 24;
    541     if (src == 0)
    542 	return;
    543 
    544     src16 = convert_8888_to_0565 (src);
    545 
    546     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
    547     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
    548 
    549     while (height--)
    550     {
    551 	dst = dst_line;
    552 	dst_line += dst_stride;
    553 	mask = mask_line;
    554 	mask_line += mask_stride;
    555 	w = width;
    556 
    557 	while (w--)
    558 	{
    559 	    ma = *mask++;
    560 	    if (ma == 0xffffffff)
    561 	    {
    562 		if (srca == 0xff)
    563 		{
    564 		    *dst = src16;
    565 		}
    566 		else
    567 		{
    568 		    d = *dst;
    569 		    d = over (src, convert_0565_to_0888 (d));
    570 		    *dst = convert_8888_to_0565 (d);
    571 		}
    572 	    }
    573 	    else if (ma)
    574 	    {
    575 		d = *dst;
    576 		d = convert_0565_to_0888 (d);
    577 
    578 		s = src;
    579 
    580 		UN8x4_MUL_UN8x4 (s, ma);
    581 		UN8x4_MUL_UN8 (ma, srca);
    582 		ma = ~ma;
    583 		UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ma, s);
    584 
    585 		*dst = convert_8888_to_0565 (d);
    586 	    }
    587 	    dst++;
    588 	}
    589     }
    590 }
    591 
    592 static void
    593 fast_composite_over_8888_8888 (pixman_implementation_t *imp,
    594                                pixman_composite_info_t *info)
    595 {
    596     PIXMAN_COMPOSITE_ARGS (info);
    597     uint32_t    *dst_line, *dst;
    598     uint32_t    *src_line, *src, s;
    599     int dst_stride, src_stride;
    600     uint8_t a;
    601     int32_t w;
    602 
    603     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
    604     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
    605 
    606     while (height--)
    607     {
    608 	dst = dst_line;
    609 	dst_line += dst_stride;
    610 	src = src_line;
    611 	src_line += src_stride;
    612 	w = width;
    613 
    614 	while (w--)
    615 	{
    616 	    s = *src++;
    617 	    a = s >> 24;
    618 	    if (a == 0xff)
    619 		*dst = s;
    620 	    else if (s)
    621 		*dst = over (s, *dst);
    622 	    dst++;
    623 	}
    624     }
    625 }
    626 
    627 static void
    628 fast_composite_src_x888_8888 (pixman_implementation_t *imp,
    629 			      pixman_composite_info_t *info)
    630 {
    631     PIXMAN_COMPOSITE_ARGS (info);
    632     uint32_t    *dst_line, *dst;
    633     uint32_t    *src_line, *src;
    634     int dst_stride, src_stride;
    635     int32_t w;
    636 
    637     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
    638     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
    639 
    640     while (height--)
    641     {
    642 	dst = dst_line;
    643 	dst_line += dst_stride;
    644 	src = src_line;
    645 	src_line += src_stride;
    646 	w = width;
    647 
    648 	while (w--)
    649 	    *dst++ = (*src++) | 0xff000000;
    650     }
    651 }
    652 
    653 #if 0
    654 static void
    655 fast_composite_over_8888_0888 (pixman_implementation_t *imp,
    656 			       pixman_composite_info_t *info)
    657 {
    658     PIXMAN_COMPOSITE_ARGS (info);
    659     uint8_t     *dst_line, *dst;
    660     uint32_t d;
    661     uint32_t    *src_line, *src, s;
    662     uint8_t a;
    663     int dst_stride, src_stride;
    664     int32_t w;
    665 
    666     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 3);
    667     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
    668 
    669     while (height--)
    670     {
    671 	dst = dst_line;
    672 	dst_line += dst_stride;
    673 	src = src_line;
    674 	src_line += src_stride;
    675 	w = width;
    676 
    677 	while (w--)
    678 	{
    679 	    s = *src++;
    680 	    a = s >> 24;
    681 	    if (a)
    682 	    {
    683 		if (a == 0xff)
    684 		    d = s;
    685 		else
    686 		    d = over (s, fetch_24 (dst));
    687 
    688 		store_24 (dst, d);
    689 	    }
    690 	    dst += 3;
    691 	}
    692     }
    693 }
    694 #endif
    695 
    696 static void
    697 fast_composite_over_8888_0565 (pixman_implementation_t *imp,
    698                                pixman_composite_info_t *info)
    699 {
    700     PIXMAN_COMPOSITE_ARGS (info);
    701     uint16_t    *dst_line, *dst;
    702     uint32_t d;
    703     uint32_t    *src_line, *src, s;
    704     uint8_t a;
    705     int dst_stride, src_stride;
    706     int32_t w;
    707 
    708     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
    709     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
    710 
    711     while (height--)
    712     {
    713 	dst = dst_line;
    714 	dst_line += dst_stride;
    715 	src = src_line;
    716 	src_line += src_stride;
    717 	w = width;
    718 
    719 	while (w--)
    720 	{
    721 	    s = *src++;
    722 	    a = s >> 24;
    723 	    if (s)
    724 	    {
    725 		if (a == 0xff)
    726 		{
    727 		    d = s;
    728 		}
    729 		else
    730 		{
    731 		    d = *dst;
    732 		    d = over (s, convert_0565_to_0888 (d));
    733 		}
    734 		*dst = convert_8888_to_0565 (d);
    735 	    }
    736 	    dst++;
    737 	}
    738     }
    739 }
    740 
    741 static void
    742 fast_composite_add_8_8 (pixman_implementation_t *imp,
    743 			pixman_composite_info_t *info)
    744 {
    745     PIXMAN_COMPOSITE_ARGS (info);
    746     uint8_t     *dst_line, *dst;
    747     uint8_t     *src_line, *src;
    748     int dst_stride, src_stride;
    749     int32_t w;
    750     uint8_t s, d;
    751     uint16_t t;
    752 
    753     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
    754     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
    755 
    756     while (height--)
    757     {
    758 	dst = dst_line;
    759 	dst_line += dst_stride;
    760 	src = src_line;
    761 	src_line += src_stride;
    762 	w = width;
    763 
    764 	while (w--)
    765 	{
    766 	    s = *src++;
    767 	    if (s)
    768 	    {
    769 		if (s != 0xff)
    770 		{
    771 		    d = *dst;
    772 		    t = d + s;
    773 		    s = t | (0 - (t >> 8));
    774 		}
    775 		*dst = s;
    776 	    }
    777 	    dst++;
    778 	}
    779     }
    780 }
    781 
    782 static void
    783 fast_composite_add_0565_0565 (pixman_implementation_t *imp,
    784                               pixman_composite_info_t *info)
    785 {
    786     PIXMAN_COMPOSITE_ARGS (info);
    787     uint16_t    *dst_line, *dst;
    788     uint32_t	d;
    789     uint16_t    *src_line, *src;
    790     uint32_t	s;
    791     int dst_stride, src_stride;
    792     int32_t w;
    793 
    794     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint16_t, src_stride, src_line, 1);
    795     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
    796 
    797     while (height--)
    798     {
    799 	dst = dst_line;
    800 	dst_line += dst_stride;
    801 	src = src_line;
    802 	src_line += src_stride;
    803 	w = width;
    804 
    805 	while (w--)
    806 	{
    807 	    s = *src++;
    808 	    if (s)
    809 	    {
    810 		d = *dst;
    811 		s = convert_0565_to_8888 (s);
    812 		if (d)
    813 		{
    814 		    d = convert_0565_to_8888 (d);
    815 		    UN8x4_ADD_UN8x4 (s, d);
    816 		}
    817 		*dst = convert_8888_to_0565 (s);
    818 	    }
    819 	    dst++;
    820 	}
    821     }
    822 }
    823 
    824 static void
    825 fast_composite_add_8888_8888 (pixman_implementation_t *imp,
    826                               pixman_composite_info_t *info)
    827 {
    828     PIXMAN_COMPOSITE_ARGS (info);
    829     uint32_t    *dst_line, *dst;
    830     uint32_t    *src_line, *src;
    831     int dst_stride, src_stride;
    832     int32_t w;
    833     uint32_t s, d;
    834 
    835     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
    836     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
    837 
    838     while (height--)
    839     {
    840 	dst = dst_line;
    841 	dst_line += dst_stride;
    842 	src = src_line;
    843 	src_line += src_stride;
    844 	w = width;
    845 
    846 	while (w--)
    847 	{
    848 	    s = *src++;
    849 	    if (s)
    850 	    {
    851 		if (s != 0xffffffff)
    852 		{
    853 		    d = *dst;
    854 		    if (d)
    855 			UN8x4_ADD_UN8x4 (s, d);
    856 		}
    857 		*dst = s;
    858 	    }
    859 	    dst++;
    860 	}
    861     }
    862 }
    863 
    864 static void
    865 fast_composite_add_n_8_8 (pixman_implementation_t *imp,
    866 			  pixman_composite_info_t *info)
    867 {
    868     PIXMAN_COMPOSITE_ARGS (info);
    869     uint8_t     *dst_line, *dst;
    870     uint8_t     *mask_line, *mask;
    871     int dst_stride, mask_stride;
    872     int32_t w;
    873     uint32_t src;
    874     uint8_t sa;
    875 
    876     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
    877     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
    878     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    879     sa = (src >> 24);
    880 
    881     while (height--)
    882     {
    883 	dst = dst_line;
    884 	dst_line += dst_stride;
    885 	mask = mask_line;
    886 	mask_line += mask_stride;
    887 	w = width;
    888 
    889 	while (w--)
    890 	{
    891 	    uint16_t tmp;
    892 	    uint16_t a;
    893 	    uint32_t m, d;
    894 	    uint32_t r;
    895 
    896 	    a = *mask++;
    897 	    d = *dst;
    898 
    899 	    m = MUL_UN8 (sa, a, tmp);
    900 	    r = ADD_UN8 (m, d, tmp);
    901 
    902 	    *dst++ = r;
    903 	}
    904     }
    905 }
    906 
    907 #ifdef WORDS_BIGENDIAN
    908 #define CREATE_BITMASK(n) (0x80000000 >> (n))
    909 #define UPDATE_BITMASK(n) ((n) >> 1)
    910 #else
    911 #define CREATE_BITMASK(n) (1U << (n))
    912 #define UPDATE_BITMASK(n) ((n) << 1)
    913 #endif
    914 
    915 #define TEST_BIT(p, n)					\
    916     (*((p) + ((n) >> 5)) & CREATE_BITMASK ((n) & 31))
    917 #define SET_BIT(p, n)							\
    918     do { *((p) + ((n) >> 5)) |= CREATE_BITMASK ((n) & 31); } while (0);
    919 
    920 static void
    921 fast_composite_add_1_1 (pixman_implementation_t *imp,
    922 			pixman_composite_info_t *info)
    923 {
    924     PIXMAN_COMPOSITE_ARGS (info);
    925     uint32_t     *dst_line, *dst;
    926     uint32_t     *src_line, *src;
    927     int           dst_stride, src_stride;
    928     int32_t       w;
    929 
    930     PIXMAN_IMAGE_GET_LINE (src_image, 0, src_y, uint32_t,
    931                            src_stride, src_line, 1);
    932     PIXMAN_IMAGE_GET_LINE (dest_image, 0, dest_y, uint32_t,
    933                            dst_stride, dst_line, 1);
    934 
    935     while (height--)
    936     {
    937 	dst = dst_line;
    938 	dst_line += dst_stride;
    939 	src = src_line;
    940 	src_line += src_stride;
    941 	w = width;
    942 
    943 	while (w--)
    944 	{
    945 	    /*
    946 	     * TODO: improve performance by processing uint32_t data instead
    947 	     *       of individual bits
    948 	     */
    949 	    if (TEST_BIT (src, src_x + w))
    950 		SET_BIT (dst, dest_x + w);
    951 	}
    952     }
    953 }
    954 
    955 static void
    956 fast_composite_over_n_1_8888 (pixman_implementation_t *imp,
    957                               pixman_composite_info_t *info)
    958 {
    959     PIXMAN_COMPOSITE_ARGS (info);
    960     uint32_t     src, srca;
    961     uint32_t    *dst, *dst_line;
    962     uint32_t    *mask, *mask_line;
    963     int          mask_stride, dst_stride;
    964     uint32_t     bitcache, bitmask;
    965     int32_t      w;
    966 
    967     if (width <= 0)
    968 	return;
    969 
    970     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
    971     srca = src >> 24;
    972     if (src == 0)
    973 	return;
    974 
    975     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t,
    976                            dst_stride, dst_line, 1);
    977     PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t,
    978                            mask_stride, mask_line, 1);
    979     mask_line += mask_x >> 5;
    980 
    981     if (srca == 0xff)
    982     {
    983 	while (height--)
    984 	{
    985 	    dst = dst_line;
    986 	    dst_line += dst_stride;
    987 	    mask = mask_line;
    988 	    mask_line += mask_stride;
    989 	    w = width;
    990 
    991 	    bitcache = *mask++;
    992 	    bitmask = CREATE_BITMASK (mask_x & 31);
    993 
    994 	    while (w--)
    995 	    {
    996 		if (bitmask == 0)
    997 		{
    998 		    bitcache = *mask++;
    999 		    bitmask = CREATE_BITMASK (0);
   1000 		}
   1001 		if (bitcache & bitmask)
   1002 		    *dst = src;
   1003 		bitmask = UPDATE_BITMASK (bitmask);
   1004 		dst++;
   1005 	    }
   1006 	}
   1007     }
   1008     else
   1009     {
   1010 	while (height--)
   1011 	{
   1012 	    dst = dst_line;
   1013 	    dst_line += dst_stride;
   1014 	    mask = mask_line;
   1015 	    mask_line += mask_stride;
   1016 	    w = width;
   1017 
   1018 	    bitcache = *mask++;
   1019 	    bitmask = CREATE_BITMASK (mask_x & 31);
   1020 
   1021 	    while (w--)
   1022 	    {
   1023 		if (bitmask == 0)
   1024 		{
   1025 		    bitcache = *mask++;
   1026 		    bitmask = CREATE_BITMASK (0);
   1027 		}
   1028 		if (bitcache & bitmask)
   1029 		    *dst = over (src, *dst);
   1030 		bitmask = UPDATE_BITMASK (bitmask);
   1031 		dst++;
   1032 	    }
   1033 	}
   1034     }
   1035 }
   1036 
   1037 static void
   1038 fast_composite_over_n_1_0565 (pixman_implementation_t *imp,
   1039                               pixman_composite_info_t *info)
   1040 {
   1041     PIXMAN_COMPOSITE_ARGS (info);
   1042     uint32_t     src, srca;
   1043     uint16_t    *dst, *dst_line;
   1044     uint32_t    *mask, *mask_line;
   1045     int          mask_stride, dst_stride;
   1046     uint32_t     bitcache, bitmask;
   1047     int32_t      w;
   1048     uint32_t     d;
   1049     uint16_t     src565;
   1050 
   1051     if (width <= 0)
   1052 	return;
   1053 
   1054     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
   1055     srca = src >> 24;
   1056     if (src == 0)
   1057 	return;
   1058 
   1059     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t,
   1060                            dst_stride, dst_line, 1);
   1061     PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t,
   1062                            mask_stride, mask_line, 1);
   1063     mask_line += mask_x >> 5;
   1064 
   1065     if (srca == 0xff)
   1066     {
   1067 	src565 = convert_8888_to_0565 (src);
   1068 	while (height--)
   1069 	{
   1070 	    dst = dst_line;
   1071 	    dst_line += dst_stride;
   1072 	    mask = mask_line;
   1073 	    mask_line += mask_stride;
   1074 	    w = width;
   1075 
   1076 	    bitcache = *mask++;
   1077 	    bitmask = CREATE_BITMASK (mask_x & 31);
   1078 
   1079 	    while (w--)
   1080 	    {
   1081 		if (bitmask == 0)
   1082 		{
   1083 		    bitcache = *mask++;
   1084 		    bitmask = CREATE_BITMASK (0);
   1085 		}
   1086 		if (bitcache & bitmask)
   1087 		    *dst = src565;
   1088 		bitmask = UPDATE_BITMASK (bitmask);
   1089 		dst++;
   1090 	    }
   1091 	}
   1092     }
   1093     else
   1094     {
   1095 	while (height--)
   1096 	{
   1097 	    dst = dst_line;
   1098 	    dst_line += dst_stride;
   1099 	    mask = mask_line;
   1100 	    mask_line += mask_stride;
   1101 	    w = width;
   1102 
   1103 	    bitcache = *mask++;
   1104 	    bitmask = CREATE_BITMASK (mask_x & 31);
   1105 
   1106 	    while (w--)
   1107 	    {
   1108 		if (bitmask == 0)
   1109 		{
   1110 		    bitcache = *mask++;
   1111 		    bitmask = CREATE_BITMASK (0);
   1112 		}
   1113 		if (bitcache & bitmask)
   1114 		{
   1115 		    d = over (src, convert_0565_to_0888 (*dst));
   1116 		    *dst = convert_8888_to_0565 (d);
   1117 		}
   1118 		bitmask = UPDATE_BITMASK (bitmask);
   1119 		dst++;
   1120 	    }
   1121 	}
   1122     }
   1123 }
   1124 
   1125 /*
   1126  * Simple bitblt
   1127  */
   1128 
   1129 static void
   1130 fast_composite_solid_fill (pixman_implementation_t *imp,
   1131                            pixman_composite_info_t *info)
   1132 {
   1133     PIXMAN_COMPOSITE_ARGS (info);
   1134     uint32_t src;
   1135 
   1136     src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
   1137 
   1138     if (dest_image->bits.format == PIXMAN_a1)
   1139     {
   1140 	src = src >> 31;
   1141     }
   1142     else if (dest_image->bits.format == PIXMAN_a8)
   1143     {
   1144 	src = src >> 24;
   1145     }
   1146     else if (dest_image->bits.format == PIXMAN_r5g6b5 ||
   1147              dest_image->bits.format == PIXMAN_b5g6r5)
   1148     {
   1149 	src = convert_8888_to_0565 (src);
   1150     }
   1151 
   1152     pixman_fill (dest_image->bits.bits, dest_image->bits.rowstride,
   1153                  PIXMAN_FORMAT_BPP (dest_image->bits.format),
   1154                  dest_x, dest_y,
   1155                  width, height,
   1156                  src);
   1157 }
   1158 
   1159 static void
   1160 fast_composite_src_memcpy (pixman_implementation_t *imp,
   1161 			   pixman_composite_info_t *info)
   1162 {
   1163     PIXMAN_COMPOSITE_ARGS (info);
   1164     int bpp = PIXMAN_FORMAT_BPP (dest_image->bits.format) / 8;
   1165     uint32_t n_bytes = width * bpp;
   1166     int dst_stride, src_stride;
   1167     uint8_t    *dst;
   1168     uint8_t    *src;
   1169 
   1170     src_stride = src_image->bits.rowstride * 4;
   1171     dst_stride = dest_image->bits.rowstride * 4;
   1172 
   1173     src = (uint8_t *)src_image->bits.bits + src_y * src_stride + src_x * bpp;
   1174     dst = (uint8_t *)dest_image->bits.bits + dest_y * dst_stride + dest_x * bpp;
   1175 
   1176     while (height--)
   1177     {
   1178 	memcpy (dst, src, n_bytes);
   1179 
   1180 	dst += dst_stride;
   1181 	src += src_stride;
   1182     }
   1183 }
   1184 
   1185 FAST_NEAREST (8888_8888_cover, 8888, 8888, uint32_t, uint32_t, SRC, COVER)
   1186 FAST_NEAREST (8888_8888_none, 8888, 8888, uint32_t, uint32_t, SRC, NONE)
   1187 FAST_NEAREST (8888_8888_pad, 8888, 8888, uint32_t, uint32_t, SRC, PAD)
   1188 FAST_NEAREST (8888_8888_normal, 8888, 8888, uint32_t, uint32_t, SRC, NORMAL)
   1189 FAST_NEAREST (x888_8888_cover, x888, 8888, uint32_t, uint32_t, SRC, COVER)
   1190 FAST_NEAREST (x888_8888_pad, x888, 8888, uint32_t, uint32_t, SRC, PAD)
   1191 FAST_NEAREST (x888_8888_normal, x888, 8888, uint32_t, uint32_t, SRC, NORMAL)
   1192 FAST_NEAREST (8888_8888_cover, 8888, 8888, uint32_t, uint32_t, OVER, COVER)
   1193 FAST_NEAREST (8888_8888_none, 8888, 8888, uint32_t, uint32_t, OVER, NONE)
   1194 FAST_NEAREST (8888_8888_pad, 8888, 8888, uint32_t, uint32_t, OVER, PAD)
   1195 FAST_NEAREST (8888_8888_normal, 8888, 8888, uint32_t, uint32_t, OVER, NORMAL)
   1196 FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, SRC, COVER)
   1197 FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, SRC, NONE)
   1198 FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, SRC, PAD)
   1199 FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, SRC, NORMAL)
   1200 FAST_NEAREST (565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL)
   1201 FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, OVER, COVER)
   1202 FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, OVER, NONE)
   1203 FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, OVER, PAD)
   1204 FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, OVER, NORMAL)
   1205 
   1206 #define REPEAT_MIN_WIDTH    32
   1207 
   1208 static void
   1209 fast_composite_tiled_repeat (pixman_implementation_t *imp,
   1210 			     pixman_composite_info_t *info)
   1211 {
   1212     PIXMAN_COMPOSITE_ARGS (info);
   1213     pixman_composite_func_t func;
   1214     pixman_format_code_t mask_format;
   1215     uint32_t src_flags, mask_flags;
   1216     int32_t sx, sy;
   1217     int32_t width_remain;
   1218     int32_t num_pixels;
   1219     int32_t src_width;
   1220     int32_t i, j;
   1221     pixman_image_t extended_src_image;
   1222     uint32_t extended_src[REPEAT_MIN_WIDTH * 2];
   1223     pixman_bool_t need_src_extension;
   1224     uint32_t *src_line;
   1225     int32_t src_stride;
   1226     int32_t src_bpp;
   1227     pixman_composite_info_t info2 = *info;
   1228 
   1229     src_flags = (info->src_flags & ~FAST_PATH_NORMAL_REPEAT) |
   1230 		    FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
   1231 
   1232     if (mask_image)
   1233     {
   1234 	mask_format = mask_image->common.extended_format_code;
   1235 	mask_flags = info->mask_flags;
   1236     }
   1237     else
   1238     {
   1239 	mask_format = PIXMAN_null;
   1240 	mask_flags = FAST_PATH_IS_OPAQUE;
   1241     }
   1242 
   1243     _pixman_implementation_lookup_composite (
   1244 	imp->toplevel, info->op,
   1245 	src_image->common.extended_format_code, src_flags,
   1246 	mask_format, mask_flags,
   1247 	dest_image->common.extended_format_code, info->dest_flags,
   1248 	&imp, &func);
   1249 
   1250     src_bpp = PIXMAN_FORMAT_BPP (src_image->bits.format);
   1251 
   1252     if (src_image->bits.width < REPEAT_MIN_WIDTH		&&
   1253 	(src_bpp == 32 || src_bpp == 16 || src_bpp == 8)	&&
   1254 	!src_image->bits.indexed)
   1255     {
   1256 	sx = src_x;
   1257 	sx = MOD (sx, src_image->bits.width);
   1258 	sx += width;
   1259 	src_width = 0;
   1260 
   1261 	while (src_width < REPEAT_MIN_WIDTH && src_width <= sx)
   1262 	    src_width += src_image->bits.width;
   1263 
   1264 	src_stride = (src_width * (src_bpp >> 3) + 3) / (int) sizeof (uint32_t);
   1265 
   1266 	/* Initialize/validate stack-allocated temporary image */
   1267 	_pixman_bits_image_init (&extended_src_image, src_image->bits.format,
   1268 				 src_width, 1, &extended_src[0], src_stride,
   1269 				 FALSE);
   1270 	_pixman_image_validate (&extended_src_image);
   1271 
   1272 	info2.src_image = &extended_src_image;
   1273 	need_src_extension = TRUE;
   1274     }
   1275     else
   1276     {
   1277 	src_width = src_image->bits.width;
   1278 	need_src_extension = FALSE;
   1279     }
   1280 
   1281     sx = src_x;
   1282     sy = src_y;
   1283 
   1284     while (--height >= 0)
   1285     {
   1286 	sx = MOD (sx, src_width);
   1287 	sy = MOD (sy, src_image->bits.height);
   1288 
   1289 	if (need_src_extension)
   1290 	{
   1291 	    if (src_bpp == 32)
   1292 	    {
   1293 		PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint32_t, src_stride, src_line, 1);
   1294 
   1295 		for (i = 0; i < src_width; )
   1296 		{
   1297 		    for (j = 0; j < src_image->bits.width; j++, i++)
   1298 			extended_src[i] = src_line[j];
   1299 		}
   1300 	    }
   1301 	    else if (src_bpp == 16)
   1302 	    {
   1303 		uint16_t *src_line_16;
   1304 
   1305 		PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint16_t, src_stride,
   1306 				       src_line_16, 1);
   1307 		src_line = (uint32_t*)src_line_16;
   1308 
   1309 		for (i = 0; i < src_width; )
   1310 		{
   1311 		    for (j = 0; j < src_image->bits.width; j++, i++)
   1312 			((uint16_t*)extended_src)[i] = ((uint16_t*)src_line)[j];
   1313 		}
   1314 	    }
   1315 	    else if (src_bpp == 8)
   1316 	    {
   1317 		uint8_t *src_line_8;
   1318 
   1319 		PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint8_t, src_stride,
   1320 				       src_line_8, 1);
   1321 		src_line = (uint32_t*)src_line_8;
   1322 
   1323 		for (i = 0; i < src_width; )
   1324 		{
   1325 		    for (j = 0; j < src_image->bits.width; j++, i++)
   1326 			((uint8_t*)extended_src)[i] = ((uint8_t*)src_line)[j];
   1327 		}
   1328 	    }
   1329 
   1330 	    info2.src_y = 0;
   1331 	}
   1332 	else
   1333 	{
   1334 	    info2.src_y = sy;
   1335 	}
   1336 
   1337 	width_remain = width;
   1338 
   1339 	while (width_remain > 0)
   1340 	{
   1341 	    num_pixels = src_width - sx;
   1342 
   1343 	    if (num_pixels > width_remain)
   1344 		num_pixels = width_remain;
   1345 
   1346 	    info2.src_x = sx;
   1347 	    info2.width = num_pixels;
   1348 	    info2.height = 1;
   1349 
   1350 	    func (imp, &info2);
   1351 
   1352 	    width_remain -= num_pixels;
   1353 	    info2.mask_x += num_pixels;
   1354 	    info2.dest_x += num_pixels;
   1355 	    sx = 0;
   1356 	}
   1357 
   1358 	sx = src_x;
   1359 	sy++;
   1360 	info2.mask_x = info->mask_x;
   1361 	info2.mask_y++;
   1362 	info2.dest_x = info->dest_x;
   1363 	info2.dest_y++;
   1364     }
   1365 
   1366     if (need_src_extension)
   1367 	_pixman_image_fini (&extended_src_image);
   1368 }
   1369 
   1370 /* Use more unrolling for src_0565_0565 because it is typically CPU bound */
   1371 static force_inline void
   1372 scaled_nearest_scanline_565_565_SRC (uint16_t *       dst,
   1373 				     const uint16_t * src,
   1374 				     int32_t          w,
   1375 				     pixman_fixed_t   vx,
   1376 				     pixman_fixed_t   unit_x,
   1377 				     pixman_fixed_t   max_vx,
   1378 				     pixman_bool_t    fully_transparent_src)
   1379 {
   1380     uint16_t tmp1, tmp2, tmp3, tmp4;
   1381     while ((w -= 4) >= 0)
   1382     {
   1383 	tmp1 = *(src + pixman_fixed_to_int (vx));
   1384 	vx += unit_x;
   1385 	tmp2 = *(src + pixman_fixed_to_int (vx));
   1386 	vx += unit_x;
   1387 	tmp3 = *(src + pixman_fixed_to_int (vx));
   1388 	vx += unit_x;
   1389 	tmp4 = *(src + pixman_fixed_to_int (vx));
   1390 	vx += unit_x;
   1391 	*dst++ = tmp1;
   1392 	*dst++ = tmp2;
   1393 	*dst++ = tmp3;
   1394 	*dst++ = tmp4;
   1395     }
   1396     if (w & 2)
   1397     {
   1398 	tmp1 = *(src + pixman_fixed_to_int (vx));
   1399 	vx += unit_x;
   1400 	tmp2 = *(src + pixman_fixed_to_int (vx));
   1401 	vx += unit_x;
   1402 	*dst++ = tmp1;
   1403 	*dst++ = tmp2;
   1404     }
   1405     if (w & 1)
   1406 	*dst = *(src + pixman_fixed_to_int (vx));
   1407 }
   1408 
   1409 FAST_NEAREST_MAINLOOP (565_565_cover_SRC,
   1410 		       scaled_nearest_scanline_565_565_SRC,
   1411 		       uint16_t, uint16_t, COVER)
   1412 FAST_NEAREST_MAINLOOP (565_565_none_SRC,
   1413 		       scaled_nearest_scanline_565_565_SRC,
   1414 		       uint16_t, uint16_t, NONE)
   1415 FAST_NEAREST_MAINLOOP (565_565_pad_SRC,
   1416 		       scaled_nearest_scanline_565_565_SRC,
   1417 		       uint16_t, uint16_t, PAD)
   1418 
   1419 static force_inline uint32_t
   1420 fetch_nearest (pixman_repeat_t src_repeat,
   1421 	       pixman_format_code_t format,
   1422 	       uint32_t *src, int x, int src_width)
   1423 {
   1424     if (repeat (src_repeat, &x, src_width))
   1425     {
   1426 	if (format == PIXMAN_x8r8g8b8 || format == PIXMAN_x8b8g8r8)
   1427 	    return *(src + x) | 0xff000000;
   1428 	else
   1429 	    return *(src + x);
   1430     }
   1431     else
   1432     {
   1433 	return 0;
   1434     }
   1435 }
   1436 
   1437 static force_inline void
   1438 combine_over (uint32_t s, uint32_t *dst)
   1439 {
   1440     if (s)
   1441     {
   1442 	uint8_t ia = 0xff - (s >> 24);
   1443 
   1444 	if (ia)
   1445 	    UN8x4_MUL_UN8_ADD_UN8x4 (*dst, ia, s);
   1446 	else
   1447 	    *dst = s;
   1448     }
   1449 }
   1450 
   1451 static force_inline void
   1452 combine_src (uint32_t s, uint32_t *dst)
   1453 {
   1454     *dst = s;
   1455 }
   1456 
   1457 static void
   1458 fast_composite_scaled_nearest (pixman_implementation_t *imp,
   1459 			       pixman_composite_info_t *info)
   1460 {
   1461     PIXMAN_COMPOSITE_ARGS (info);
   1462     uint32_t       *dst_line;
   1463     uint32_t       *src_line;
   1464     int             dst_stride, src_stride;
   1465     int		    src_width, src_height;
   1466     pixman_repeat_t src_repeat;
   1467     pixman_fixed_t unit_x, unit_y;
   1468     pixman_format_code_t src_format;
   1469     pixman_vector_t v;
   1470     pixman_fixed_t vy;
   1471 
   1472     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
   1473     /* pass in 0 instead of src_x and src_y because src_x and src_y need to be
   1474      * transformed from destination space to source space
   1475      */
   1476     PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, uint32_t, src_stride, src_line, 1);
   1477 
   1478     /* reference point is the center of the pixel */
   1479     v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2;
   1480     v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2;
   1481     v.vector[2] = pixman_fixed_1;
   1482 
   1483     if (!pixman_transform_point_3d (src_image->common.transform, &v))
   1484 	return;
   1485 
   1486     unit_x = src_image->common.transform->matrix[0][0];
   1487     unit_y = src_image->common.transform->matrix[1][1];
   1488 
   1489     /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
   1490     v.vector[0] -= pixman_fixed_e;
   1491     v.vector[1] -= pixman_fixed_e;
   1492 
   1493     src_height = src_image->bits.height;
   1494     src_width = src_image->bits.width;
   1495     src_repeat = src_image->common.repeat;
   1496     src_format = src_image->bits.format;
   1497 
   1498     vy = v.vector[1];
   1499     while (height--)
   1500     {
   1501         pixman_fixed_t vx = v.vector[0];
   1502 	int y = pixman_fixed_to_int (vy);
   1503 	uint32_t *dst = dst_line;
   1504 
   1505 	dst_line += dst_stride;
   1506 
   1507         /* adjust the y location by a unit vector in the y direction
   1508          * this is equivalent to transforming y+1 of the destination point to source space */
   1509         vy += unit_y;
   1510 
   1511 	if (!repeat (src_repeat, &y, src_height))
   1512 	{
   1513 	    if (op == PIXMAN_OP_SRC)
   1514 		memset (dst, 0, sizeof (*dst) * width);
   1515 	}
   1516 	else
   1517 	{
   1518 	    int w = width;
   1519 
   1520 	    uint32_t *src = src_line + y * src_stride;
   1521 
   1522 	    while (w >= 2)
   1523 	    {
   1524 		uint32_t s1, s2;
   1525 		int x1, x2;
   1526 
   1527 		x1 = pixman_fixed_to_int (vx);
   1528 		vx += unit_x;
   1529 
   1530 		x2 = pixman_fixed_to_int (vx);
   1531 		vx += unit_x;
   1532 
   1533 		w -= 2;
   1534 
   1535 		s1 = fetch_nearest (src_repeat, src_format, src, x1, src_width);
   1536 		s2 = fetch_nearest (src_repeat, src_format, src, x2, src_width);
   1537 
   1538 		if (op == PIXMAN_OP_OVER)
   1539 		{
   1540 		    combine_over (s1, dst++);
   1541 		    combine_over (s2, dst++);
   1542 		}
   1543 		else
   1544 		{
   1545 		    combine_src (s1, dst++);
   1546 		    combine_src (s2, dst++);
   1547 		}
   1548 	    }
   1549 
   1550 	    while (w--)
   1551 	    {
   1552 		uint32_t s;
   1553 		int x;
   1554 
   1555 		x = pixman_fixed_to_int (vx);
   1556 		vx += unit_x;
   1557 
   1558 		s = fetch_nearest (src_repeat, src_format, src, x, src_width);
   1559 
   1560 		if (op == PIXMAN_OP_OVER)
   1561 		    combine_over (s, dst++);
   1562 		else
   1563 		    combine_src (s, dst++);
   1564 	    }
   1565 	}
   1566     }
   1567 }
   1568 
   1569 #define CACHE_LINE_SIZE 64
   1570 
   1571 #define FAST_SIMPLE_ROTATE(suffix, pix_type)                                  \
   1572                                                                               \
   1573 static void                                                                   \
   1574 blt_rotated_90_trivial_##suffix (pix_type       *dst,                         \
   1575 				 int             dst_stride,                  \
   1576 				 const pix_type *src,                         \
   1577 				 int             src_stride,                  \
   1578 				 int             w,                           \
   1579 				 int             h)                           \
   1580 {                                                                             \
   1581     int x, y;                                                                 \
   1582     for (y = 0; y < h; y++)                                                   \
   1583     {                                                                         \
   1584 	const pix_type *s = src + (h - y - 1);                                \
   1585 	pix_type *d = dst + dst_stride * y;                                   \
   1586 	for (x = 0; x < w; x++)                                               \
   1587 	{                                                                     \
   1588 	    *d++ = *s;                                                        \
   1589 	    s += src_stride;                                                  \
   1590 	}                                                                     \
   1591     }                                                                         \
   1592 }                                                                             \
   1593                                                                               \
   1594 static void                                                                   \
   1595 blt_rotated_270_trivial_##suffix (pix_type       *dst,                        \
   1596 				  int             dst_stride,                 \
   1597 				  const pix_type *src,                        \
   1598 				  int             src_stride,                 \
   1599 				  int             w,                          \
   1600 				  int             h)                          \
   1601 {                                                                             \
   1602     int x, y;                                                                 \
   1603     for (y = 0; y < h; y++)                                                   \
   1604     {                                                                         \
   1605 	const pix_type *s = src + src_stride * (w - 1) + y;                   \
   1606 	pix_type *d = dst + dst_stride * y;                                   \
   1607 	for (x = 0; x < w; x++)                                               \
   1608 	{                                                                     \
   1609 	    *d++ = *s;                                                        \
   1610 	    s -= src_stride;                                                  \
   1611 	}                                                                     \
   1612     }                                                                         \
   1613 }                                                                             \
   1614                                                                               \
   1615 static void                                                                   \
   1616 blt_rotated_90_##suffix (pix_type       *dst,                                 \
   1617 			 int             dst_stride,                          \
   1618 			 const pix_type *src,                                 \
   1619 			 int             src_stride,                          \
   1620 			 int             W,                                   \
   1621 			 int             H)                                   \
   1622 {                                                                             \
   1623     int x;                                                                    \
   1624     int leading_pixels = 0, trailing_pixels = 0;                              \
   1625     const int TILE_SIZE = CACHE_LINE_SIZE / sizeof(pix_type);                 \
   1626                                                                               \
   1627     /*                                                                        \
   1628      * split processing into handling destination as TILE_SIZExH cache line   \
   1629      * aligned vertical stripes (optimistically assuming that destination     \
   1630      * stride is a multiple of cache line, if not - it will be just a bit     \
   1631      * slower)                                                                \
   1632      */                                                                       \
   1633                                                                               \
   1634     if ((uintptr_t)dst & (CACHE_LINE_SIZE - 1))                               \
   1635     {                                                                         \
   1636 	leading_pixels = TILE_SIZE - (((uintptr_t)dst &                       \
   1637 			    (CACHE_LINE_SIZE - 1)) / sizeof(pix_type));       \
   1638 	if (leading_pixels > W)                                               \
   1639 	    leading_pixels = W;                                               \
   1640                                                                               \
   1641 	/* unaligned leading part NxH (where N < TILE_SIZE) */                \
   1642 	blt_rotated_90_trivial_##suffix (                                     \
   1643 	    dst,                                                              \
   1644 	    dst_stride,                                                       \
   1645 	    src,                                                              \
   1646 	    src_stride,                                                       \
   1647 	    leading_pixels,                                                   \
   1648 	    H);                                                               \
   1649 	                                                                      \
   1650 	dst += leading_pixels;                                                \
   1651 	src += leading_pixels * src_stride;                                   \
   1652 	W -= leading_pixels;                                                  \
   1653     }                                                                         \
   1654                                                                               \
   1655     if ((uintptr_t)(dst + W) & (CACHE_LINE_SIZE - 1))                         \
   1656     {                                                                         \
   1657 	trailing_pixels = (((uintptr_t)(dst + W) &                            \
   1658 			    (CACHE_LINE_SIZE - 1)) / sizeof(pix_type));       \
   1659 	if (trailing_pixels > W)                                              \
   1660 	    trailing_pixels = W;                                              \
   1661 	W -= trailing_pixels;                                                 \
   1662     }                                                                         \
   1663                                                                               \
   1664     for (x = 0; x < W; x += TILE_SIZE)                                        \
   1665     {                                                                         \
   1666 	/* aligned middle part TILE_SIZExH */                                 \
   1667 	blt_rotated_90_trivial_##suffix (                                     \
   1668 	    dst + x,                                                          \
   1669 	    dst_stride,                                                       \
   1670 	    src + src_stride * x,                                             \
   1671 	    src_stride,                                                       \
   1672 	    TILE_SIZE,                                                        \
   1673 	    H);                                                               \
   1674     }                                                                         \
   1675                                                                               \
   1676     if (trailing_pixels)                                                      \
   1677     {                                                                         \
   1678 	/* unaligned trailing part NxH (where N < TILE_SIZE) */               \
   1679 	blt_rotated_90_trivial_##suffix (                                     \
   1680 	    dst + W,                                                          \
   1681 	    dst_stride,                                                       \
   1682 	    src + W * src_stride,                                             \
   1683 	    src_stride,                                                       \
   1684 	    trailing_pixels,                                                  \
   1685 	    H);                                                               \
   1686     }                                                                         \
   1687 }                                                                             \
   1688                                                                               \
   1689 static void                                                                   \
   1690 blt_rotated_270_##suffix (pix_type       *dst,                                \
   1691 			  int             dst_stride,                         \
   1692 			  const pix_type *src,                                \
   1693 			  int             src_stride,                         \
   1694 			  int             W,                                  \
   1695 			  int             H)                                  \
   1696 {                                                                             \
   1697     int x;                                                                    \
   1698     int leading_pixels = 0, trailing_pixels = 0;                              \
   1699     const int TILE_SIZE = CACHE_LINE_SIZE / sizeof(pix_type);                 \
   1700                                                                               \
   1701     /*                                                                        \
   1702      * split processing into handling destination as TILE_SIZExH cache line   \
   1703      * aligned vertical stripes (optimistically assuming that destination     \
   1704      * stride is a multiple of cache line, if not - it will be just a bit     \
   1705      * slower)                                                                \
   1706      */                                                                       \
   1707                                                                               \
   1708     if ((uintptr_t)dst & (CACHE_LINE_SIZE - 1))                               \
   1709     {                                                                         \
   1710 	leading_pixels = TILE_SIZE - (((uintptr_t)dst &                       \
   1711 			    (CACHE_LINE_SIZE - 1)) / sizeof(pix_type));       \
   1712 	if (leading_pixels > W)                                               \
   1713 	    leading_pixels = W;                                               \
   1714                                                                               \
   1715 	/* unaligned leading part NxH (where N < TILE_SIZE) */                \
   1716 	blt_rotated_270_trivial_##suffix (                                    \
   1717 	    dst,                                                              \
   1718 	    dst_stride,                                                       \
   1719 	    src + src_stride * (W - leading_pixels),                          \
   1720 	    src_stride,                                                       \
   1721 	    leading_pixels,                                                   \
   1722 	    H);                                                               \
   1723 	                                                                      \
   1724 	dst += leading_pixels;                                                \
   1725 	W -= leading_pixels;                                                  \
   1726     }                                                                         \
   1727                                                                               \
   1728     if ((uintptr_t)(dst + W) & (CACHE_LINE_SIZE - 1))                         \
   1729     {                                                                         \
   1730 	trailing_pixels = (((uintptr_t)(dst + W) &                            \
   1731 			    (CACHE_LINE_SIZE - 1)) / sizeof(pix_type));       \
   1732 	if (trailing_pixels > W)                                              \
   1733 	    trailing_pixels = W;                                              \
   1734 	W -= trailing_pixels;                                                 \
   1735 	src += trailing_pixels * src_stride;                                  \
   1736     }                                                                         \
   1737                                                                               \
   1738     for (x = 0; x < W; x += TILE_SIZE)                                        \
   1739     {                                                                         \
   1740 	/* aligned middle part TILE_SIZExH */                                 \
   1741 	blt_rotated_270_trivial_##suffix (                                    \
   1742 	    dst + x,                                                          \
   1743 	    dst_stride,                                                       \
   1744 	    src + src_stride * (W - x - TILE_SIZE),                           \
   1745 	    src_stride,                                                       \
   1746 	    TILE_SIZE,                                                        \
   1747 	    H);                                                               \
   1748     }                                                                         \
   1749                                                                               \
   1750     if (trailing_pixels)                                                      \
   1751     {                                                                         \
   1752 	/* unaligned trailing part NxH (where N < TILE_SIZE) */               \
   1753 	blt_rotated_270_trivial_##suffix (                                    \
   1754 	    dst + W,                                                          \
   1755 	    dst_stride,                                                       \
   1756 	    src - trailing_pixels * src_stride,                               \
   1757 	    src_stride,                                                       \
   1758 	    trailing_pixels,                                                  \
   1759 	    H);                                                               \
   1760     }                                                                         \
   1761 }                                                                             \
   1762                                                                               \
   1763 static void                                                                   \
   1764 fast_composite_rotate_90_##suffix (pixman_implementation_t *imp,              \
   1765 				   pixman_composite_info_t *info)	      \
   1766 {									      \
   1767     PIXMAN_COMPOSITE_ARGS (info);					      \
   1768     pix_type       *dst_line;						      \
   1769     pix_type       *src_line;                                                 \
   1770     int             dst_stride, src_stride;                                   \
   1771     int             src_x_t, src_y_t;                                         \
   1772                                                                               \
   1773     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, pix_type,              \
   1774 			   dst_stride, dst_line, 1);                          \
   1775     src_x_t = -src_y + pixman_fixed_to_int (                                  \
   1776 				src_image->common.transform->matrix[0][2] +   \
   1777 				pixman_fixed_1 / 2 - pixman_fixed_e) - height;\
   1778     src_y_t = src_x + pixman_fixed_to_int (                                   \
   1779 				src_image->common.transform->matrix[1][2] +   \
   1780 				pixman_fixed_1 / 2 - pixman_fixed_e);         \
   1781     PIXMAN_IMAGE_GET_LINE (src_image, src_x_t, src_y_t, pix_type,             \
   1782 			   src_stride, src_line, 1);                          \
   1783     blt_rotated_90_##suffix (dst_line, dst_stride, src_line, src_stride,      \
   1784 			     width, height);                                  \
   1785 }                                                                             \
   1786                                                                               \
   1787 static void                                                                   \
   1788 fast_composite_rotate_270_##suffix (pixman_implementation_t *imp,             \
   1789 				    pixman_composite_info_t *info)            \
   1790 {                                                                             \
   1791     PIXMAN_COMPOSITE_ARGS (info);					      \
   1792     pix_type       *dst_line;						      \
   1793     pix_type       *src_line;                                                 \
   1794     int             dst_stride, src_stride;                                   \
   1795     int             src_x_t, src_y_t;                                         \
   1796                                                                               \
   1797     PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, pix_type,              \
   1798 			   dst_stride, dst_line, 1);                          \
   1799     src_x_t = src_y + pixman_fixed_to_int (                                   \
   1800 				src_image->common.transform->matrix[0][2] +   \
   1801 				pixman_fixed_1 / 2 - pixman_fixed_e);         \
   1802     src_y_t = -src_x + pixman_fixed_to_int (                                  \
   1803 				src_image->common.transform->matrix[1][2] +   \
   1804 				pixman_fixed_1 / 2 - pixman_fixed_e) - width; \
   1805     PIXMAN_IMAGE_GET_LINE (src_image, src_x_t, src_y_t, pix_type,             \
   1806 			   src_stride, src_line, 1);                          \
   1807     blt_rotated_270_##suffix (dst_line, dst_stride, src_line, src_stride,     \
   1808 			      width, height);                                 \
   1809 }
   1810 
   1811 FAST_SIMPLE_ROTATE (8, uint8_t)
   1812 FAST_SIMPLE_ROTATE (565, uint16_t)
   1813 FAST_SIMPLE_ROTATE (8888, uint32_t)
   1814 
   1815 static const pixman_fast_path_t c_fast_paths[] =
   1816 {
   1817     PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, fast_composite_over_n_8_0565),
   1818     PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, fast_composite_over_n_8_0565),
   1819     PIXMAN_STD_FAST_PATH (OVER, solid, a8, r8g8b8, fast_composite_over_n_8_0888),
   1820     PIXMAN_STD_FAST_PATH (OVER, solid, a8, b8g8r8, fast_composite_over_n_8_0888),
   1821     PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, fast_composite_over_n_8_8888),
   1822     PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, fast_composite_over_n_8_8888),
   1823     PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, fast_composite_over_n_8_8888),
   1824     PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, fast_composite_over_n_8_8888),
   1825     PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8r8g8b8, fast_composite_over_n_1_8888),
   1826     PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8r8g8b8, fast_composite_over_n_1_8888),
   1827     PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8b8g8r8, fast_composite_over_n_1_8888),
   1828     PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8b8g8r8, fast_composite_over_n_1_8888),
   1829     PIXMAN_STD_FAST_PATH (OVER, solid, a1, r5g6b5,   fast_composite_over_n_1_0565),
   1830     PIXMAN_STD_FAST_PATH (OVER, solid, a1, b5g6r5,   fast_composite_over_n_1_0565),
   1831     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, fast_composite_over_n_8888_8888_ca),
   1832     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, fast_composite_over_n_8888_8888_ca),
   1833     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, fast_composite_over_n_8888_0565_ca),
   1834     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, fast_composite_over_n_8888_8888_ca),
   1835     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, fast_composite_over_n_8888_8888_ca),
   1836     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, fast_composite_over_n_8888_0565_ca),
   1837     PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, fast_composite_over_x888_8_8888),
   1838     PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, fast_composite_over_x888_8_8888),
   1839     PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, fast_composite_over_x888_8_8888),
   1840     PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, fast_composite_over_x888_8_8888),
   1841     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, fast_composite_over_8888_8888),
   1842     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, fast_composite_over_8888_8888),
   1843     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, fast_composite_over_8888_0565),
   1844     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, fast_composite_over_8888_8888),
   1845     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, fast_composite_over_8888_8888),
   1846     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, fast_composite_over_8888_0565),
   1847     PIXMAN_STD_FAST_PATH (ADD, r5g6b5, null, r5g6b5, fast_composite_add_0565_0565),
   1848     PIXMAN_STD_FAST_PATH (ADD, b5g6r5, null, b5g6r5, fast_composite_add_0565_0565),
   1849     PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, fast_composite_add_8888_8888),
   1850     PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, fast_composite_add_8888_8888),
   1851     PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, fast_composite_add_8_8),
   1852     PIXMAN_STD_FAST_PATH (ADD, a1, null, a1, fast_composite_add_1_1),
   1853     PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, fast_composite_add_n_8888_8888_ca),
   1854     PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, fast_composite_add_n_8_8),
   1855     PIXMAN_STD_FAST_PATH (SRC, solid, null, a8r8g8b8, fast_composite_solid_fill),
   1856     PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill),
   1857     PIXMAN_STD_FAST_PATH (SRC, solid, null, a8b8g8r8, fast_composite_solid_fill),
   1858     PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, fast_composite_solid_fill),
   1859     PIXMAN_STD_FAST_PATH (SRC, solid, null, a1, fast_composite_solid_fill),
   1860     PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill),
   1861     PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill),
   1862     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, fast_composite_src_x888_8888),
   1863     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, fast_composite_src_x888_8888),
   1864     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, fast_composite_src_memcpy),
   1865     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, fast_composite_src_memcpy),
   1866     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, fast_composite_src_memcpy),
   1867     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, fast_composite_src_memcpy),
   1868     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, fast_composite_src_memcpy),
   1869     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, fast_composite_src_memcpy),
   1870     PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8x8, fast_composite_src_memcpy),
   1871     PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8a8, fast_composite_src_memcpy),
   1872     PIXMAN_STD_FAST_PATH (SRC, b8g8r8x8, null, b8g8r8x8, fast_composite_src_memcpy),
   1873     PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, fast_composite_src_memcpy),
   1874     PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, fast_composite_src_memcpy),
   1875     PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, fast_composite_src_memcpy),
   1876     PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, b8g8r8, fast_composite_src_memcpy),
   1877     PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, fast_composite_src_memcpy),
   1878     PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, fast_composite_src_memcpy),
   1879     PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, fast_composite_src_memcpy),
   1880     PIXMAN_STD_FAST_PATH (IN, a8, null, a8, fast_composite_in_8_8),
   1881     PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, fast_composite_in_n_8_8),
   1882 
   1883     SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, 8888_8888),
   1884     SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, 8888_8888),
   1885     SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, 8888_8888),
   1886     SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, 8888_8888),
   1887 
   1888     SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, 8888_8888),
   1889     SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, 8888_8888),
   1890 
   1891     SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, 8888_565),
   1892     SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, 8888_565),
   1893 
   1894     SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565),
   1895 
   1896     SIMPLE_NEAREST_FAST_PATH_COVER (SRC, x8r8g8b8, a8r8g8b8, x888_8888),
   1897     SIMPLE_NEAREST_FAST_PATH_COVER (SRC, x8b8g8r8, a8b8g8r8, x888_8888),
   1898     SIMPLE_NEAREST_FAST_PATH_PAD (SRC, x8r8g8b8, a8r8g8b8, x888_8888),
   1899     SIMPLE_NEAREST_FAST_PATH_PAD (SRC, x8b8g8r8, a8b8g8r8, x888_8888),
   1900     SIMPLE_NEAREST_FAST_PATH_NORMAL (SRC, x8r8g8b8, a8r8g8b8, x888_8888),
   1901     SIMPLE_NEAREST_FAST_PATH_NORMAL (SRC, x8b8g8r8, a8b8g8r8, x888_8888),
   1902 
   1903     SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, 8888_8888),
   1904     SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, 8888_8888),
   1905     SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, 8888_8888),
   1906     SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, 8888_8888),
   1907 
   1908     SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, 8888_565),
   1909 
   1910 #define NEAREST_FAST_PATH(op,s,d)		\
   1911     {   PIXMAN_OP_ ## op,			\
   1912 	PIXMAN_ ## s, SCALED_NEAREST_FLAGS,	\
   1913 	PIXMAN_null, 0,				\
   1914 	PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,	\
   1915 	fast_composite_scaled_nearest,		\
   1916     }
   1917 
   1918     NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8),
   1919     NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8),
   1920     NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8),
   1921     NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8),
   1922 
   1923     NEAREST_FAST_PATH (SRC, x8r8g8b8, a8r8g8b8),
   1924     NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8),
   1925     NEAREST_FAST_PATH (SRC, x8b8g8r8, a8b8g8r8),
   1926     NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8),
   1927 
   1928     NEAREST_FAST_PATH (OVER, x8r8g8b8, x8r8g8b8),
   1929     NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8),
   1930     NEAREST_FAST_PATH (OVER, x8b8g8r8, x8b8g8r8),
   1931     NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8),
   1932 
   1933     NEAREST_FAST_PATH (OVER, x8r8g8b8, a8r8g8b8),
   1934     NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8),
   1935     NEAREST_FAST_PATH (OVER, x8b8g8r8, a8b8g8r8),
   1936     NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8),
   1937 
   1938 #define SIMPLE_ROTATE_FLAGS(angle)					  \
   1939     (FAST_PATH_ROTATE_ ## angle ## _TRANSFORM	|			  \
   1940      FAST_PATH_NEAREST_FILTER			|			  \
   1941      FAST_PATH_SAMPLES_COVER_CLIP_NEAREST	|			  \
   1942      FAST_PATH_STANDARD_FLAGS)
   1943 
   1944 #define SIMPLE_ROTATE_FAST_PATH(op,s,d,suffix)				  \
   1945     {   PIXMAN_OP_ ## op,						  \
   1946 	PIXMAN_ ## s, SIMPLE_ROTATE_FLAGS (90),				  \
   1947 	PIXMAN_null, 0,							  \
   1948 	PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,				  \
   1949 	fast_composite_rotate_90_##suffix,				  \
   1950     },									  \
   1951     {   PIXMAN_OP_ ## op,						  \
   1952 	PIXMAN_ ## s, SIMPLE_ROTATE_FLAGS (270),			  \
   1953 	PIXMAN_null, 0,							  \
   1954 	PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,				  \
   1955 	fast_composite_rotate_270_##suffix,				  \
   1956     }
   1957 
   1958     SIMPLE_ROTATE_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, 8888),
   1959     SIMPLE_ROTATE_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, 8888),
   1960     SIMPLE_ROTATE_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, 8888),
   1961     SIMPLE_ROTATE_FAST_PATH (SRC, r5g6b5, r5g6b5, 565),
   1962     SIMPLE_ROTATE_FAST_PATH (SRC, a8, a8, 8),
   1963 
   1964     /* Simple repeat fast path entry. */
   1965     {	PIXMAN_OP_any,
   1966 	PIXMAN_any,
   1967 	(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | FAST_PATH_BITS_IMAGE |
   1968 	 FAST_PATH_NORMAL_REPEAT),
   1969 	PIXMAN_any, 0,
   1970 	PIXMAN_any, FAST_PATH_STD_DEST_FLAGS,
   1971 	fast_composite_tiled_repeat
   1972     },
   1973 
   1974     {   PIXMAN_OP_NONE	},
   1975 };
   1976 
   1977 #ifdef WORDS_BIGENDIAN
   1978 #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n)))
   1979 #else
   1980 #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs))
   1981 #endif
   1982 
   1983 static force_inline void
   1984 pixman_fill1_line (uint32_t *dst, int offs, int width, int v)
   1985 {
   1986     if (offs)
   1987     {
   1988 	int leading_pixels = 32 - offs;
   1989 	if (leading_pixels >= width)
   1990 	{
   1991 	    if (v)
   1992 		*dst |= A1_FILL_MASK (width, offs);
   1993 	    else
   1994 		*dst &= ~A1_FILL_MASK (width, offs);
   1995 	    return;
   1996 	}
   1997 	else
   1998 	{
   1999 	    if (v)
   2000 		*dst++ |= A1_FILL_MASK (leading_pixels, offs);
   2001 	    else
   2002 		*dst++ &= ~A1_FILL_MASK (leading_pixels, offs);
   2003 	    width -= leading_pixels;
   2004 	}
   2005     }
   2006     while (width >= 32)
   2007     {
   2008 	if (v)
   2009 	    *dst++ = 0xFFFFFFFF;
   2010 	else
   2011 	    *dst++ = 0;
   2012 	width -= 32;
   2013     }
   2014     if (width > 0)
   2015     {
   2016 	if (v)
   2017 	    *dst |= A1_FILL_MASK (width, 0);
   2018 	else
   2019 	    *dst &= ~A1_FILL_MASK (width, 0);
   2020     }
   2021 }
   2022 
   2023 static void
   2024 pixman_fill1 (uint32_t *bits,
   2025               int       stride,
   2026               int       x,
   2027               int       y,
   2028               int       width,
   2029               int       height,
   2030               uint32_t  filler)
   2031 {
   2032     uint32_t *dst = bits + y * stride + (x >> 5);
   2033     int offs = x & 31;
   2034 
   2035     if (filler & 1)
   2036     {
   2037 	while (height--)
   2038 	{
   2039 	    pixman_fill1_line (dst, offs, width, 1);
   2040 	    dst += stride;
   2041 	}
   2042     }
   2043     else
   2044     {
   2045 	while (height--)
   2046 	{
   2047 	    pixman_fill1_line (dst, offs, width, 0);
   2048 	    dst += stride;
   2049 	}
   2050     }
   2051 }
   2052 
   2053 static void
   2054 pixman_fill8 (uint32_t *bits,
   2055               int       stride,
   2056               int       x,
   2057               int       y,
   2058               int       width,
   2059               int       height,
   2060               uint32_t  filler)
   2061 {
   2062     int byte_stride = stride * (int) sizeof (uint32_t);
   2063     uint8_t *dst = (uint8_t *) bits;
   2064     uint8_t v = filler & 0xff;
   2065     int i;
   2066 
   2067     dst = dst + y * byte_stride + x;
   2068 
   2069     while (height--)
   2070     {
   2071 	for (i = 0; i < width; ++i)
   2072 	    dst[i] = v;
   2073 
   2074 	dst += byte_stride;
   2075     }
   2076 }
   2077 
   2078 static void
   2079 pixman_fill16 (uint32_t *bits,
   2080                int       stride,
   2081                int       x,
   2082                int       y,
   2083                int       width,
   2084                int       height,
   2085                uint32_t  filler)
   2086 {
   2087     int short_stride =
   2088 	(stride * (int)sizeof (uint32_t)) / (int)sizeof (uint16_t);
   2089     uint16_t *dst = (uint16_t *)bits;
   2090     uint16_t v = filler & 0xffff;
   2091     int i;
   2092 
   2093     dst = dst + y * short_stride + x;
   2094 
   2095     while (height--)
   2096     {
   2097 	for (i = 0; i < width; ++i)
   2098 	    dst[i] = v;
   2099 
   2100 	dst += short_stride;
   2101     }
   2102 }
   2103 
   2104 static void
   2105 pixman_fill32 (uint32_t *bits,
   2106                int       stride,
   2107                int       x,
   2108                int       y,
   2109                int       width,
   2110                int       height,
   2111                uint32_t  filler)
   2112 {
   2113     int i;
   2114 
   2115     bits = bits + y * stride + x;
   2116 
   2117     while (height--)
   2118     {
   2119 	for (i = 0; i < width; ++i)
   2120 	    bits[i] = filler;
   2121 
   2122 	bits += stride;
   2123     }
   2124 }
   2125 
   2126 static pixman_bool_t
   2127 fast_path_fill (pixman_implementation_t *imp,
   2128                 uint32_t *               bits,
   2129                 int                      stride,
   2130                 int                      bpp,
   2131                 int                      x,
   2132                 int                      y,
   2133                 int                      width,
   2134                 int                      height,
   2135                 uint32_t		 filler)
   2136 {
   2137     switch (bpp)
   2138     {
   2139     case 1:
   2140 	pixman_fill1 (bits, stride, x, y, width, height, filler);
   2141 	break;
   2142 
   2143     case 8:
   2144 	pixman_fill8 (bits, stride, x, y, width, height, filler);
   2145 	break;
   2146 
   2147     case 16:
   2148 	pixman_fill16 (bits, stride, x, y, width, height, filler);
   2149 	break;
   2150 
   2151     case 32:
   2152 	pixman_fill32 (bits, stride, x, y, width, height, filler);
   2153 	break;
   2154 
   2155     default:
   2156 	return FALSE;
   2157     }
   2158 
   2159     return TRUE;
   2160 }
   2161 
   2162 /*****************************************************************************/
   2163 
   2164 static uint32_t *
   2165 fast_fetch_r5g6b5 (pixman_iter_t *iter, const uint32_t *mask)
   2166 {
   2167     int32_t w = iter->width;
   2168     uint32_t *dst = iter->buffer;
   2169     const uint16_t *src = (const uint16_t *)iter->bits;
   2170 
   2171     iter->bits += iter->stride;
   2172 
   2173     /* Align the source buffer at 4 bytes boundary */
   2174     if (w > 0 && ((uintptr_t)src & 3))
   2175     {
   2176 	*dst++ = convert_0565_to_8888 (*src++);
   2177 	w--;
   2178     }
   2179     /* Process two pixels per iteration */
   2180     while ((w -= 2) >= 0)
   2181     {
   2182 	uint32_t sr, sb, sg, t0, t1;
   2183 	uint32_t s = *(const uint32_t *)src;
   2184 	src += 2;
   2185 	sr = (s >> 8) & 0x00F800F8;
   2186 	sb = (s << 3) & 0x00F800F8;
   2187 	sg = (s >> 3) & 0x00FC00FC;
   2188 	sr |= sr >> 5;
   2189 	sb |= sb >> 5;
   2190 	sg |= sg >> 6;
   2191 	t0 = ((sr << 16) & 0x00FF0000) | ((sg << 8) & 0x0000FF00) |
   2192 	     (sb & 0xFF) | 0xFF000000;
   2193 	t1 = (sr & 0x00FF0000) | ((sg >> 8) & 0x0000FF00) |
   2194 	     (sb >> 16) | 0xFF000000;
   2195 #ifdef WORDS_BIGENDIAN
   2196 	*dst++ = t1;
   2197 	*dst++ = t0;
   2198 #else
   2199 	*dst++ = t0;
   2200 	*dst++ = t1;
   2201 #endif
   2202     }
   2203     if (w & 1)
   2204     {
   2205 	*dst = convert_0565_to_8888 (*src);
   2206     }
   2207 
   2208     return iter->buffer;
   2209 }
   2210 
   2211 static uint32_t *
   2212 fast_dest_fetch_noop (pixman_iter_t *iter, const uint32_t *mask)
   2213 {
   2214     iter->bits += iter->stride;
   2215     return iter->buffer;
   2216 }
   2217 
   2218 /* Helper function for a workaround, which tries to ensure that 0x1F001F
   2219  * constant is always allocated in a register on RISC architectures.
   2220  */
   2221 static force_inline uint32_t
   2222 convert_8888_to_0565_workaround (uint32_t s, uint32_t x1F001F)
   2223 {
   2224     uint32_t a, b;
   2225     a = (s >> 3) & x1F001F;
   2226     b = s & 0xFC00;
   2227     a |= a >> 5;
   2228     a |= b >> 5;
   2229     return a;
   2230 }
   2231 
   2232 static void
   2233 fast_write_back_r5g6b5 (pixman_iter_t *iter)
   2234 {
   2235     int32_t w = iter->width;
   2236     uint16_t *dst = (uint16_t *)(iter->bits - iter->stride);
   2237     const uint32_t *src = iter->buffer;
   2238     /* Workaround to ensure that x1F001F variable is allocated in a register */
   2239     static volatile uint32_t volatile_x1F001F = 0x1F001F;
   2240     uint32_t x1F001F = volatile_x1F001F;
   2241 
   2242     while ((w -= 4) >= 0)
   2243     {
   2244 	uint32_t s1 = *src++;
   2245 	uint32_t s2 = *src++;
   2246 	uint32_t s3 = *src++;
   2247 	uint32_t s4 = *src++;
   2248 	*dst++ = convert_8888_to_0565_workaround (s1, x1F001F);
   2249 	*dst++ = convert_8888_to_0565_workaround (s2, x1F001F);
   2250 	*dst++ = convert_8888_to_0565_workaround (s3, x1F001F);
   2251 	*dst++ = convert_8888_to_0565_workaround (s4, x1F001F);
   2252     }
   2253     if (w & 2)
   2254     {
   2255 	*dst++ = convert_8888_to_0565_workaround (*src++, x1F001F);
   2256 	*dst++ = convert_8888_to_0565_workaround (*src++, x1F001F);
   2257     }
   2258     if (w & 1)
   2259     {
   2260 	*dst = convert_8888_to_0565_workaround (*src, x1F001F);
   2261     }
   2262 }
   2263 
   2264 typedef struct
   2265 {
   2266     int		y;
   2267     uint64_t *	buffer;
   2268 } line_t;
   2269 
   2270 typedef struct
   2271 {
   2272     line_t		lines[2];
   2273     pixman_fixed_t	y;
   2274     pixman_fixed_t	x;
   2275     uint64_t		data[1];
   2276 } bilinear_info_t;
   2277 
   2278 static void
   2279 fetch_horizontal (bits_image_t *image, line_t *line,
   2280 		  int y, pixman_fixed_t x, pixman_fixed_t ux, int n)
   2281 {
   2282     uint32_t *bits = image->bits + y * image->rowstride;
   2283     int i;
   2284 
   2285     for (i = 0; i < n; ++i)
   2286     {
   2287 	int x0 = pixman_fixed_to_int (x);
   2288 	int x1 = x0 + 1;
   2289 	int32_t dist_x;
   2290 
   2291 	uint32_t left = *(bits + x0);
   2292 	uint32_t right = *(bits + x1);
   2293 
   2294 	dist_x = pixman_fixed_to_bilinear_weight (x);
   2295 	dist_x <<= (8 - BILINEAR_INTERPOLATION_BITS);
   2296 
   2297 #if SIZEOF_LONG <= 4
   2298 	{
   2299 	    uint32_t lag, rag, ag;
   2300 	    uint32_t lrb, rrb, rb;
   2301 
   2302 	    lag = (left & 0xff00ff00) >> 8;
   2303 	    rag = (right & 0xff00ff00) >> 8;
   2304 	    ag = (lag << 8) + dist_x * (rag - lag);
   2305 
   2306 	    lrb = (left & 0x00ff00ff);
   2307 	    rrb = (right & 0x00ff00ff);
   2308 	    rb = (lrb << 8) + dist_x * (rrb - lrb);
   2309 
   2310 	    *((uint32_t *)(line->buffer + i)) = ag;
   2311 	    *((uint32_t *)(line->buffer + i) + 1) = rb;
   2312 	}
   2313 #else
   2314 	{
   2315 	    uint64_t lagrb, ragrb;
   2316 	    uint32_t lag, rag;
   2317 	    uint32_t lrb, rrb;
   2318 
   2319 	    lag = (left & 0xff00ff00);
   2320 	    lrb = (left & 0x00ff00ff);
   2321 	    rag = (right & 0xff00ff00);
   2322 	    rrb = (right & 0x00ff00ff);
   2323 	    lagrb = (((uint64_t)lag) << 24) | lrb;
   2324 	    ragrb = (((uint64_t)rag) << 24) | rrb;
   2325 
   2326 	    line->buffer[i] = (lagrb << 8) + dist_x * (ragrb - lagrb);
   2327 	}
   2328 #endif
   2329 
   2330 	x += ux;
   2331     }
   2332 
   2333     line->y = y;
   2334 }
   2335 
   2336 static uint32_t *
   2337 fast_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask)
   2338 {
   2339     pixman_fixed_t fx, ux;
   2340     bilinear_info_t *info = iter->data;
   2341     line_t *line0, *line1;
   2342     int y0, y1;
   2343     int32_t dist_y;
   2344     int i;
   2345 
   2346     COMPILE_TIME_ASSERT (BILINEAR_INTERPOLATION_BITS < 8);
   2347 
   2348     fx = info->x;
   2349     ux = iter->image->common.transform->matrix[0][0];
   2350 
   2351     y0 = pixman_fixed_to_int (info->y);
   2352     y1 = y0 + 1;
   2353     dist_y = pixman_fixed_to_bilinear_weight (info->y);
   2354     dist_y <<= (8 - BILINEAR_INTERPOLATION_BITS);
   2355 
   2356     line0 = &info->lines[y0 & 0x01];
   2357     line1 = &info->lines[y1 & 0x01];
   2358 
   2359     if (line0->y != y0)
   2360     {
   2361 	fetch_horizontal (
   2362 	    &iter->image->bits, line0, y0, fx, ux, iter->width);
   2363     }
   2364 
   2365     if (line1->y != y1)
   2366     {
   2367 	fetch_horizontal (
   2368 	    &iter->image->bits, line1, y1, fx, ux, iter->width);
   2369     }
   2370 
   2371     for (i = 0; i < iter->width; ++i)
   2372     {
   2373 #if SIZEOF_LONG <= 4
   2374 	uint32_t ta, tr, tg, tb;
   2375 	uint32_t ba, br, bg, bb;
   2376 	uint32_t tag, trb;
   2377 	uint32_t bag, brb;
   2378 	uint32_t a, r, g, b;
   2379 
   2380 	tag = *((uint32_t *)(line0->buffer + i));
   2381 	trb = *((uint32_t *)(line0->buffer + i) + 1);
   2382 	bag = *((uint32_t *)(line1->buffer + i));
   2383 	brb = *((uint32_t *)(line1->buffer + i) + 1);
   2384 
   2385 	ta = tag >> 16;
   2386 	ba = bag >> 16;
   2387 	a = (ta << 8) + dist_y * (ba - ta);
   2388 
   2389 	tr = trb >> 16;
   2390 	br = brb >> 16;
   2391 	r = (tr << 8) + dist_y * (br - tr);
   2392 
   2393 	tg = tag & 0xffff;
   2394 	bg = bag & 0xffff;
   2395 	g = (tg << 8) + dist_y * (bg - tg);
   2396 
   2397 	tb = trb & 0xffff;
   2398 	bb = brb & 0xffff;
   2399 	b = (tb << 8) + dist_y * (bb - tb);
   2400 
   2401 	a = (a <<  8) & 0xff000000;
   2402 	r = (r <<  0) & 0x00ff0000;
   2403 	g = (g >>  8) & 0x0000ff00;
   2404 	b = (b >> 16) & 0x000000ff;
   2405 #else
   2406 	uint64_t top = line0->buffer[i];
   2407 	uint64_t bot = line1->buffer[i];
   2408 	uint64_t tar = (top & 0xffff0000ffff0000ULL) >> 16;
   2409 	uint64_t bar = (bot & 0xffff0000ffff0000ULL) >> 16;
   2410 	uint64_t tgb = (top & 0x0000ffff0000ffffULL);
   2411 	uint64_t bgb = (bot & 0x0000ffff0000ffffULL);
   2412 	uint64_t ar, gb;
   2413 	uint32_t a, r, g, b;
   2414 
   2415 	ar = (tar << 8) + dist_y * (bar - tar);
   2416 	gb = (tgb << 8) + dist_y * (bgb - tgb);
   2417 
   2418 	a = ((ar >> 24) & 0xff000000);
   2419 	r = ((ar >>  0) & 0x00ff0000);
   2420 	g = ((gb >> 40) & 0x0000ff00);
   2421 	b = ((gb >> 16) & 0x000000ff);
   2422 #endif
   2423 
   2424 	iter->buffer[i] = a | r | g | b;
   2425     }
   2426 
   2427     info->y += iter->image->common.transform->matrix[1][1];
   2428 
   2429     return iter->buffer;
   2430 }
   2431 
   2432 static void
   2433 bilinear_cover_iter_fini (pixman_iter_t *iter)
   2434 {
   2435     free (iter->data);
   2436 }
   2437 
   2438 static void
   2439 fast_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *iter_info)
   2440 {
   2441     int width = iter->width;
   2442     bilinear_info_t *info;
   2443     pixman_vector_t v;
   2444 
   2445     /* Reference point is the center of the pixel */
   2446     v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2;
   2447     v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2;
   2448     v.vector[2] = pixman_fixed_1;
   2449 
   2450     if (!pixman_transform_point_3d (iter->image->common.transform, &v))
   2451 	goto fail;
   2452 
   2453     info = malloc (sizeof (*info) + (2 * width - 1) * sizeof (uint64_t));
   2454     if (!info)
   2455 	goto fail;
   2456 
   2457     info->x = v.vector[0] - pixman_fixed_1 / 2;
   2458     info->y = v.vector[1] - pixman_fixed_1 / 2;
   2459 
   2460     /* It is safe to set the y coordinates to -1 initially
   2461      * because COVER_CLIP_BILINEAR ensures that we will only
   2462      * be asked to fetch lines in the [0, height) interval
   2463      */
   2464     info->lines[0].y = -1;
   2465     info->lines[0].buffer = &(info->data[0]);
   2466     info->lines[1].y = -1;
   2467     info->lines[1].buffer = &(info->data[width]);
   2468 
   2469     iter->get_scanline = fast_fetch_bilinear_cover;
   2470     iter->fini = bilinear_cover_iter_fini;
   2471 
   2472     iter->data = info;
   2473     return;
   2474 
   2475 fail:
   2476     /* Something went wrong, either a bad matrix or OOM; in such cases,
   2477      * we don't guarantee any particular rendering.
   2478      */
   2479     _pixman_log_error (
   2480 	FUNC, "Allocation failure or bad matrix, skipping rendering\n");
   2481 
   2482     iter->get_scanline = _pixman_iter_get_scanline_noop;
   2483     iter->fini = NULL;
   2484 }
   2485 
   2486 static uint32_t *
   2487 bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
   2488 					  const uint32_t *mask)
   2489 {
   2490 
   2491     pixman_image_t * ima = iter->image;
   2492     int              offset = iter->x;
   2493     int              line = iter->y++;
   2494     int              width = iter->width;
   2495     uint32_t *       buffer = iter->buffer;
   2496 
   2497     bits_image_t *bits = &ima->bits;
   2498     pixman_fixed_t x_top, x_bottom, x;
   2499     pixman_fixed_t ux_top, ux_bottom, ux;
   2500     pixman_vector_t v;
   2501     uint32_t top_mask, bottom_mask;
   2502     uint32_t *top_row;
   2503     uint32_t *bottom_row;
   2504     uint32_t *end;
   2505     uint32_t zero[2] = { 0, 0 };
   2506     uint32_t one = 1;
   2507     int y, y1, y2;
   2508     int disty;
   2509     int mask_inc;
   2510     int w;
   2511 
   2512     /* reference point is the center of the pixel */
   2513     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
   2514     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
   2515     v.vector[2] = pixman_fixed_1;
   2516 
   2517     if (!pixman_transform_point_3d (bits->common.transform, &v))
   2518 	return iter->buffer;
   2519 
   2520     ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
   2521     x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
   2522 
   2523     y = v.vector[1] - pixman_fixed_1/2;
   2524     disty = pixman_fixed_to_bilinear_weight (y);
   2525 
   2526     /* Load the pointers to the first and second lines from the source
   2527      * image that bilinear code must read.
   2528      *
   2529      * The main trick in this code is about the check if any line are
   2530      * outside of the image;
   2531      *
   2532      * When I realize that a line (any one) is outside, I change
   2533      * the pointer to a dummy area with zeros. Once I change this, I
   2534      * must be sure the pointer will not change, so I set the
   2535      * variables to each pointer increments inside the loop.
   2536      */
   2537     y1 = pixman_fixed_to_int (y);
   2538     y2 = y1 + 1;
   2539 
   2540     if (y1 < 0 || y1 >= bits->height)
   2541     {
   2542 	top_row = zero;
   2543 	x_top = 0;
   2544 	ux_top = 0;
   2545     }
   2546     else
   2547     {
   2548 	top_row = bits->bits + y1 * bits->rowstride;
   2549 	x_top = x;
   2550 	ux_top = ux;
   2551     }
   2552 
   2553     if (y2 < 0 || y2 >= bits->height)
   2554     {
   2555 	bottom_row = zero;
   2556 	x_bottom = 0;
   2557 	ux_bottom = 0;
   2558     }
   2559     else
   2560     {
   2561 	bottom_row = bits->bits + y2 * bits->rowstride;
   2562 	x_bottom = x;
   2563 	ux_bottom = ux;
   2564     }
   2565 
   2566     /* Instead of checking whether the operation uses the mast in
   2567      * each loop iteration, verify this only once and prepare the
   2568      * variables to make the code smaller inside the loop.
   2569      */
   2570     if (!mask)
   2571     {
   2572         mask_inc = 0;
   2573         mask = &one;
   2574     }
   2575     else
   2576     {
   2577         /* If have a mask, prepare the variables to check it */
   2578         mask_inc = 1;
   2579     }
   2580 
   2581     /* If both are zero, then the whole thing is zero */
   2582     if (top_row == zero && bottom_row == zero)
   2583     {
   2584 	memset (buffer, 0, width * sizeof (uint32_t));
   2585 	return iter->buffer;
   2586     }
   2587     else if (bits->format == PIXMAN_x8r8g8b8)
   2588     {
   2589 	if (top_row == zero)
   2590 	{
   2591 	    top_mask = 0;
   2592 	    bottom_mask = 0xff000000;
   2593 	}
   2594 	else if (bottom_row == zero)
   2595 	{
   2596 	    top_mask = 0xff000000;
   2597 	    bottom_mask = 0;
   2598 	}
   2599 	else
   2600 	{
   2601 	    top_mask = 0xff000000;
   2602 	    bottom_mask = 0xff000000;
   2603 	}
   2604     }
   2605     else
   2606     {
   2607 	top_mask = 0;
   2608 	bottom_mask = 0;
   2609     }
   2610 
   2611     end = buffer + width;
   2612 
   2613     /* Zero fill to the left of the image */
   2614     while (buffer < end && x < pixman_fixed_minus_1)
   2615     {
   2616 	*buffer++ = 0;
   2617 	x += ux;
   2618 	x_top += ux_top;
   2619 	x_bottom += ux_bottom;
   2620 	mask += mask_inc;
   2621     }
   2622 
   2623     /* Left edge
   2624      */
   2625     while (buffer < end && x < 0)
   2626     {
   2627 	uint32_t tr, br;
   2628 	int32_t distx;
   2629 
   2630 	tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask;
   2631 	br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
   2632 
   2633 	distx = pixman_fixed_to_bilinear_weight (x);
   2634 
   2635 	*buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
   2636 
   2637 	x += ux;
   2638 	x_top += ux_top;
   2639 	x_bottom += ux_bottom;
   2640 	mask += mask_inc;
   2641     }
   2642 
   2643     /* Main part */
   2644     w = pixman_int_to_fixed (bits->width - 1);
   2645 
   2646     while (buffer < end  &&  x < w)
   2647     {
   2648 	if (*mask)
   2649 	{
   2650 	    uint32_t tl, tr, bl, br;
   2651 	    int32_t distx;
   2652 
   2653 	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
   2654 	    tr = top_row [pixman_fixed_to_int (x_top) + 1] | top_mask;
   2655 	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
   2656 	    br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
   2657 
   2658 	    distx = pixman_fixed_to_bilinear_weight (x);
   2659 
   2660 	    *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
   2661 	}
   2662 
   2663 	buffer++;
   2664 	x += ux;
   2665 	x_top += ux_top;
   2666 	x_bottom += ux_bottom;
   2667 	mask += mask_inc;
   2668     }
   2669 
   2670     /* Right Edge */
   2671     w = pixman_int_to_fixed (bits->width);
   2672     while (buffer < end  &&  x < w)
   2673     {
   2674 	if (*mask)
   2675 	{
   2676 	    uint32_t tl, bl;
   2677 	    int32_t distx;
   2678 
   2679 	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
   2680 	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
   2681 
   2682 	    distx = pixman_fixed_to_bilinear_weight (x);
   2683 
   2684 	    *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
   2685 	}
   2686 
   2687 	buffer++;
   2688 	x += ux;
   2689 	x_top += ux_top;
   2690 	x_bottom += ux_bottom;
   2691 	mask += mask_inc;
   2692     }
   2693 
   2694     /* Zero fill to the left of the image */
   2695     while (buffer < end)
   2696 	*buffer++ = 0;
   2697 
   2698     return iter->buffer;
   2699 }
   2700 
   2701 typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
   2702 
   2703 static force_inline void
   2704 bits_image_fetch_separable_convolution_affine (pixman_image_t * image,
   2705 					       int              offset,
   2706 					       int              line,
   2707 					       int              width,
   2708 					       uint32_t *       buffer,
   2709 					       const uint32_t * mask,
   2710 
   2711 					       convert_pixel_t	convert_pixel,
   2712 					       pixman_format_code_t	format,
   2713 					       pixman_repeat_t	repeat_mode)
   2714 {
   2715     bits_image_t *bits = &image->bits;
   2716     pixman_fixed_t *params = image->common.filter_params;
   2717     int cwidth = pixman_fixed_to_int (params[0]);
   2718     int cheight = pixman_fixed_to_int (params[1]);
   2719     int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
   2720     int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
   2721     int x_phase_bits = pixman_fixed_to_int (params[2]);
   2722     int y_phase_bits = pixman_fixed_to_int (params[3]);
   2723     int x_phase_shift = 16 - x_phase_bits;
   2724     int y_phase_shift = 16 - y_phase_bits;
   2725     pixman_fixed_t vx, vy;
   2726     pixman_fixed_t ux, uy;
   2727     pixman_vector_t v;
   2728     int k;
   2729 
   2730     /* reference point is the center of the pixel */
   2731     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
   2732     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
   2733     v.vector[2] = pixman_fixed_1;
   2734 
   2735     if (!pixman_transform_point_3d (image->common.transform, &v))
   2736 	return;
   2737 
   2738     ux = image->common.transform->matrix[0][0];
   2739     uy = image->common.transform->matrix[1][0];
   2740 
   2741     vx = v.vector[0];
   2742     vy = v.vector[1];
   2743 
   2744     for (k = 0; k < width; ++k)
   2745     {
   2746 	pixman_fixed_t *y_params;
   2747 	int satot, srtot, sgtot, sbtot;
   2748 	pixman_fixed_t x, y;
   2749 	int32_t x1, x2, y1, y2;
   2750 	int32_t px, py;
   2751 	int i, j;
   2752 
   2753 	if (mask && !mask[k])
   2754 	    goto next;
   2755 
   2756 	/* Round x and y to the middle of the closest phase before continuing. This
   2757 	 * ensures that the convolution matrix is aligned right, since it was
   2758 	 * positioned relative to a particular phase (and not relative to whatever
   2759 	 * exact fraction we happen to get here).
   2760 	 */
   2761 	x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
   2762 	y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
   2763 
   2764 	px = (x & 0xffff) >> x_phase_shift;
   2765 	py = (y & 0xffff) >> y_phase_shift;
   2766 
   2767 	x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
   2768 	y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
   2769 	x2 = x1 + cwidth;
   2770 	y2 = y1 + cheight;
   2771 
   2772 	satot = srtot = sgtot = sbtot = 0;
   2773 
   2774 	y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
   2775 
   2776 	for (i = y1; i < y2; ++i)
   2777 	{
   2778 	    pixman_fixed_t fy = *y_params++;
   2779 
   2780 	    if (fy)
   2781 	    {
   2782 		pixman_fixed_t *x_params = params + 4 + px * cwidth;
   2783 
   2784 		for (j = x1; j < x2; ++j)
   2785 		{
   2786 		    pixman_fixed_t fx = *x_params++;
   2787 		    int rx = j;
   2788 		    int ry = i;
   2789 
   2790 		    if (fx)
   2791 		    {
   2792 			pixman_fixed_t f;
   2793 			uint32_t pixel, mask;
   2794 			uint8_t *row;
   2795 
   2796 			mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
   2797 
   2798 			if (repeat_mode != PIXMAN_REPEAT_NONE)
   2799 			{
   2800 			    repeat (repeat_mode, &rx, bits->width);
   2801 			    repeat (repeat_mode, &ry, bits->height);
   2802 
   2803 			    row = (uint8_t *)(bits->bits + bits->rowstride * ry);
   2804 			    pixel = convert_pixel (row, rx) | mask;
   2805 			}
   2806 			else
   2807 			{
   2808 			    if (rx < 0 || ry < 0 || rx >= bits->width || ry >= bits->height)
   2809 			    {
   2810 				pixel = 0;
   2811 			    }
   2812 			    else
   2813 			    {
   2814 				row = (uint8_t *)(bits->bits + bits->rowstride * ry);
   2815 				pixel = convert_pixel (row, rx) | mask;
   2816 			    }
   2817 			}
   2818 
   2819 			f = ((pixman_fixed_32_32_t)fx * fy + 0x8000) >> 16;
   2820 			srtot += (int)RED_8 (pixel) * f;
   2821 			sgtot += (int)GREEN_8 (pixel) * f;
   2822 			sbtot += (int)BLUE_8 (pixel) * f;
   2823 			satot += (int)ALPHA_8 (pixel) * f;
   2824 		    }
   2825 		}
   2826 	    }
   2827 	}
   2828 
   2829 	satot = (satot + 0x8000) >> 16;
   2830 	srtot = (srtot + 0x8000) >> 16;
   2831 	sgtot = (sgtot + 0x8000) >> 16;
   2832 	sbtot = (sbtot + 0x8000) >> 16;
   2833 
   2834 	satot = CLIP (satot, 0, 0xff);
   2835 	srtot = CLIP (srtot, 0, 0xff);
   2836 	sgtot = CLIP (sgtot, 0, 0xff);
   2837 	sbtot = CLIP (sbtot, 0, 0xff);
   2838 
   2839 	buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0);
   2840 
   2841     next:
   2842 	vx += ux;
   2843 	vy += uy;
   2844     }
   2845 }
   2846 
   2847 static const uint32_t zero[2] = { 0, 0 };
   2848 
   2849 static force_inline void
   2850 bits_image_fetch_bilinear_affine (pixman_image_t * image,
   2851 				  int              offset,
   2852 				  int              line,
   2853 				  int              width,
   2854 				  uint32_t *       buffer,
   2855 				  const uint32_t * mask,
   2856 
   2857 				  convert_pixel_t	convert_pixel,
   2858 				  pixman_format_code_t	format,
   2859 				  pixman_repeat_t	repeat_mode)
   2860 {
   2861     pixman_fixed_t x, y;
   2862     pixman_fixed_t ux, uy;
   2863     pixman_vector_t v;
   2864     bits_image_t *bits = &image->bits;
   2865     int i;
   2866 
   2867     /* reference point is the center of the pixel */
   2868     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
   2869     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
   2870     v.vector[2] = pixman_fixed_1;
   2871 
   2872     if (!pixman_transform_point_3d (image->common.transform, &v))
   2873 	return;
   2874 
   2875     ux = image->common.transform->matrix[0][0];
   2876     uy = image->common.transform->matrix[1][0];
   2877 
   2878     x = v.vector[0];
   2879     y = v.vector[1];
   2880 
   2881     for (i = 0; i < width; ++i)
   2882     {
   2883 	int x1, y1, x2, y2;
   2884 	uint32_t tl, tr, bl, br;
   2885 	int32_t distx, disty;
   2886 	int width = image->bits.width;
   2887 	int height = image->bits.height;
   2888 	const uint8_t *row1;
   2889 	const uint8_t *row2;
   2890 
   2891 	if (mask && !mask[i])
   2892 	    goto next;
   2893 
   2894 	x1 = x - pixman_fixed_1 / 2;
   2895 	y1 = y - pixman_fixed_1 / 2;
   2896 
   2897 	distx = pixman_fixed_to_bilinear_weight (x1);
   2898 	disty = pixman_fixed_to_bilinear_weight (y1);
   2899 
   2900 	y1 = pixman_fixed_to_int (y1);
   2901 	y2 = y1 + 1;
   2902 	x1 = pixman_fixed_to_int (x1);
   2903 	x2 = x1 + 1;
   2904 
   2905 	if (repeat_mode != PIXMAN_REPEAT_NONE)
   2906 	{
   2907 	    uint32_t mask;
   2908 
   2909 	    mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
   2910 
   2911 	    repeat (repeat_mode, &x1, width);
   2912 	    repeat (repeat_mode, &y1, height);
   2913 	    repeat (repeat_mode, &x2, width);
   2914 	    repeat (repeat_mode, &y2, height);
   2915 
   2916 	    row1 = (uint8_t *)(bits->bits + bits->rowstride * y1);
   2917 	    row2 = (uint8_t *)(bits->bits + bits->rowstride * y2);
   2918 
   2919 	    tl = convert_pixel (row1, x1) | mask;
   2920 	    tr = convert_pixel (row1, x2) | mask;
   2921 	    bl = convert_pixel (row2, x1) | mask;
   2922 	    br = convert_pixel (row2, x2) | mask;
   2923 	}
   2924 	else
   2925 	{
   2926 	    uint32_t mask1, mask2;
   2927 	    int bpp;
   2928 
   2929 	    /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value,
   2930 	     * which means if you use it in expressions, those
   2931 	     * expressions become unsigned themselves. Since
   2932 	     * the variables below can be negative in some cases,
   2933 	     * that will lead to crashes on 64 bit architectures.
   2934 	     *
   2935 	     * So this line makes sure bpp is signed
   2936 	     */
   2937 	    bpp = PIXMAN_FORMAT_BPP (format);
   2938 
   2939 	    if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0)
   2940 	    {
   2941 		buffer[i] = 0;
   2942 		goto next;
   2943 	    }
   2944 
   2945 	    if (y2 == 0)
   2946 	    {
   2947 		row1 = (const uint8_t *)zero;
   2948 		mask1 = 0;
   2949 	    }
   2950 	    else
   2951 	    {
   2952 		row1 = (uint8_t *)(bits->bits + bits->rowstride * y1);
   2953 		row1 += bpp / 8 * x1;
   2954 
   2955 		mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
   2956 	    }
   2957 
   2958 	    if (y1 == height - 1)
   2959 	    {
   2960 		row2 = (const uint8_t *)zero;
   2961 		mask2 = 0;
   2962 	    }
   2963 	    else
   2964 	    {
   2965 		row2 = (uint8_t *)(bits->bits + bits->rowstride * y2);
   2966 		row2 += bpp / 8 * x1;
   2967 
   2968 		mask2 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
   2969 	    }
   2970 
   2971 	    if (x2 == 0)
   2972 	    {
   2973 		tl = 0;
   2974 		bl = 0;
   2975 	    }
   2976 	    else
   2977 	    {
   2978 		tl = convert_pixel (row1, 0) | mask1;
   2979 		bl = convert_pixel (row2, 0) | mask2;
   2980 	    }
   2981 
   2982 	    if (x1 == width - 1)
   2983 	    {
   2984 		tr = 0;
   2985 		br = 0;
   2986 	    }
   2987 	    else
   2988 	    {
   2989 		tr = convert_pixel (row1, 1) | mask1;
   2990 		br = convert_pixel (row2, 1) | mask2;
   2991 	    }
   2992 	}
   2993 
   2994 	buffer[i] = bilinear_interpolation (
   2995 	    tl, tr, bl, br, distx, disty);
   2996 
   2997     next:
   2998 	x += ux;
   2999 	y += uy;
   3000     }
   3001 }
   3002 
   3003 static force_inline void
   3004 bits_image_fetch_nearest_affine (pixman_image_t * image,
   3005 				 int              offset,
   3006 				 int              line,
   3007 				 int              width,
   3008 				 uint32_t *       buffer,
   3009 				 const uint32_t * mask,
   3010 
   3011 				 convert_pixel_t	convert_pixel,
   3012 				 pixman_format_code_t	format,
   3013 				 pixman_repeat_t	repeat_mode)
   3014 {
   3015     pixman_fixed_t x, y;
   3016     pixman_fixed_t ux, uy;
   3017     pixman_vector_t v;
   3018     bits_image_t *bits = &image->bits;
   3019     int i;
   3020 
   3021     /* reference point is the center of the pixel */
   3022     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
   3023     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
   3024     v.vector[2] = pixman_fixed_1;
   3025 
   3026     if (!pixman_transform_point_3d (image->common.transform, &v))
   3027 	return;
   3028 
   3029     ux = image->common.transform->matrix[0][0];
   3030     uy = image->common.transform->matrix[1][0];
   3031 
   3032     x = v.vector[0];
   3033     y = v.vector[1];
   3034 
   3035     for (i = 0; i < width; ++i)
   3036     {
   3037 	int width, height, x0, y0;
   3038 	const uint8_t *row;
   3039 
   3040 	if (mask && !mask[i])
   3041 	    goto next;
   3042 
   3043 	width = image->bits.width;
   3044 	height = image->bits.height;
   3045 	x0 = pixman_fixed_to_int (x - pixman_fixed_e);
   3046 	y0 = pixman_fixed_to_int (y - pixman_fixed_e);
   3047 
   3048 	if (repeat_mode == PIXMAN_REPEAT_NONE &&
   3049 	    (y0 < 0 || y0 >= height || x0 < 0 || x0 >= width))
   3050 	{
   3051 	    buffer[i] = 0;
   3052 	}
   3053 	else
   3054 	{
   3055 	    uint32_t mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
   3056 
   3057 	    if (repeat_mode != PIXMAN_REPEAT_NONE)
   3058 	    {
   3059 		repeat (repeat_mode, &x0, width);
   3060 		repeat (repeat_mode, &y0, height);
   3061 	    }
   3062 
   3063 	    row = (uint8_t *)(bits->bits + bits->rowstride * y0);
   3064 
   3065 	    buffer[i] = convert_pixel (row, x0) | mask;
   3066 	}
   3067 
   3068     next:
   3069 	x += ux;
   3070 	y += uy;
   3071     }
   3072 }
   3073 
   3074 static force_inline uint32_t
   3075 convert_a8r8g8b8 (const uint8_t *row, int x)
   3076 {
   3077     return *(((uint32_t *)row) + x);
   3078 }
   3079 
   3080 static force_inline uint32_t
   3081 convert_x8r8g8b8 (const uint8_t *row, int x)
   3082 {
   3083     return *(((uint32_t *)row) + x);
   3084 }
   3085 
   3086 static force_inline uint32_t
   3087 convert_a8 (const uint8_t *row, int x)
   3088 {
   3089     return (uint32_t) *(row + x) << 24;
   3090 }
   3091 
   3092 static force_inline uint32_t
   3093 convert_r5g6b5 (const uint8_t *row, int x)
   3094 {
   3095     return convert_0565_to_0888 (*((uint16_t *)row + x));
   3096 }
   3097 
   3098 #define MAKE_SEPARABLE_CONVOLUTION_FETCHER(name, format, repeat_mode)  \
   3099     static uint32_t *							\
   3100     bits_image_fetch_separable_convolution_affine_ ## name (pixman_iter_t   *iter, \
   3101 							    const uint32_t * mask) \
   3102     {									\
   3103 	bits_image_fetch_separable_convolution_affine (                 \
   3104 	    iter->image,                                                \
   3105 	    iter->x, iter->y++,                                         \
   3106 	    iter->width,                                                \
   3107 	    iter->buffer, mask,                                         \
   3108 	    convert_ ## format,                                         \
   3109 	    PIXMAN_ ## format,                                          \
   3110 	    repeat_mode);                                               \
   3111 									\
   3112 	return iter->buffer;                                            \
   3113     }
   3114 
   3115 #define MAKE_BILINEAR_FETCHER(name, format, repeat_mode)		\
   3116     static uint32_t *							\
   3117     bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t   *iter,	\
   3118 					       const uint32_t * mask)	\
   3119     {									\
   3120 	bits_image_fetch_bilinear_affine (iter->image,			\
   3121 					  iter->x, iter->y++,		\
   3122 					  iter->width,			\
   3123 					  iter->buffer, mask,		\
   3124 					  convert_ ## format,		\
   3125 					  PIXMAN_ ## format,		\
   3126 					  repeat_mode);			\
   3127 	return iter->buffer;						\
   3128     }
   3129 
   3130 #define MAKE_NEAREST_FETCHER(name, format, repeat_mode)			\
   3131     static uint32_t *							\
   3132     bits_image_fetch_nearest_affine_ ## name (pixman_iter_t   *iter,	\
   3133 					      const uint32_t * mask)	\
   3134     {									\
   3135 	bits_image_fetch_nearest_affine (iter->image,			\
   3136 					 iter->x, iter->y++,		\
   3137 					 iter->width,			\
   3138 					 iter->buffer, mask,		\
   3139 					 convert_ ## format,		\
   3140 					 PIXMAN_ ## format,		\
   3141 					 repeat_mode);			\
   3142 	return iter->buffer;						\
   3143     }
   3144 
   3145 #define MAKE_FETCHERS(name, format, repeat_mode)			\
   3146     MAKE_NEAREST_FETCHER (name, format, repeat_mode)			\
   3147     MAKE_BILINEAR_FETCHER (name, format, repeat_mode)			\
   3148     MAKE_SEPARABLE_CONVOLUTION_FETCHER (name, format, repeat_mode)
   3149 
   3150 MAKE_FETCHERS (pad_a8r8g8b8,     a8r8g8b8, PIXMAN_REPEAT_PAD)
   3151 MAKE_FETCHERS (none_a8r8g8b8,    a8r8g8b8, PIXMAN_REPEAT_NONE)
   3152 MAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT)
   3153 MAKE_FETCHERS (normal_a8r8g8b8,  a8r8g8b8, PIXMAN_REPEAT_NORMAL)
   3154 MAKE_FETCHERS (pad_x8r8g8b8,     x8r8g8b8, PIXMAN_REPEAT_PAD)
   3155 MAKE_FETCHERS (none_x8r8g8b8,    x8r8g8b8, PIXMAN_REPEAT_NONE)
   3156 MAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT)
   3157 MAKE_FETCHERS (normal_x8r8g8b8,  x8r8g8b8, PIXMAN_REPEAT_NORMAL)
   3158 MAKE_FETCHERS (pad_a8,           a8,       PIXMAN_REPEAT_PAD)
   3159 MAKE_FETCHERS (none_a8,          a8,       PIXMAN_REPEAT_NONE)
   3160 MAKE_FETCHERS (reflect_a8,	 a8,       PIXMAN_REPEAT_REFLECT)
   3161 MAKE_FETCHERS (normal_a8,	 a8,       PIXMAN_REPEAT_NORMAL)
   3162 MAKE_FETCHERS (pad_r5g6b5,       r5g6b5,   PIXMAN_REPEAT_PAD)
   3163 MAKE_FETCHERS (none_r5g6b5,      r5g6b5,   PIXMAN_REPEAT_NONE)
   3164 MAKE_FETCHERS (reflect_r5g6b5,   r5g6b5,   PIXMAN_REPEAT_REFLECT)
   3165 MAKE_FETCHERS (normal_r5g6b5,    r5g6b5,   PIXMAN_REPEAT_NORMAL)
   3166 
   3167 #define IMAGE_FLAGS							\
   3168     (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
   3169      FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
   3170 
   3171 static const pixman_iter_info_t fast_iters[] =
   3172 {
   3173     { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW | ITER_SRC,
   3174       _pixman_iter_init_bits_stride, fast_fetch_r5g6b5, NULL },
   3175 
   3176     { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS,
   3177       ITER_NARROW | ITER_DEST,
   3178       _pixman_iter_init_bits_stride,
   3179       fast_fetch_r5g6b5, fast_write_back_r5g6b5 },
   3180 
   3181     { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS,
   3182       ITER_NARROW | ITER_DEST | ITER_IGNORE_RGB | ITER_IGNORE_ALPHA,
   3183       _pixman_iter_init_bits_stride,
   3184       fast_dest_fetch_noop, fast_write_back_r5g6b5 },
   3185 
   3186     { PIXMAN_a8r8g8b8,
   3187       (FAST_PATH_STANDARD_FLAGS			|
   3188        FAST_PATH_SCALE_TRANSFORM		|
   3189        FAST_PATH_BILINEAR_FILTER		|
   3190        FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR),
   3191       ITER_NARROW | ITER_SRC,
   3192       fast_bilinear_cover_iter_init,
   3193       NULL, NULL
   3194     },
   3195 
   3196 #define FAST_BILINEAR_FLAGS						\
   3197     (FAST_PATH_NO_ALPHA_MAP		|				\
   3198      FAST_PATH_NO_ACCESSORS		|				\
   3199      FAST_PATH_HAS_TRANSFORM		|				\
   3200      FAST_PATH_AFFINE_TRANSFORM		|				\
   3201      FAST_PATH_X_UNIT_POSITIVE		|				\
   3202      FAST_PATH_Y_UNIT_ZERO		|				\
   3203      FAST_PATH_NONE_REPEAT		|				\
   3204      FAST_PATH_BILINEAR_FILTER)
   3205 
   3206     { PIXMAN_a8r8g8b8,
   3207       FAST_BILINEAR_FLAGS,
   3208       ITER_NARROW | ITER_SRC,
   3209       NULL, bits_image_fetch_bilinear_no_repeat_8888, NULL
   3210     },
   3211 
   3212     { PIXMAN_x8r8g8b8,
   3213       FAST_BILINEAR_FLAGS,
   3214       ITER_NARROW | ITER_SRC,
   3215       NULL, bits_image_fetch_bilinear_no_repeat_8888, NULL
   3216     },
   3217 
   3218 #define GENERAL_BILINEAR_FLAGS						\
   3219     (FAST_PATH_NO_ALPHA_MAP		|				\
   3220      FAST_PATH_NO_ACCESSORS		|				\
   3221      FAST_PATH_HAS_TRANSFORM		|				\
   3222      FAST_PATH_AFFINE_TRANSFORM		|				\
   3223      FAST_PATH_BILINEAR_FILTER)
   3224 
   3225 #define GENERAL_NEAREST_FLAGS						\
   3226     (FAST_PATH_NO_ALPHA_MAP		|				\
   3227      FAST_PATH_NO_ACCESSORS		|				\
   3228      FAST_PATH_HAS_TRANSFORM		|				\
   3229      FAST_PATH_AFFINE_TRANSFORM		|				\
   3230      FAST_PATH_NEAREST_FILTER)
   3231 
   3232 #define GENERAL_SEPARABLE_CONVOLUTION_FLAGS				\
   3233     (FAST_PATH_NO_ALPHA_MAP            |				\
   3234      FAST_PATH_NO_ACCESSORS            |				\
   3235      FAST_PATH_HAS_TRANSFORM           |				\
   3236      FAST_PATH_AFFINE_TRANSFORM        |				\
   3237      FAST_PATH_SEPARABLE_CONVOLUTION_FILTER)
   3238 
   3239 #define SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat)   \
   3240     { PIXMAN_ ## format,						\
   3241       GENERAL_SEPARABLE_CONVOLUTION_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \
   3242       ITER_NARROW | ITER_SRC,						\
   3243       NULL, bits_image_fetch_separable_convolution_affine_ ## name, NULL \
   3244     },
   3245 
   3246 #define BILINEAR_AFFINE_FAST_PATH(name, format, repeat)			\
   3247     { PIXMAN_ ## format,						\
   3248       GENERAL_BILINEAR_FLAGS | FAST_PATH_ ## repeat ## _REPEAT,		\
   3249       ITER_NARROW | ITER_SRC,						\
   3250       NULL, bits_image_fetch_bilinear_affine_ ## name, NULL,		\
   3251     },
   3252 
   3253 #define NEAREST_AFFINE_FAST_PATH(name, format, repeat)			\
   3254     { PIXMAN_ ## format,						\
   3255       GENERAL_NEAREST_FLAGS | FAST_PATH_ ## repeat ## _REPEAT,		\
   3256       ITER_NARROW | ITER_SRC,						\
   3257       NULL, bits_image_fetch_nearest_affine_ ## name, NULL		\
   3258     },
   3259 
   3260 #define AFFINE_FAST_PATHS(name, format, repeat)				\
   3261     NEAREST_AFFINE_FAST_PATH(name, format, repeat)			\
   3262     BILINEAR_AFFINE_FAST_PATH(name, format, repeat)			\
   3263     SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat)
   3264 
   3265     AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD)
   3266     AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE)
   3267     AFFINE_FAST_PATHS (reflect_a8r8g8b8, a8r8g8b8, REFLECT)
   3268     AFFINE_FAST_PATHS (normal_a8r8g8b8, a8r8g8b8, NORMAL)
   3269     AFFINE_FAST_PATHS (pad_x8r8g8b8, x8r8g8b8, PAD)
   3270     AFFINE_FAST_PATHS (none_x8r8g8b8, x8r8g8b8, NONE)
   3271     AFFINE_FAST_PATHS (reflect_x8r8g8b8, x8r8g8b8, REFLECT)
   3272     AFFINE_FAST_PATHS (normal_x8r8g8b8, x8r8g8b8, NORMAL)
   3273     AFFINE_FAST_PATHS (pad_a8, a8, PAD)
   3274     AFFINE_FAST_PATHS (none_a8, a8, NONE)
   3275     AFFINE_FAST_PATHS (reflect_a8, a8, REFLECT)
   3276     AFFINE_FAST_PATHS (normal_a8, a8, NORMAL)
   3277     AFFINE_FAST_PATHS (pad_r5g6b5, r5g6b5, PAD)
   3278     AFFINE_FAST_PATHS (none_r5g6b5, r5g6b5, NONE)
   3279     AFFINE_FAST_PATHS (reflect_r5g6b5, r5g6b5, REFLECT)
   3280     AFFINE_FAST_PATHS (normal_r5g6b5, r5g6b5, NORMAL)
   3281 
   3282     { PIXMAN_null },
   3283 };
   3284 
   3285 pixman_implementation_t *
   3286 _pixman_implementation_create_fast_path (pixman_implementation_t *fallback)
   3287 {
   3288     pixman_implementation_t *imp = _pixman_implementation_create (fallback, c_fast_paths);
   3289 
   3290     imp->fill = fast_path_fill;
   3291     imp->iter_info = fast_iters;
   3292 
   3293     return imp;
   3294 }
   3295