2 * Copyright © 2000 SuSE, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of SuSE not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. SuSE makes no representations about the
11 * suitability of this software for any purpose. It is provided "as is"
12 * without express or implied warranty.
14 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
16 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Author: Keith Packard, SuSE, Inc.
30 #include "pixman-private.h"
31 #include "pixman-mmx.h"
32 #include "pixman-sse2.h"
34 #if defined(USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
35 __attribute__((__force_align_arg_pointer__))
37 PIXMAN_EXPORT pixman_bool_t
38 pixman_blt (uint32_t *src_bits,
46 int width, int height)
49 if (pixman_have_sse2())
51 return pixmanBltsse2 (src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
52 src_x, src_y, dst_x, dst_y, width, height);
57 if (pixman_have_mmx())
59 return pixman_blt_mmx (src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
60 src_x, src_y, dst_x, dst_y, width, height);
68 pixman_fill8 (uint32_t *bits,
76 int byte_stride = stride * (int) sizeof (uint32_t);
77 uint8_t *dst = (uint8_t *) bits;
78 uint8_t v = xor & 0xff;
81 dst = dst + y * byte_stride + x;
85 for (i = 0; i < width; ++i)
93 pixman_fill16 (uint32_t *bits,
101 int short_stride = (stride * (int) sizeof (uint32_t)) / (int) sizeof (uint16_t);
102 uint16_t *dst = (uint16_t *)bits;
103 uint16_t v = xor & 0xffff;
106 dst = dst + y * short_stride + x;
110 for (i = 0; i < width; ++i)
118 pixman_fill32 (uint32_t *bits,
128 bits = bits + y * stride + x;
132 for (i = 0; i < width; ++i)
139 #if defined(USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
140 __attribute__((__force_align_arg_pointer__))
142 PIXMAN_EXPORT pixman_bool_t
143 pixman_fill (uint32_t *bits,
153 printf ("filling: %d %d %d %d (stride: %d, bpp: %d) pixel: %x\n",
154 x, y, width, height, stride, bpp, xor);
158 if (pixman_have_sse2() && pixmanFillsse2 (bits, stride, bpp, x, y, width, height, xor))
163 if (pixman_have_mmx() && pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
170 pixman_fill8 (bits, stride, x, y, width, height, xor);
174 pixman_fill16 (bits, stride, x, y, width, height, xor);
178 pixman_fill32 (bits, stride, x, y, width, height, xor);
191 * Compute the smallest value no less than y which is on a
195 PIXMAN_EXPORT pixman_fixed_t
196 pixman_sample_ceil_y (pixman_fixed_t y, int n)
198 pixman_fixed_t f = pixman_fixed_frac(y);
199 pixman_fixed_t i = pixman_fixed_floor(y);
201 f = ((f + Y_FRAC_FIRST(n)) / STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
202 if (f > Y_FRAC_LAST(n))
204 if (pixman_fixed_to_int(i) == 0x7fff)
206 f = 0xffff; /* saturate */
215 #define _div(a,b) ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b)))
218 * Compute the largest value no greater than y which is on a
221 PIXMAN_EXPORT pixman_fixed_t
222 pixman_sample_floor_y (pixman_fixed_t y, int n)
224 pixman_fixed_t f = pixman_fixed_frac(y);
225 pixman_fixed_t i = pixman_fixed_floor (y);
227 f = _div(f - Y_FRAC_FIRST(n), STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
228 if (f < Y_FRAC_FIRST(n))
230 if (pixman_fixed_to_int(i) == 0x8000)
232 f = 0; /* saturate */
242 * Step an edge by any amount (including negative values)
245 pixman_edge_step (pixman_edge_t *e, int n)
247 pixman_fixed_48_16_t ne;
249 e->x += n * e->stepx;
251 ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
257 int nx = (ne + e->dy - 1) / e->dy;
258 e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
259 e->x += nx * e->signdx;
266 int nx = (-ne) / e->dy;
267 e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
268 e->x -= nx * e->signdx;
274 * A private routine to initialize the multi-step
275 * elements of an edge structure
278 _pixman_edge_multi_init (pixman_edge_t *e, int n, pixman_fixed_t *stepx_p, pixman_fixed_t *dx_p)
280 pixman_fixed_t stepx;
281 pixman_fixed_48_16_t ne;
283 ne = n * (pixman_fixed_48_16_t) e->dx;
284 stepx = n * e->stepx;
289 stepx += nx * e->signdx;
296 * Initialize one edge structure given the line endpoints and a
300 pixman_edge_init (pixman_edge_t *e,
302 pixman_fixed_t y_start,
303 pixman_fixed_t x_top,
304 pixman_fixed_t y_top,
305 pixman_fixed_t x_bot,
306 pixman_fixed_t y_bot)
308 pixman_fixed_t dx, dy;
328 e->stepx = -(-dx / dy);
333 _pixman_edge_multi_init (e, STEP_Y_SMALL(n), &e->stepx_small, &e->dx_small);
334 _pixman_edge_multi_init (e, STEP_Y_BIG(n), &e->stepx_big, &e->dx_big);
336 pixman_edge_step (e, y_start - y_top);
340 * Initialize one edge structure given a line, starting y value
341 * and a pixel offset for the line
344 pixman_line_fixed_edge_init (pixman_edge_t *e,
347 const pixman_line_fixed_t *line,
351 pixman_fixed_t x_off_fixed = pixman_int_to_fixed(x_off);
352 pixman_fixed_t y_off_fixed = pixman_int_to_fixed(y_off);
353 const pixman_point_fixed_t *top, *bot;
355 if (line->p1.y <= line->p2.y)
365 pixman_edge_init (e, n, y,
366 top->x + x_off_fixed,
367 top->y + y_off_fixed,
368 bot->x + x_off_fixed,
369 bot->y + y_off_fixed);
373 pixman_multiply_overflows_int (unsigned int a,
376 return a >= INT32_MAX / b;
380 pixman_addition_overflows_int (unsigned int a,
383 return a > INT32_MAX - b;
387 pixman_malloc_ab(unsigned int a,
390 if (a >= INT32_MAX / b)
393 return malloc (a * b);
397 pixman_malloc_abc (unsigned int a,
401 if (a >= INT32_MAX / b)
403 else if (a * b >= INT32_MAX / c)
406 return malloc (a * b * c);
413 * Returns the version of the pixman library encoded in a single
414 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
415 * later versions compare greater than earlier versions.
417 * A run-time comparison to check that pixman's version is greater than
418 * or equal to version X.Y.Z could be performed as follows:
420 * <informalexample><programlisting>
421 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
422 * </programlisting></informalexample>
424 * See also pixman_version_string() as well as the compile-time
425 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
427 * Return value: the encoded version.
430 pixman_version (void)
432 return PIXMAN_VERSION;
436 * pixman_version_string:
438 * Returns the version of the pixman library as a human-readable string
439 * of the form "X.Y.Z".
441 * See also pixman_version() as well as the compile-time equivalents
442 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
444 * Return value: a string containing the version.
446 PIXMAN_EXPORT const char*
447 pixman_version_string (void)
449 return PIXMAN_VERSION_STRING;
453 * pixman_format_supported_destination:
454 * @format: A pixman_format_code_t format
456 * Return value: whether the provided format code is a supported
457 * format for a pixman surface used as a destination in
460 * Currently, all pixman_format_code_t values are supported
461 * except for the YUV formats.
463 PIXMAN_EXPORT pixman_bool_t
464 pixman_format_supported_destination (pixman_format_code_t format)
468 case PIXMAN_a2b10g10r10:
469 case PIXMAN_x2b10g10r10:
470 case PIXMAN_a8r8g8b8:
471 case PIXMAN_x8r8g8b8:
472 case PIXMAN_a8b8g8r8:
473 case PIXMAN_x8b8g8r8:
474 case PIXMAN_b8g8r8a8:
475 case PIXMAN_b8g8r8x8:
481 case PIXMAN_a1r5g5b5:
482 case PIXMAN_x1r5g5b5:
483 case PIXMAN_a1b5g5r5:
484 case PIXMAN_x1b5g5r5:
485 case PIXMAN_a4r4g4b4:
486 case PIXMAN_x4r4g4b4:
487 case PIXMAN_a4b4g4r4:
488 case PIXMAN_x4b4g4r4:
493 case PIXMAN_a2r2g2b2:
494 case PIXMAN_a2b2g2r2:
498 /* Collides with PIXMAN_c8
501 /* Collides with PIXMAN_g8
508 case PIXMAN_a1r1g1b1:
509 case PIXMAN_a1b1g1r1:
526 * pixman_format_supported_source:
527 * @format: A pixman_format_code_t format
529 * Return value: whether the provided format code is a supported
530 * format for a pixman surface used as a source in
533 * Currently, all pixman_format_code_t values are supported.
535 PIXMAN_EXPORT pixman_bool_t
536 pixman_format_supported_source (pixman_format_code_t format)
540 case PIXMAN_a2b10g10r10:
541 case PIXMAN_x2b10g10r10:
542 case PIXMAN_a8r8g8b8:
543 case PIXMAN_x8r8g8b8:
544 case PIXMAN_a8b8g8r8:
545 case PIXMAN_x8b8g8r8:
546 case PIXMAN_b8g8r8a8:
547 case PIXMAN_b8g8r8x8:
553 case PIXMAN_a1r5g5b5:
554 case PIXMAN_x1r5g5b5:
555 case PIXMAN_a1b5g5r5:
556 case PIXMAN_x1b5g5r5:
557 case PIXMAN_a4r4g4b4:
558 case PIXMAN_x4r4g4b4:
559 case PIXMAN_a4b4g4r4:
560 case PIXMAN_x4b4g4r4:
565 case PIXMAN_a2r2g2b2:
566 case PIXMAN_a2b2g2r2:
570 /* Collides with PIXMAN_c8
573 /* Collides with PIXMAN_g8
580 case PIXMAN_a1r1g1b1:
581 case PIXMAN_a1b1g1r1: