gfx/cairo/libpixman/src/pixman-fast-path.c

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

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

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

michael@0 1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
michael@0 2 /*
michael@0 3 * Copyright © 2000 SuSE, Inc.
michael@0 4 * Copyright © 2007 Red Hat, Inc.
michael@0 5 *
michael@0 6 * Permission to use, copy, modify, distribute, and sell this software and its
michael@0 7 * documentation for any purpose is hereby granted without fee, provided that
michael@0 8 * the above copyright notice appear in all copies and that both that
michael@0 9 * copyright notice and this permission notice appear in supporting
michael@0 10 * documentation, and that the name of SuSE not be used in advertising or
michael@0 11 * publicity pertaining to distribution of the software without specific,
michael@0 12 * written prior permission. SuSE makes no representations about the
michael@0 13 * suitability of this software for any purpose. It is provided "as is"
michael@0 14 * without express or implied warranty.
michael@0 15 *
michael@0 16 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
michael@0 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
michael@0 18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
michael@0 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
michael@0 20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
michael@0 21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
michael@0 22 *
michael@0 23 * Author: Keith Packard, SuSE, Inc.
michael@0 24 */
michael@0 25
michael@0 26 #ifdef HAVE_CONFIG_H
michael@0 27 #include <config.h>
michael@0 28 #endif
michael@0 29 #include <string.h>
michael@0 30 #include <stdlib.h>
michael@0 31 #include "pixman-private.h"
michael@0 32 #include "pixman-combine32.h"
michael@0 33 #include "pixman-inlines.h"
michael@0 34
michael@0 35 static force_inline uint32_t
michael@0 36 fetch_24 (uint8_t *a)
michael@0 37 {
michael@0 38 if (((uintptr_t)a) & 1)
michael@0 39 {
michael@0 40 #ifdef WORDS_BIGENDIAN
michael@0 41 return (*a << 16) | (*(uint16_t *)(a + 1));
michael@0 42 #else
michael@0 43 return *a | (*(uint16_t *)(a + 1) << 8);
michael@0 44 #endif
michael@0 45 }
michael@0 46 else
michael@0 47 {
michael@0 48 #ifdef WORDS_BIGENDIAN
michael@0 49 return (*(uint16_t *)a << 8) | *(a + 2);
michael@0 50 #else
michael@0 51 return *(uint16_t *)a | (*(a + 2) << 16);
michael@0 52 #endif
michael@0 53 }
michael@0 54 }
michael@0 55
michael@0 56 static force_inline void
michael@0 57 store_24 (uint8_t *a,
michael@0 58 uint32_t v)
michael@0 59 {
michael@0 60 if (((uintptr_t)a) & 1)
michael@0 61 {
michael@0 62 #ifdef WORDS_BIGENDIAN
michael@0 63 *a = (uint8_t) (v >> 16);
michael@0 64 *(uint16_t *)(a + 1) = (uint16_t) (v);
michael@0 65 #else
michael@0 66 *a = (uint8_t) (v);
michael@0 67 *(uint16_t *)(a + 1) = (uint16_t) (v >> 8);
michael@0 68 #endif
michael@0 69 }
michael@0 70 else
michael@0 71 {
michael@0 72 #ifdef WORDS_BIGENDIAN
michael@0 73 *(uint16_t *)a = (uint16_t)(v >> 8);
michael@0 74 *(a + 2) = (uint8_t)v;
michael@0 75 #else
michael@0 76 *(uint16_t *)a = (uint16_t)v;
michael@0 77 *(a + 2) = (uint8_t)(v >> 16);
michael@0 78 #endif
michael@0 79 }
michael@0 80 }
michael@0 81
michael@0 82 static force_inline uint32_t
michael@0 83 over (uint32_t src,
michael@0 84 uint32_t dest)
michael@0 85 {
michael@0 86 uint32_t a = ~src >> 24;
michael@0 87
michael@0 88 UN8x4_MUL_UN8_ADD_UN8x4 (dest, a, src);
michael@0 89
michael@0 90 return dest;
michael@0 91 }
michael@0 92
michael@0 93 static force_inline uint32_t
michael@0 94 in (uint32_t x,
michael@0 95 uint8_t y)
michael@0 96 {
michael@0 97 uint16_t a = y;
michael@0 98
michael@0 99 UN8x4_MUL_UN8 (x, a);
michael@0 100
michael@0 101 return x;
michael@0 102 }
michael@0 103
michael@0 104 /*
michael@0 105 * Naming convention:
michael@0 106 *
michael@0 107 * op_src_mask_dest
michael@0 108 */
michael@0 109 static void
michael@0 110 fast_composite_over_x888_8_8888 (pixman_implementation_t *imp,
michael@0 111 pixman_composite_info_t *info)
michael@0 112 {
michael@0 113 PIXMAN_COMPOSITE_ARGS (info);
michael@0 114 uint32_t *src, *src_line;
michael@0 115 uint32_t *dst, *dst_line;
michael@0 116 uint8_t *mask, *mask_line;
michael@0 117 int src_stride, mask_stride, dst_stride;
michael@0 118 uint8_t m;
michael@0 119 uint32_t s, d;
michael@0 120 int32_t w;
michael@0 121
michael@0 122 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 123 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
michael@0 124 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
michael@0 125
michael@0 126 while (height--)
michael@0 127 {
michael@0 128 src = src_line;
michael@0 129 src_line += src_stride;
michael@0 130 dst = dst_line;
michael@0 131 dst_line += dst_stride;
michael@0 132 mask = mask_line;
michael@0 133 mask_line += mask_stride;
michael@0 134
michael@0 135 w = width;
michael@0 136 while (w--)
michael@0 137 {
michael@0 138 m = *mask++;
michael@0 139 if (m)
michael@0 140 {
michael@0 141 s = *src | 0xff000000;
michael@0 142
michael@0 143 if (m == 0xff)
michael@0 144 {
michael@0 145 *dst = s;
michael@0 146 }
michael@0 147 else
michael@0 148 {
michael@0 149 d = in (s, m);
michael@0 150 *dst = over (d, *dst);
michael@0 151 }
michael@0 152 }
michael@0 153 src++;
michael@0 154 dst++;
michael@0 155 }
michael@0 156 }
michael@0 157 }
michael@0 158
michael@0 159 static void
michael@0 160 fast_composite_in_n_8_8 (pixman_implementation_t *imp,
michael@0 161 pixman_composite_info_t *info)
michael@0 162 {
michael@0 163 PIXMAN_COMPOSITE_ARGS (info);
michael@0 164 uint32_t src, srca;
michael@0 165 uint8_t *dst_line, *dst;
michael@0 166 uint8_t *mask_line, *mask, m;
michael@0 167 int dst_stride, mask_stride;
michael@0 168 int32_t w;
michael@0 169 uint16_t t;
michael@0 170
michael@0 171 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 172
michael@0 173 srca = src >> 24;
michael@0 174
michael@0 175 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
michael@0 176 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
michael@0 177
michael@0 178 if (srca == 0xff)
michael@0 179 {
michael@0 180 while (height--)
michael@0 181 {
michael@0 182 dst = dst_line;
michael@0 183 dst_line += dst_stride;
michael@0 184 mask = mask_line;
michael@0 185 mask_line += mask_stride;
michael@0 186 w = width;
michael@0 187
michael@0 188 while (w--)
michael@0 189 {
michael@0 190 m = *mask++;
michael@0 191
michael@0 192 if (m == 0)
michael@0 193 *dst = 0;
michael@0 194 else if (m != 0xff)
michael@0 195 *dst = MUL_UN8 (m, *dst, t);
michael@0 196
michael@0 197 dst++;
michael@0 198 }
michael@0 199 }
michael@0 200 }
michael@0 201 else
michael@0 202 {
michael@0 203 while (height--)
michael@0 204 {
michael@0 205 dst = dst_line;
michael@0 206 dst_line += dst_stride;
michael@0 207 mask = mask_line;
michael@0 208 mask_line += mask_stride;
michael@0 209 w = width;
michael@0 210
michael@0 211 while (w--)
michael@0 212 {
michael@0 213 m = *mask++;
michael@0 214 m = MUL_UN8 (m, srca, t);
michael@0 215
michael@0 216 if (m == 0)
michael@0 217 *dst = 0;
michael@0 218 else if (m != 0xff)
michael@0 219 *dst = MUL_UN8 (m, *dst, t);
michael@0 220
michael@0 221 dst++;
michael@0 222 }
michael@0 223 }
michael@0 224 }
michael@0 225 }
michael@0 226
michael@0 227 static void
michael@0 228 fast_composite_in_8_8 (pixman_implementation_t *imp,
michael@0 229 pixman_composite_info_t *info)
michael@0 230 {
michael@0 231 PIXMAN_COMPOSITE_ARGS (info);
michael@0 232 uint8_t *dst_line, *dst;
michael@0 233 uint8_t *src_line, *src;
michael@0 234 int dst_stride, src_stride;
michael@0 235 int32_t w;
michael@0 236 uint8_t s;
michael@0 237 uint16_t t;
michael@0 238
michael@0 239 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
michael@0 240 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
michael@0 241
michael@0 242 while (height--)
michael@0 243 {
michael@0 244 dst = dst_line;
michael@0 245 dst_line += dst_stride;
michael@0 246 src = src_line;
michael@0 247 src_line += src_stride;
michael@0 248 w = width;
michael@0 249
michael@0 250 while (w--)
michael@0 251 {
michael@0 252 s = *src++;
michael@0 253
michael@0 254 if (s == 0)
michael@0 255 *dst = 0;
michael@0 256 else if (s != 0xff)
michael@0 257 *dst = MUL_UN8 (s, *dst, t);
michael@0 258
michael@0 259 dst++;
michael@0 260 }
michael@0 261 }
michael@0 262 }
michael@0 263
michael@0 264 static void
michael@0 265 fast_composite_over_n_8_8888 (pixman_implementation_t *imp,
michael@0 266 pixman_composite_info_t *info)
michael@0 267 {
michael@0 268 PIXMAN_COMPOSITE_ARGS (info);
michael@0 269 uint32_t src, srca;
michael@0 270 uint32_t *dst_line, *dst, d;
michael@0 271 uint8_t *mask_line, *mask, m;
michael@0 272 int dst_stride, mask_stride;
michael@0 273 int32_t w;
michael@0 274
michael@0 275 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 276
michael@0 277 srca = src >> 24;
michael@0 278 if (src == 0)
michael@0 279 return;
michael@0 280
michael@0 281 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 282 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
michael@0 283
michael@0 284 while (height--)
michael@0 285 {
michael@0 286 dst = dst_line;
michael@0 287 dst_line += dst_stride;
michael@0 288 mask = mask_line;
michael@0 289 mask_line += mask_stride;
michael@0 290 w = width;
michael@0 291
michael@0 292 while (w--)
michael@0 293 {
michael@0 294 m = *mask++;
michael@0 295 if (m == 0xff)
michael@0 296 {
michael@0 297 if (srca == 0xff)
michael@0 298 *dst = src;
michael@0 299 else
michael@0 300 *dst = over (src, *dst);
michael@0 301 }
michael@0 302 else if (m)
michael@0 303 {
michael@0 304 d = in (src, m);
michael@0 305 *dst = over (d, *dst);
michael@0 306 }
michael@0 307 dst++;
michael@0 308 }
michael@0 309 }
michael@0 310 }
michael@0 311
michael@0 312 static void
michael@0 313 fast_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
michael@0 314 pixman_composite_info_t *info)
michael@0 315 {
michael@0 316 PIXMAN_COMPOSITE_ARGS (info);
michael@0 317 uint32_t src, s;
michael@0 318 uint32_t *dst_line, *dst, d;
michael@0 319 uint32_t *mask_line, *mask, ma;
michael@0 320 int dst_stride, mask_stride;
michael@0 321 int32_t w;
michael@0 322
michael@0 323 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 324
michael@0 325 if (src == 0)
michael@0 326 return;
michael@0 327
michael@0 328 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 329 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
michael@0 330
michael@0 331 while (height--)
michael@0 332 {
michael@0 333 dst = dst_line;
michael@0 334 dst_line += dst_stride;
michael@0 335 mask = mask_line;
michael@0 336 mask_line += mask_stride;
michael@0 337 w = width;
michael@0 338
michael@0 339 while (w--)
michael@0 340 {
michael@0 341 ma = *mask++;
michael@0 342
michael@0 343 if (ma)
michael@0 344 {
michael@0 345 d = *dst;
michael@0 346 s = src;
michael@0 347
michael@0 348 UN8x4_MUL_UN8x4_ADD_UN8x4 (s, ma, d);
michael@0 349
michael@0 350 *dst = s;
michael@0 351 }
michael@0 352
michael@0 353 dst++;
michael@0 354 }
michael@0 355 }
michael@0 356 }
michael@0 357
michael@0 358 static void
michael@0 359 fast_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
michael@0 360 pixman_composite_info_t *info)
michael@0 361 {
michael@0 362 PIXMAN_COMPOSITE_ARGS (info);
michael@0 363 uint32_t src, srca, s;
michael@0 364 uint32_t *dst_line, *dst, d;
michael@0 365 uint32_t *mask_line, *mask, ma;
michael@0 366 int dst_stride, mask_stride;
michael@0 367 int32_t w;
michael@0 368
michael@0 369 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 370
michael@0 371 srca = src >> 24;
michael@0 372 if (src == 0)
michael@0 373 return;
michael@0 374
michael@0 375 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 376 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
michael@0 377
michael@0 378 while (height--)
michael@0 379 {
michael@0 380 dst = dst_line;
michael@0 381 dst_line += dst_stride;
michael@0 382 mask = mask_line;
michael@0 383 mask_line += mask_stride;
michael@0 384 w = width;
michael@0 385
michael@0 386 while (w--)
michael@0 387 {
michael@0 388 ma = *mask++;
michael@0 389 if (ma == 0xffffffff)
michael@0 390 {
michael@0 391 if (srca == 0xff)
michael@0 392 *dst = src;
michael@0 393 else
michael@0 394 *dst = over (src, *dst);
michael@0 395 }
michael@0 396 else if (ma)
michael@0 397 {
michael@0 398 d = *dst;
michael@0 399 s = src;
michael@0 400
michael@0 401 UN8x4_MUL_UN8x4 (s, ma);
michael@0 402 UN8x4_MUL_UN8 (ma, srca);
michael@0 403 ma = ~ma;
michael@0 404 UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ma, s);
michael@0 405
michael@0 406 *dst = d;
michael@0 407 }
michael@0 408
michael@0 409 dst++;
michael@0 410 }
michael@0 411 }
michael@0 412 }
michael@0 413
michael@0 414 static void
michael@0 415 fast_composite_over_n_8_0888 (pixman_implementation_t *imp,
michael@0 416 pixman_composite_info_t *info)
michael@0 417 {
michael@0 418 PIXMAN_COMPOSITE_ARGS (info);
michael@0 419 uint32_t src, srca;
michael@0 420 uint8_t *dst_line, *dst;
michael@0 421 uint32_t d;
michael@0 422 uint8_t *mask_line, *mask, m;
michael@0 423 int dst_stride, mask_stride;
michael@0 424 int32_t w;
michael@0 425
michael@0 426 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 427
michael@0 428 srca = src >> 24;
michael@0 429 if (src == 0)
michael@0 430 return;
michael@0 431
michael@0 432 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 3);
michael@0 433 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
michael@0 434
michael@0 435 while (height--)
michael@0 436 {
michael@0 437 dst = dst_line;
michael@0 438 dst_line += dst_stride;
michael@0 439 mask = mask_line;
michael@0 440 mask_line += mask_stride;
michael@0 441 w = width;
michael@0 442
michael@0 443 while (w--)
michael@0 444 {
michael@0 445 m = *mask++;
michael@0 446 if (m == 0xff)
michael@0 447 {
michael@0 448 if (srca == 0xff)
michael@0 449 {
michael@0 450 d = src;
michael@0 451 }
michael@0 452 else
michael@0 453 {
michael@0 454 d = fetch_24 (dst);
michael@0 455 d = over (src, d);
michael@0 456 }
michael@0 457 store_24 (dst, d);
michael@0 458 }
michael@0 459 else if (m)
michael@0 460 {
michael@0 461 d = over (in (src, m), fetch_24 (dst));
michael@0 462 store_24 (dst, d);
michael@0 463 }
michael@0 464 dst += 3;
michael@0 465 }
michael@0 466 }
michael@0 467 }
michael@0 468
michael@0 469 static void
michael@0 470 fast_composite_over_n_8_0565 (pixman_implementation_t *imp,
michael@0 471 pixman_composite_info_t *info)
michael@0 472 {
michael@0 473 PIXMAN_COMPOSITE_ARGS (info);
michael@0 474 uint32_t src, srca;
michael@0 475 uint16_t *dst_line, *dst;
michael@0 476 uint32_t d;
michael@0 477 uint8_t *mask_line, *mask, m;
michael@0 478 int dst_stride, mask_stride;
michael@0 479 int32_t w;
michael@0 480
michael@0 481 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 482
michael@0 483 srca = src >> 24;
michael@0 484 if (src == 0)
michael@0 485 return;
michael@0 486
michael@0 487 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
michael@0 488 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
michael@0 489
michael@0 490 while (height--)
michael@0 491 {
michael@0 492 dst = dst_line;
michael@0 493 dst_line += dst_stride;
michael@0 494 mask = mask_line;
michael@0 495 mask_line += mask_stride;
michael@0 496 w = width;
michael@0 497
michael@0 498 while (w--)
michael@0 499 {
michael@0 500 m = *mask++;
michael@0 501 if (m == 0xff)
michael@0 502 {
michael@0 503 if (srca == 0xff)
michael@0 504 {
michael@0 505 d = src;
michael@0 506 }
michael@0 507 else
michael@0 508 {
michael@0 509 d = *dst;
michael@0 510 d = over (src, convert_0565_to_0888 (d));
michael@0 511 }
michael@0 512 *dst = convert_8888_to_0565 (d);
michael@0 513 }
michael@0 514 else if (m)
michael@0 515 {
michael@0 516 d = *dst;
michael@0 517 d = over (in (src, m), convert_0565_to_0888 (d));
michael@0 518 *dst = convert_8888_to_0565 (d);
michael@0 519 }
michael@0 520 dst++;
michael@0 521 }
michael@0 522 }
michael@0 523 }
michael@0 524
michael@0 525 static void
michael@0 526 fast_composite_over_n_8888_0565_ca (pixman_implementation_t *imp,
michael@0 527 pixman_composite_info_t *info)
michael@0 528 {
michael@0 529 PIXMAN_COMPOSITE_ARGS (info);
michael@0 530 uint32_t src, srca, s;
michael@0 531 uint16_t src16;
michael@0 532 uint16_t *dst_line, *dst;
michael@0 533 uint32_t d;
michael@0 534 uint32_t *mask_line, *mask, ma;
michael@0 535 int dst_stride, mask_stride;
michael@0 536 int32_t w;
michael@0 537
michael@0 538 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 539
michael@0 540 srca = src >> 24;
michael@0 541 if (src == 0)
michael@0 542 return;
michael@0 543
michael@0 544 src16 = convert_8888_to_0565 (src);
michael@0 545
michael@0 546 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
michael@0 547 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
michael@0 548
michael@0 549 while (height--)
michael@0 550 {
michael@0 551 dst = dst_line;
michael@0 552 dst_line += dst_stride;
michael@0 553 mask = mask_line;
michael@0 554 mask_line += mask_stride;
michael@0 555 w = width;
michael@0 556
michael@0 557 while (w--)
michael@0 558 {
michael@0 559 ma = *mask++;
michael@0 560 if (ma == 0xffffffff)
michael@0 561 {
michael@0 562 if (srca == 0xff)
michael@0 563 {
michael@0 564 *dst = src16;
michael@0 565 }
michael@0 566 else
michael@0 567 {
michael@0 568 d = *dst;
michael@0 569 d = over (src, convert_0565_to_0888 (d));
michael@0 570 *dst = convert_8888_to_0565 (d);
michael@0 571 }
michael@0 572 }
michael@0 573 else if (ma)
michael@0 574 {
michael@0 575 d = *dst;
michael@0 576 d = convert_0565_to_0888 (d);
michael@0 577
michael@0 578 s = src;
michael@0 579
michael@0 580 UN8x4_MUL_UN8x4 (s, ma);
michael@0 581 UN8x4_MUL_UN8 (ma, srca);
michael@0 582 ma = ~ma;
michael@0 583 UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ma, s);
michael@0 584
michael@0 585 *dst = convert_8888_to_0565 (d);
michael@0 586 }
michael@0 587 dst++;
michael@0 588 }
michael@0 589 }
michael@0 590 }
michael@0 591
michael@0 592 static void
michael@0 593 fast_composite_over_8888_8888 (pixman_implementation_t *imp,
michael@0 594 pixman_composite_info_t *info)
michael@0 595 {
michael@0 596 PIXMAN_COMPOSITE_ARGS (info);
michael@0 597 uint32_t *dst_line, *dst;
michael@0 598 uint32_t *src_line, *src, s;
michael@0 599 int dst_stride, src_stride;
michael@0 600 uint8_t a;
michael@0 601 int32_t w;
michael@0 602
michael@0 603 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 604 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
michael@0 605
michael@0 606 while (height--)
michael@0 607 {
michael@0 608 dst = dst_line;
michael@0 609 dst_line += dst_stride;
michael@0 610 src = src_line;
michael@0 611 src_line += src_stride;
michael@0 612 w = width;
michael@0 613
michael@0 614 while (w--)
michael@0 615 {
michael@0 616 s = *src++;
michael@0 617 a = s >> 24;
michael@0 618 if (a == 0xff)
michael@0 619 *dst = s;
michael@0 620 else if (s)
michael@0 621 *dst = over (s, *dst);
michael@0 622 dst++;
michael@0 623 }
michael@0 624 }
michael@0 625 }
michael@0 626
michael@0 627 static void
michael@0 628 fast_composite_src_x888_8888 (pixman_implementation_t *imp,
michael@0 629 pixman_composite_info_t *info)
michael@0 630 {
michael@0 631 PIXMAN_COMPOSITE_ARGS (info);
michael@0 632 uint32_t *dst_line, *dst;
michael@0 633 uint32_t *src_line, *src;
michael@0 634 int dst_stride, src_stride;
michael@0 635 int32_t w;
michael@0 636
michael@0 637 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 638 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
michael@0 639
michael@0 640 while (height--)
michael@0 641 {
michael@0 642 dst = dst_line;
michael@0 643 dst_line += dst_stride;
michael@0 644 src = src_line;
michael@0 645 src_line += src_stride;
michael@0 646 w = width;
michael@0 647
michael@0 648 while (w--)
michael@0 649 *dst++ = (*src++) | 0xff000000;
michael@0 650 }
michael@0 651 }
michael@0 652
michael@0 653 #if 0
michael@0 654 static void
michael@0 655 fast_composite_over_8888_0888 (pixman_implementation_t *imp,
michael@0 656 pixman_composite_info_t *info)
michael@0 657 {
michael@0 658 PIXMAN_COMPOSITE_ARGS (info);
michael@0 659 uint8_t *dst_line, *dst;
michael@0 660 uint32_t d;
michael@0 661 uint32_t *src_line, *src, s;
michael@0 662 uint8_t a;
michael@0 663 int dst_stride, src_stride;
michael@0 664 int32_t w;
michael@0 665
michael@0 666 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 3);
michael@0 667 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
michael@0 668
michael@0 669 while (height--)
michael@0 670 {
michael@0 671 dst = dst_line;
michael@0 672 dst_line += dst_stride;
michael@0 673 src = src_line;
michael@0 674 src_line += src_stride;
michael@0 675 w = width;
michael@0 676
michael@0 677 while (w--)
michael@0 678 {
michael@0 679 s = *src++;
michael@0 680 a = s >> 24;
michael@0 681 if (a)
michael@0 682 {
michael@0 683 if (a == 0xff)
michael@0 684 d = s;
michael@0 685 else
michael@0 686 d = over (s, fetch_24 (dst));
michael@0 687
michael@0 688 store_24 (dst, d);
michael@0 689 }
michael@0 690 dst += 3;
michael@0 691 }
michael@0 692 }
michael@0 693 }
michael@0 694 #endif
michael@0 695
michael@0 696 static void
michael@0 697 fast_composite_over_8888_0565 (pixman_implementation_t *imp,
michael@0 698 pixman_composite_info_t *info)
michael@0 699 {
michael@0 700 PIXMAN_COMPOSITE_ARGS (info);
michael@0 701 uint16_t *dst_line, *dst;
michael@0 702 uint32_t d;
michael@0 703 uint32_t *src_line, *src, s;
michael@0 704 uint8_t a;
michael@0 705 int dst_stride, src_stride;
michael@0 706 int32_t w;
michael@0 707
michael@0 708 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
michael@0 709 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
michael@0 710
michael@0 711 while (height--)
michael@0 712 {
michael@0 713 dst = dst_line;
michael@0 714 dst_line += dst_stride;
michael@0 715 src = src_line;
michael@0 716 src_line += src_stride;
michael@0 717 w = width;
michael@0 718
michael@0 719 while (w--)
michael@0 720 {
michael@0 721 s = *src++;
michael@0 722 a = s >> 24;
michael@0 723 if (s)
michael@0 724 {
michael@0 725 if (a == 0xff)
michael@0 726 {
michael@0 727 d = s;
michael@0 728 }
michael@0 729 else
michael@0 730 {
michael@0 731 d = *dst;
michael@0 732 d = over (s, convert_0565_to_0888 (d));
michael@0 733 }
michael@0 734 *dst = convert_8888_to_0565 (d);
michael@0 735 }
michael@0 736 dst++;
michael@0 737 }
michael@0 738 }
michael@0 739 }
michael@0 740
michael@0 741 static void
michael@0 742 fast_composite_add_8_8 (pixman_implementation_t *imp,
michael@0 743 pixman_composite_info_t *info)
michael@0 744 {
michael@0 745 PIXMAN_COMPOSITE_ARGS (info);
michael@0 746 uint8_t *dst_line, *dst;
michael@0 747 uint8_t *src_line, *src;
michael@0 748 int dst_stride, src_stride;
michael@0 749 int32_t w;
michael@0 750 uint8_t s, d;
michael@0 751 uint16_t t;
michael@0 752
michael@0 753 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
michael@0 754 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
michael@0 755
michael@0 756 while (height--)
michael@0 757 {
michael@0 758 dst = dst_line;
michael@0 759 dst_line += dst_stride;
michael@0 760 src = src_line;
michael@0 761 src_line += src_stride;
michael@0 762 w = width;
michael@0 763
michael@0 764 while (w--)
michael@0 765 {
michael@0 766 s = *src++;
michael@0 767 if (s)
michael@0 768 {
michael@0 769 if (s != 0xff)
michael@0 770 {
michael@0 771 d = *dst;
michael@0 772 t = d + s;
michael@0 773 s = t | (0 - (t >> 8));
michael@0 774 }
michael@0 775 *dst = s;
michael@0 776 }
michael@0 777 dst++;
michael@0 778 }
michael@0 779 }
michael@0 780 }
michael@0 781
michael@0 782 static void
michael@0 783 fast_composite_add_0565_0565 (pixman_implementation_t *imp,
michael@0 784 pixman_composite_info_t *info)
michael@0 785 {
michael@0 786 PIXMAN_COMPOSITE_ARGS (info);
michael@0 787 uint16_t *dst_line, *dst;
michael@0 788 uint32_t d;
michael@0 789 uint16_t *src_line, *src;
michael@0 790 uint32_t s;
michael@0 791 int dst_stride, src_stride;
michael@0 792 int32_t w;
michael@0 793
michael@0 794 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint16_t, src_stride, src_line, 1);
michael@0 795 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
michael@0 796
michael@0 797 while (height--)
michael@0 798 {
michael@0 799 dst = dst_line;
michael@0 800 dst_line += dst_stride;
michael@0 801 src = src_line;
michael@0 802 src_line += src_stride;
michael@0 803 w = width;
michael@0 804
michael@0 805 while (w--)
michael@0 806 {
michael@0 807 s = *src++;
michael@0 808 if (s)
michael@0 809 {
michael@0 810 d = *dst;
michael@0 811 s = convert_0565_to_8888 (s);
michael@0 812 if (d)
michael@0 813 {
michael@0 814 d = convert_0565_to_8888 (d);
michael@0 815 UN8x4_ADD_UN8x4 (s, d);
michael@0 816 }
michael@0 817 *dst = convert_8888_to_0565 (s);
michael@0 818 }
michael@0 819 dst++;
michael@0 820 }
michael@0 821 }
michael@0 822 }
michael@0 823
michael@0 824 static void
michael@0 825 fast_composite_add_8888_8888 (pixman_implementation_t *imp,
michael@0 826 pixman_composite_info_t *info)
michael@0 827 {
michael@0 828 PIXMAN_COMPOSITE_ARGS (info);
michael@0 829 uint32_t *dst_line, *dst;
michael@0 830 uint32_t *src_line, *src;
michael@0 831 int dst_stride, src_stride;
michael@0 832 int32_t w;
michael@0 833 uint32_t s, d;
michael@0 834
michael@0 835 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
michael@0 836 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 837
michael@0 838 while (height--)
michael@0 839 {
michael@0 840 dst = dst_line;
michael@0 841 dst_line += dst_stride;
michael@0 842 src = src_line;
michael@0 843 src_line += src_stride;
michael@0 844 w = width;
michael@0 845
michael@0 846 while (w--)
michael@0 847 {
michael@0 848 s = *src++;
michael@0 849 if (s)
michael@0 850 {
michael@0 851 if (s != 0xffffffff)
michael@0 852 {
michael@0 853 d = *dst;
michael@0 854 if (d)
michael@0 855 UN8x4_ADD_UN8x4 (s, d);
michael@0 856 }
michael@0 857 *dst = s;
michael@0 858 }
michael@0 859 dst++;
michael@0 860 }
michael@0 861 }
michael@0 862 }
michael@0 863
michael@0 864 static void
michael@0 865 fast_composite_add_n_8_8 (pixman_implementation_t *imp,
michael@0 866 pixman_composite_info_t *info)
michael@0 867 {
michael@0 868 PIXMAN_COMPOSITE_ARGS (info);
michael@0 869 uint8_t *dst_line, *dst;
michael@0 870 uint8_t *mask_line, *mask;
michael@0 871 int dst_stride, mask_stride;
michael@0 872 int32_t w;
michael@0 873 uint32_t src;
michael@0 874 uint8_t sa;
michael@0 875
michael@0 876 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
michael@0 877 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
michael@0 878 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 879 sa = (src >> 24);
michael@0 880
michael@0 881 while (height--)
michael@0 882 {
michael@0 883 dst = dst_line;
michael@0 884 dst_line += dst_stride;
michael@0 885 mask = mask_line;
michael@0 886 mask_line += mask_stride;
michael@0 887 w = width;
michael@0 888
michael@0 889 while (w--)
michael@0 890 {
michael@0 891 uint16_t tmp;
michael@0 892 uint16_t a;
michael@0 893 uint32_t m, d;
michael@0 894 uint32_t r;
michael@0 895
michael@0 896 a = *mask++;
michael@0 897 d = *dst;
michael@0 898
michael@0 899 m = MUL_UN8 (sa, a, tmp);
michael@0 900 r = ADD_UN8 (m, d, tmp);
michael@0 901
michael@0 902 *dst++ = r;
michael@0 903 }
michael@0 904 }
michael@0 905 }
michael@0 906
michael@0 907 #ifdef WORDS_BIGENDIAN
michael@0 908 #define CREATE_BITMASK(n) (0x80000000 >> (n))
michael@0 909 #define UPDATE_BITMASK(n) ((n) >> 1)
michael@0 910 #else
michael@0 911 #define CREATE_BITMASK(n) (1 << (n))
michael@0 912 #define UPDATE_BITMASK(n) ((n) << 1)
michael@0 913 #endif
michael@0 914
michael@0 915 #define TEST_BIT(p, n) \
michael@0 916 (*((p) + ((n) >> 5)) & CREATE_BITMASK ((n) & 31))
michael@0 917 #define SET_BIT(p, n) \
michael@0 918 do { *((p) + ((n) >> 5)) |= CREATE_BITMASK ((n) & 31); } while (0);
michael@0 919
michael@0 920 static void
michael@0 921 fast_composite_add_1_1 (pixman_implementation_t *imp,
michael@0 922 pixman_composite_info_t *info)
michael@0 923 {
michael@0 924 PIXMAN_COMPOSITE_ARGS (info);
michael@0 925 uint32_t *dst_line, *dst;
michael@0 926 uint32_t *src_line, *src;
michael@0 927 int dst_stride, src_stride;
michael@0 928 int32_t w;
michael@0 929
michael@0 930 PIXMAN_IMAGE_GET_LINE (src_image, 0, src_y, uint32_t,
michael@0 931 src_stride, src_line, 1);
michael@0 932 PIXMAN_IMAGE_GET_LINE (dest_image, 0, dest_y, uint32_t,
michael@0 933 dst_stride, dst_line, 1);
michael@0 934
michael@0 935 while (height--)
michael@0 936 {
michael@0 937 dst = dst_line;
michael@0 938 dst_line += dst_stride;
michael@0 939 src = src_line;
michael@0 940 src_line += src_stride;
michael@0 941 w = width;
michael@0 942
michael@0 943 while (w--)
michael@0 944 {
michael@0 945 /*
michael@0 946 * TODO: improve performance by processing uint32_t data instead
michael@0 947 * of individual bits
michael@0 948 */
michael@0 949 if (TEST_BIT (src, src_x + w))
michael@0 950 SET_BIT (dst, dest_x + w);
michael@0 951 }
michael@0 952 }
michael@0 953 }
michael@0 954
michael@0 955 static void
michael@0 956 fast_composite_over_n_1_8888 (pixman_implementation_t *imp,
michael@0 957 pixman_composite_info_t *info)
michael@0 958 {
michael@0 959 PIXMAN_COMPOSITE_ARGS (info);
michael@0 960 uint32_t src, srca;
michael@0 961 uint32_t *dst, *dst_line;
michael@0 962 uint32_t *mask, *mask_line;
michael@0 963 int mask_stride, dst_stride;
michael@0 964 uint32_t bitcache, bitmask;
michael@0 965 int32_t w;
michael@0 966
michael@0 967 if (width <= 0)
michael@0 968 return;
michael@0 969
michael@0 970 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 971 srca = src >> 24;
michael@0 972 if (src == 0)
michael@0 973 return;
michael@0 974
michael@0 975 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t,
michael@0 976 dst_stride, dst_line, 1);
michael@0 977 PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t,
michael@0 978 mask_stride, mask_line, 1);
michael@0 979 mask_line += mask_x >> 5;
michael@0 980
michael@0 981 if (srca == 0xff)
michael@0 982 {
michael@0 983 while (height--)
michael@0 984 {
michael@0 985 dst = dst_line;
michael@0 986 dst_line += dst_stride;
michael@0 987 mask = mask_line;
michael@0 988 mask_line += mask_stride;
michael@0 989 w = width;
michael@0 990
michael@0 991 bitcache = *mask++;
michael@0 992 bitmask = CREATE_BITMASK (mask_x & 31);
michael@0 993
michael@0 994 while (w--)
michael@0 995 {
michael@0 996 if (bitmask == 0)
michael@0 997 {
michael@0 998 bitcache = *mask++;
michael@0 999 bitmask = CREATE_BITMASK (0);
michael@0 1000 }
michael@0 1001 if (bitcache & bitmask)
michael@0 1002 *dst = src;
michael@0 1003 bitmask = UPDATE_BITMASK (bitmask);
michael@0 1004 dst++;
michael@0 1005 }
michael@0 1006 }
michael@0 1007 }
michael@0 1008 else
michael@0 1009 {
michael@0 1010 while (height--)
michael@0 1011 {
michael@0 1012 dst = dst_line;
michael@0 1013 dst_line += dst_stride;
michael@0 1014 mask = mask_line;
michael@0 1015 mask_line += mask_stride;
michael@0 1016 w = width;
michael@0 1017
michael@0 1018 bitcache = *mask++;
michael@0 1019 bitmask = CREATE_BITMASK (mask_x & 31);
michael@0 1020
michael@0 1021 while (w--)
michael@0 1022 {
michael@0 1023 if (bitmask == 0)
michael@0 1024 {
michael@0 1025 bitcache = *mask++;
michael@0 1026 bitmask = CREATE_BITMASK (0);
michael@0 1027 }
michael@0 1028 if (bitcache & bitmask)
michael@0 1029 *dst = over (src, *dst);
michael@0 1030 bitmask = UPDATE_BITMASK (bitmask);
michael@0 1031 dst++;
michael@0 1032 }
michael@0 1033 }
michael@0 1034 }
michael@0 1035 }
michael@0 1036
michael@0 1037 static void
michael@0 1038 fast_composite_over_n_1_0565 (pixman_implementation_t *imp,
michael@0 1039 pixman_composite_info_t *info)
michael@0 1040 {
michael@0 1041 PIXMAN_COMPOSITE_ARGS (info);
michael@0 1042 uint32_t src, srca;
michael@0 1043 uint16_t *dst, *dst_line;
michael@0 1044 uint32_t *mask, *mask_line;
michael@0 1045 int mask_stride, dst_stride;
michael@0 1046 uint32_t bitcache, bitmask;
michael@0 1047 int32_t w;
michael@0 1048 uint32_t d;
michael@0 1049 uint16_t src565;
michael@0 1050
michael@0 1051 if (width <= 0)
michael@0 1052 return;
michael@0 1053
michael@0 1054 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 1055 srca = src >> 24;
michael@0 1056 if (src == 0)
michael@0 1057 return;
michael@0 1058
michael@0 1059 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t,
michael@0 1060 dst_stride, dst_line, 1);
michael@0 1061 PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t,
michael@0 1062 mask_stride, mask_line, 1);
michael@0 1063 mask_line += mask_x >> 5;
michael@0 1064
michael@0 1065 if (srca == 0xff)
michael@0 1066 {
michael@0 1067 src565 = convert_8888_to_0565 (src);
michael@0 1068 while (height--)
michael@0 1069 {
michael@0 1070 dst = dst_line;
michael@0 1071 dst_line += dst_stride;
michael@0 1072 mask = mask_line;
michael@0 1073 mask_line += mask_stride;
michael@0 1074 w = width;
michael@0 1075
michael@0 1076 bitcache = *mask++;
michael@0 1077 bitmask = CREATE_BITMASK (mask_x & 31);
michael@0 1078
michael@0 1079 while (w--)
michael@0 1080 {
michael@0 1081 if (bitmask == 0)
michael@0 1082 {
michael@0 1083 bitcache = *mask++;
michael@0 1084 bitmask = CREATE_BITMASK (0);
michael@0 1085 }
michael@0 1086 if (bitcache & bitmask)
michael@0 1087 *dst = src565;
michael@0 1088 bitmask = UPDATE_BITMASK (bitmask);
michael@0 1089 dst++;
michael@0 1090 }
michael@0 1091 }
michael@0 1092 }
michael@0 1093 else
michael@0 1094 {
michael@0 1095 while (height--)
michael@0 1096 {
michael@0 1097 dst = dst_line;
michael@0 1098 dst_line += dst_stride;
michael@0 1099 mask = mask_line;
michael@0 1100 mask_line += mask_stride;
michael@0 1101 w = width;
michael@0 1102
michael@0 1103 bitcache = *mask++;
michael@0 1104 bitmask = CREATE_BITMASK (mask_x & 31);
michael@0 1105
michael@0 1106 while (w--)
michael@0 1107 {
michael@0 1108 if (bitmask == 0)
michael@0 1109 {
michael@0 1110 bitcache = *mask++;
michael@0 1111 bitmask = CREATE_BITMASK (0);
michael@0 1112 }
michael@0 1113 if (bitcache & bitmask)
michael@0 1114 {
michael@0 1115 d = over (src, convert_0565_to_0888 (*dst));
michael@0 1116 *dst = convert_8888_to_0565 (d);
michael@0 1117 }
michael@0 1118 bitmask = UPDATE_BITMASK (bitmask);
michael@0 1119 dst++;
michael@0 1120 }
michael@0 1121 }
michael@0 1122 }
michael@0 1123 }
michael@0 1124
michael@0 1125 /*
michael@0 1126 * Simple bitblt
michael@0 1127 */
michael@0 1128
michael@0 1129 static void
michael@0 1130 fast_composite_solid_fill (pixman_implementation_t *imp,
michael@0 1131 pixman_composite_info_t *info)
michael@0 1132 {
michael@0 1133 PIXMAN_COMPOSITE_ARGS (info);
michael@0 1134 uint32_t src;
michael@0 1135
michael@0 1136 src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
michael@0 1137
michael@0 1138 if (dest_image->bits.format == PIXMAN_a1)
michael@0 1139 {
michael@0 1140 src = src >> 31;
michael@0 1141 }
michael@0 1142 else if (dest_image->bits.format == PIXMAN_a8)
michael@0 1143 {
michael@0 1144 src = src >> 24;
michael@0 1145 }
michael@0 1146 else if (dest_image->bits.format == PIXMAN_r5g6b5 ||
michael@0 1147 dest_image->bits.format == PIXMAN_b5g6r5)
michael@0 1148 {
michael@0 1149 src = convert_8888_to_0565 (src);
michael@0 1150 }
michael@0 1151
michael@0 1152 pixman_fill (dest_image->bits.bits, dest_image->bits.rowstride,
michael@0 1153 PIXMAN_FORMAT_BPP (dest_image->bits.format),
michael@0 1154 dest_x, dest_y,
michael@0 1155 width, height,
michael@0 1156 src);
michael@0 1157 }
michael@0 1158
michael@0 1159 static void
michael@0 1160 fast_composite_src_memcpy (pixman_implementation_t *imp,
michael@0 1161 pixman_composite_info_t *info)
michael@0 1162 {
michael@0 1163 PIXMAN_COMPOSITE_ARGS (info);
michael@0 1164 int bpp = PIXMAN_FORMAT_BPP (dest_image->bits.format) / 8;
michael@0 1165 uint32_t n_bytes = width * bpp;
michael@0 1166 int dst_stride, src_stride;
michael@0 1167 uint8_t *dst;
michael@0 1168 uint8_t *src;
michael@0 1169
michael@0 1170 src_stride = src_image->bits.rowstride * 4;
michael@0 1171 dst_stride = dest_image->bits.rowstride * 4;
michael@0 1172
michael@0 1173 src = (uint8_t *)src_image->bits.bits + src_y * src_stride + src_x * bpp;
michael@0 1174 dst = (uint8_t *)dest_image->bits.bits + dest_y * dst_stride + dest_x * bpp;
michael@0 1175
michael@0 1176 while (height--)
michael@0 1177 {
michael@0 1178 memcpy (dst, src, n_bytes);
michael@0 1179
michael@0 1180 dst += dst_stride;
michael@0 1181 src += src_stride;
michael@0 1182 }
michael@0 1183 }
michael@0 1184
michael@0 1185 FAST_NEAREST (8888_8888_cover, 8888, 8888, uint32_t, uint32_t, SRC, COVER)
michael@0 1186 FAST_NEAREST (8888_8888_none, 8888, 8888, uint32_t, uint32_t, SRC, NONE)
michael@0 1187 FAST_NEAREST (8888_8888_pad, 8888, 8888, uint32_t, uint32_t, SRC, PAD)
michael@0 1188 FAST_NEAREST (8888_8888_normal, 8888, 8888, uint32_t, uint32_t, SRC, NORMAL)
michael@0 1189 FAST_NEAREST (x888_8888_cover, x888, 8888, uint32_t, uint32_t, SRC, COVER)
michael@0 1190 FAST_NEAREST (x888_8888_pad, x888, 8888, uint32_t, uint32_t, SRC, PAD)
michael@0 1191 FAST_NEAREST (x888_8888_normal, x888, 8888, uint32_t, uint32_t, SRC, NORMAL)
michael@0 1192 FAST_NEAREST (8888_8888_cover, 8888, 8888, uint32_t, uint32_t, OVER, COVER)
michael@0 1193 FAST_NEAREST (8888_8888_none, 8888, 8888, uint32_t, uint32_t, OVER, NONE)
michael@0 1194 FAST_NEAREST (8888_8888_pad, 8888, 8888, uint32_t, uint32_t, OVER, PAD)
michael@0 1195 FAST_NEAREST (8888_8888_normal, 8888, 8888, uint32_t, uint32_t, OVER, NORMAL)
michael@0 1196 FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, SRC, COVER)
michael@0 1197 FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, SRC, NONE)
michael@0 1198 FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, SRC, PAD)
michael@0 1199 FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, SRC, NORMAL)
michael@0 1200 FAST_NEAREST (565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL)
michael@0 1201 FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, OVER, COVER)
michael@0 1202 FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, OVER, NONE)
michael@0 1203 FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, OVER, PAD)
michael@0 1204 FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, OVER, NORMAL)
michael@0 1205
michael@0 1206 static force_inline void
michael@0 1207 scaled_bilinear_scanline_8888_565_OVER (uint16_t * dst,
michael@0 1208 const uint32_t * mask,
michael@0 1209 const uint32_t * src_top,
michael@0 1210 const uint32_t * src_bottom,
michael@0 1211 int32_t w,
michael@0 1212 int wt,
michael@0 1213 int wb,
michael@0 1214 pixman_fixed_t vx,
michael@0 1215 pixman_fixed_t unit_x,
michael@0 1216 pixman_fixed_t max_vx,
michael@0 1217 pixman_bool_t zero_src)
michael@0 1218 {
michael@0 1219 while ((w -= 1) >= 0)
michael@0 1220 {
michael@0 1221 uint32_t tl = src_top [pixman_fixed_to_int (vx)];
michael@0 1222 uint32_t tr = src_top [pixman_fixed_to_int (vx) + 1];
michael@0 1223 uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
michael@0 1224 uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
michael@0 1225 uint32_t src, result;
michael@0 1226 uint16_t d;
michael@0 1227 d = *dst;
michael@0 1228 src = bilinear_interpolation (tl, tr,
michael@0 1229 bl, br,
michael@0 1230 pixman_fixed_to_bilinear_weight(vx),
michael@0 1231 wb);
michael@0 1232 vx += unit_x;
michael@0 1233 result = over (src, convert_0565_to_0888 (d));
michael@0 1234 *dst++ = convert_8888_to_0565 (result);
michael@0 1235 }
michael@0 1236 }
michael@0 1237
michael@0 1238 static force_inline void
michael@0 1239 scaled_bilinear_scanline_8888_8888_OVER (uint32_t * dst,
michael@0 1240 const uint32_t * mask,
michael@0 1241 const uint32_t * src_top,
michael@0 1242 const uint32_t * src_bottom,
michael@0 1243 int32_t w,
michael@0 1244 int wt,
michael@0 1245 int wb,
michael@0 1246 pixman_fixed_t vx,
michael@0 1247 pixman_fixed_t unit_x,
michael@0 1248 pixman_fixed_t max_vx,
michael@0 1249 pixman_bool_t zero_src)
michael@0 1250 {
michael@0 1251 while ((w -= 1) >= 0)
michael@0 1252 {
michael@0 1253 uint32_t tl = src_top [pixman_fixed_to_int (vx)];
michael@0 1254 uint32_t tr = src_top [pixman_fixed_to_int (vx) + 1];
michael@0 1255 uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
michael@0 1256 uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
michael@0 1257 uint32_t src;
michael@0 1258 uint32_t d;
michael@0 1259 uint32_t result;
michael@0 1260 d = *dst;
michael@0 1261 src = bilinear_interpolation (tl, tr,
michael@0 1262 bl, br,
michael@0 1263 pixman_fixed_to_bilinear_weight(vx),
michael@0 1264 wb);
michael@0 1265 vx += unit_x;
michael@0 1266 *dst++ = over (src, d);
michael@0 1267 }
michael@0 1268 }
michael@0 1269
michael@0 1270 #ifndef LOWER_QUALITY_INTERPOLATION
michael@0 1271
michael@0 1272 static force_inline void
michael@0 1273 scaled_bilinear_scanline_565_565_SRC (uint16_t * dst,
michael@0 1274 const uint32_t * mask,
michael@0 1275 const uint16_t * src_top,
michael@0 1276 const uint16_t * src_bottom,
michael@0 1277 int32_t w,
michael@0 1278 int wt,
michael@0 1279 int wb,
michael@0 1280 pixman_fixed_t vx,
michael@0 1281 pixman_fixed_t unit_x,
michael@0 1282 pixman_fixed_t max_vx,
michael@0 1283 pixman_bool_t zero_src)
michael@0 1284 {
michael@0 1285 while ((w -= 1) >= 0)
michael@0 1286 {
michael@0 1287 uint16_t tl = src_top [pixman_fixed_to_int (vx)];
michael@0 1288 uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
michael@0 1289 uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
michael@0 1290 uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
michael@0 1291 uint32_t d;
michael@0 1292 d = bilinear_interpolation(convert_0565_to_8888 (tl),
michael@0 1293 convert_0565_to_8888 (tr),
michael@0 1294 convert_0565_to_8888 (bl),
michael@0 1295 convert_0565_to_8888 (br),
michael@0 1296 pixman_fixed_to_bilinear_weight (vx),
michael@0 1297 wb);
michael@0 1298 vx += unit_x;
michael@0 1299 *dst++ = convert_8888_to_0565 (d);
michael@0 1300 }
michael@0 1301 }
michael@0 1302
michael@0 1303 #else
michael@0 1304
michael@0 1305 /* This is a clever low resolution bilinear interpolation inspired by the code
michael@0 1306 in Skia */
michael@0 1307
michael@0 1308 /* This takes the green component from the 565 representation and moves it:
michael@0 1309 00000000 00000000 rrrrrggg gggbbbbb
michael@0 1310
michael@0 1311 00000ggg ggg00000 rrrrr000 000bbbbb
michael@0 1312
michael@0 1313 This gives us 5 extra bits of space before each component to let us do
michael@0 1314 SWAR style optimizations
michael@0 1315 */
michael@0 1316
michael@0 1317 #define GREEN_MASK (((1 << 6) - 1) << 5)
michael@0 1318
michael@0 1319 static inline uint32_t
michael@0 1320 expand_rgb_565 (uint16_t c) {
michael@0 1321 return ((c & GREEN_MASK) << 16) | (c & ~GREEN_MASK);
michael@0 1322 }
michael@0 1323
michael@0 1324 static inline uint16_t
michael@0 1325 compact_rgb_565 (uint32_t c) {
michael@0 1326 return ((c >> 16) & GREEN_MASK) | (c & ~GREEN_MASK);
michael@0 1327 }
michael@0 1328
michael@0 1329 static inline uint16_t
michael@0 1330 bilinear_interpolation_565(uint16_t tl, uint16_t tr,
michael@0 1331 uint16_t bl, uint16_t br,
michael@0 1332 int x, int y)
michael@0 1333 {
michael@0 1334 int xy;
michael@0 1335 uint32_t a00 = expand_rgb_565 (tl);
michael@0 1336 uint32_t a01 = expand_rgb_565 (tr);
michael@0 1337 uint32_t a10 = expand_rgb_565 (bl);
michael@0 1338 uint32_t a11 = expand_rgb_565 (br);
michael@0 1339
michael@0 1340 xy = (x * y) >> 3;
michael@0 1341 return compact_rgb_565 ((a00 * (32 - 2*y - 2*x + xy) +
michael@0 1342 a01 * (2*x - xy) +
michael@0 1343 a10 * (2*y - xy) +
michael@0 1344 a11 * xy) >> 5);
michael@0 1345 }
michael@0 1346
michael@0 1347 static force_inline void
michael@0 1348 scaled_bilinear_scanline_565_565_SRC (uint16_t * dst,
michael@0 1349 const uint32_t * mask,
michael@0 1350 const uint16_t * src_top,
michael@0 1351 const uint16_t * src_bottom,
michael@0 1352 int32_t w,
michael@0 1353 int wt,
michael@0 1354 int wb,
michael@0 1355 pixman_fixed_t vx,
michael@0 1356 pixman_fixed_t unit_x,
michael@0 1357 pixman_fixed_t max_vx,
michael@0 1358 pixman_bool_t zero_src)
michael@0 1359 {
michael@0 1360 while ((w -= 1) >= 0)
michael@0 1361 {
michael@0 1362 uint16_t tl = src_top [pixman_fixed_to_int (vx)];
michael@0 1363 uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
michael@0 1364 uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
michael@0 1365 uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
michael@0 1366
michael@0 1367 uint16_t d = bilinear_interpolation_565 (tl, tr, bl, br,
michael@0 1368 pixman_fixed_to_bilinear_weight(vx),
michael@0 1369 wb);
michael@0 1370 vx += unit_x;
michael@0 1371 *dst++ = d;
michael@0 1372 }
michael@0 1373 }
michael@0 1374
michael@0 1375 #endif
michael@0 1376
michael@0 1377 FAST_BILINEAR_MAINLOOP_COMMON (565_565_cover_SRC,
michael@0 1378 scaled_bilinear_scanline_565_565_SRC, NULL,
michael@0 1379 uint16_t, uint32_t, uint16_t,
michael@0 1380 COVER, FLAG_NONE)
michael@0 1381 FAST_BILINEAR_MAINLOOP_COMMON (565_565_pad_SRC,
michael@0 1382 scaled_bilinear_scanline_565_565_SRC, NULL,
michael@0 1383 uint16_t, uint32_t, uint16_t,
michael@0 1384 PAD, FLAG_NONE)
michael@0 1385 FAST_BILINEAR_MAINLOOP_COMMON (565_565_none_SRC,
michael@0 1386 scaled_bilinear_scanline_565_565_SRC, NULL,
michael@0 1387 uint16_t, uint32_t, uint16_t,
michael@0 1388 NONE, FLAG_NONE)
michael@0 1389 FAST_BILINEAR_MAINLOOP_COMMON (565_565_normal_SRC,
michael@0 1390 scaled_bilinear_scanline_565_565_SRC, NULL,
michael@0 1391 uint16_t, uint32_t, uint16_t,
michael@0 1392 NORMAL, FLAG_NONE)
michael@0 1393
michael@0 1394 FAST_BILINEAR_MAINLOOP_COMMON (8888_565_cover_OVER,
michael@0 1395 scaled_bilinear_scanline_8888_565_OVER, NULL,
michael@0 1396 uint32_t, uint32_t, uint16_t,
michael@0 1397 COVER, FLAG_NONE)
michael@0 1398 FAST_BILINEAR_MAINLOOP_COMMON (8888_565_pad_OVER,
michael@0 1399 scaled_bilinear_scanline_8888_565_OVER, NULL,
michael@0 1400 uint32_t, uint32_t, uint16_t,
michael@0 1401 PAD, FLAG_NONE)
michael@0 1402 FAST_BILINEAR_MAINLOOP_COMMON (8888_565_none_OVER,
michael@0 1403 scaled_bilinear_scanline_8888_565_OVER, NULL,
michael@0 1404 uint32_t, uint32_t, uint16_t,
michael@0 1405 NONE, FLAG_NONE)
michael@0 1406 FAST_BILINEAR_MAINLOOP_COMMON (8888_565_normal_OVER,
michael@0 1407 scaled_bilinear_scanline_8888_565_OVER, NULL,
michael@0 1408 uint32_t, uint32_t, uint16_t,
michael@0 1409 NORMAL, FLAG_NONE)
michael@0 1410
michael@0 1411 FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_cover_OVER,
michael@0 1412 scaled_bilinear_scanline_8888_8888_OVER, NULL,
michael@0 1413 uint32_t, uint32_t, uint32_t,
michael@0 1414 COVER, FLAG_NONE)
michael@0 1415 FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_pad_OVER,
michael@0 1416 scaled_bilinear_scanline_8888_8888_OVER, NULL,
michael@0 1417 uint32_t, uint32_t, uint32_t,
michael@0 1418 PAD, FLAG_NONE)
michael@0 1419 FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_none_OVER,
michael@0 1420 scaled_bilinear_scanline_8888_8888_OVER, NULL,
michael@0 1421 uint32_t, uint32_t, uint32_t,
michael@0 1422 NONE, FLAG_NONE)
michael@0 1423 FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_normal_OVER,
michael@0 1424 scaled_bilinear_scanline_8888_8888_OVER, NULL,
michael@0 1425 uint32_t, uint32_t, uint32_t,
michael@0 1426 NORMAL, FLAG_NONE)
michael@0 1427
michael@0 1428 #define REPEAT_MIN_WIDTH 32
michael@0 1429
michael@0 1430 static void
michael@0 1431 fast_composite_tiled_repeat (pixman_implementation_t *imp,
michael@0 1432 pixman_composite_info_t *info)
michael@0 1433 {
michael@0 1434 PIXMAN_COMPOSITE_ARGS (info);
michael@0 1435 pixman_composite_func_t func;
michael@0 1436 pixman_format_code_t mask_format;
michael@0 1437 uint32_t src_flags, mask_flags;
michael@0 1438 int32_t sx, sy;
michael@0 1439 int32_t width_remain;
michael@0 1440 int32_t num_pixels;
michael@0 1441 int32_t src_width;
michael@0 1442 int32_t i, j;
michael@0 1443 pixman_image_t extended_src_image;
michael@0 1444 uint32_t extended_src[REPEAT_MIN_WIDTH * 2];
michael@0 1445 pixman_bool_t need_src_extension;
michael@0 1446 uint32_t *src_line;
michael@0 1447 int32_t src_stride;
michael@0 1448 int32_t src_bpp;
michael@0 1449 pixman_composite_info_t info2 = *info;
michael@0 1450
michael@0 1451 src_flags = (info->src_flags & ~FAST_PATH_NORMAL_REPEAT) |
michael@0 1452 FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
michael@0 1453
michael@0 1454 if (mask_image)
michael@0 1455 {
michael@0 1456 mask_format = mask_image->common.extended_format_code;
michael@0 1457 mask_flags = info->mask_flags;
michael@0 1458 }
michael@0 1459 else
michael@0 1460 {
michael@0 1461 mask_format = PIXMAN_null;
michael@0 1462 mask_flags = FAST_PATH_IS_OPAQUE;
michael@0 1463 }
michael@0 1464
michael@0 1465 _pixman_implementation_lookup_composite (
michael@0 1466 imp->toplevel, info->op,
michael@0 1467 src_image->common.extended_format_code, src_flags,
michael@0 1468 mask_format, mask_flags,
michael@0 1469 dest_image->common.extended_format_code, info->dest_flags,
michael@0 1470 &imp, &func);
michael@0 1471
michael@0 1472 src_bpp = PIXMAN_FORMAT_BPP (src_image->bits.format);
michael@0 1473
michael@0 1474 if (src_image->bits.width < REPEAT_MIN_WIDTH &&
michael@0 1475 (src_bpp == 32 || src_bpp == 16 || src_bpp == 8) &&
michael@0 1476 !src_image->bits.indexed)
michael@0 1477 {
michael@0 1478 sx = src_x;
michael@0 1479 sx = MOD (sx, src_image->bits.width);
michael@0 1480 sx += width;
michael@0 1481 src_width = 0;
michael@0 1482
michael@0 1483 while (src_width < REPEAT_MIN_WIDTH && src_width <= sx)
michael@0 1484 src_width += src_image->bits.width;
michael@0 1485
michael@0 1486 src_stride = (src_width * (src_bpp >> 3) + 3) / (int) sizeof (uint32_t);
michael@0 1487
michael@0 1488 /* Initialize/validate stack-allocated temporary image */
michael@0 1489 _pixman_bits_image_init (&extended_src_image, src_image->bits.format,
michael@0 1490 src_width, 1, &extended_src[0], src_stride,
michael@0 1491 FALSE);
michael@0 1492 _pixman_image_validate (&extended_src_image);
michael@0 1493
michael@0 1494 info2.src_image = &extended_src_image;
michael@0 1495 need_src_extension = TRUE;
michael@0 1496 }
michael@0 1497 else
michael@0 1498 {
michael@0 1499 src_width = src_image->bits.width;
michael@0 1500 need_src_extension = FALSE;
michael@0 1501 }
michael@0 1502
michael@0 1503 sx = src_x;
michael@0 1504 sy = src_y;
michael@0 1505
michael@0 1506 while (--height >= 0)
michael@0 1507 {
michael@0 1508 sx = MOD (sx, src_width);
michael@0 1509 sy = MOD (sy, src_image->bits.height);
michael@0 1510
michael@0 1511 if (need_src_extension)
michael@0 1512 {
michael@0 1513 if (src_bpp == 32)
michael@0 1514 {
michael@0 1515 PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint32_t, src_stride, src_line, 1);
michael@0 1516
michael@0 1517 for (i = 0; i < src_width; )
michael@0 1518 {
michael@0 1519 for (j = 0; j < src_image->bits.width; j++, i++)
michael@0 1520 extended_src[i] = src_line[j];
michael@0 1521 }
michael@0 1522 }
michael@0 1523 else if (src_bpp == 16)
michael@0 1524 {
michael@0 1525 uint16_t *src_line_16;
michael@0 1526
michael@0 1527 PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint16_t, src_stride,
michael@0 1528 src_line_16, 1);
michael@0 1529 src_line = (uint32_t*)src_line_16;
michael@0 1530
michael@0 1531 for (i = 0; i < src_width; )
michael@0 1532 {
michael@0 1533 for (j = 0; j < src_image->bits.width; j++, i++)
michael@0 1534 ((uint16_t*)extended_src)[i] = ((uint16_t*)src_line)[j];
michael@0 1535 }
michael@0 1536 }
michael@0 1537 else if (src_bpp == 8)
michael@0 1538 {
michael@0 1539 uint8_t *src_line_8;
michael@0 1540
michael@0 1541 PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint8_t, src_stride,
michael@0 1542 src_line_8, 1);
michael@0 1543 src_line = (uint32_t*)src_line_8;
michael@0 1544
michael@0 1545 for (i = 0; i < src_width; )
michael@0 1546 {
michael@0 1547 for (j = 0; j < src_image->bits.width; j++, i++)
michael@0 1548 ((uint8_t*)extended_src)[i] = ((uint8_t*)src_line)[j];
michael@0 1549 }
michael@0 1550 }
michael@0 1551
michael@0 1552 info2.src_y = 0;
michael@0 1553 }
michael@0 1554 else
michael@0 1555 {
michael@0 1556 info2.src_y = sy;
michael@0 1557 }
michael@0 1558
michael@0 1559 width_remain = width;
michael@0 1560
michael@0 1561 while (width_remain > 0)
michael@0 1562 {
michael@0 1563 num_pixels = src_width - sx;
michael@0 1564
michael@0 1565 if (num_pixels > width_remain)
michael@0 1566 num_pixels = width_remain;
michael@0 1567
michael@0 1568 info2.src_x = sx;
michael@0 1569 info2.width = num_pixels;
michael@0 1570 info2.height = 1;
michael@0 1571
michael@0 1572 func (imp, &info2);
michael@0 1573
michael@0 1574 width_remain -= num_pixels;
michael@0 1575 info2.mask_x += num_pixels;
michael@0 1576 info2.dest_x += num_pixels;
michael@0 1577 sx = 0;
michael@0 1578 }
michael@0 1579
michael@0 1580 sx = src_x;
michael@0 1581 sy++;
michael@0 1582 info2.mask_x = info->mask_x;
michael@0 1583 info2.mask_y++;
michael@0 1584 info2.dest_x = info->dest_x;
michael@0 1585 info2.dest_y++;
michael@0 1586 }
michael@0 1587
michael@0 1588 if (need_src_extension)
michael@0 1589 _pixman_image_fini (&extended_src_image);
michael@0 1590 }
michael@0 1591
michael@0 1592 /* Use more unrolling for src_0565_0565 because it is typically CPU bound */
michael@0 1593 static force_inline void
michael@0 1594 scaled_nearest_scanline_565_565_SRC (uint16_t * dst,
michael@0 1595 const uint16_t * src,
michael@0 1596 int32_t w,
michael@0 1597 pixman_fixed_t vx,
michael@0 1598 pixman_fixed_t unit_x,
michael@0 1599 pixman_fixed_t max_vx,
michael@0 1600 pixman_bool_t fully_transparent_src)
michael@0 1601 {
michael@0 1602 uint16_t tmp1, tmp2, tmp3, tmp4;
michael@0 1603 while ((w -= 4) >= 0)
michael@0 1604 {
michael@0 1605 tmp1 = *(src + pixman_fixed_to_int (vx));
michael@0 1606 vx += unit_x;
michael@0 1607 tmp2 = *(src + pixman_fixed_to_int (vx));
michael@0 1608 vx += unit_x;
michael@0 1609 tmp3 = *(src + pixman_fixed_to_int (vx));
michael@0 1610 vx += unit_x;
michael@0 1611 tmp4 = *(src + pixman_fixed_to_int (vx));
michael@0 1612 vx += unit_x;
michael@0 1613 *dst++ = tmp1;
michael@0 1614 *dst++ = tmp2;
michael@0 1615 *dst++ = tmp3;
michael@0 1616 *dst++ = tmp4;
michael@0 1617 }
michael@0 1618 if (w & 2)
michael@0 1619 {
michael@0 1620 tmp1 = *(src + pixman_fixed_to_int (vx));
michael@0 1621 vx += unit_x;
michael@0 1622 tmp2 = *(src + pixman_fixed_to_int (vx));
michael@0 1623 vx += unit_x;
michael@0 1624 *dst++ = tmp1;
michael@0 1625 *dst++ = tmp2;
michael@0 1626 }
michael@0 1627 if (w & 1)
michael@0 1628 *dst = *(src + pixman_fixed_to_int (vx));
michael@0 1629 }
michael@0 1630
michael@0 1631 FAST_NEAREST_MAINLOOP (565_565_cover_SRC,
michael@0 1632 scaled_nearest_scanline_565_565_SRC,
michael@0 1633 uint16_t, uint16_t, COVER)
michael@0 1634 FAST_NEAREST_MAINLOOP (565_565_none_SRC,
michael@0 1635 scaled_nearest_scanline_565_565_SRC,
michael@0 1636 uint16_t, uint16_t, NONE)
michael@0 1637 FAST_NEAREST_MAINLOOP (565_565_pad_SRC,
michael@0 1638 scaled_nearest_scanline_565_565_SRC,
michael@0 1639 uint16_t, uint16_t, PAD)
michael@0 1640
michael@0 1641 static force_inline uint32_t
michael@0 1642 fetch_nearest (pixman_repeat_t src_repeat,
michael@0 1643 pixman_format_code_t format,
michael@0 1644 uint32_t *src, int x, int src_width)
michael@0 1645 {
michael@0 1646 if (repeat (src_repeat, &x, src_width))
michael@0 1647 {
michael@0 1648 if (format == PIXMAN_x8r8g8b8 || format == PIXMAN_x8b8g8r8)
michael@0 1649 return *(src + x) | 0xff000000;
michael@0 1650 else
michael@0 1651 return *(src + x);
michael@0 1652 }
michael@0 1653 else
michael@0 1654 {
michael@0 1655 return 0;
michael@0 1656 }
michael@0 1657 }
michael@0 1658
michael@0 1659 static force_inline void
michael@0 1660 combine_over (uint32_t s, uint32_t *dst)
michael@0 1661 {
michael@0 1662 if (s)
michael@0 1663 {
michael@0 1664 uint8_t ia = 0xff - (s >> 24);
michael@0 1665
michael@0 1666 if (ia)
michael@0 1667 UN8x4_MUL_UN8_ADD_UN8x4 (*dst, ia, s);
michael@0 1668 else
michael@0 1669 *dst = s;
michael@0 1670 }
michael@0 1671 }
michael@0 1672
michael@0 1673 static force_inline void
michael@0 1674 combine_src (uint32_t s, uint32_t *dst)
michael@0 1675 {
michael@0 1676 *dst = s;
michael@0 1677 }
michael@0 1678
michael@0 1679 static void
michael@0 1680 fast_composite_scaled_nearest (pixman_implementation_t *imp,
michael@0 1681 pixman_composite_info_t *info)
michael@0 1682 {
michael@0 1683 PIXMAN_COMPOSITE_ARGS (info);
michael@0 1684 uint32_t *dst_line;
michael@0 1685 uint32_t *src_line;
michael@0 1686 int dst_stride, src_stride;
michael@0 1687 int src_width, src_height;
michael@0 1688 pixman_repeat_t src_repeat;
michael@0 1689 pixman_fixed_t unit_x, unit_y;
michael@0 1690 pixman_format_code_t src_format;
michael@0 1691 pixman_vector_t v;
michael@0 1692 pixman_fixed_t vy;
michael@0 1693
michael@0 1694 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
michael@0 1695 /* pass in 0 instead of src_x and src_y because src_x and src_y need to be
michael@0 1696 * transformed from destination space to source space
michael@0 1697 */
michael@0 1698 PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, uint32_t, src_stride, src_line, 1);
michael@0 1699
michael@0 1700 /* reference point is the center of the pixel */
michael@0 1701 v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2;
michael@0 1702 v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2;
michael@0 1703 v.vector[2] = pixman_fixed_1;
michael@0 1704
michael@0 1705 if (!pixman_transform_point_3d (src_image->common.transform, &v))
michael@0 1706 return;
michael@0 1707
michael@0 1708 unit_x = src_image->common.transform->matrix[0][0];
michael@0 1709 unit_y = src_image->common.transform->matrix[1][1];
michael@0 1710
michael@0 1711 /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
michael@0 1712 v.vector[0] -= pixman_fixed_e;
michael@0 1713 v.vector[1] -= pixman_fixed_e;
michael@0 1714
michael@0 1715 src_height = src_image->bits.height;
michael@0 1716 src_width = src_image->bits.width;
michael@0 1717 src_repeat = src_image->common.repeat;
michael@0 1718 src_format = src_image->bits.format;
michael@0 1719
michael@0 1720 vy = v.vector[1];
michael@0 1721 while (height--)
michael@0 1722 {
michael@0 1723 pixman_fixed_t vx = v.vector[0];
michael@0 1724 int y = pixman_fixed_to_int (vy);
michael@0 1725 uint32_t *dst = dst_line;
michael@0 1726
michael@0 1727 dst_line += dst_stride;
michael@0 1728
michael@0 1729 /* adjust the y location by a unit vector in the y direction
michael@0 1730 * this is equivalent to transforming y+1 of the destination point to source space */
michael@0 1731 vy += unit_y;
michael@0 1732
michael@0 1733 if (!repeat (src_repeat, &y, src_height))
michael@0 1734 {
michael@0 1735 if (op == PIXMAN_OP_SRC)
michael@0 1736 memset (dst, 0, sizeof (*dst) * width);
michael@0 1737 }
michael@0 1738 else
michael@0 1739 {
michael@0 1740 int w = width;
michael@0 1741
michael@0 1742 uint32_t *src = src_line + y * src_stride;
michael@0 1743
michael@0 1744 while (w >= 2)
michael@0 1745 {
michael@0 1746 uint32_t s1, s2;
michael@0 1747 int x1, x2;
michael@0 1748
michael@0 1749 x1 = pixman_fixed_to_int (vx);
michael@0 1750 vx += unit_x;
michael@0 1751
michael@0 1752 x2 = pixman_fixed_to_int (vx);
michael@0 1753 vx += unit_x;
michael@0 1754
michael@0 1755 w -= 2;
michael@0 1756
michael@0 1757 s1 = fetch_nearest (src_repeat, src_format, src, x1, src_width);
michael@0 1758 s2 = fetch_nearest (src_repeat, src_format, src, x2, src_width);
michael@0 1759
michael@0 1760 if (op == PIXMAN_OP_OVER)
michael@0 1761 {
michael@0 1762 combine_over (s1, dst++);
michael@0 1763 combine_over (s2, dst++);
michael@0 1764 }
michael@0 1765 else
michael@0 1766 {
michael@0 1767 combine_src (s1, dst++);
michael@0 1768 combine_src (s2, dst++);
michael@0 1769 }
michael@0 1770 }
michael@0 1771
michael@0 1772 while (w--)
michael@0 1773 {
michael@0 1774 uint32_t s;
michael@0 1775 int x;
michael@0 1776
michael@0 1777 x = pixman_fixed_to_int (vx);
michael@0 1778 vx += unit_x;
michael@0 1779
michael@0 1780 s = fetch_nearest (src_repeat, src_format, src, x, src_width);
michael@0 1781
michael@0 1782 if (op == PIXMAN_OP_OVER)
michael@0 1783 combine_over (s, dst++);
michael@0 1784 else
michael@0 1785 combine_src (s, dst++);
michael@0 1786 }
michael@0 1787 }
michael@0 1788 }
michael@0 1789 }
michael@0 1790
michael@0 1791 #define CACHE_LINE_SIZE 64
michael@0 1792
michael@0 1793 #define FAST_SIMPLE_ROTATE(suffix, pix_type) \
michael@0 1794 \
michael@0 1795 static void \
michael@0 1796 blt_rotated_90_trivial_##suffix (pix_type *dst, \
michael@0 1797 int dst_stride, \
michael@0 1798 const pix_type *src, \
michael@0 1799 int src_stride, \
michael@0 1800 int w, \
michael@0 1801 int h) \
michael@0 1802 { \
michael@0 1803 int x, y; \
michael@0 1804 for (y = 0; y < h; y++) \
michael@0 1805 { \
michael@0 1806 const pix_type *s = src + (h - y - 1); \
michael@0 1807 pix_type *d = dst + dst_stride * y; \
michael@0 1808 for (x = 0; x < w; x++) \
michael@0 1809 { \
michael@0 1810 *d++ = *s; \
michael@0 1811 s += src_stride; \
michael@0 1812 } \
michael@0 1813 } \
michael@0 1814 } \
michael@0 1815 \
michael@0 1816 static void \
michael@0 1817 blt_rotated_270_trivial_##suffix (pix_type *dst, \
michael@0 1818 int dst_stride, \
michael@0 1819 const pix_type *src, \
michael@0 1820 int src_stride, \
michael@0 1821 int w, \
michael@0 1822 int h) \
michael@0 1823 { \
michael@0 1824 int x, y; \
michael@0 1825 for (y = 0; y < h; y++) \
michael@0 1826 { \
michael@0 1827 const pix_type *s = src + src_stride * (w - 1) + y; \
michael@0 1828 pix_type *d = dst + dst_stride * y; \
michael@0 1829 for (x = 0; x < w; x++) \
michael@0 1830 { \
michael@0 1831 *d++ = *s; \
michael@0 1832 s -= src_stride; \
michael@0 1833 } \
michael@0 1834 } \
michael@0 1835 } \
michael@0 1836 \
michael@0 1837 static void \
michael@0 1838 blt_rotated_90_##suffix (pix_type *dst, \
michael@0 1839 int dst_stride, \
michael@0 1840 const pix_type *src, \
michael@0 1841 int src_stride, \
michael@0 1842 int W, \
michael@0 1843 int H) \
michael@0 1844 { \
michael@0 1845 int x; \
michael@0 1846 int leading_pixels = 0, trailing_pixels = 0; \
michael@0 1847 const int TILE_SIZE = CACHE_LINE_SIZE / sizeof(pix_type); \
michael@0 1848 \
michael@0 1849 /* \
michael@0 1850 * split processing into handling destination as TILE_SIZExH cache line \
michael@0 1851 * aligned vertical stripes (optimistically assuming that destination \
michael@0 1852 * stride is a multiple of cache line, if not - it will be just a bit \
michael@0 1853 * slower) \
michael@0 1854 */ \
michael@0 1855 \
michael@0 1856 if ((uintptr_t)dst & (CACHE_LINE_SIZE - 1)) \
michael@0 1857 { \
michael@0 1858 leading_pixels = TILE_SIZE - (((uintptr_t)dst & \
michael@0 1859 (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
michael@0 1860 if (leading_pixels > W) \
michael@0 1861 leading_pixels = W; \
michael@0 1862 \
michael@0 1863 /* unaligned leading part NxH (where N < TILE_SIZE) */ \
michael@0 1864 blt_rotated_90_trivial_##suffix ( \
michael@0 1865 dst, \
michael@0 1866 dst_stride, \
michael@0 1867 src, \
michael@0 1868 src_stride, \
michael@0 1869 leading_pixels, \
michael@0 1870 H); \
michael@0 1871 \
michael@0 1872 dst += leading_pixels; \
michael@0 1873 src += leading_pixels * src_stride; \
michael@0 1874 W -= leading_pixels; \
michael@0 1875 } \
michael@0 1876 \
michael@0 1877 if ((uintptr_t)(dst + W) & (CACHE_LINE_SIZE - 1)) \
michael@0 1878 { \
michael@0 1879 trailing_pixels = (((uintptr_t)(dst + W) & \
michael@0 1880 (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
michael@0 1881 if (trailing_pixels > W) \
michael@0 1882 trailing_pixels = W; \
michael@0 1883 W -= trailing_pixels; \
michael@0 1884 } \
michael@0 1885 \
michael@0 1886 for (x = 0; x < W; x += TILE_SIZE) \
michael@0 1887 { \
michael@0 1888 /* aligned middle part TILE_SIZExH */ \
michael@0 1889 blt_rotated_90_trivial_##suffix ( \
michael@0 1890 dst + x, \
michael@0 1891 dst_stride, \
michael@0 1892 src + src_stride * x, \
michael@0 1893 src_stride, \
michael@0 1894 TILE_SIZE, \
michael@0 1895 H); \
michael@0 1896 } \
michael@0 1897 \
michael@0 1898 if (trailing_pixels) \
michael@0 1899 { \
michael@0 1900 /* unaligned trailing part NxH (where N < TILE_SIZE) */ \
michael@0 1901 blt_rotated_90_trivial_##suffix ( \
michael@0 1902 dst + W, \
michael@0 1903 dst_stride, \
michael@0 1904 src + W * src_stride, \
michael@0 1905 src_stride, \
michael@0 1906 trailing_pixels, \
michael@0 1907 H); \
michael@0 1908 } \
michael@0 1909 } \
michael@0 1910 \
michael@0 1911 static void \
michael@0 1912 blt_rotated_270_##suffix (pix_type *dst, \
michael@0 1913 int dst_stride, \
michael@0 1914 const pix_type *src, \
michael@0 1915 int src_stride, \
michael@0 1916 int W, \
michael@0 1917 int H) \
michael@0 1918 { \
michael@0 1919 int x; \
michael@0 1920 int leading_pixels = 0, trailing_pixels = 0; \
michael@0 1921 const int TILE_SIZE = CACHE_LINE_SIZE / sizeof(pix_type); \
michael@0 1922 \
michael@0 1923 /* \
michael@0 1924 * split processing into handling destination as TILE_SIZExH cache line \
michael@0 1925 * aligned vertical stripes (optimistically assuming that destination \
michael@0 1926 * stride is a multiple of cache line, if not - it will be just a bit \
michael@0 1927 * slower) \
michael@0 1928 */ \
michael@0 1929 \
michael@0 1930 if ((uintptr_t)dst & (CACHE_LINE_SIZE - 1)) \
michael@0 1931 { \
michael@0 1932 leading_pixels = TILE_SIZE - (((uintptr_t)dst & \
michael@0 1933 (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
michael@0 1934 if (leading_pixels > W) \
michael@0 1935 leading_pixels = W; \
michael@0 1936 \
michael@0 1937 /* unaligned leading part NxH (where N < TILE_SIZE) */ \
michael@0 1938 blt_rotated_270_trivial_##suffix ( \
michael@0 1939 dst, \
michael@0 1940 dst_stride, \
michael@0 1941 src + src_stride * (W - leading_pixels), \
michael@0 1942 src_stride, \
michael@0 1943 leading_pixels, \
michael@0 1944 H); \
michael@0 1945 \
michael@0 1946 dst += leading_pixels; \
michael@0 1947 W -= leading_pixels; \
michael@0 1948 } \
michael@0 1949 \
michael@0 1950 if ((uintptr_t)(dst + W) & (CACHE_LINE_SIZE - 1)) \
michael@0 1951 { \
michael@0 1952 trailing_pixels = (((uintptr_t)(dst + W) & \
michael@0 1953 (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
michael@0 1954 if (trailing_pixels > W) \
michael@0 1955 trailing_pixels = W; \
michael@0 1956 W -= trailing_pixels; \
michael@0 1957 src += trailing_pixels * src_stride; \
michael@0 1958 } \
michael@0 1959 \
michael@0 1960 for (x = 0; x < W; x += TILE_SIZE) \
michael@0 1961 { \
michael@0 1962 /* aligned middle part TILE_SIZExH */ \
michael@0 1963 blt_rotated_270_trivial_##suffix ( \
michael@0 1964 dst + x, \
michael@0 1965 dst_stride, \
michael@0 1966 src + src_stride * (W - x - TILE_SIZE), \
michael@0 1967 src_stride, \
michael@0 1968 TILE_SIZE, \
michael@0 1969 H); \
michael@0 1970 } \
michael@0 1971 \
michael@0 1972 if (trailing_pixels) \
michael@0 1973 { \
michael@0 1974 /* unaligned trailing part NxH (where N < TILE_SIZE) */ \
michael@0 1975 blt_rotated_270_trivial_##suffix ( \
michael@0 1976 dst + W, \
michael@0 1977 dst_stride, \
michael@0 1978 src - trailing_pixels * src_stride, \
michael@0 1979 src_stride, \
michael@0 1980 trailing_pixels, \
michael@0 1981 H); \
michael@0 1982 } \
michael@0 1983 } \
michael@0 1984 \
michael@0 1985 static void \
michael@0 1986 fast_composite_rotate_90_##suffix (pixman_implementation_t *imp, \
michael@0 1987 pixman_composite_info_t *info) \
michael@0 1988 { \
michael@0 1989 PIXMAN_COMPOSITE_ARGS (info); \
michael@0 1990 pix_type *dst_line; \
michael@0 1991 pix_type *src_line; \
michael@0 1992 int dst_stride, src_stride; \
michael@0 1993 int src_x_t, src_y_t; \
michael@0 1994 \
michael@0 1995 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, pix_type, \
michael@0 1996 dst_stride, dst_line, 1); \
michael@0 1997 src_x_t = -src_y + pixman_fixed_to_int ( \
michael@0 1998 src_image->common.transform->matrix[0][2] + \
michael@0 1999 pixman_fixed_1 / 2 - pixman_fixed_e) - height;\
michael@0 2000 src_y_t = src_x + pixman_fixed_to_int ( \
michael@0 2001 src_image->common.transform->matrix[1][2] + \
michael@0 2002 pixman_fixed_1 / 2 - pixman_fixed_e); \
michael@0 2003 PIXMAN_IMAGE_GET_LINE (src_image, src_x_t, src_y_t, pix_type, \
michael@0 2004 src_stride, src_line, 1); \
michael@0 2005 blt_rotated_90_##suffix (dst_line, dst_stride, src_line, src_stride, \
michael@0 2006 width, height); \
michael@0 2007 } \
michael@0 2008 \
michael@0 2009 static void \
michael@0 2010 fast_composite_rotate_270_##suffix (pixman_implementation_t *imp, \
michael@0 2011 pixman_composite_info_t *info) \
michael@0 2012 { \
michael@0 2013 PIXMAN_COMPOSITE_ARGS (info); \
michael@0 2014 pix_type *dst_line; \
michael@0 2015 pix_type *src_line; \
michael@0 2016 int dst_stride, src_stride; \
michael@0 2017 int src_x_t, src_y_t; \
michael@0 2018 \
michael@0 2019 PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, pix_type, \
michael@0 2020 dst_stride, dst_line, 1); \
michael@0 2021 src_x_t = src_y + pixman_fixed_to_int ( \
michael@0 2022 src_image->common.transform->matrix[0][2] + \
michael@0 2023 pixman_fixed_1 / 2 - pixman_fixed_e); \
michael@0 2024 src_y_t = -src_x + pixman_fixed_to_int ( \
michael@0 2025 src_image->common.transform->matrix[1][2] + \
michael@0 2026 pixman_fixed_1 / 2 - pixman_fixed_e) - width; \
michael@0 2027 PIXMAN_IMAGE_GET_LINE (src_image, src_x_t, src_y_t, pix_type, \
michael@0 2028 src_stride, src_line, 1); \
michael@0 2029 blt_rotated_270_##suffix (dst_line, dst_stride, src_line, src_stride, \
michael@0 2030 width, height); \
michael@0 2031 }
michael@0 2032
michael@0 2033 FAST_SIMPLE_ROTATE (8, uint8_t)
michael@0 2034 FAST_SIMPLE_ROTATE (565, uint16_t)
michael@0 2035 FAST_SIMPLE_ROTATE (8888, uint32_t)
michael@0 2036
michael@0 2037 static const pixman_fast_path_t c_fast_paths[] =
michael@0 2038 {
michael@0 2039 PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, fast_composite_over_n_8_0565),
michael@0 2040 PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, fast_composite_over_n_8_0565),
michael@0 2041 PIXMAN_STD_FAST_PATH (OVER, solid, a8, r8g8b8, fast_composite_over_n_8_0888),
michael@0 2042 PIXMAN_STD_FAST_PATH (OVER, solid, a8, b8g8r8, fast_composite_over_n_8_0888),
michael@0 2043 PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, fast_composite_over_n_8_8888),
michael@0 2044 PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, fast_composite_over_n_8_8888),
michael@0 2045 PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, fast_composite_over_n_8_8888),
michael@0 2046 PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, fast_composite_over_n_8_8888),
michael@0 2047 PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8r8g8b8, fast_composite_over_n_1_8888),
michael@0 2048 PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8r8g8b8, fast_composite_over_n_1_8888),
michael@0 2049 PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8b8g8r8, fast_composite_over_n_1_8888),
michael@0 2050 PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8b8g8r8, fast_composite_over_n_1_8888),
michael@0 2051 PIXMAN_STD_FAST_PATH (OVER, solid, a1, r5g6b5, fast_composite_over_n_1_0565),
michael@0 2052 PIXMAN_STD_FAST_PATH (OVER, solid, a1, b5g6r5, fast_composite_over_n_1_0565),
michael@0 2053 PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, fast_composite_over_n_8888_8888_ca),
michael@0 2054 PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, fast_composite_over_n_8888_8888_ca),
michael@0 2055 PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, fast_composite_over_n_8888_0565_ca),
michael@0 2056 PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, fast_composite_over_n_8888_8888_ca),
michael@0 2057 PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, fast_composite_over_n_8888_8888_ca),
michael@0 2058 PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, fast_composite_over_n_8888_0565_ca),
michael@0 2059 PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, fast_composite_over_x888_8_8888),
michael@0 2060 PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, fast_composite_over_x888_8_8888),
michael@0 2061 PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, fast_composite_over_x888_8_8888),
michael@0 2062 PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, fast_composite_over_x888_8_8888),
michael@0 2063 PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, fast_composite_over_8888_8888),
michael@0 2064 PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, fast_composite_over_8888_8888),
michael@0 2065 PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, fast_composite_over_8888_0565),
michael@0 2066 PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, fast_composite_over_8888_8888),
michael@0 2067 PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, fast_composite_over_8888_8888),
michael@0 2068 PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, fast_composite_over_8888_0565),
michael@0 2069 PIXMAN_STD_FAST_PATH (ADD, r5g6b5, null, r5g6b5, fast_composite_add_0565_0565),
michael@0 2070 PIXMAN_STD_FAST_PATH (ADD, b5g6r5, null, b5g6r5, fast_composite_add_0565_0565),
michael@0 2071 PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, fast_composite_add_8888_8888),
michael@0 2072 PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, fast_composite_add_8888_8888),
michael@0 2073 PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, fast_composite_add_8_8),
michael@0 2074 PIXMAN_STD_FAST_PATH (ADD, a1, null, a1, fast_composite_add_1_1),
michael@0 2075 PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, fast_composite_add_n_8888_8888_ca),
michael@0 2076 PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, fast_composite_add_n_8_8),
michael@0 2077 PIXMAN_STD_FAST_PATH (SRC, solid, null, a8r8g8b8, fast_composite_solid_fill),
michael@0 2078 PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill),
michael@0 2079 PIXMAN_STD_FAST_PATH (SRC, solid, null, a8b8g8r8, fast_composite_solid_fill),
michael@0 2080 PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, fast_composite_solid_fill),
michael@0 2081 PIXMAN_STD_FAST_PATH (SRC, solid, null, a1, fast_composite_solid_fill),
michael@0 2082 PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill),
michael@0 2083 PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill),
michael@0 2084 PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, fast_composite_src_x888_8888),
michael@0 2085 PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, fast_composite_src_x888_8888),
michael@0 2086 PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, fast_composite_src_memcpy),
michael@0 2087 PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, fast_composite_src_memcpy),
michael@0 2088 PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, fast_composite_src_memcpy),
michael@0 2089 PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, fast_composite_src_memcpy),
michael@0 2090 PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, fast_composite_src_memcpy),
michael@0 2091 PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, fast_composite_src_memcpy),
michael@0 2092 PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8x8, fast_composite_src_memcpy),
michael@0 2093 PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8a8, fast_composite_src_memcpy),
michael@0 2094 PIXMAN_STD_FAST_PATH (SRC, b8g8r8x8, null, b8g8r8x8, fast_composite_src_memcpy),
michael@0 2095 PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, fast_composite_src_memcpy),
michael@0 2096 PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, fast_composite_src_memcpy),
michael@0 2097 PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, fast_composite_src_memcpy),
michael@0 2098 PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, b8g8r8, fast_composite_src_memcpy),
michael@0 2099 PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, fast_composite_src_memcpy),
michael@0 2100 PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, fast_composite_src_memcpy),
michael@0 2101 PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, fast_composite_src_memcpy),
michael@0 2102 PIXMAN_STD_FAST_PATH (IN, a8, null, a8, fast_composite_in_8_8),
michael@0 2103 PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, fast_composite_in_n_8_8),
michael@0 2104
michael@0 2105 SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, 8888_8888),
michael@0 2106 SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, 8888_8888),
michael@0 2107 SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, 8888_8888),
michael@0 2108 SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, 8888_8888),
michael@0 2109
michael@0 2110 SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, 8888_8888),
michael@0 2111 SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, 8888_8888),
michael@0 2112
michael@0 2113 SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, 8888_565),
michael@0 2114 SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, 8888_565),
michael@0 2115
michael@0 2116 SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565),
michael@0 2117
michael@0 2118 SIMPLE_NEAREST_FAST_PATH_COVER (SRC, x8r8g8b8, a8r8g8b8, x888_8888),
michael@0 2119 SIMPLE_NEAREST_FAST_PATH_COVER (SRC, x8b8g8r8, a8b8g8r8, x888_8888),
michael@0 2120 SIMPLE_NEAREST_FAST_PATH_PAD (SRC, x8r8g8b8, a8r8g8b8, x888_8888),
michael@0 2121 SIMPLE_NEAREST_FAST_PATH_PAD (SRC, x8b8g8r8, a8b8g8r8, x888_8888),
michael@0 2122 SIMPLE_NEAREST_FAST_PATH_NORMAL (SRC, x8r8g8b8, a8r8g8b8, x888_8888),
michael@0 2123 SIMPLE_NEAREST_FAST_PATH_NORMAL (SRC, x8b8g8r8, a8b8g8r8, x888_8888),
michael@0 2124
michael@0 2125 SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, 8888_8888),
michael@0 2126 SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, 8888_8888),
michael@0 2127 SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, 8888_8888),
michael@0 2128 SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, 8888_8888),
michael@0 2129
michael@0 2130 SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, 8888_565),
michael@0 2131
michael@0 2132 #define NEAREST_FAST_PATH(op,s,d) \
michael@0 2133 { PIXMAN_OP_ ## op, \
michael@0 2134 PIXMAN_ ## s, SCALED_NEAREST_FLAGS, \
michael@0 2135 PIXMAN_null, 0, \
michael@0 2136 PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
michael@0 2137 fast_composite_scaled_nearest, \
michael@0 2138 }
michael@0 2139
michael@0 2140 NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8),
michael@0 2141 NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8),
michael@0 2142 NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8),
michael@0 2143 NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8),
michael@0 2144
michael@0 2145 NEAREST_FAST_PATH (SRC, x8r8g8b8, a8r8g8b8),
michael@0 2146 NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8),
michael@0 2147 NEAREST_FAST_PATH (SRC, x8b8g8r8, a8b8g8r8),
michael@0 2148 NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8),
michael@0 2149
michael@0 2150 NEAREST_FAST_PATH (OVER, x8r8g8b8, x8r8g8b8),
michael@0 2151 NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8),
michael@0 2152 NEAREST_FAST_PATH (OVER, x8b8g8r8, x8b8g8r8),
michael@0 2153 NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8),
michael@0 2154
michael@0 2155 NEAREST_FAST_PATH (OVER, x8r8g8b8, a8r8g8b8),
michael@0 2156 NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8),
michael@0 2157 NEAREST_FAST_PATH (OVER, x8b8g8r8, a8b8g8r8),
michael@0 2158 NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8),
michael@0 2159
michael@0 2160 #define SIMPLE_ROTATE_FLAGS(angle) \
michael@0 2161 (FAST_PATH_ROTATE_ ## angle ## _TRANSFORM | \
michael@0 2162 FAST_PATH_NEAREST_FILTER | \
michael@0 2163 FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | \
michael@0 2164 FAST_PATH_STANDARD_FLAGS)
michael@0 2165
michael@0 2166 #define SIMPLE_ROTATE_FAST_PATH(op,s,d,suffix) \
michael@0 2167 { PIXMAN_OP_ ## op, \
michael@0 2168 PIXMAN_ ## s, SIMPLE_ROTATE_FLAGS (90), \
michael@0 2169 PIXMAN_null, 0, \
michael@0 2170 PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
michael@0 2171 fast_composite_rotate_90_##suffix, \
michael@0 2172 }, \
michael@0 2173 { PIXMAN_OP_ ## op, \
michael@0 2174 PIXMAN_ ## s, SIMPLE_ROTATE_FLAGS (270), \
michael@0 2175 PIXMAN_null, 0, \
michael@0 2176 PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
michael@0 2177 fast_composite_rotate_270_##suffix, \
michael@0 2178 }
michael@0 2179
michael@0 2180 SIMPLE_ROTATE_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, 8888),
michael@0 2181 SIMPLE_ROTATE_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, 8888),
michael@0 2182 SIMPLE_ROTATE_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, 8888),
michael@0 2183 SIMPLE_ROTATE_FAST_PATH (SRC, r5g6b5, r5g6b5, 565),
michael@0 2184 SIMPLE_ROTATE_FAST_PATH (SRC, a8, a8, 8),
michael@0 2185
michael@0 2186 /* Simple repeat fast path entry. */
michael@0 2187 { PIXMAN_OP_any,
michael@0 2188 PIXMAN_any,
michael@0 2189 (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | FAST_PATH_BITS_IMAGE |
michael@0 2190 FAST_PATH_NORMAL_REPEAT),
michael@0 2191 PIXMAN_any, 0,
michael@0 2192 PIXMAN_any, FAST_PATH_STD_DEST_FLAGS,
michael@0 2193 fast_composite_tiled_repeat
michael@0 2194 },
michael@0 2195
michael@0 2196 SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565),
michael@0 2197 SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, r5g6b5, 8888_565),
michael@0 2198 SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, 8888_8888),
michael@0 2199
michael@0 2200 { PIXMAN_OP_NONE },
michael@0 2201 };
michael@0 2202
michael@0 2203 #ifdef WORDS_BIGENDIAN
michael@0 2204 #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n)))
michael@0 2205 #else
michael@0 2206 #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs))
michael@0 2207 #endif
michael@0 2208
michael@0 2209 static force_inline void
michael@0 2210 pixman_fill1_line (uint32_t *dst, int offs, int width, int v)
michael@0 2211 {
michael@0 2212 if (offs)
michael@0 2213 {
michael@0 2214 int leading_pixels = 32 - offs;
michael@0 2215 if (leading_pixels >= width)
michael@0 2216 {
michael@0 2217 if (v)
michael@0 2218 *dst |= A1_FILL_MASK (width, offs);
michael@0 2219 else
michael@0 2220 *dst &= ~A1_FILL_MASK (width, offs);
michael@0 2221 return;
michael@0 2222 }
michael@0 2223 else
michael@0 2224 {
michael@0 2225 if (v)
michael@0 2226 *dst++ |= A1_FILL_MASK (leading_pixels, offs);
michael@0 2227 else
michael@0 2228 *dst++ &= ~A1_FILL_MASK (leading_pixels, offs);
michael@0 2229 width -= leading_pixels;
michael@0 2230 }
michael@0 2231 }
michael@0 2232 while (width >= 32)
michael@0 2233 {
michael@0 2234 if (v)
michael@0 2235 *dst++ = 0xFFFFFFFF;
michael@0 2236 else
michael@0 2237 *dst++ = 0;
michael@0 2238 width -= 32;
michael@0 2239 }
michael@0 2240 if (width > 0)
michael@0 2241 {
michael@0 2242 if (v)
michael@0 2243 *dst |= A1_FILL_MASK (width, 0);
michael@0 2244 else
michael@0 2245 *dst &= ~A1_FILL_MASK (width, 0);
michael@0 2246 }
michael@0 2247 }
michael@0 2248
michael@0 2249 static void
michael@0 2250 pixman_fill1 (uint32_t *bits,
michael@0 2251 int stride,
michael@0 2252 int x,
michael@0 2253 int y,
michael@0 2254 int width,
michael@0 2255 int height,
michael@0 2256 uint32_t filler)
michael@0 2257 {
michael@0 2258 uint32_t *dst = bits + y * stride + (x >> 5);
michael@0 2259 int offs = x & 31;
michael@0 2260
michael@0 2261 if (filler & 1)
michael@0 2262 {
michael@0 2263 while (height--)
michael@0 2264 {
michael@0 2265 pixman_fill1_line (dst, offs, width, 1);
michael@0 2266 dst += stride;
michael@0 2267 }
michael@0 2268 }
michael@0 2269 else
michael@0 2270 {
michael@0 2271 while (height--)
michael@0 2272 {
michael@0 2273 pixman_fill1_line (dst, offs, width, 0);
michael@0 2274 dst += stride;
michael@0 2275 }
michael@0 2276 }
michael@0 2277 }
michael@0 2278
michael@0 2279 static void
michael@0 2280 pixman_fill8 (uint32_t *bits,
michael@0 2281 int stride,
michael@0 2282 int x,
michael@0 2283 int y,
michael@0 2284 int width,
michael@0 2285 int height,
michael@0 2286 uint32_t filler)
michael@0 2287 {
michael@0 2288 int byte_stride = stride * (int) sizeof (uint32_t);
michael@0 2289 uint8_t *dst = (uint8_t *) bits;
michael@0 2290 uint8_t v = filler & 0xff;
michael@0 2291 int i;
michael@0 2292
michael@0 2293 dst = dst + y * byte_stride + x;
michael@0 2294
michael@0 2295 while (height--)
michael@0 2296 {
michael@0 2297 for (i = 0; i < width; ++i)
michael@0 2298 dst[i] = v;
michael@0 2299
michael@0 2300 dst += byte_stride;
michael@0 2301 }
michael@0 2302 }
michael@0 2303
michael@0 2304 static void
michael@0 2305 pixman_fill16 (uint32_t *bits,
michael@0 2306 int stride,
michael@0 2307 int x,
michael@0 2308 int y,
michael@0 2309 int width,
michael@0 2310 int height,
michael@0 2311 uint32_t filler)
michael@0 2312 {
michael@0 2313 int short_stride =
michael@0 2314 (stride * (int)sizeof (uint32_t)) / (int)sizeof (uint16_t);
michael@0 2315 uint16_t *dst = (uint16_t *)bits;
michael@0 2316 uint16_t v = filler & 0xffff;
michael@0 2317 int i;
michael@0 2318
michael@0 2319 dst = dst + y * short_stride + x;
michael@0 2320
michael@0 2321 while (height--)
michael@0 2322 {
michael@0 2323 for (i = 0; i < width; ++i)
michael@0 2324 dst[i] = v;
michael@0 2325
michael@0 2326 dst += short_stride;
michael@0 2327 }
michael@0 2328 }
michael@0 2329
michael@0 2330 static void
michael@0 2331 pixman_fill32 (uint32_t *bits,
michael@0 2332 int stride,
michael@0 2333 int x,
michael@0 2334 int y,
michael@0 2335 int width,
michael@0 2336 int height,
michael@0 2337 uint32_t filler)
michael@0 2338 {
michael@0 2339 int i;
michael@0 2340
michael@0 2341 bits = bits + y * stride + x;
michael@0 2342
michael@0 2343 while (height--)
michael@0 2344 {
michael@0 2345 for (i = 0; i < width; ++i)
michael@0 2346 bits[i] = filler;
michael@0 2347
michael@0 2348 bits += stride;
michael@0 2349 }
michael@0 2350 }
michael@0 2351
michael@0 2352 static pixman_bool_t
michael@0 2353 fast_path_fill (pixman_implementation_t *imp,
michael@0 2354 uint32_t * bits,
michael@0 2355 int stride,
michael@0 2356 int bpp,
michael@0 2357 int x,
michael@0 2358 int y,
michael@0 2359 int width,
michael@0 2360 int height,
michael@0 2361 uint32_t filler)
michael@0 2362 {
michael@0 2363 switch (bpp)
michael@0 2364 {
michael@0 2365 case 1:
michael@0 2366 pixman_fill1 (bits, stride, x, y, width, height, filler);
michael@0 2367 break;
michael@0 2368
michael@0 2369 case 8:
michael@0 2370 pixman_fill8 (bits, stride, x, y, width, height, filler);
michael@0 2371 break;
michael@0 2372
michael@0 2373 case 16:
michael@0 2374 pixman_fill16 (bits, stride, x, y, width, height, filler);
michael@0 2375 break;
michael@0 2376
michael@0 2377 case 32:
michael@0 2378 pixman_fill32 (bits, stride, x, y, width, height, filler);
michael@0 2379 break;
michael@0 2380
michael@0 2381 default:
michael@0 2382 return FALSE;
michael@0 2383 }
michael@0 2384
michael@0 2385 return TRUE;
michael@0 2386 }
michael@0 2387
michael@0 2388 /*****************************************************************************/
michael@0 2389
michael@0 2390 static uint32_t *
michael@0 2391 fast_fetch_r5g6b5 (pixman_iter_t *iter, const uint32_t *mask)
michael@0 2392 {
michael@0 2393 int32_t w = iter->width;
michael@0 2394 uint32_t *dst = iter->buffer;
michael@0 2395 const uint16_t *src = (const uint16_t *)iter->bits;
michael@0 2396
michael@0 2397 iter->bits += iter->stride;
michael@0 2398
michael@0 2399 /* Align the source buffer at 4 bytes boundary */
michael@0 2400 if (w > 0 && ((uintptr_t)src & 3))
michael@0 2401 {
michael@0 2402 *dst++ = convert_0565_to_8888 (*src++);
michael@0 2403 w--;
michael@0 2404 }
michael@0 2405 /* Process two pixels per iteration */
michael@0 2406 while ((w -= 2) >= 0)
michael@0 2407 {
michael@0 2408 uint32_t sr, sb, sg, t0, t1;
michael@0 2409 uint32_t s = *(const uint32_t *)src;
michael@0 2410 src += 2;
michael@0 2411 sr = (s >> 8) & 0x00F800F8;
michael@0 2412 sb = (s << 3) & 0x00F800F8;
michael@0 2413 sg = (s >> 3) & 0x00FC00FC;
michael@0 2414 sr |= sr >> 5;
michael@0 2415 sb |= sb >> 5;
michael@0 2416 sg |= sg >> 6;
michael@0 2417 t0 = ((sr << 16) & 0x00FF0000) | ((sg << 8) & 0x0000FF00) |
michael@0 2418 (sb & 0xFF) | 0xFF000000;
michael@0 2419 t1 = (sr & 0x00FF0000) | ((sg >> 8) & 0x0000FF00) |
michael@0 2420 (sb >> 16) | 0xFF000000;
michael@0 2421 #ifdef WORDS_BIGENDIAN
michael@0 2422 *dst++ = t1;
michael@0 2423 *dst++ = t0;
michael@0 2424 #else
michael@0 2425 *dst++ = t0;
michael@0 2426 *dst++ = t1;
michael@0 2427 #endif
michael@0 2428 }
michael@0 2429 if (w & 1)
michael@0 2430 {
michael@0 2431 *dst = convert_0565_to_8888 (*src);
michael@0 2432 }
michael@0 2433
michael@0 2434 return iter->buffer;
michael@0 2435 }
michael@0 2436
michael@0 2437 static uint32_t *
michael@0 2438 fast_dest_fetch_noop (pixman_iter_t *iter, const uint32_t *mask)
michael@0 2439 {
michael@0 2440 iter->bits += iter->stride;
michael@0 2441 return iter->buffer;
michael@0 2442 }
michael@0 2443
michael@0 2444 /* Helper function for a workaround, which tries to ensure that 0x1F001F
michael@0 2445 * constant is always allocated in a register on RISC architectures.
michael@0 2446 */
michael@0 2447 static force_inline uint32_t
michael@0 2448 convert_8888_to_0565_workaround (uint32_t s, uint32_t x1F001F)
michael@0 2449 {
michael@0 2450 uint32_t a, b;
michael@0 2451 a = (s >> 3) & x1F001F;
michael@0 2452 b = s & 0xFC00;
michael@0 2453 a |= a >> 5;
michael@0 2454 a |= b >> 5;
michael@0 2455 return a;
michael@0 2456 }
michael@0 2457
michael@0 2458 static void
michael@0 2459 fast_write_back_r5g6b5 (pixman_iter_t *iter)
michael@0 2460 {
michael@0 2461 int32_t w = iter->width;
michael@0 2462 uint16_t *dst = (uint16_t *)(iter->bits - iter->stride);
michael@0 2463 const uint32_t *src = iter->buffer;
michael@0 2464 /* Workaround to ensure that x1F001F variable is allocated in a register */
michael@0 2465 static volatile uint32_t volatile_x1F001F = 0x1F001F;
michael@0 2466 uint32_t x1F001F = volatile_x1F001F;
michael@0 2467
michael@0 2468 while ((w -= 4) >= 0)
michael@0 2469 {
michael@0 2470 uint32_t s1 = *src++;
michael@0 2471 uint32_t s2 = *src++;
michael@0 2472 uint32_t s3 = *src++;
michael@0 2473 uint32_t s4 = *src++;
michael@0 2474 *dst++ = convert_8888_to_0565_workaround (s1, x1F001F);
michael@0 2475 *dst++ = convert_8888_to_0565_workaround (s2, x1F001F);
michael@0 2476 *dst++ = convert_8888_to_0565_workaround (s3, x1F001F);
michael@0 2477 *dst++ = convert_8888_to_0565_workaround (s4, x1F001F);
michael@0 2478 }
michael@0 2479 if (w & 2)
michael@0 2480 {
michael@0 2481 *dst++ = convert_8888_to_0565_workaround (*src++, x1F001F);
michael@0 2482 *dst++ = convert_8888_to_0565_workaround (*src++, x1F001F);
michael@0 2483 }
michael@0 2484 if (w & 1)
michael@0 2485 {
michael@0 2486 *dst = convert_8888_to_0565_workaround (*src, x1F001F);
michael@0 2487 }
michael@0 2488 }
michael@0 2489
michael@0 2490 typedef struct
michael@0 2491 {
michael@0 2492 pixman_format_code_t format;
michael@0 2493 pixman_iter_get_scanline_t get_scanline;
michael@0 2494 pixman_iter_write_back_t write_back;
michael@0 2495 } fetcher_info_t;
michael@0 2496
michael@0 2497 static const fetcher_info_t fetchers[] =
michael@0 2498 {
michael@0 2499 { PIXMAN_r5g6b5, fast_fetch_r5g6b5, fast_write_back_r5g6b5 },
michael@0 2500 { PIXMAN_null }
michael@0 2501 };
michael@0 2502
michael@0 2503 static pixman_bool_t
michael@0 2504 fast_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
michael@0 2505 {
michael@0 2506 pixman_image_t *image = iter->image;
michael@0 2507
michael@0 2508 #define FLAGS \
michael@0 2509 (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \
michael@0 2510 FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
michael@0 2511
michael@0 2512 if (iter->iter_flags & ITER_16)
michael@0 2513 return FALSE;
michael@0 2514
michael@0 2515 if ((iter->iter_flags & ITER_NARROW) &&
michael@0 2516 (iter->image_flags & FLAGS) == FLAGS)
michael@0 2517 {
michael@0 2518 const fetcher_info_t *f;
michael@0 2519
michael@0 2520 for (f = &fetchers[0]; f->format != PIXMAN_null; f++)
michael@0 2521 {
michael@0 2522 if (image->common.extended_format_code == f->format)
michael@0 2523 {
michael@0 2524 uint8_t *b = (uint8_t *)image->bits.bits;
michael@0 2525 int s = image->bits.rowstride * 4;
michael@0 2526
michael@0 2527 iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (f->format) / 8;
michael@0 2528 iter->stride = s;
michael@0 2529
michael@0 2530 iter->get_scanline = f->get_scanline;
michael@0 2531 return TRUE;
michael@0 2532 }
michael@0 2533 }
michael@0 2534 }
michael@0 2535
michael@0 2536 return FALSE;
michael@0 2537 }
michael@0 2538
michael@0 2539 static pixman_bool_t
michael@0 2540 fast_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
michael@0 2541 {
michael@0 2542 pixman_image_t *image = iter->image;
michael@0 2543
michael@0 2544 if (iter->iter_flags & ITER_16)
michael@0 2545 return FALSE;
michael@0 2546
michael@0 2547 if ((iter->iter_flags & ITER_NARROW) &&
michael@0 2548 (iter->image_flags & FAST_PATH_STD_DEST_FLAGS) == FAST_PATH_STD_DEST_FLAGS)
michael@0 2549 {
michael@0 2550 const fetcher_info_t *f;
michael@0 2551
michael@0 2552 for (f = &fetchers[0]; f->format != PIXMAN_null; f++)
michael@0 2553 {
michael@0 2554 if (image->common.extended_format_code == f->format)
michael@0 2555 {
michael@0 2556 uint8_t *b = (uint8_t *)image->bits.bits;
michael@0 2557 int s = image->bits.rowstride * 4;
michael@0 2558
michael@0 2559 iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (f->format) / 8;
michael@0 2560 iter->stride = s;
michael@0 2561
michael@0 2562 if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
michael@0 2563 (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
michael@0 2564 {
michael@0 2565 iter->get_scanline = fast_dest_fetch_noop;
michael@0 2566 }
michael@0 2567 else
michael@0 2568 {
michael@0 2569 iter->get_scanline = f->get_scanline;
michael@0 2570 }
michael@0 2571 iter->write_back = f->write_back;
michael@0 2572 return TRUE;
michael@0 2573 }
michael@0 2574 }
michael@0 2575 }
michael@0 2576 return FALSE;
michael@0 2577 }
michael@0 2578
michael@0 2579
michael@0 2580 pixman_implementation_t *
michael@0 2581 _pixman_implementation_create_fast_path (pixman_implementation_t *fallback)
michael@0 2582 {
michael@0 2583 pixman_implementation_t *imp = _pixman_implementation_create (fallback, c_fast_paths);
michael@0 2584
michael@0 2585 imp->fill = fast_path_fill;
michael@0 2586 imp->src_iter_init = fast_src_iter_init;
michael@0 2587 imp->dest_iter_init = fast_dest_iter_init;
michael@0 2588
michael@0 2589 return imp;
michael@0 2590 }

mercurial