Coverage Report

Created: 2025-07-23 08:13

/src/cairo/subprojects/pixman-0.44.2/pixman/pixman-inlines.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef PIXMAN_FAST_PATH_H__
27
#define PIXMAN_FAST_PATH_H__
28
29
#include "pixman-private.h"
30
31
0
#define PIXMAN_REPEAT_COVER -1
32
33
/* Flags describing input parameters to fast path macro template.
34
 * Turning on some flag values may indicate that
35
 * "some property X is available so template can use this" or
36
 * "some property X should be handled by template".
37
 *
38
 * FLAG_HAVE_SOLID_MASK
39
 *  Input mask is solid so template should handle this.
40
 *
41
 * FLAG_HAVE_NON_SOLID_MASK
42
 *  Input mask is bits mask so template should handle this.
43
 *
44
 * FLAG_HAVE_SOLID_MASK and FLAG_HAVE_NON_SOLID_MASK are mutually
45
 * exclusive. (It's not allowed to turn both flags on)
46
 */
47
#define FLAG_NONE       (0)
48
0
#define FLAG_HAVE_SOLID_MASK      (1 <<   1)
49
0
#define FLAG_HAVE_NON_SOLID_MASK    (1 <<   2)
50
51
/* To avoid too short repeated scanline function calls, extend source
52
 * scanlines having width less than below constant value.
53
 */
54
0
#define REPEAT_NORMAL_MIN_WIDTH     64
55
56
static force_inline pixman_bool_t
57
repeat (pixman_repeat_t repeat, int *c, int size)
58
0
{
59
0
    if (repeat == PIXMAN_REPEAT_NONE)
60
0
    {
61
0
  if (*c < 0 || *c >= size)
62
0
      return FALSE;
63
0
    }
64
0
    else if (repeat == PIXMAN_REPEAT_NORMAL)
65
0
    {
66
0
  while (*c >= size)
67
0
      *c -= size;
68
0
  while (*c < 0)
69
0
      *c += size;
70
0
    }
71
0
    else if (repeat == PIXMAN_REPEAT_PAD)
72
0
    {
73
0
  *c = CLIP (*c, 0, size - 1);
74
0
    }
75
0
    else /* REFLECT */
76
0
    {
77
0
  *c = MOD (*c, size * 2);
78
0
  if (*c >= size)
79
0
      *c = size * 2 - *c - 1;
80
0
    }
81
0
    return TRUE;
82
0
}
Unexecuted instantiation: pixman-bits-image.c:repeat
Unexecuted instantiation: pixman-noop.c:repeat
Unexecuted instantiation: pixman-mmx.c:repeat
Unexecuted instantiation: pixman-sse2.c:repeat
Unexecuted instantiation: pixman-ssse3.c:repeat
Unexecuted instantiation: pixman-fast-path.c:repeat
83
84
static force_inline int
85
pixman_fixed_to_bilinear_weight (pixman_fixed_t x)
86
0
{
87
0
    return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) &
88
0
     ((1 << BILINEAR_INTERPOLATION_BITS) - 1);
89
0
}
Unexecuted instantiation: pixman-bits-image.c:pixman_fixed_to_bilinear_weight
Unexecuted instantiation: pixman-noop.c:pixman_fixed_to_bilinear_weight
Unexecuted instantiation: pixman-mmx.c:pixman_fixed_to_bilinear_weight
Unexecuted instantiation: pixman-sse2.c:pixman_fixed_to_bilinear_weight
Unexecuted instantiation: pixman-ssse3.c:pixman_fixed_to_bilinear_weight
Unexecuted instantiation: pixman-fast-path.c:pixman_fixed_to_bilinear_weight
90
91
#if BILINEAR_INTERPOLATION_BITS <= 4
92
/* Inspired by Filter_32_opaque from Skia */
93
static force_inline uint32_t
94
bilinear_interpolation (uint32_t tl, uint32_t tr,
95
      uint32_t bl, uint32_t br,
96
      int distx, int disty)
97
{
98
    int distxy, distxiy, distixy, distixiy;
99
    uint32_t lo, hi;
100
101
    distx <<= (4 - BILINEAR_INTERPOLATION_BITS);
102
    disty <<= (4 - BILINEAR_INTERPOLATION_BITS);
103
104
    distxy = distx * disty;
105
    distxiy = (distx << 4) - distxy;  /* distx * (16 - disty) */
106
    distixy = (disty << 4) - distxy;  /* disty * (16 - distx) */
107
    distixiy =
108
  16 * 16 - (disty << 4) -
109
  (distx << 4) + distxy; /* (16 - distx) * (16 - disty) */
110
111
    lo = (tl & 0xff00ff) * distixiy;
112
    hi = ((tl >> 8) & 0xff00ff) * distixiy;
113
114
    lo += (tr & 0xff00ff) * distxiy;
115
    hi += ((tr >> 8) & 0xff00ff) * distxiy;
116
117
    lo += (bl & 0xff00ff) * distixy;
118
    hi += ((bl >> 8) & 0xff00ff) * distixy;
119
120
    lo += (br & 0xff00ff) * distxy;
121
    hi += ((br >> 8) & 0xff00ff) * distxy;
122
123
    return ((lo >> 8) & 0xff00ff) | (hi & ~0xff00ff);
124
}
125
126
#else
127
#if SIZEOF_LONG > 4
128
129
static force_inline uint32_t
130
bilinear_interpolation (uint32_t tl, uint32_t tr,
131
      uint32_t bl, uint32_t br,
132
      int distx, int disty)
133
0
{
134
0
    uint64_t distxy, distxiy, distixy, distixiy;
135
0
    uint64_t tl64, tr64, bl64, br64;
136
0
    uint64_t f, r;
137
138
0
    distx <<= (8 - BILINEAR_INTERPOLATION_BITS);
139
0
    disty <<= (8 - BILINEAR_INTERPOLATION_BITS);
140
141
0
    distxy = distx * disty;
142
0
    distxiy = distx * (256 - disty);
143
0
    distixy = (256 - distx) * disty;
144
0
    distixiy = (256 - distx) * (256 - disty);
145
146
    /* Alpha and Blue */
147
0
    tl64 = tl & 0xff0000ff;
148
0
    tr64 = tr & 0xff0000ff;
149
0
    bl64 = bl & 0xff0000ff;
150
0
    br64 = br & 0xff0000ff;
151
152
0
    f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy;
153
0
    r = f & 0x0000ff0000ff0000ull;
154
155
    /* Red and Green */
156
0
    tl64 = tl;
157
0
    tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull);
158
159
0
    tr64 = tr;
160
0
    tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull);
161
162
0
    bl64 = bl;
163
0
    bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull);
164
165
0
    br64 = br;
166
0
    br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull);
167
168
0
    f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy;
169
0
    r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull);
170
171
0
    return (uint32_t)(r >> 16);
172
0
}
Unexecuted instantiation: pixman-bits-image.c:bilinear_interpolation
Unexecuted instantiation: pixman-noop.c:bilinear_interpolation
Unexecuted instantiation: pixman-mmx.c:bilinear_interpolation
Unexecuted instantiation: pixman-sse2.c:bilinear_interpolation
Unexecuted instantiation: pixman-ssse3.c:bilinear_interpolation
Unexecuted instantiation: pixman-fast-path.c:bilinear_interpolation
173
174
#else
175
176
static force_inline uint32_t
177
bilinear_interpolation (uint32_t tl, uint32_t tr,
178
      uint32_t bl, uint32_t br,
179
      int distx, int disty)
180
{
181
    int distxy, distxiy, distixy, distixiy;
182
    uint32_t f, r;
183
184
    distx <<= (8 - BILINEAR_INTERPOLATION_BITS);
185
    disty <<= (8 - BILINEAR_INTERPOLATION_BITS);
186
187
    distxy = distx * disty;
188
    distxiy = (distx << 8) - distxy;  /* distx * (256 - disty) */
189
    distixy = (disty << 8) - distxy;  /* disty * (256 - distx) */
190
    distixiy =
191
  256 * 256 - (disty << 8) -
192
  (distx << 8) + distxy;    /* (256 - distx) * (256 - disty) */
193
194
    /* Blue */
195
    r = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
196
      + (bl & 0x000000ff) * distixy  + (br & 0x000000ff) * distxy;
197
198
    /* Green */
199
    f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
200
      + (bl & 0x0000ff00) * distixy  + (br & 0x0000ff00) * distxy;
201
    r |= f & 0xff000000;
202
203
    tl >>= 16;
204
    tr >>= 16;
205
    bl >>= 16;
206
    br >>= 16;
207
    r >>= 16;
208
209
    /* Red */
210
    f = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
211
      + (bl & 0x000000ff) * distixy  + (br & 0x000000ff) * distxy;
212
    r |= f & 0x00ff0000;
213
214
    /* Alpha */
215
    f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
216
      + (bl & 0x0000ff00) * distixy  + (br & 0x0000ff00) * distxy;
217
    r |= f & 0xff000000;
218
219
    return r;
220
}
221
222
#endif
223
#endif // BILINEAR_INTERPOLATION_BITS <= 4
224
225
static force_inline argb_t
226
bilinear_interpolation_float (argb_t tl, argb_t tr,
227
            argb_t bl, argb_t br,
228
            float distx, float disty)
229
0
{
230
0
    float distxy, distxiy, distixy, distixiy;
231
0
    argb_t r;
232
233
0
    distxy = distx * disty;
234
0
    distxiy = distx * (1.f - disty);
235
0
    distixy = (1.f - distx) * disty;
236
0
    distixiy = (1.f - distx) * (1.f - disty);
237
238
0
    r.a = tl.a * distixiy + tr.a * distxiy +
239
0
          bl.a * distixy  + br.a * distxy;
240
0
    r.r = tl.r * distixiy + tr.r * distxiy +
241
0
          bl.r * distixy  + br.r * distxy;
242
0
    r.g = tl.g * distixiy + tr.g * distxiy +
243
0
          bl.g * distixy  + br.g * distxy;
244
0
    r.b = tl.b * distixiy + tr.b * distxiy +
245
0
          bl.b * distixy  + br.b * distxy;
246
247
0
    return r;
248
0
}
Unexecuted instantiation: pixman-bits-image.c:bilinear_interpolation_float
Unexecuted instantiation: pixman-noop.c:bilinear_interpolation_float
Unexecuted instantiation: pixman-mmx.c:bilinear_interpolation_float
Unexecuted instantiation: pixman-sse2.c:bilinear_interpolation_float
Unexecuted instantiation: pixman-ssse3.c:bilinear_interpolation_float
Unexecuted instantiation: pixman-fast-path.c:bilinear_interpolation_float
249
250
/*
251
 * For each scanline fetched from source image with PAD repeat:
252
 * - calculate how many pixels need to be padded on the left side
253
 * - calculate how many pixels need to be padded on the right side
254
 * - update width to only count pixels which are fetched from the image
255
 * All this information is returned via 'width', 'left_pad', 'right_pad'
256
 * arguments. The code is assuming that 'unit_x' is positive.
257
 *
258
 * Note: 64-bit math is used in order to avoid potential overflows, which
259
 *       is probably excessive in many cases. This particular function
260
 *       may need its own correctness test and performance tuning.
261
 */
262
static force_inline void
263
pad_repeat_get_scanline_bounds (int32_t         source_image_width,
264
        pixman_fixed_t  vx,
265
        pixman_fixed_t  unit_x,
266
        int32_t *       width,
267
        int32_t *       left_pad,
268
        int32_t *       right_pad)
269
0
{
270
0
    int64_t max_vx = (int64_t) source_image_width << 16;
271
0
    int64_t tmp;
272
0
    if (vx < 0)
273
0
    {
274
0
  tmp = ((int64_t) unit_x - 1 - vx) / unit_x;
275
0
  if (tmp > *width)
276
0
  {
277
0
      *left_pad = *width;
278
0
      *width = 0;
279
0
  }
280
0
  else
281
0
  {
282
0
      *left_pad = (int32_t) tmp;
283
0
      *width -= (int32_t) tmp;
284
0
  }
285
0
    }
286
0
    else
287
0
    {
288
0
  *left_pad = 0;
289
0
    }
290
0
    tmp = ((int64_t) unit_x - 1 - vx + max_vx) / unit_x - *left_pad;
291
0
    if (tmp < 0)
292
0
    {
293
0
  *right_pad = *width;
294
0
  *width = 0;
295
0
    }
296
0
    else if (tmp >= *width)
297
0
    {
298
0
  *right_pad = 0;
299
0
    }
300
0
    else
301
0
    {
302
0
  *right_pad = *width - (int32_t) tmp;
303
0
  *width = (int32_t) tmp;
304
0
    }
305
0
}
Unexecuted instantiation: pixman-bits-image.c:pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-noop.c:pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-mmx.c:pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-sse2.c:pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-ssse3.c:pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-fast-path.c:pad_repeat_get_scanline_bounds
306
307
/* A macroified version of specialized nearest scalers for some
308
 * common 8888 and 565 formats. It supports SRC and OVER ops.
309
 *
310
 * There are two repeat versions, one that handles repeat normal,
311
 * and one without repeat handling that only works if the src region
312
 * used is completely covered by the pre-repeated source samples.
313
 *
314
 * The loops are unrolled to process two pixels per iteration for better
315
 * performance on most CPU architectures (superscalar processors
316
 * can issue several operations simultaneously, other processors can hide
317
 * instructions latencies by pipelining operations). Unrolling more
318
 * does not make much sense because the compiler will start running out
319
 * of spare registers soon.
320
 */
321
322
0
#define GET_8888_ALPHA(s) ((s) >> 24)
323
 /* This is not actually used since we don't have an OVER with
324
    565 source, but it is needed to build. */
325
0
#define GET_0565_ALPHA(s) 0xff
326
0
#define GET_x888_ALPHA(s) 0xff
327
328
#define FAST_NEAREST_SCANLINE(scanline_func_name, SRC_FORMAT, DST_FORMAT,     \
329
            src_type_t, dst_type_t, OP, repeat_mode)        \
330
static force_inline void                  \
331
scanline_func_name (dst_type_t       *dst,              \
332
        const src_type_t *src,              \
333
        int32_t           w,              \
334
        pixman_fixed_t    vx,             \
335
        pixman_fixed_t    unit_x,             \
336
        pixman_fixed_t    src_width_fixed,            \
337
0
        pixman_bool_t     fully_transparent_src)          \
338
0
{                       \
339
0
  uint32_t   d;                   \
340
0
  src_type_t s1, s2;                  \
341
0
  uint8_t    a1, a2;                  \
342
0
  int        x1, x2;                  \
343
0
                        \
344
0
  if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER && fully_transparent_src)     \
345
0
      return;                   \
346
0
                        \
347
0
  if (PIXMAN_OP_ ## OP != PIXMAN_OP_SRC && PIXMAN_OP_ ## OP != PIXMAN_OP_OVER)   \
348
0
      abort();                   \
349
0
                        \
350
0
  while ((w -= 2) >= 0)                 \
351
0
  {                     \
352
0
      x1 = pixman_fixed_to_int (vx);              \
353
0
      vx += unit_x;                 \
354
0
      if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)       \
355
0
      {                     \
356
0
    /* This works because we know that unit_x is positive */      \
357
0
    while (vx >= 0)                 \
358
0
        vx -= src_width_fixed;             \
359
0
      }                     \
360
0
      s1 = *(src + x1);                 \
361
0
                        \
362
0
      x2 = pixman_fixed_to_int (vx);              \
363
0
      vx += unit_x;                 \
364
0
      if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)       \
365
0
      {                     \
366
0
    /* This works because we know that unit_x is positive */      \
367
0
    while (vx >= 0)                 \
368
0
        vx -= src_width_fixed;             \
369
0
      }                     \
370
0
      s2 = *(src + x2);                 \
371
0
                        \
372
0
      if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER)           \
373
0
      {                     \
374
0
    a1 = GET_ ## SRC_FORMAT ## _ALPHA(s1);            \
375
0
    a2 = GET_ ## SRC_FORMAT ## _ALPHA(s2);            \
376
0
                        \
377
0
    if (a1 == 0xff)                 \
378
0
    {                   \
379
0
        *dst = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1);     \
380
0
    }                    \
381
0
    else if (s1)                 \
382
0
    {                   \
383
0
        d = convert_ ## DST_FORMAT ## _to_8888 (*dst);        \
384
0
        s1 = convert_ ## SRC_FORMAT ## _to_8888 (s1);       \
385
0
        a1 ^= 0xff;                 \
386
0
        UN8x4_MUL_UN8_ADD_UN8x4 (d, a1, s1);         \
387
0
        *dst = convert_8888_to_ ## DST_FORMAT (d);          \
388
0
    }                   \
389
0
    dst++;                    \
390
0
                        \
391
0
    if (a2 == 0xff)                 \
392
0
    {                   \
393
0
        *dst = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s2);     \
394
0
    }                    \
395
0
    else if (s2)                 \
396
0
    {                   \
397
0
        d = convert_## DST_FORMAT ## _to_8888 (*dst);       \
398
0
        s2 = convert_## SRC_FORMAT ## _to_8888 (s2);        \
399
0
        a2 ^= 0xff;                 \
400
0
        UN8x4_MUL_UN8_ADD_UN8x4 (d, a2, s2);         \
401
0
        *dst = convert_8888_to_ ## DST_FORMAT (d);          \
402
0
    }                   \
403
0
    dst++;                    \
404
0
      }                     \
405
0
      else /* PIXMAN_OP_SRC */                \
406
0
      {                     \
407
0
    *dst++ = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1);     \
408
0
    *dst++ = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s2);     \
409
0
      }                      \
410
0
  }                     \
411
0
                        \
412
0
  if (w & 1)                   \
413
0
  {                     \
414
0
      x1 = pixman_fixed_to_int (vx);              \
415
0
      s1 = *(src + x1);                 \
416
0
                        \
417
0
      if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER)           \
418
0
      {                     \
419
0
    a1 = GET_ ## SRC_FORMAT ## _ALPHA(s1);            \
420
0
                        \
421
0
    if (a1 == 0xff)                 \
422
0
    {                   \
423
0
        *dst = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1);     \
424
0
    }                    \
425
0
    else if (s1)                 \
426
0
    {                   \
427
0
        d = convert_## DST_FORMAT ## _to_8888 (*dst);       \
428
0
        s1 = convert_ ## SRC_FORMAT ## _to_8888 (s1);       \
429
0
        a1 ^= 0xff;                 \
430
0
        UN8x4_MUL_UN8_ADD_UN8x4 (d, a1, s1);         \
431
0
        *dst = convert_8888_to_ ## DST_FORMAT (d);          \
432
0
    }                   \
433
0
    dst++;                    \
434
0
      }                     \
435
0
      else /* PIXMAN_OP_SRC */                \
436
0
      {                     \
437
0
    *dst++ = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1);     \
438
0
      }                      \
439
0
  }                     \
440
0
}
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_cover_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_none_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_pad_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_cover_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_none_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_pad_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_565_565_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_x888_8888_cover_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_x888_8888_pad_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_x888_8888_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_cover_OVER
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_none_OVER
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_pad_OVER
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_normal_OVER
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_cover_OVER
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_none_OVER
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_pad_OVER
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_normal_OVER
441
442
#define FAST_NEAREST_MAINLOOP_INT(scale_func_name, scanline_func, src_type_t, mask_type_t,  \
443
          dst_type_t, repeat_mode, have_mask, mask_is_solid)    \
444
static void                     \
445
fast_composite_scaled_nearest  ## scale_func_name (pixman_implementation_t *imp,    \
446
0
               pixman_composite_info_t *info)               \
447
0
{                       \
448
0
    PIXMAN_COMPOSITE_ARGS (info);                                  \
449
0
    dst_type_t *dst_line;                                   \
450
0
    mask_type_t *mask_line;                 \
451
0
    src_type_t *src_first_line;                 \
452
0
    int       y;                    \
453
0
    pixman_fixed_t src_width_fixed = pixman_int_to_fixed (src_image->bits.width);   \
454
0
    pixman_fixed_t max_vy;                  \
455
0
    pixman_vector_t v;                    \
456
0
    pixman_fixed_t vx, vy;                  \
457
0
    pixman_fixed_t unit_x, unit_y;                \
458
0
    int32_t left_pad, right_pad;                \
459
0
                        \
460
0
    src_type_t *src;                    \
461
0
    dst_type_t *dst;                    \
462
0
    mask_type_t solid_mask;                 \
463
0
    const mask_type_t *mask = &solid_mask;              \
464
0
    int src_stride, mask_stride, dst_stride;              \
465
0
                        \
466
0
    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type_t, dst_stride, dst_line, 1); \
467
0
    if (have_mask)                   \
468
0
    {                       \
469
0
  if (mask_is_solid)                 \
470
0
      solid_mask = _pixman_image_get_solid (imp, mask_image, dest_image->bits.format); \
471
0
  else                      \
472
0
      PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type_t,      \
473
0
           mask_stride, mask_line, 1);          \
474
0
    }                       \
475
0
    /* pass in 0 instead of src_x and src_y because src_x and src_y need to be      \
476
0
     * transformed from destination space to source space */          \
477
0
    PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, src_type_t, src_stride, src_first_line, 1);    \
478
0
                        \
479
0
    /* reference point is the center of the pixel */            \
480
0
    v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2;       \
481
0
    v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2;       \
482
0
    v.vector[2] = pixman_fixed_1;               \
483
0
                        \
484
0
    if (!pixman_transform_point_3d (src_image->common.transform, &v))       \
485
0
  return;                     \
486
0
                        \
487
0
    unit_x = src_image->common.transform->matrix[0][0];           \
488
0
    unit_y = src_image->common.transform->matrix[1][1];           \
489
0
                        \
490
0
    /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */     \
491
0
    v.vector[0] -= pixman_fixed_e;               \
492
0
    v.vector[1] -= pixman_fixed_e;               \
493
0
                        \
494
0
    vx = v.vector[0];                   \
495
0
    vy = v.vector[1];                   \
496
0
                        \
497
0
    if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)         \
498
0
    {                       \
499
0
  max_vy = pixman_int_to_fixed (src_image->bits.height);          \
500
0
                        \
501
0
  /* Clamp repeating positions inside the actual samples */       \
502
0
  repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed);          \
503
0
  repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy);           \
504
0
    }                       \
505
0
                        \
506
0
    if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD ||         \
507
0
  PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE)         \
508
0
    {                       \
509
0
  pad_repeat_get_scanline_bounds (src_image->bits.width, vx, unit_x,      \
510
0
          &width, &left_pad, &right_pad);       \
511
0
  vx += left_pad * unit_x;                \
512
0
    }                        \
513
0
                        \
514
0
    while (--height >= 0)                 \
515
0
    {                       \
516
0
  dst = dst_line;                   \
517
0
  dst_line += dst_stride;                 \
518
0
  if (have_mask && !mask_is_solid)             \
519
0
  {                     \
520
0
      mask = mask_line;                 \
521
0
      mask_line += mask_stride;               \
522
0
  }                      \
523
0
                        \
524
0
  y = pixman_fixed_to_int (vy);                \
525
0
  vy += unit_y;                   \
526
0
  if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)       \
527
0
      repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy);           \
528
0
  if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD)         \
529
0
  {                     \
530
0
      repeat (PIXMAN_REPEAT_PAD, &y, src_image->bits.height);       \
531
0
      src = src_first_line + src_stride * y;            \
532
0
      if (left_pad > 0)                 \
533
0
      {                     \
534
0
    scanline_func (mask, dst,             \
535
0
             src + src_image->bits.width - src_image->bits.width + 1,   \
536
0
             left_pad, -pixman_fixed_e, 0, src_width_fixed, FALSE);    \
537
0
      }                     \
538
0
      if (width > 0)                 \
539
0
      {                     \
540
0
    scanline_func (mask + (mask_is_solid ? 0 : left_pad),        \
541
0
             dst + left_pad, src + src_image->bits.width, width,    \
542
0
             vx - src_width_fixed, unit_x, src_width_fixed, FALSE);    \
543
0
      }                     \
544
0
      if (right_pad > 0)                 \
545
0
      {                     \
546
0
    scanline_func (mask + (mask_is_solid ? 0 : left_pad + width),      \
547
0
             dst + left_pad + width, src + src_image->bits.width,   \
548
0
             right_pad, -pixman_fixed_e, 0, src_width_fixed, FALSE);    \
549
0
      }                     \
550
0
  }                     \
551
0
  else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE)       \
552
0
  {                     \
553
0
      static const src_type_t zero[1] = { 0 };            \
554
0
      if (y < 0 || y >= src_image->bits.height)           \
555
0
      {                     \
556
0
    scanline_func (mask, dst, zero + 1, left_pad + width + right_pad,   \
557
0
             -pixman_fixed_e, 0, src_width_fixed, TRUE);      \
558
0
    continue;                 \
559
0
      }                     \
560
0
      src = src_first_line + src_stride * y;            \
561
0
      if (left_pad > 0)                 \
562
0
      {                     \
563
0
    scanline_func (mask, dst, zero + 1, left_pad,         \
564
0
             -pixman_fixed_e, 0, src_width_fixed, TRUE);      \
565
0
      }                     \
566
0
      if (width > 0)                 \
567
0
      {                     \
568
0
    scanline_func (mask + (mask_is_solid ? 0 : left_pad),        \
569
0
             dst + left_pad, src + src_image->bits.width, width,    \
570
0
             vx - src_width_fixed, unit_x, src_width_fixed, FALSE);    \
571
0
      }                     \
572
0
      if (right_pad > 0)                 \
573
0
      {                     \
574
0
    scanline_func (mask + (mask_is_solid ? 0 : left_pad + width),      \
575
0
             dst + left_pad + width, zero + 1, right_pad,     \
576
0
             -pixman_fixed_e, 0, src_width_fixed, TRUE);      \
577
0
      }                     \
578
0
  }                     \
579
0
  else                      \
580
0
  {                     \
581
0
      src = src_first_line + src_stride * y;            \
582
0
      scanline_func (mask, dst, src + src_image->bits.width, width, vx - src_width_fixed, \
583
0
         unit_x, src_width_fixed, FALSE);          \
584
0
  }                     \
585
0
    }                       \
586
0
}
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_8888_cover_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_8888_none_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_8888_pad_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_8888_normal_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_n_8888_cover_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_n_8888_none_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_n_8888_pad_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_nearest_mmx_8888_n_8888_normal_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_8888_cover_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_8888_none_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_8888_pad_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_8888_normal_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_n_8888_cover_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_n_8888_none_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_n_8888_pad_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_nearest_sse2_8888_n_8888_normal_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_cover_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_none_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_pad_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_cover_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_none_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_pad_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_565_565_cover_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_565_565_none_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_565_565_pad_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_565_565_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_x888_8888_cover_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_x888_8888_pad_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_x888_8888_normal_SRC
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_cover_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_none_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_pad_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_8888_normal_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_cover_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_none_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_pad_OVER
Unexecuted instantiation: pixman-fast-path.c:fast_composite_scaled_nearest_8888_565_normal_OVER
587
588
/* A workaround for old sun studio, see: https://bugs.freedesktop.org/show_bug.cgi?id=32764 */
589
#define FAST_NEAREST_MAINLOOP_COMMON(scale_func_name, scanline_func, src_type_t, mask_type_t, \
590
          dst_type_t, repeat_mode, have_mask, mask_is_solid)    \
591
  FAST_NEAREST_MAINLOOP_INT(_ ## scale_func_name, scanline_func, src_type_t, mask_type_t, \
592
          dst_type_t, repeat_mode, have_mask, mask_is_solid)
593
594
#define FAST_NEAREST_MAINLOOP_NOMASK(scale_func_name, scanline_func, src_type_t, dst_type_t,  \
595
            repeat_mode)              \
596
    static force_inline void                  \
597
    scanline_func##scale_func_name##_wrapper (              \
598
        const uint8_t    *mask,             \
599
        dst_type_t       *dst,              \
600
        const src_type_t *src,              \
601
        int32_t          w,               \
602
        pixman_fixed_t   vx,              \
603
        pixman_fixed_t   unit_x,              \
604
        pixman_fixed_t   max_vx,              \
605
        pixman_bool_t    fully_transparent_src)         \
606
0
    {                       \
607
0
  scanline_func (dst, src, w, vx, unit_x, max_vx, fully_transparent_src);     \
608
0
    }                        \
Unexecuted instantiation: pixman-mmx.c:scaled_nearest_scanline_mmx_8888_8888_OVER_mmx_8888_8888_cover_OVER_wrapper
Unexecuted instantiation: pixman-mmx.c:scaled_nearest_scanline_mmx_8888_8888_OVER_mmx_8888_8888_none_OVER_wrapper
Unexecuted instantiation: pixman-mmx.c:scaled_nearest_scanline_mmx_8888_8888_OVER_mmx_8888_8888_pad_OVER_wrapper
Unexecuted instantiation: pixman-mmx.c:scaled_nearest_scanline_mmx_8888_8888_OVER_mmx_8888_8888_normal_OVER_wrapper
Unexecuted instantiation: pixman-sse2.c:scaled_nearest_scanline_sse2_8888_8888_OVER_sse2_8888_8888_cover_OVER_wrapper
Unexecuted instantiation: pixman-sse2.c:scaled_nearest_scanline_sse2_8888_8888_OVER_sse2_8888_8888_none_OVER_wrapper
Unexecuted instantiation: pixman-sse2.c:scaled_nearest_scanline_sse2_8888_8888_OVER_sse2_8888_8888_pad_OVER_wrapper
Unexecuted instantiation: pixman-sse2.c:scaled_nearest_scanline_sse2_8888_8888_OVER_sse2_8888_8888_normal_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_cover_SRC_8888_8888_cover_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_none_SRC_8888_8888_none_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_pad_SRC_8888_8888_pad_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_normal_SRC_8888_8888_normal_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_cover_SRC_8888_565_cover_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_none_SRC_8888_565_none_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_pad_SRC_8888_565_pad_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_normal_SRC_8888_565_normal_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_565_565_SRC_565_565_cover_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_565_565_SRC_565_565_none_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_565_565_SRC_565_565_pad_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_565_565_normal_SRC_565_565_normal_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_x888_8888_cover_SRC_x888_8888_cover_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_x888_8888_pad_SRC_x888_8888_pad_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_x888_8888_normal_SRC_x888_8888_normal_SRC_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_cover_OVER_8888_8888_cover_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_none_OVER_8888_8888_none_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_pad_OVER_8888_8888_pad_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_8888_normal_OVER_8888_8888_normal_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_cover_OVER_8888_565_cover_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_none_OVER_8888_565_none_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_pad_OVER_8888_565_pad_OVER_wrapper
Unexecuted instantiation: pixman-fast-path.c:scaled_nearest_scanline_8888_565_normal_OVER_8888_565_normal_OVER_wrapper
609
    FAST_NEAREST_MAINLOOP_INT (scale_func_name, scanline_func##scale_func_name##_wrapper, \
610
             src_type_t, uint8_t, dst_type_t, repeat_mode, FALSE, FALSE)
611
612
#define FAST_NEAREST_MAINLOOP(scale_func_name, scanline_func, src_type_t, dst_type_t,   \
613
            repeat_mode)              \
614
  FAST_NEAREST_MAINLOOP_NOMASK(_ ## scale_func_name, scanline_func, src_type_t,   \
615
            dst_type_t, repeat_mode)
616
617
#define FAST_NEAREST(scale_func_name, SRC_FORMAT, DST_FORMAT,       \
618
         src_type_t, dst_type_t, OP, repeat_mode)       \
619
    FAST_NEAREST_SCANLINE(scaled_nearest_scanline_ ## scale_func_name ## _ ## OP, \
620
        SRC_FORMAT, DST_FORMAT, src_type_t, dst_type_t,   \
621
        OP, repeat_mode)            \
622
    FAST_NEAREST_MAINLOOP_NOMASK(_ ## scale_func_name ## _ ## OP,     \
623
        scaled_nearest_scanline_ ## scale_func_name ## _ ## OP, \
624
        src_type_t, dst_type_t, repeat_mode)
625
626
627
#define SCALED_NEAREST_FLAGS            \
628
    (FAST_PATH_SCALE_TRANSFORM  |         \
629
     FAST_PATH_NO_ALPHA_MAP |         \
630
     FAST_PATH_NEAREST_FILTER |         \
631
     FAST_PATH_NO_ACCESSORS |         \
632
     FAST_PATH_NARROW_FORMAT)
633
634
#define SIMPLE_NEAREST_FAST_PATH_NORMAL(op,s,d,func)      \
635
    {   PIXMAN_OP_ ## op,           \
636
  PIXMAN_ ## s,             \
637
  (SCALED_NEAREST_FLAGS   |       \
638
   FAST_PATH_NORMAL_REPEAT  |       \
639
   FAST_PATH_X_UNIT_POSITIVE),          \
640
  PIXMAN_null, 0,             \
641
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
642
  fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \
643
    }
644
645
#define SIMPLE_NEAREST_FAST_PATH_PAD(op,s,d,func)     \
646
    {   PIXMAN_OP_ ## op,           \
647
  PIXMAN_ ## s,             \
648
  (SCALED_NEAREST_FLAGS   |       \
649
   FAST_PATH_PAD_REPEAT   |       \
650
   FAST_PATH_X_UNIT_POSITIVE),          \
651
  PIXMAN_null, 0,             \
652
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
653
  fast_composite_scaled_nearest_ ## func ## _pad ## _ ## op,  \
654
    }
655
656
#define SIMPLE_NEAREST_FAST_PATH_NONE(op,s,d,func)      \
657
    {   PIXMAN_OP_ ## op,           \
658
  PIXMAN_ ## s,             \
659
  (SCALED_NEAREST_FLAGS   |       \
660
   FAST_PATH_NONE_REPEAT    |       \
661
   FAST_PATH_X_UNIT_POSITIVE),          \
662
  PIXMAN_null, 0,             \
663
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
664
  fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \
665
    }
666
667
#define SIMPLE_NEAREST_FAST_PATH_COVER(op,s,d,func)     \
668
    {   PIXMAN_OP_ ## op,           \
669
  PIXMAN_ ## s,             \
670
  SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST,    \
671
  PIXMAN_null, 0,             \
672
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
673
  fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op,  \
674
    }
675
676
#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_NORMAL(op,s,d,func)    \
677
    {   PIXMAN_OP_ ## op,           \
678
  PIXMAN_ ## s,             \
679
  (SCALED_NEAREST_FLAGS   |       \
680
   FAST_PATH_NORMAL_REPEAT  |       \
681
   FAST_PATH_X_UNIT_POSITIVE),          \
682
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
683
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
684
  fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \
685
    }
686
687
#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD(op,s,d,func)   \
688
    {   PIXMAN_OP_ ## op,           \
689
  PIXMAN_ ## s,             \
690
  (SCALED_NEAREST_FLAGS   |       \
691
   FAST_PATH_PAD_REPEAT   |       \
692
   FAST_PATH_X_UNIT_POSITIVE),          \
693
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
694
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
695
  fast_composite_scaled_nearest_ ## func ## _pad ## _ ## op,  \
696
    }
697
698
#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE(op,s,d,func)    \
699
    {   PIXMAN_OP_ ## op,           \
700
  PIXMAN_ ## s,             \
701
  (SCALED_NEAREST_FLAGS   |       \
702
   FAST_PATH_NONE_REPEAT    |       \
703
   FAST_PATH_X_UNIT_POSITIVE),          \
704
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
705
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
706
  fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \
707
    }
708
709
#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER(op,s,d,func)   \
710
    {   PIXMAN_OP_ ## op,           \
711
  PIXMAN_ ## s,             \
712
  SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST,  \
713
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
714
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
715
  fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op,  \
716
    }
717
718
#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL(op,s,d,func)   \
719
    {   PIXMAN_OP_ ## op,           \
720
  PIXMAN_ ## s,             \
721
  (SCALED_NEAREST_FLAGS   |       \
722
   FAST_PATH_NORMAL_REPEAT  |       \
723
   FAST_PATH_X_UNIT_POSITIVE),          \
724
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
725
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
726
  fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \
727
    }
728
729
#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_PAD(op,s,d,func)    \
730
    {   PIXMAN_OP_ ## op,           \
731
  PIXMAN_ ## s,             \
732
  (SCALED_NEAREST_FLAGS   |       \
733
   FAST_PATH_PAD_REPEAT   |       \
734
   FAST_PATH_X_UNIT_POSITIVE),          \
735
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
736
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
737
  fast_composite_scaled_nearest_ ## func ## _pad ## _ ## op,  \
738
    }
739
740
#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NONE(op,s,d,func)   \
741
    {   PIXMAN_OP_ ## op,           \
742
  PIXMAN_ ## s,             \
743
  (SCALED_NEAREST_FLAGS   |       \
744
   FAST_PATH_NONE_REPEAT    |       \
745
   FAST_PATH_X_UNIT_POSITIVE),          \
746
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
747
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
748
  fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \
749
    }
750
751
#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_COVER(op,s,d,func)    \
752
    {   PIXMAN_OP_ ## op,           \
753
  PIXMAN_ ## s,             \
754
  SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST,  \
755
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
756
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
757
  fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op,  \
758
    }
759
760
/* Prefer the use of 'cover' variant, because it is faster */
761
#define SIMPLE_NEAREST_FAST_PATH(op,s,d,func)       \
762
    SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func),     \
763
    SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func),      \
764
    SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func),       \
765
    SIMPLE_NEAREST_FAST_PATH_NORMAL (op,s,d,func)
766
767
#define SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func)     \
768
    SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER (op,s,d,func),   \
769
    SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE (op,s,d,func),    \
770
    SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD (op,s,d,func)
771
772
#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH(op,s,d,func)    \
773
    SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_COVER (op,s,d,func),    \
774
    SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NONE (op,s,d,func),   \
775
    SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_PAD (op,s,d,func),              \
776
    SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (op,s,d,func)
777
778
/*****************************************************************************/
779
780
/*
781
 * Identify 5 zones in each scanline for bilinear scaling. Depending on
782
 * whether 2 pixels to be interpolated are fetched from the image itself,
783
 * from the padding area around it or from both image and padding area.
784
 */
785
static force_inline void
786
bilinear_pad_repeat_get_scanline_bounds (int32_t         source_image_width,
787
           pixman_fixed_t  vx,
788
           pixman_fixed_t  unit_x,
789
           int32_t *       left_pad,
790
           int32_t *       left_tz,
791
           int32_t *       width,
792
           int32_t *       right_tz,
793
           int32_t *       right_pad)
794
0
{
795
0
  int width1 = *width, left_pad1, right_pad1;
796
0
  int width2 = *width, left_pad2, right_pad2;
797
798
0
  pad_repeat_get_scanline_bounds (source_image_width, vx, unit_x,
799
0
          &width1, &left_pad1, &right_pad1);
800
0
  pad_repeat_get_scanline_bounds (source_image_width, vx + pixman_fixed_1,
801
0
          unit_x, &width2, &left_pad2, &right_pad2);
802
803
0
  *left_pad = left_pad2;
804
0
  *left_tz = left_pad1 - left_pad2;
805
0
  *right_tz = right_pad2 - right_pad1;
806
0
  *right_pad = right_pad1;
807
0
  *width -= *left_pad + *left_tz + *right_tz + *right_pad;
808
0
}
Unexecuted instantiation: pixman-bits-image.c:bilinear_pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-noop.c:bilinear_pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-mmx.c:bilinear_pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-sse2.c:bilinear_pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-ssse3.c:bilinear_pad_repeat_get_scanline_bounds
Unexecuted instantiation: pixman-fast-path.c:bilinear_pad_repeat_get_scanline_bounds
809
810
/*
811
 * Main loop template for single pass bilinear scaling. It needs to be
812
 * provided with 'scanline_func' which should do the compositing operation.
813
 * The needed function has the following prototype:
814
 *
815
 *  scanline_func (dst_type_t *       dst,
816
 *           const mask_type_ * mask,
817
 *           const src_type_t * src_top,
818
 *           const src_type_t * src_bottom,
819
 *           int32_t            width,
820
 *           int                weight_top,
821
 *           int                weight_bottom,
822
 *           pixman_fixed_t     vx,
823
 *           pixman_fixed_t     unit_x,
824
 *           pixman_fixed_t     max_vx,
825
 *           pixman_bool_t      zero_src)
826
 *
827
 * Where:
828
 *  dst                 - destination scanline buffer for storing results
829
 *  mask                - mask buffer (or single value for solid mask)
830
 *  src_top, src_bottom - two source scanlines
831
 *  width               - number of pixels to process
832
 *  weight_top          - weight of the top row for interpolation
833
 *  weight_bottom       - weight of the bottom row for interpolation
834
 *  vx                  - initial position for fetching the first pair of
835
 *                        pixels from the source buffer
836
 *  unit_x              - position increment needed to move to the next pair
837
 *                        of pixels
838
 *  max_vx              - image size as a fixed point value, can be used for
839
 *                        implementing NORMAL repeat (when it is supported)
840
 *  zero_src            - boolean hint variable, which is set to TRUE when
841
 *                        all source pixels are fetched from zero padding
842
 *                        zone for NONE repeat
843
 *
844
 * Note: normally the sum of 'weight_top' and 'weight_bottom' is equal to
845
 *       BILINEAR_INTERPOLATION_RANGE, but sometimes it may be less than that
846
 *       for NONE repeat when handling fuzzy antialiased top or bottom image
847
 *       edges. Also both top and bottom weight variables are guaranteed to
848
 *       have value, which is less than BILINEAR_INTERPOLATION_RANGE.
849
 *       For example, the weights can fit into unsigned byte or be used
850
 *       with 8-bit SIMD multiplication instructions for 8-bit interpolation
851
 *       precision.
852
 */
853
#define FAST_BILINEAR_MAINLOOP_INT(scale_func_name, scanline_func, src_type_t, mask_type_t, \
854
          dst_type_t, repeat_mode, flags)       \
855
static void                     \
856
fast_composite_scaled_bilinear ## scale_func_name (pixman_implementation_t *imp,    \
857
0
               pixman_composite_info_t *info)   \
858
0
{                       \
859
0
    PIXMAN_COMPOSITE_ARGS (info);                \
860
0
    dst_type_t *dst_line;                 \
861
0
    mask_type_t *mask_line;                 \
862
0
    src_type_t *src_first_line;                 \
863
0
    int       y1, y2;                   \
864
0
    pixman_fixed_t max_vx = INT32_MAX; /* suppress uninitialized variable warning */    \
865
0
    pixman_vector_t v;                    \
866
0
    pixman_fixed_t vx, vy;                  \
867
0
    pixman_fixed_t unit_x, unit_y;                \
868
0
    int32_t left_pad, left_tz, right_tz, right_pad;           \
869
0
                        \
870
0
    dst_type_t *dst;                    \
871
0
    mask_type_t solid_mask;                 \
872
0
    const mask_type_t *mask = &solid_mask;              \
873
0
    int src_stride, mask_stride, dst_stride;              \
874
0
                        \
875
0
    int src_width;                    \
876
0
    pixman_fixed_t src_width_fixed;               \
877
0
    int max_x;                      \
878
0
    pixman_bool_t need_src_extension;               \
879
0
                        \
880
0
    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type_t, dst_stride, dst_line, 1); \
881
0
    if (flags & FLAG_HAVE_SOLID_MASK)               \
882
0
    {                       \
883
0
  solid_mask = _pixman_image_get_solid (imp, mask_image, dest_image->bits.format);  \
884
0
  mask_stride = 0;                  \
885
0
    }                        \
886
0
    else if (flags & FLAG_HAVE_NON_SOLID_MASK)             \
887
0
    {                       \
888
0
  PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type_t,        \
889
0
             mask_stride, mask_line, 1);          \
890
0
    }                       \
891
0
                        \
892
0
    /* pass in 0 instead of src_x and src_y because src_x and src_y need to be      \
893
0
     * transformed from destination space to source space */          \
894
0
    PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, src_type_t, src_stride, src_first_line, 1);    \
895
0
                        \
896
0
    /* reference point is the center of the pixel */            \
897
0
    v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2;       \
898
0
    v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2;       \
899
0
    v.vector[2] = pixman_fixed_1;               \
900
0
                        \
901
0
    if (!pixman_transform_point_3d (src_image->common.transform, &v))       \
902
0
  return;                     \
903
0
                        \
904
0
    unit_x = src_image->common.transform->matrix[0][0];           \
905
0
    unit_y = src_image->common.transform->matrix[1][1];           \
906
0
                        \
907
0
    v.vector[0] -= pixman_fixed_1 / 2;               \
908
0
    v.vector[1] -= pixman_fixed_1 / 2;               \
909
0
                        \
910
0
    vy = v.vector[1];                   \
911
0
                        \
912
0
    if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD ||         \
913
0
  PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE)         \
914
0
    {                       \
915
0
  bilinear_pad_repeat_get_scanline_bounds (src_image->bits.width, v.vector[0], unit_x,  \
916
0
          &left_pad, &left_tz, &width, &right_tz, &right_pad);  \
917
0
  if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD)         \
918
0
  {                     \
919
0
      /* PAD repeat does not need special handling for 'transition zones' and */    \
920
0
      /* they can be combined with 'padding zones' safely */        \
921
0
      left_pad += left_tz;                \
922
0
      right_pad += right_tz;                \
923
0
      left_tz = right_tz = 0;               \
924
0
  }                      \
925
0
  v.vector[0] += left_pad * unit_x;             \
926
0
    }                       \
927
0
                        \
928
0
    if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)         \
929
0
    {                       \
930
0
  vx = v.vector[0];                 \
931
0
  repeat (PIXMAN_REPEAT_NORMAL, &vx, pixman_int_to_fixed(src_image->bits.width));   \
932
0
  max_x = pixman_fixed_to_int (vx + (width - 1) * (int64_t)unit_x) + 1;      \
933
0
                        \
934
0
  if (src_image->bits.width < REPEAT_NORMAL_MIN_WIDTH)         \
935
0
  {                     \
936
0
      src_width = 0;                  \
937
0
                        \
938
0
      while (src_width < REPEAT_NORMAL_MIN_WIDTH && src_width <= max_x)     \
939
0
    src_width += src_image->bits.width;           \
940
0
                        \
941
0
      need_src_extension = TRUE;               \
942
0
  }                     \
943
0
  else                      \
944
0
  {                     \
945
0
      src_width = src_image->bits.width;              \
946
0
      need_src_extension = FALSE;               \
947
0
  }                     \
948
0
                        \
949
0
  src_width_fixed = pixman_int_to_fixed (src_width);         \
950
0
    }                       \
951
0
                        \
952
0
    while (--height >= 0)                 \
953
0
    {                       \
954
0
  int weight1, weight2;                 \
955
0
  dst = dst_line;                   \
956
0
  dst_line += dst_stride;                 \
957
0
  vx = v.vector[0];                 \
958
0
  if (flags & FLAG_HAVE_NON_SOLID_MASK)             \
959
0
  {                     \
960
0
      mask = mask_line;                 \
961
0
      mask_line += mask_stride;               \
962
0
  }                      \
963
0
                        \
964
0
  y1 = pixman_fixed_to_int (vy);                \
965
0
  weight2 = pixman_fixed_to_bilinear_weight (vy);           \
966
0
  if (weight2)                   \
967
0
  {                     \
968
0
      /* both weight1 and weight2 are smaller than BILINEAR_INTERPOLATION_RANGE */  \
969
0
      y2 = y1 + 1;                  \
970
0
      weight1 = BILINEAR_INTERPOLATION_RANGE - weight2;         \
971
0
  }                     \
972
0
  else                      \
973
0
  {                     \
974
0
      /* set both top and bottom row to the same scanline and tweak weights */    \
975
0
      y2 = y1;                    \
976
0
      weight1 = weight2 = BILINEAR_INTERPOLATION_RANGE / 2;       \
977
0
  }                     \
978
0
  vy += unit_y;                   \
979
0
  if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD)         \
980
0
  {                     \
981
0
      src_type_t *src1, *src2;                \
982
0
      src_type_t buf1[2];                 \
983
0
      src_type_t buf2[2];                 \
984
0
      repeat (PIXMAN_REPEAT_PAD, &y1, src_image->bits.height);        \
985
0
      repeat (PIXMAN_REPEAT_PAD, &y2, src_image->bits.height);        \
986
0
      src1 = src_first_line + src_stride * y1;            \
987
0
      src2 = src_first_line + src_stride * y2;            \
988
0
                        \
989
0
      if (left_pad > 0)                 \
990
0
      {                     \
991
0
    buf1[0] = buf1[1] = src1[0];              \
992
0
    buf2[0] = buf2[1] = src2[0];              \
993
0
    scanline_func (dst, mask,             \
994
0
             buf1, buf2, left_pad, weight1, weight2, 0, 0, 0, FALSE);    \
995
0
    dst += left_pad;                \
996
0
    if (flags & FLAG_HAVE_NON_SOLID_MASK)           \
997
0
        mask += left_pad;               \
998
0
      }                     \
999
0
      if (width > 0)                 \
1000
0
      {                     \
1001
0
    scanline_func (dst, mask,             \
1002
0
             src1, src2, width, weight1, weight2, vx, unit_x, 0, FALSE);  \
1003
0
    dst += width;                 \
1004
0
    if (flags & FLAG_HAVE_NON_SOLID_MASK)           \
1005
0
        mask += width;               \
1006
0
      }                     \
1007
0
      if (right_pad > 0)                 \
1008
0
      {                     \
1009
0
    buf1[0] = buf1[1] = src1[src_image->bits.width - 1];        \
1010
0
    buf2[0] = buf2[1] = src2[src_image->bits.width - 1];        \
1011
0
    scanline_func (dst, mask,             \
1012
0
             buf1, buf2, right_pad, weight1, weight2, 0, 0, 0, FALSE);  \
1013
0
      }                     \
1014
0
  }                     \
1015
0
  else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE)       \
1016
0
  {                     \
1017
0
      src_type_t *src1, *src2;                \
1018
0
      src_type_t buf1[2];                 \
1019
0
      src_type_t buf2[2];                 \
1020
0
      /* handle top/bottom zero padding by just setting weights to 0 if needed */   \
1021
0
      if (y1 < 0)                   \
1022
0
      {                     \
1023
0
    weight1 = 0;                  \
1024
0
    y1 = 0;                   \
1025
0
      }                      \
1026
0
      if (y1 >= src_image->bits.height)             \
1027
0
      {                     \
1028
0
    weight1 = 0;                  \
1029
0
    y1 = src_image->bits.height - 1;            \
1030
0
      }                      \
1031
0
      if (y2 < 0)                   \
1032
0
      {                     \
1033
0
    weight2 = 0;                  \
1034
0
    y2 = 0;                   \
1035
0
      }                      \
1036
0
      if (y2 >= src_image->bits.height)             \
1037
0
      {                     \
1038
0
    weight2 = 0;                  \
1039
0
    y2 = src_image->bits.height - 1;            \
1040
0
      }                      \
1041
0
      src1 = src_first_line + src_stride * y1;            \
1042
0
      src2 = src_first_line + src_stride * y2;            \
1043
0
                        \
1044
0
      if (left_pad > 0)                 \
1045
0
      {                     \
1046
0
    buf1[0] = buf1[1] = 0;                \
1047
0
    buf2[0] = buf2[1] = 0;                \
1048
0
    scanline_func (dst, mask,             \
1049
0
             buf1, buf2, left_pad, weight1, weight2, 0, 0, 0, TRUE);    \
1050
0
    dst += left_pad;                \
1051
0
    if (flags & FLAG_HAVE_NON_SOLID_MASK)           \
1052
0
        mask += left_pad;               \
1053
0
      }                     \
1054
0
      if (left_tz > 0)                 \
1055
0
      {                     \
1056
0
    buf1[0] = 0;                  \
1057
0
    buf1[1] = src1[0];                \
1058
0
    buf2[0] = 0;                  \
1059
0
    buf2[1] = src2[0];                \
1060
0
    scanline_func (dst, mask,             \
1061
0
             buf1, buf2, left_tz, weight1, weight2,       \
1062
0
             pixman_fixed_frac (vx), unit_x, 0, FALSE);      \
1063
0
    dst += left_tz;                 \
1064
0
    if (flags & FLAG_HAVE_NON_SOLID_MASK)           \
1065
0
        mask += left_tz;               \
1066
0
    vx += left_tz * unit_x;               \
1067
0
      }                     \
1068
0
      if (width > 0)                 \
1069
0
      {                     \
1070
0
    scanline_func (dst, mask,             \
1071
0
             src1, src2, width, weight1, weight2, vx, unit_x, 0, FALSE);  \
1072
0
    dst += width;                 \
1073
0
    if (flags & FLAG_HAVE_NON_SOLID_MASK)           \
1074
0
        mask += width;               \
1075
0
    vx += width * unit_x;               \
1076
0
      }                     \
1077
0
      if (right_tz > 0)                 \
1078
0
      {                     \
1079
0
    buf1[0] = src1[src_image->bits.width - 1];          \
1080
0
    buf1[1] = 0;                  \
1081
0
    buf2[0] = src2[src_image->bits.width - 1];          \
1082
0
    buf2[1] = 0;                  \
1083
0
    scanline_func (dst, mask,             \
1084
0
             buf1, buf2, right_tz, weight1, weight2,        \
1085
0
             pixman_fixed_frac (vx), unit_x, 0, FALSE);      \
1086
0
    dst += right_tz;                \
1087
0
    if (flags & FLAG_HAVE_NON_SOLID_MASK)           \
1088
0
        mask += right_tz;               \
1089
0
      }                     \
1090
0
      if (right_pad > 0)                 \
1091
0
      {                     \
1092
0
    buf1[0] = buf1[1] = 0;                \
1093
0
    buf2[0] = buf2[1] = 0;                \
1094
0
    scanline_func (dst, mask,             \
1095
0
             buf1, buf2, right_pad, weight1, weight2, 0, 0, 0, TRUE);    \
1096
0
      }                     \
1097
0
  }                     \
1098
0
  else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)       \
1099
0
  {                     \
1100
0
      int32_t     num_pixels;               \
1101
0
      int32_t     width_remain;             \
1102
0
      src_type_t *    src_line_top;             \
1103
0
      src_type_t *    src_line_bottom;              \
1104
0
      src_type_t      buf1[2];                \
1105
0
      src_type_t      buf2[2];                \
1106
0
      src_type_t      extended_src_line0[REPEAT_NORMAL_MIN_WIDTH*2];      \
1107
0
      src_type_t      extended_src_line1[REPEAT_NORMAL_MIN_WIDTH*2];      \
1108
0
      int       i, j;               \
1109
0
                        \
1110
0
      repeat (PIXMAN_REPEAT_NORMAL, &y1, src_image->bits.height);       \
1111
0
      repeat (PIXMAN_REPEAT_NORMAL, &y2, src_image->bits.height);       \
1112
0
      src_line_top = src_first_line + src_stride * y1;          \
1113
0
      src_line_bottom = src_first_line + src_stride * y2;         \
1114
0
                        \
1115
0
      if (need_src_extension)               \
1116
0
      {                     \
1117
0
    for (i=0; i<src_width;)                \
1118
0
    {                   \
1119
0
        for (j=0; j<src_image->bits.width; j++, i++)       \
1120
0
        {                   \
1121
0
      extended_src_line0[i] = src_line_top[j];        \
1122
0
      extended_src_line1[i] = src_line_bottom[j];       \
1123
0
        }                    \
1124
0
    }                   \
1125
0
                        \
1126
0
    src_line_top = &extended_src_line0[0];            \
1127
0
    src_line_bottom = &extended_src_line1[0];         \
1128
0
      }                     \
1129
0
                        \
1130
0
      /* Top & Bottom wrap around buffer */           \
1131
0
      buf1[0] = src_line_top[src_width - 1];            \
1132
0
      buf1[1] = src_line_top[0];                \
1133
0
      buf2[0] = src_line_bottom[src_width - 1];           \
1134
0
      buf2[1] = src_line_bottom[0];             \
1135
0
                        \
1136
0
      width_remain = width;               \
1137
0
                        \
1138
0
      while (width_remain > 0)               \
1139
0
      {                     \
1140
0
    /* We use src_width_fixed because it can make vx in original source range */  \
1141
0
    repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed);        \
1142
0
                        \
1143
0
    /* Wrap around part */                \
1144
0
    if (pixman_fixed_to_int (vx) == src_width - 1)         \
1145
0
    {                   \
1146
0
        /* for positive unit_x              \
1147
0
         * num_pixels = max(n) + 1, where vx + n*unit_x < src_width_fixed   \
1148
0
         *                    \
1149
0
         * vx is in range [0, src_width_fixed - pixman_fixed_e]     \
1150
0
         * So we are safe from overflow.            \
1151
0
         */                   \
1152
0
        num_pixels = ((src_width_fixed - vx - pixman_fixed_e) / unit_x) + 1;  \
1153
0
                        \
1154
0
        if (num_pixels > width_remain)           \
1155
0
      num_pixels = width_remain;           \
1156
0
                        \
1157
0
        scanline_func (dst, mask, buf1, buf2, num_pixels,       \
1158
0
           weight1, weight2, pixman_fixed_frac(vx),     \
1159
0
           unit_x, src_width_fixed, FALSE);        \
1160
0
                        \
1161
0
        width_remain -= num_pixels;             \
1162
0
        vx += num_pixels * unit_x;              \
1163
0
        dst += num_pixels;                \
1164
0
                        \
1165
0
        if (flags & FLAG_HAVE_NON_SOLID_MASK)         \
1166
0
      mask += num_pixels;             \
1167
0
                        \
1168
0
        repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed);      \
1169
0
    }                   \
1170
0
                        \
1171
0
    /* Normal scanline composite */             \
1172
0
    if (pixman_fixed_to_int (vx) != src_width - 1 && width_remain > 0)   \
1173
0
    {                   \
1174
0
        /* for positive unit_x              \
1175
0
         * num_pixels = max(n) + 1, where vx + n*unit_x < (src_width_fixed - 1) \
1176
0
         *                    \
1177
0
         * vx is in range [0, src_width_fixed - pixman_fixed_e]     \
1178
0
         * So we are safe from overflow here.         \
1179
0
         */                   \
1180
0
        num_pixels = ((src_width_fixed - pixman_fixed_1 - vx - pixman_fixed_e) \
1181
0
          / unit_x) + 1;            \
1182
0
                        \
1183
0
        if (num_pixels > width_remain)           \
1184
0
      num_pixels = width_remain;           \
1185
0
                        \
1186
0
        scanline_func (dst, mask, src_line_top, src_line_bottom, num_pixels,  \
1187
0
           weight1, weight2, vx, unit_x, src_width_fixed, FALSE);  \
1188
0
                        \
1189
0
        width_remain -= num_pixels;             \
1190
0
        vx += num_pixels * unit_x;              \
1191
0
        dst += num_pixels;                \
1192
0
                        \
1193
0
        if (flags & FLAG_HAVE_NON_SOLID_MASK)         \
1194
0
            mask += num_pixels;             \
1195
0
    }                   \
1196
0
      }                     \
1197
0
  }                     \
1198
0
  else                      \
1199
0
  {                     \
1200
0
      scanline_func (dst, mask, src_first_line + src_stride * y1,       \
1201
0
         src_first_line + src_stride * y2, width,       \
1202
0
         weight1, weight2, vx, unit_x, max_vx, FALSE);      \
1203
0
  }                     \
1204
0
    }                       \
1205
0
}
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_cover_SRC
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_none_SRC
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_pad_SRC
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_normal_SRC
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_cover_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_none_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_pad_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8888_normal_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8_8888_cover_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8_8888_none_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8_8888_pad_OVER
Unexecuted instantiation: pixman-mmx.c:fast_composite_scaled_bilinear_mmx_8888_8_8888_normal_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_cover_SRC
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_none_SRC
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_pad_SRC
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_normal_SRC
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_x888_8888_cover_SRC
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_x888_8888_pad_SRC
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_x888_8888_normal_SRC
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_cover_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_none_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_pad_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8888_normal_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_n_8888_cover_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_n_8888_none_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_n_8888_pad_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_n_8888_normal_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8_8888_cover_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8_8888_none_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8_8888_pad_OVER
Unexecuted instantiation: pixman-sse2.c:fast_composite_scaled_bilinear_sse2_8888_8_8888_normal_OVER
1206
1207
/* A workaround for old sun studio, see: https://bugs.freedesktop.org/show_bug.cgi?id=32764 */
1208
#define FAST_BILINEAR_MAINLOOP_COMMON(scale_func_name, scanline_func, src_type_t, mask_type_t,  \
1209
          dst_type_t, repeat_mode, flags)       \
1210
  FAST_BILINEAR_MAINLOOP_INT(_ ## scale_func_name, scanline_func, src_type_t, mask_type_t,\
1211
          dst_type_t, repeat_mode, flags)
1212
1213
#define SCALED_BILINEAR_FLAGS           \
1214
    (FAST_PATH_SCALE_TRANSFORM  |         \
1215
     FAST_PATH_NO_ALPHA_MAP |         \
1216
     FAST_PATH_BILINEAR_FILTER  |         \
1217
     FAST_PATH_NO_ACCESSORS |         \
1218
     FAST_PATH_NARROW_FORMAT)
1219
1220
#define SIMPLE_BILINEAR_FAST_PATH_PAD(op,s,d,func)      \
1221
    {   PIXMAN_OP_ ## op,           \
1222
  PIXMAN_ ## s,             \
1223
  (SCALED_BILINEAR_FLAGS    |       \
1224
   FAST_PATH_PAD_REPEAT   |       \
1225
   FAST_PATH_X_UNIT_POSITIVE),          \
1226
  PIXMAN_null, 0,             \
1227
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1228
  fast_composite_scaled_bilinear_ ## func ## _pad ## _ ## op, \
1229
    }
1230
1231
#define SIMPLE_BILINEAR_FAST_PATH_NONE(op,s,d,func)     \
1232
    {   PIXMAN_OP_ ## op,           \
1233
  PIXMAN_ ## s,             \
1234
  (SCALED_BILINEAR_FLAGS    |       \
1235
   FAST_PATH_NONE_REPEAT    |       \
1236
   FAST_PATH_X_UNIT_POSITIVE),          \
1237
  PIXMAN_null, 0,             \
1238
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1239
  fast_composite_scaled_bilinear_ ## func ## _none ## _ ## op,  \
1240
    }
1241
1242
#define SIMPLE_BILINEAR_FAST_PATH_COVER(op,s,d,func)      \
1243
    {   PIXMAN_OP_ ## op,           \
1244
  PIXMAN_ ## s,             \
1245
  SCALED_BILINEAR_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR,  \
1246
  PIXMAN_null, 0,             \
1247
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1248
  fast_composite_scaled_bilinear_ ## func ## _cover ## _ ## op, \
1249
    }
1250
1251
#define SIMPLE_BILINEAR_FAST_PATH_NORMAL(op,s,d,func)     \
1252
    {   PIXMAN_OP_ ## op,           \
1253
  PIXMAN_ ## s,             \
1254
  (SCALED_BILINEAR_FLAGS    |       \
1255
   FAST_PATH_NORMAL_REPEAT  |       \
1256
   FAST_PATH_X_UNIT_POSITIVE),          \
1257
  PIXMAN_null, 0,             \
1258
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1259
  fast_composite_scaled_bilinear_ ## func ## _normal ## _ ## op,  \
1260
    }
1261
1262
#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_PAD(op,s,d,func)    \
1263
    {   PIXMAN_OP_ ## op,           \
1264
  PIXMAN_ ## s,             \
1265
  (SCALED_BILINEAR_FLAGS    |       \
1266
   FAST_PATH_PAD_REPEAT   |       \
1267
   FAST_PATH_X_UNIT_POSITIVE),          \
1268
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
1269
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1270
  fast_composite_scaled_bilinear_ ## func ## _pad ## _ ## op, \
1271
    }
1272
1273
#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NONE(op,s,d,func)   \
1274
    {   PIXMAN_OP_ ## op,           \
1275
  PIXMAN_ ## s,             \
1276
  (SCALED_BILINEAR_FLAGS    |       \
1277
   FAST_PATH_NONE_REPEAT    |       \
1278
   FAST_PATH_X_UNIT_POSITIVE),          \
1279
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
1280
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1281
  fast_composite_scaled_bilinear_ ## func ## _none ## _ ## op,  \
1282
    }
1283
1284
#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_COVER(op,s,d,func)    \
1285
    {   PIXMAN_OP_ ## op,           \
1286
  PIXMAN_ ## s,             \
1287
  SCALED_BILINEAR_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR,  \
1288
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
1289
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1290
  fast_composite_scaled_bilinear_ ## func ## _cover ## _ ## op, \
1291
    }
1292
1293
#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NORMAL(op,s,d,func)   \
1294
    {   PIXMAN_OP_ ## op,           \
1295
  PIXMAN_ ## s,             \
1296
  (SCALED_BILINEAR_FLAGS    |       \
1297
   FAST_PATH_NORMAL_REPEAT  |       \
1298
   FAST_PATH_X_UNIT_POSITIVE),          \
1299
  PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA),    \
1300
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1301
  fast_composite_scaled_bilinear_ ## func ## _normal ## _ ## op,  \
1302
    }
1303
1304
#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_PAD(op,s,d,func)   \
1305
    {   PIXMAN_OP_ ## op,           \
1306
  PIXMAN_ ## s,             \
1307
  (SCALED_BILINEAR_FLAGS    |       \
1308
   FAST_PATH_PAD_REPEAT   |       \
1309
   FAST_PATH_X_UNIT_POSITIVE),          \
1310
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
1311
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1312
  fast_composite_scaled_bilinear_ ## func ## _pad ## _ ## op, \
1313
    }
1314
1315
#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NONE(op,s,d,func)    \
1316
    {   PIXMAN_OP_ ## op,           \
1317
  PIXMAN_ ## s,             \
1318
  (SCALED_BILINEAR_FLAGS    |       \
1319
   FAST_PATH_NONE_REPEAT    |       \
1320
   FAST_PATH_X_UNIT_POSITIVE),          \
1321
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
1322
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1323
  fast_composite_scaled_bilinear_ ## func ## _none ## _ ## op,  \
1324
    }
1325
1326
#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_COVER(op,s,d,func)   \
1327
    {   PIXMAN_OP_ ## op,           \
1328
  PIXMAN_ ## s,             \
1329
  SCALED_BILINEAR_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR,  \
1330
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
1331
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1332
  fast_composite_scaled_bilinear_ ## func ## _cover ## _ ## op, \
1333
    }
1334
1335
#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NORMAL(op,s,d,func)  \
1336
    {   PIXMAN_OP_ ## op,           \
1337
  PIXMAN_ ## s,             \
1338
  (SCALED_BILINEAR_FLAGS    |       \
1339
   FAST_PATH_NORMAL_REPEAT  |       \
1340
   FAST_PATH_X_UNIT_POSITIVE),          \
1341
  PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA),  \
1342
  PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS,       \
1343
  fast_composite_scaled_bilinear_ ## func ## _normal ## _ ## op,  \
1344
    }
1345
1346
/* Prefer the use of 'cover' variant, because it is faster */
1347
#define SIMPLE_BILINEAR_FAST_PATH(op,s,d,func)        \
1348
    SIMPLE_BILINEAR_FAST_PATH_COVER (op,s,d,func),      \
1349
    SIMPLE_BILINEAR_FAST_PATH_NONE (op,s,d,func),     \
1350
    SIMPLE_BILINEAR_FAST_PATH_PAD (op,s,d,func),      \
1351
    SIMPLE_BILINEAR_FAST_PATH_NORMAL (op,s,d,func)
1352
1353
#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH(op,s,d,func)      \
1354
    SIMPLE_BILINEAR_A8_MASK_FAST_PATH_COVER (op,s,d,func),    \
1355
    SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NONE (op,s,d,func),   \
1356
    SIMPLE_BILINEAR_A8_MASK_FAST_PATH_PAD (op,s,d,func),    \
1357
    SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NORMAL (op,s,d,func)
1358
1359
#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH(op,s,d,func)   \
1360
    SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_COVER (op,s,d,func),   \
1361
    SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NONE (op,s,d,func),    \
1362
    SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_PAD (op,s,d,func),   \
1363
    SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NORMAL (op,s,d,func)
1364
1365
#endif