1/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
2/*
3 * Copyright © 2000 SuSE, Inc.
4 * Copyright © 2007 Red Hat, Inc.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of SuSE not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission.  SuSE makes no representations about the
13 * suitability of this software for any purpose.  It is provided "as is"
14 * without express or implied warranty.
15 *
16 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Author:  Keith Packard, SuSE, Inc.
24 */
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29#include "pixman-private.h"
30
31#include <stdlib.h>
32
33pixman_implementation_t *global_implementation;
34
35#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
36static void __attribute__((constructor))
37pixman_constructor (void)
38{
39    global_implementation = _pixman_choose_implementation ();
40}
41#endif
42
43typedef struct operator_info_t operator_info_t;
44
45struct operator_info_t
46{
47    uint8_t	opaque_info[4];
48};
49
50#define PACK(neither, src, dest, both)			\
51    {{	    (uint8_t)PIXMAN_OP_ ## neither,		\
52	    (uint8_t)PIXMAN_OP_ ## src,			\
53	    (uint8_t)PIXMAN_OP_ ## dest,		\
54	    (uint8_t)PIXMAN_OP_ ## both		}}
55
56static const operator_info_t operator_table[] =
57{
58    /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
59    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
60    PACK (SRC,                   SRC,                   SRC,                   SRC),
61    PACK (DST,                   DST,                   DST,                   DST),
62    PACK (OVER,                  SRC,                   OVER,                  SRC),
63    PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
64    PACK (IN,                    IN,                    SRC,                   SRC),
65    PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
66    PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
67    PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
68    PACK (ATOP,                  IN,                    OVER,                  SRC),
69    PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
70    PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
71    PACK (ADD,                   ADD,                   ADD,                   ADD),
72    PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
73
74    {{ 0 /* 0x0e */ }},
75    {{ 0 /* 0x0f */ }},
76
77    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
78    PACK (SRC,                   SRC,                   SRC,                   SRC),
79    PACK (DST,                   DST,                   DST,                   DST),
80    PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
81    PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
82    PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
83    PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
84    PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
85    PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
86    PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
87    PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
88    PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
89
90    {{ 0 /* 0x1c */ }},
91    {{ 0 /* 0x1d */ }},
92    {{ 0 /* 0x1e */ }},
93    {{ 0 /* 0x1f */ }},
94
95    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
96    PACK (SRC,                   SRC,                   SRC,                   SRC),
97    PACK (DST,                   DST,                   DST,                   DST),
98    PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
99    PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
100    PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
101    PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
102    PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
103    PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
104    PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
105    PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
106    PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
107
108    {{ 0 /* 0x2c */ }},
109    {{ 0 /* 0x2d */ }},
110    {{ 0 /* 0x2e */ }},
111    {{ 0 /* 0x2f */ }},
112
113    PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
114    PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
115    PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
116    PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
117    PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
118    PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
119    PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
120    PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
121    PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
122    PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
123    PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
124    PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
125    PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
126    PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
127    PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
128};
129
130/*
131 * Optimize the current operator based on opacity of source or destination
132 * The output operator should be mathematically equivalent to the source.
133 */
134static pixman_op_t
135optimize_operator (pixman_op_t     op,
136		   uint32_t        src_flags,
137		   uint32_t        mask_flags,
138		   uint32_t        dst_flags)
139{
140    pixman_bool_t is_source_opaque, is_dest_opaque;
141
142#define OPAQUE_SHIFT 13
143
144    COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
145
146    is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
147    is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
148
149    is_dest_opaque >>= OPAQUE_SHIFT - 1;
150    is_source_opaque >>= OPAQUE_SHIFT;
151
152    return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
153}
154
155/*
156 * Computing composite region
157 */
158static inline pixman_bool_t
159clip_general_image (pixman_region32_t * region,
160                    pixman_region32_t * clip,
161                    int                 dx,
162                    int                 dy)
163{
164    if (pixman_region32_n_rects (region) == 1 &&
165        pixman_region32_n_rects (clip) == 1)
166    {
167	pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
168	pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
169	int v;
170
171	if (rbox->x1 < (v = cbox->x1 + dx))
172	    rbox->x1 = v;
173	if (rbox->x2 > (v = cbox->x2 + dx))
174	    rbox->x2 = v;
175	if (rbox->y1 < (v = cbox->y1 + dy))
176	    rbox->y1 = v;
177	if (rbox->y2 > (v = cbox->y2 + dy))
178	    rbox->y2 = v;
179	if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
180	{
181	    pixman_region32_init (region);
182	    return FALSE;
183	}
184    }
185    else if (!pixman_region32_not_empty (clip))
186    {
187	return FALSE;
188    }
189    else
190    {
191	if (dx || dy)
192	    pixman_region32_translate (region, -dx, -dy);
193
194	if (!pixman_region32_intersect (region, region, clip))
195	    return FALSE;
196
197	if (dx || dy)
198	    pixman_region32_translate (region, dx, dy);
199    }
200
201    return pixman_region32_not_empty (region);
202}
203
204static inline pixman_bool_t
205clip_source_image (pixman_region32_t * region,
206                   pixman_image_t *    image,
207                   int                 dx,
208                   int                 dy)
209{
210    /* Source clips are ignored, unless they are explicitly turned on
211     * and the clip in question was set by an X client. (Because if
212     * the clip was not set by a client, then it is a hierarchy
213     * clip and those should always be ignored for sources).
214     */
215    if (!image->common.clip_sources || !image->common.client_clip)
216	return TRUE;
217
218    return clip_general_image (region,
219                               &image->common.clip_region,
220                               dx, dy);
221}
222
223/*
224 * returns FALSE if the final region is empty.  Indistinguishable from
225 * an allocation failure, but rendering ignores those anyways.
226 */
227pixman_bool_t
228_pixman_compute_composite_region32 (pixman_region32_t * region,
229				    pixman_image_t *    src_image,
230				    pixman_image_t *    mask_image,
231				    pixman_image_t *    dest_image,
232				    int32_t             src_x,
233				    int32_t             src_y,
234				    int32_t             mask_x,
235				    int32_t             mask_y,
236				    int32_t             dest_x,
237				    int32_t             dest_y,
238				    int32_t             width,
239				    int32_t             height)
240{
241    region->extents.x1 = dest_x;
242    region->extents.x2 = dest_x + width;
243    region->extents.y1 = dest_y;
244    region->extents.y2 = dest_y + height;
245
246    region->extents.x1 = MAX (region->extents.x1, 0);
247    region->extents.y1 = MAX (region->extents.y1, 0);
248    region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
249    region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
250
251    region->data = 0;
252
253    /* Check for empty operation */
254    if (region->extents.x1 >= region->extents.x2 ||
255        region->extents.y1 >= region->extents.y2)
256    {
257	region->extents.x1 = 0;
258	region->extents.x2 = 0;
259	region->extents.y1 = 0;
260	region->extents.y2 = 0;
261	return FALSE;
262    }
263
264    if (dest_image->common.have_clip_region)
265    {
266	if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
267	    return FALSE;
268    }
269
270    if (dest_image->common.alpha_map)
271    {
272	if (!pixman_region32_intersect_rect (region, region,
273					     dest_image->common.alpha_origin_x,
274					     dest_image->common.alpha_origin_y,
275					     dest_image->common.alpha_map->width,
276					     dest_image->common.alpha_map->height))
277	{
278	    return FALSE;
279	}
280	if (!pixman_region32_not_empty (region))
281	    return FALSE;
282	if (dest_image->common.alpha_map->common.have_clip_region)
283	{
284	    if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
285				     -dest_image->common.alpha_origin_x,
286				     -dest_image->common.alpha_origin_y))
287	    {
288		return FALSE;
289	    }
290	}
291    }
292
293    /* clip against src */
294    if (src_image->common.have_clip_region)
295    {
296	if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
297	    return FALSE;
298    }
299    if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
300    {
301	if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
302	                        dest_x - (src_x - src_image->common.alpha_origin_x),
303	                        dest_y - (src_y - src_image->common.alpha_origin_y)))
304	{
305	    return FALSE;
306	}
307    }
308    /* clip against mask */
309    if (mask_image && mask_image->common.have_clip_region)
310    {
311	if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
312	    return FALSE;
313
314	if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
315	{
316	    if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
317	                            dest_x - (mask_x - mask_image->common.alpha_origin_x),
318	                            dest_y - (mask_y - mask_image->common.alpha_origin_y)))
319	    {
320		return FALSE;
321	    }
322	}
323    }
324
325    return TRUE;
326}
327
328typedef struct
329{
330    pixman_fixed_48_16_t	x1;
331    pixman_fixed_48_16_t	y1;
332    pixman_fixed_48_16_t	x2;
333    pixman_fixed_48_16_t	y2;
334} box_48_16_t;
335
336static pixman_bool_t
337compute_transformed_extents (pixman_transform_t *transform,
338			     const pixman_box32_t *extents,
339			     box_48_16_t *transformed)
340{
341    pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
342    pixman_fixed_t x1, y1, x2, y2;
343    int i;
344
345    x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
346    y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
347    x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
348    y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
349
350    if (!transform)
351    {
352	transformed->x1 = x1;
353	transformed->y1 = y1;
354	transformed->x2 = x2;
355	transformed->y2 = y2;
356
357	return TRUE;
358    }
359
360    tx1 = ty1 = INT64_MAX;
361    tx2 = ty2 = INT64_MIN;
362
363    for (i = 0; i < 4; ++i)
364    {
365	pixman_fixed_48_16_t tx, ty;
366	pixman_vector_t v;
367
368	v.vector[0] = (i & 0x01)? x1 : x2;
369	v.vector[1] = (i & 0x02)? y1 : y2;
370	v.vector[2] = pixman_fixed_1;
371
372	if (!pixman_transform_point (transform, &v))
373	    return FALSE;
374
375	tx = (pixman_fixed_48_16_t)v.vector[0];
376	ty = (pixman_fixed_48_16_t)v.vector[1];
377
378	if (tx < tx1)
379	    tx1 = tx;
380	if (ty < ty1)
381	    ty1 = ty;
382	if (tx > tx2)
383	    tx2 = tx;
384	if (ty > ty2)
385	    ty2 = ty;
386    }
387
388    transformed->x1 = tx1;
389    transformed->y1 = ty1;
390    transformed->x2 = tx2;
391    transformed->y2 = ty2;
392
393    return TRUE;
394}
395
396#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
397#define ABS(f)      (((f) < 0)?  (-(f)) : (f))
398#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
399
400static pixman_bool_t
401analyze_extent (pixman_image_t       *image,
402		const pixman_box32_t *extents,
403		uint32_t             *flags)
404{
405    pixman_transform_t *transform;
406    pixman_fixed_t x_off, y_off;
407    pixman_fixed_t width, height;
408    pixman_fixed_t *params;
409    box_48_16_t transformed;
410    pixman_box32_t exp_extents;
411
412    if (!image)
413	return TRUE;
414
415    /* Some compositing functions walk one step
416     * outside the destination rectangle, so we
417     * check here that the expanded-by-one source
418     * extents in destination space fits in 16 bits
419     */
420    if (!IS_16BIT (extents->x1 - 1)		||
421	!IS_16BIT (extents->y1 - 1)		||
422	!IS_16BIT (extents->x2 + 1)		||
423	!IS_16BIT (extents->y2 + 1))
424    {
425	return FALSE;
426    }
427
428    transform = image->common.transform;
429    if (image->common.type == BITS)
430    {
431	/* During repeat mode calculations we might convert the
432	 * width/height of an image to fixed 16.16, so we need
433	 * them to be smaller than 16 bits.
434	 */
435	if (image->bits.width >= 0x7fff	|| image->bits.height >= 0x7fff)
436	    return FALSE;
437
438	if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
439	    extents->x1 >= 0 &&
440	    extents->y1 >= 0 &&
441	    extents->x2 <= image->bits.width &&
442	    extents->y2 <= image->bits.height)
443	{
444	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
445	    return TRUE;
446	}
447
448	switch (image->common.filter)
449	{
450	case PIXMAN_FILTER_CONVOLUTION:
451	    params = image->common.filter_params;
452	    x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
453	    y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
454	    width = params[0];
455	    height = params[1];
456	    break;
457
458	case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
459	    params = image->common.filter_params;
460	    x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
461	    y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
462	    width = params[0];
463	    height = params[1];
464	    break;
465
466	case PIXMAN_FILTER_GOOD:
467	case PIXMAN_FILTER_BEST:
468	case PIXMAN_FILTER_BILINEAR:
469	    x_off = - pixman_fixed_1 / 2;
470	    y_off = - pixman_fixed_1 / 2;
471	    width = pixman_fixed_1;
472	    height = pixman_fixed_1;
473	    break;
474
475	case PIXMAN_FILTER_FAST:
476	case PIXMAN_FILTER_NEAREST:
477	    x_off = - pixman_fixed_e;
478	    y_off = - pixman_fixed_e;
479	    width = 0;
480	    height = 0;
481	    break;
482
483	default:
484	    return FALSE;
485	}
486    }
487    else
488    {
489	x_off = 0;
490	y_off = 0;
491	width = 0;
492	height = 0;
493    }
494
495    if (!compute_transformed_extents (transform, extents, &transformed))
496	return FALSE;
497
498    /* Expand the source area by a tiny bit so account of different rounding that
499     * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
500     * 0.5 so this won't cause the area computed to be overly pessimistic.
501     */
502    transformed.x1 -= 8 * pixman_fixed_e;
503    transformed.y1 -= 8 * pixman_fixed_e;
504    transformed.x2 += 8 * pixman_fixed_e;
505    transformed.y2 += 8 * pixman_fixed_e;
506
507    if (image->common.type == BITS)
508    {
509	if (pixman_fixed_to_int (transformed.x1) >= 0			&&
510	    pixman_fixed_to_int (transformed.y1) >= 0			&&
511	    pixman_fixed_to_int (transformed.x2) < image->bits.width	&&
512	    pixman_fixed_to_int (transformed.y2) < image->bits.height)
513	{
514	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
515	}
516
517	if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0		  &&
518	    pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0		  &&
519	    pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
520	    pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
521	{
522	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
523	}
524    }
525
526    /* Check we don't overflow when the destination extents are expanded by one.
527     * This ensures that compositing functions can simply walk the source space
528     * using 16.16 variables without worrying about overflow.
529     */
530    exp_extents = *extents;
531    exp_extents.x1 -= 1;
532    exp_extents.y1 -= 1;
533    exp_extents.x2 += 1;
534    exp_extents.y2 += 1;
535
536    if (!compute_transformed_extents (transform, &exp_extents, &transformed))
537	return FALSE;
538
539    if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e)	||
540	!IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e)	||
541	!IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width)	||
542	!IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
543    {
544	return FALSE;
545    }
546
547    return TRUE;
548}
549
550/*
551 * Work around GCC bug causing crashes in Mozilla with SSE2
552 *
553 * When using -msse, gcc generates movdqa instructions assuming that
554 * the stack is 16 byte aligned. Unfortunately some applications, such
555 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
556 * causes the movdqa instructions to fail.
557 *
558 * The __force_align_arg_pointer__ makes gcc generate a prologue that
559 * realigns the stack pointer to 16 bytes.
560 *
561 * On x86-64 this is not necessary because the standard ABI already
562 * calls for a 16 byte aligned stack.
563 *
564 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
565 */
566#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
567__attribute__((__force_align_arg_pointer__))
568#endif
569PIXMAN_EXPORT void
570pixman_image_composite32 (pixman_op_t      op,
571                          pixman_image_t * src,
572                          pixman_image_t * mask,
573                          pixman_image_t * dest,
574                          int32_t          src_x,
575                          int32_t          src_y,
576                          int32_t          mask_x,
577                          int32_t          mask_y,
578                          int32_t          dest_x,
579                          int32_t          dest_y,
580                          int32_t          width,
581                          int32_t          height)
582{
583    pixman_format_code_t src_format, mask_format, dest_format;
584    pixman_region32_t region;
585    pixman_box32_t extents;
586    pixman_implementation_t *imp;
587    pixman_composite_func_t func;
588    pixman_composite_info_t info;
589    const pixman_box32_t *pbox;
590    int n;
591
592    _pixman_image_validate (src);
593    if (mask)
594	_pixman_image_validate (mask);
595    _pixman_image_validate (dest);
596
597    src_format = src->common.extended_format_code;
598    info.src_flags = src->common.flags;
599
600    if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE))
601    {
602	mask_format = mask->common.extended_format_code;
603	info.mask_flags = mask->common.flags;
604    }
605    else
606    {
607	mask_format = PIXMAN_null;
608	info.mask_flags = FAST_PATH_IS_OPAQUE;
609    }
610
611    dest_format = dest->common.extended_format_code;
612    info.dest_flags = dest->common.flags;
613
614    /* Check for pixbufs */
615    if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
616	(src->type == BITS && src->bits.bits == mask->bits.bits)	   &&
617	(src->common.repeat == mask->common.repeat)			   &&
618	(info.src_flags & info.mask_flags & FAST_PATH_ID_TRANSFORM)	   &&
619	(src_x == mask_x && src_y == mask_y))
620    {
621	if (src_format == PIXMAN_x8b8g8r8)
622	    src_format = mask_format = PIXMAN_pixbuf;
623	else if (src_format == PIXMAN_x8r8g8b8)
624	    src_format = mask_format = PIXMAN_rpixbuf;
625    }
626
627    pixman_region32_init (&region);
628
629    if (!_pixman_compute_composite_region32 (
630	    &region, src, mask, dest,
631	    src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
632    {
633	goto out;
634    }
635
636    extents = *pixman_region32_extents (&region);
637
638    extents.x1 -= dest_x - src_x;
639    extents.y1 -= dest_y - src_y;
640    extents.x2 -= dest_x - src_x;
641    extents.y2 -= dest_y - src_y;
642
643    if (!analyze_extent (src, &extents, &info.src_flags))
644	goto out;
645
646    extents.x1 -= src_x - mask_x;
647    extents.y1 -= src_y - mask_y;
648    extents.x2 -= src_x - mask_x;
649    extents.y2 -= src_y - mask_y;
650
651    if (!analyze_extent (mask, &extents, &info.mask_flags))
652	goto out;
653
654    /* If the clip is within the source samples, and the samples are
655     * opaque, then the source is effectively opaque.
656     */
657#define NEAREST_OPAQUE	(FAST_PATH_SAMPLES_OPAQUE |			\
658			 FAST_PATH_NEAREST_FILTER |			\
659			 FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
660#define BILINEAR_OPAQUE	(FAST_PATH_SAMPLES_OPAQUE |			\
661			 FAST_PATH_BILINEAR_FILTER |			\
662			 FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
663
664    if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
665	(info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
666    {
667	info.src_flags |= FAST_PATH_IS_OPAQUE;
668    }
669
670    if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
671	(info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
672    {
673	info.mask_flags |= FAST_PATH_IS_OPAQUE;
674    }
675
676    /*
677     * Check if we can replace our operator by a simpler one
678     * if the src or dest are opaque. The output operator should be
679     * mathematically equivalent to the source.
680     */
681    info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags);
682
683    _pixman_implementation_lookup_composite (
684	get_implementation (), info.op,
685	src_format, info.src_flags,
686	mask_format, info.mask_flags,
687	dest_format, info.dest_flags,
688	&imp, &func);
689
690    info.src_image = src;
691    info.mask_image = mask;
692    info.dest_image = dest;
693
694    pbox = pixman_region32_rectangles (&region, &n);
695
696    while (n--)
697    {
698	info.src_x = pbox->x1 + src_x - dest_x;
699	info.src_y = pbox->y1 + src_y - dest_y;
700	info.mask_x = pbox->x1 + mask_x - dest_x;
701	info.mask_y = pbox->y1 + mask_y - dest_y;
702	info.dest_x = pbox->x1;
703	info.dest_y = pbox->y1;
704	info.width = pbox->x2 - pbox->x1;
705	info.height = pbox->y2 - pbox->y1;
706
707	func (imp, &info);
708
709	pbox++;
710    }
711
712out:
713    pixman_region32_fini (&region);
714}
715
716PIXMAN_EXPORT void
717pixman_image_composite (pixman_op_t      op,
718                        pixman_image_t * src,
719                        pixman_image_t * mask,
720                        pixman_image_t * dest,
721                        int16_t          src_x,
722                        int16_t          src_y,
723                        int16_t          mask_x,
724                        int16_t          mask_y,
725                        int16_t          dest_x,
726                        int16_t          dest_y,
727                        uint16_t         width,
728                        uint16_t         height)
729{
730    pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
731                              mask_x, mask_y, dest_x, dest_y, width, height);
732}
733
734PIXMAN_EXPORT pixman_bool_t
735pixman_blt (uint32_t *src_bits,
736            uint32_t *dst_bits,
737            int       src_stride,
738            int       dst_stride,
739            int       src_bpp,
740            int       dst_bpp,
741            int       src_x,
742            int       src_y,
743            int       dest_x,
744            int       dest_y,
745            int       width,
746            int       height)
747{
748    return _pixman_implementation_blt (get_implementation(),
749				       src_bits, dst_bits, src_stride, dst_stride,
750                                       src_bpp, dst_bpp,
751                                       src_x, src_y,
752                                       dest_x, dest_y,
753                                       width, height);
754}
755
756PIXMAN_EXPORT pixman_bool_t
757pixman_fill (uint32_t *bits,
758             int       stride,
759             int       bpp,
760             int       x,
761             int       y,
762             int       width,
763             int       height,
764             uint32_t  filler)
765{
766    return _pixman_implementation_fill (
767	get_implementation(), bits, stride, bpp, x, y, width, height, filler);
768}
769
770static uint32_t
771color_to_uint32 (const pixman_color_t *color)
772{
773    return
774        (color->alpha >> 8 << 24) |
775        (color->red >> 8 << 16) |
776        (color->green & 0xff00) |
777        (color->blue >> 8);
778}
779
780static pixman_bool_t
781color_to_pixel (const pixman_color_t *color,
782                uint32_t *            pixel,
783                pixman_format_code_t  format)
784{
785    uint32_t c = color_to_uint32 (color);
786
787    if (!(format == PIXMAN_a8r8g8b8     ||
788          format == PIXMAN_x8r8g8b8     ||
789          format == PIXMAN_a8b8g8r8     ||
790          format == PIXMAN_x8b8g8r8     ||
791          format == PIXMAN_b8g8r8a8     ||
792          format == PIXMAN_b8g8r8x8     ||
793          format == PIXMAN_r8g8b8a8     ||
794          format == PIXMAN_r8g8b8x8     ||
795          format == PIXMAN_r5g6b5       ||
796          format == PIXMAN_b5g6r5       ||
797          format == PIXMAN_a8           ||
798          format == PIXMAN_a1))
799    {
800	return FALSE;
801    }
802
803    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
804    {
805	c = ((c & 0xff000000) >>  0) |
806	    ((c & 0x00ff0000) >> 16) |
807	    ((c & 0x0000ff00) >>  0) |
808	    ((c & 0x000000ff) << 16);
809    }
810    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
811    {
812	c = ((c & 0xff000000) >> 24) |
813	    ((c & 0x00ff0000) >>  8) |
814	    ((c & 0x0000ff00) <<  8) |
815	    ((c & 0x000000ff) << 24);
816    }
817    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
818	c = ((c & 0xff000000) >> 24) | (c << 8);
819
820    if (format == PIXMAN_a1)
821	c = c >> 31;
822    else if (format == PIXMAN_a8)
823	c = c >> 24;
824    else if (format == PIXMAN_r5g6b5 ||
825             format == PIXMAN_b5g6r5)
826	c = convert_8888_to_0565 (c);
827
828#if 0
829    printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
830    printf ("pixel: %x\n", c);
831#endif
832
833    *pixel = c;
834    return TRUE;
835}
836
837PIXMAN_EXPORT pixman_bool_t
838pixman_image_fill_rectangles (pixman_op_t                 op,
839                              pixman_image_t *            dest,
840			      const pixman_color_t *      color,
841                              int                         n_rects,
842                              const pixman_rectangle16_t *rects)
843{
844    pixman_box32_t stack_boxes[6];
845    pixman_box32_t *boxes;
846    pixman_bool_t result;
847    int i;
848
849    if (n_rects > 6)
850    {
851        boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
852        if (boxes == NULL)
853            return FALSE;
854    }
855    else
856    {
857        boxes = stack_boxes;
858    }
859
860    for (i = 0; i < n_rects; ++i)
861    {
862        boxes[i].x1 = rects[i].x;
863        boxes[i].y1 = rects[i].y;
864        boxes[i].x2 = boxes[i].x1 + rects[i].width;
865        boxes[i].y2 = boxes[i].y1 + rects[i].height;
866    }
867
868    result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
869
870    if (boxes != stack_boxes)
871        free (boxes);
872
873    return result;
874}
875
876PIXMAN_EXPORT pixman_bool_t
877pixman_image_fill_boxes (pixman_op_t           op,
878                         pixman_image_t *      dest,
879                         const pixman_color_t *color,
880                         int                   n_boxes,
881                         const pixman_box32_t *boxes)
882{
883    pixman_image_t *solid;
884    pixman_color_t c;
885    int i;
886
887    _pixman_image_validate (dest);
888
889    if (color->alpha == 0xffff)
890    {
891        if (op == PIXMAN_OP_OVER)
892            op = PIXMAN_OP_SRC;
893    }
894
895    if (op == PIXMAN_OP_CLEAR)
896    {
897        c.red = 0;
898        c.green = 0;
899        c.blue = 0;
900        c.alpha = 0;
901
902        color = &c;
903
904        op = PIXMAN_OP_SRC;
905    }
906
907    if (op == PIXMAN_OP_SRC)
908    {
909        uint32_t pixel;
910
911        if (color_to_pixel (color, &pixel, dest->bits.format))
912        {
913            pixman_region32_t fill_region;
914            int n_rects, j;
915            pixman_box32_t *rects;
916
917            if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
918                return FALSE;
919
920            if (dest->common.have_clip_region)
921            {
922                if (!pixman_region32_intersect (&fill_region,
923                                                &fill_region,
924                                                &dest->common.clip_region))
925                    return FALSE;
926            }
927
928            rects = pixman_region32_rectangles (&fill_region, &n_rects);
929            for (j = 0; j < n_rects; ++j)
930            {
931                const pixman_box32_t *rect = &(rects[j]);
932                pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
933                             rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
934                             pixel);
935            }
936
937            pixman_region32_fini (&fill_region);
938            return TRUE;
939        }
940    }
941
942    solid = pixman_image_create_solid_fill (color);
943    if (!solid)
944        return FALSE;
945
946    for (i = 0; i < n_boxes; ++i)
947    {
948        const pixman_box32_t *box = &(boxes[i]);
949
950        pixman_image_composite32 (op, solid, NULL, dest,
951                                  0, 0, 0, 0,
952                                  box->x1, box->y1,
953                                  box->x2 - box->x1, box->y2 - box->y1);
954    }
955
956    pixman_image_unref (solid);
957
958    return TRUE;
959}
960
961/**
962 * pixman_version:
963 *
964 * Returns the version of the pixman library encoded in a single
965 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
966 * later versions compare greater than earlier versions.
967 *
968 * A run-time comparison to check that pixman's version is greater than
969 * or equal to version X.Y.Z could be performed as follows:
970 *
971 * <informalexample><programlisting>
972 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
973 * </programlisting></informalexample>
974 *
975 * See also pixman_version_string() as well as the compile-time
976 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
977 *
978 * Return value: the encoded version.
979 **/
980PIXMAN_EXPORT int
981pixman_version (void)
982{
983    return PIXMAN_VERSION;
984}
985
986/**
987 * pixman_version_string:
988 *
989 * Returns the version of the pixman library as a human-readable string
990 * of the form "X.Y.Z".
991 *
992 * See also pixman_version() as well as the compile-time equivalents
993 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
994 *
995 * Return value: a string containing the version.
996 **/
997PIXMAN_EXPORT const char*
998pixman_version_string (void)
999{
1000    return PIXMAN_VERSION_STRING;
1001}
1002
1003/**
1004 * pixman_format_supported_source:
1005 * @format: A pixman_format_code_t format
1006 *
1007 * Return value: whether the provided format code is a supported
1008 * format for a pixman surface used as a source in
1009 * rendering.
1010 *
1011 * Currently, all pixman_format_code_t values are supported.
1012 **/
1013PIXMAN_EXPORT pixman_bool_t
1014pixman_format_supported_source (pixman_format_code_t format)
1015{
1016    switch (format)
1017    {
1018    /* 32 bpp formats */
1019    case PIXMAN_a2b10g10r10:
1020    case PIXMAN_x2b10g10r10:
1021    case PIXMAN_a2r10g10b10:
1022    case PIXMAN_x2r10g10b10:
1023    case PIXMAN_a8r8g8b8:
1024    case PIXMAN_a8r8g8b8_sRGB:
1025    case PIXMAN_x8r8g8b8:
1026    case PIXMAN_a8b8g8r8:
1027    case PIXMAN_x8b8g8r8:
1028    case PIXMAN_b8g8r8a8:
1029    case PIXMAN_b8g8r8x8:
1030    case PIXMAN_r8g8b8a8:
1031    case PIXMAN_r8g8b8x8:
1032    case PIXMAN_r8g8b8:
1033    case PIXMAN_b8g8r8:
1034    case PIXMAN_r5g6b5:
1035    case PIXMAN_b5g6r5:
1036    case PIXMAN_x14r6g6b6:
1037    /* 16 bpp formats */
1038    case PIXMAN_a1r5g5b5:
1039    case PIXMAN_x1r5g5b5:
1040    case PIXMAN_a1b5g5r5:
1041    case PIXMAN_x1b5g5r5:
1042    case PIXMAN_a4r4g4b4:
1043    case PIXMAN_x4r4g4b4:
1044    case PIXMAN_a4b4g4r4:
1045    case PIXMAN_x4b4g4r4:
1046    /* 8bpp formats */
1047    case PIXMAN_a8:
1048    case PIXMAN_r3g3b2:
1049    case PIXMAN_b2g3r3:
1050    case PIXMAN_a2r2g2b2:
1051    case PIXMAN_a2b2g2r2:
1052    case PIXMAN_c8:
1053    case PIXMAN_g8:
1054    case PIXMAN_x4a4:
1055    /* Collides with PIXMAN_c8
1056       case PIXMAN_x4c4:
1057     */
1058    /* Collides with PIXMAN_g8
1059       case PIXMAN_x4g4:
1060     */
1061    /* 4bpp formats */
1062    case PIXMAN_a4:
1063    case PIXMAN_r1g2b1:
1064    case PIXMAN_b1g2r1:
1065    case PIXMAN_a1r1g1b1:
1066    case PIXMAN_a1b1g1r1:
1067    case PIXMAN_c4:
1068    case PIXMAN_g4:
1069    /* 1bpp formats */
1070    case PIXMAN_a1:
1071    case PIXMAN_g1:
1072    /* YUV formats */
1073    case PIXMAN_yuy2:
1074    case PIXMAN_yv12:
1075	return TRUE;
1076
1077    default:
1078	return FALSE;
1079    }
1080}
1081
1082/**
1083 * pixman_format_supported_destination:
1084 * @format: A pixman_format_code_t format
1085 *
1086 * Return value: whether the provided format code is a supported
1087 * format for a pixman surface used as a destination in
1088 * rendering.
1089 *
1090 * Currently, all pixman_format_code_t values are supported
1091 * except for the YUV formats.
1092 **/
1093PIXMAN_EXPORT pixman_bool_t
1094pixman_format_supported_destination (pixman_format_code_t format)
1095{
1096    /* YUV formats cannot be written to at the moment */
1097    if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1098	return FALSE;
1099
1100    return pixman_format_supported_source (format);
1101}
1102
1103PIXMAN_EXPORT pixman_bool_t
1104pixman_compute_composite_region (pixman_region16_t * region,
1105                                 pixman_image_t *    src_image,
1106                                 pixman_image_t *    mask_image,
1107                                 pixman_image_t *    dest_image,
1108                                 int16_t             src_x,
1109                                 int16_t             src_y,
1110                                 int16_t             mask_x,
1111                                 int16_t             mask_y,
1112                                 int16_t             dest_x,
1113                                 int16_t             dest_y,
1114                                 uint16_t            width,
1115                                 uint16_t            height)
1116{
1117    pixman_region32_t r32;
1118    pixman_bool_t retval;
1119
1120    pixman_region32_init (&r32);
1121
1122    retval = _pixman_compute_composite_region32 (
1123	&r32, src_image, mask_image, dest_image,
1124	src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1125	width, height);
1126
1127    if (retval)
1128    {
1129	if (!pixman_region16_copy_from_region32 (region, &r32))
1130	    retval = FALSE;
1131    }
1132
1133    pixman_region32_fini (&r32);
1134    return retval;
1135}
1136