/work/workdir/UnpackedTarball/pixman/pixman/pixman-inlines.h
Line | Count | Source |
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 | | #define FLAG_HAVE_SOLID_MASK (1 << 1) |
49 | | #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 | | #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 | 6.91k | { |
59 | 6.91k | if (repeat == PIXMAN_REPEAT_NONE) |
60 | 0 | { |
61 | 0 | if (*c < 0 || *c >= size) |
62 | 0 | return FALSE; |
63 | 0 | } |
64 | 6.91k | 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 | 6.91k | else if (repeat == PIXMAN_REPEAT_PAD) |
72 | 6.91k | { |
73 | 6.91k | *c = CLIP (*c, 0, size - 1); |
74 | 6.91k | } |
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 | 6.91k | return TRUE; |
82 | 6.91k | } pixman-bits-image.c:repeat Line | Count | Source | 58 | 12 | { | 59 | 12 | if (repeat == PIXMAN_REPEAT_NONE) | 60 | 0 | { | 61 | 0 | if (*c < 0 || *c >= size) | 62 | 0 | return FALSE; | 63 | 0 | } | 64 | 12 | 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 | 12 | else if (repeat == PIXMAN_REPEAT_PAD) | 72 | 12 | { | 73 | 12 | *c = CLIP (*c, 0, size - 1); | 74 | 12 | } | 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 | 12 | return TRUE; | 82 | 12 | } |
Unexecuted instantiation: pixman-noop.c:repeat pixman-fast-path.c:repeat Line | Count | Source | 58 | 6.90k | { | 59 | 6.90k | if (repeat == PIXMAN_REPEAT_NONE) | 60 | 0 | { | 61 | 0 | if (*c < 0 || *c >= size) | 62 | 0 | return FALSE; | 63 | 0 | } | 64 | 6.90k | 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 | 6.90k | else if (repeat == PIXMAN_REPEAT_PAD) | 72 | 6.90k | { | 73 | 6.90k | *c = CLIP (*c, 0, size - 1); | 74 | 6.90k | } | 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 | 6.90k | return TRUE; | 82 | 6.90k | } |
|
83 | | |
84 | | static force_inline int |
85 | | pixman_fixed_to_bilinear_weight (pixman_fixed_t x) |
86 | 192 | { |
87 | 192 | return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) & |
88 | 192 | ((1 << BILINEAR_INTERPOLATION_BITS) - 1); |
89 | 192 | } pixman-bits-image.c:pixman_fixed_to_bilinear_weight Line | Count | Source | 86 | 6 | { | 87 | 6 | return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) & | 88 | 6 | ((1 << BILINEAR_INTERPOLATION_BITS) - 1); | 89 | 6 | } |
Unexecuted instantiation: pixman-noop.c:pixman_fixed_to_bilinear_weight pixman-fast-path.c:pixman_fixed_to_bilinear_weight Line | Count | Source | 86 | 186 | { | 87 | 186 | return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) & | 88 | 186 | ((1 << BILINEAR_INTERPOLATION_BITS) - 1); | 89 | 186 | } |
|
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 | 96 | { |
134 | 96 | uint64_t distxy, distxiy, distixy, distixiy; |
135 | 96 | uint64_t tl64, tr64, bl64, br64; |
136 | 96 | uint64_t f, r; |
137 | | |
138 | 96 | distx <<= (8 - BILINEAR_INTERPOLATION_BITS); |
139 | 96 | disty <<= (8 - BILINEAR_INTERPOLATION_BITS); |
140 | | |
141 | 96 | distxy = distx * disty; |
142 | 96 | distxiy = distx * (256 - disty); |
143 | 96 | distixy = (256 - distx) * disty; |
144 | 96 | distixiy = (256 - distx) * (256 - disty); |
145 | | |
146 | | /* Alpha and Blue */ |
147 | 96 | tl64 = tl & 0xff0000ff; |
148 | 96 | tr64 = tr & 0xff0000ff; |
149 | 96 | bl64 = bl & 0xff0000ff; |
150 | 96 | br64 = br & 0xff0000ff; |
151 | | |
152 | 96 | f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; |
153 | 96 | r = f & 0x0000ff0000ff0000ull; |
154 | | |
155 | | /* Red and Green */ |
156 | 96 | tl64 = tl; |
157 | 96 | tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull); |
158 | | |
159 | 96 | tr64 = tr; |
160 | 96 | tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull); |
161 | | |
162 | 96 | bl64 = bl; |
163 | 96 | bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull); |
164 | | |
165 | 96 | br64 = br; |
166 | 96 | br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull); |
167 | | |
168 | 96 | f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; |
169 | 96 | r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull); |
170 | | |
171 | 96 | return (uint32_t)(r >> 16); |
172 | 96 | } pixman-bits-image.c:bilinear_interpolation Line | Count | Source | 133 | 3 | { | 134 | 3 | uint64_t distxy, distxiy, distixy, distixiy; | 135 | 3 | uint64_t tl64, tr64, bl64, br64; | 136 | 3 | uint64_t f, r; | 137 | | | 138 | 3 | distx <<= (8 - BILINEAR_INTERPOLATION_BITS); | 139 | 3 | disty <<= (8 - BILINEAR_INTERPOLATION_BITS); | 140 | | | 141 | 3 | distxy = distx * disty; | 142 | 3 | distxiy = distx * (256 - disty); | 143 | 3 | distixy = (256 - distx) * disty; | 144 | 3 | distixiy = (256 - distx) * (256 - disty); | 145 | | | 146 | | /* Alpha and Blue */ | 147 | 3 | tl64 = tl & 0xff0000ff; | 148 | 3 | tr64 = tr & 0xff0000ff; | 149 | 3 | bl64 = bl & 0xff0000ff; | 150 | 3 | br64 = br & 0xff0000ff; | 151 | | | 152 | 3 | f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; | 153 | 3 | r = f & 0x0000ff0000ff0000ull; | 154 | | | 155 | | /* Red and Green */ | 156 | 3 | tl64 = tl; | 157 | 3 | tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull); | 158 | | | 159 | 3 | tr64 = tr; | 160 | 3 | tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull); | 161 | | | 162 | 3 | bl64 = bl; | 163 | 3 | bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull); | 164 | | | 165 | 3 | br64 = br; | 166 | 3 | br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull); | 167 | | | 168 | 3 | f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; | 169 | 3 | r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull); | 170 | | | 171 | 3 | return (uint32_t)(r >> 16); | 172 | 3 | } |
Unexecuted instantiation: pixman-noop.c:bilinear_interpolation pixman-fast-path.c:bilinear_interpolation Line | Count | Source | 133 | 93 | { | 134 | 93 | uint64_t distxy, distxiy, distixy, distixiy; | 135 | 93 | uint64_t tl64, tr64, bl64, br64; | 136 | 93 | uint64_t f, r; | 137 | | | 138 | 93 | distx <<= (8 - BILINEAR_INTERPOLATION_BITS); | 139 | 93 | disty <<= (8 - BILINEAR_INTERPOLATION_BITS); | 140 | | | 141 | 93 | distxy = distx * disty; | 142 | 93 | distxiy = distx * (256 - disty); | 143 | 93 | distixy = (256 - distx) * disty; | 144 | 93 | distixiy = (256 - distx) * (256 - disty); | 145 | | | 146 | | /* Alpha and Blue */ | 147 | 93 | tl64 = tl & 0xff0000ff; | 148 | 93 | tr64 = tr & 0xff0000ff; | 149 | 93 | bl64 = bl & 0xff0000ff; | 150 | 93 | br64 = br & 0xff0000ff; | 151 | | | 152 | 93 | f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; | 153 | 93 | r = f & 0x0000ff0000ff0000ull; | 154 | | | 155 | | /* Red and Green */ | 156 | 93 | tl64 = tl; | 157 | 93 | tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull); | 158 | | | 159 | 93 | tr64 = tr; | 160 | 93 | tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull); | 161 | | | 162 | 93 | bl64 = bl; | 163 | 93 | bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull); | 164 | | | 165 | 93 | br64 = br; | 166 | 93 | br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull); | 167 | | | 168 | 93 | f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; | 169 | 93 | r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull); | 170 | | | 171 | 93 | return (uint32_t)(r >> 16); | 172 | 93 | } |
|
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-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-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-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-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 | 0 |
|
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 | 0 |
|
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-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 | | pixman_composite_info_t *info) \ |
858 | | { \ |
859 | | PIXMAN_COMPOSITE_ARGS (info); \ |
860 | | dst_type_t *dst_line; \ |
861 | | mask_type_t *mask_line; \ |
862 | | src_type_t *src_first_line; \ |
863 | | int y1, y2; \ |
864 | | pixman_fixed_t max_vx = INT32_MAX; /* suppress uninitialized variable warning */ \ |
865 | | pixman_vector_t v; \ |
866 | | pixman_fixed_t vx, vy; \ |
867 | | pixman_fixed_t unit_x, unit_y; \ |
868 | | int32_t left_pad, left_tz, right_tz, right_pad; \ |
869 | | \ |
870 | | dst_type_t *dst; \ |
871 | | mask_type_t solid_mask; \ |
872 | | const mask_type_t *mask = &solid_mask; \ |
873 | | int src_stride, mask_stride, dst_stride; \ |
874 | | \ |
875 | | int src_width; \ |
876 | | pixman_fixed_t src_width_fixed; \ |
877 | | int max_x; \ |
878 | | pixman_bool_t need_src_extension; \ |
879 | | \ |
880 | | PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type_t, dst_stride, dst_line, 1); \ |
881 | | if (flags & FLAG_HAVE_SOLID_MASK) \ |
882 | | { \ |
883 | | solid_mask = _pixman_image_get_solid (imp, mask_image, dest_image->bits.format); \ |
884 | | mask_stride = 0; \ |
885 | | } \ |
886 | | else if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
887 | | { \ |
888 | | PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type_t, \ |
889 | | mask_stride, mask_line, 1); \ |
890 | | } \ |
891 | | \ |
892 | | /* pass in 0 instead of src_x and src_y because src_x and src_y need to be \ |
893 | | * transformed from destination space to source space */ \ |
894 | | PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, src_type_t, src_stride, src_first_line, 1); \ |
895 | | \ |
896 | | /* reference point is the center of the pixel */ \ |
897 | | v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2; \ |
898 | | v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2; \ |
899 | | v.vector[2] = pixman_fixed_1; \ |
900 | | \ |
901 | | if (!pixman_transform_point_3d (src_image->common.transform, &v)) \ |
902 | | return; \ |
903 | | \ |
904 | | unit_x = src_image->common.transform->matrix[0][0]; \ |
905 | | unit_y = src_image->common.transform->matrix[1][1]; \ |
906 | | \ |
907 | | v.vector[0] -= pixman_fixed_1 / 2; \ |
908 | | v.vector[1] -= pixman_fixed_1 / 2; \ |
909 | | \ |
910 | | vy = v.vector[1]; \ |
911 | | \ |
912 | | if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD || \ |
913 | | PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ |
914 | | { \ |
915 | | bilinear_pad_repeat_get_scanline_bounds (src_image->bits.width, v.vector[0], unit_x, \ |
916 | | &left_pad, &left_tz, &width, &right_tz, &right_pad); \ |
917 | | if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD) \ |
918 | | { \ |
919 | | /* PAD repeat does not need special handling for 'transition zones' and */ \ |
920 | | /* they can be combined with 'padding zones' safely */ \ |
921 | | left_pad += left_tz; \ |
922 | | right_pad += right_tz; \ |
923 | | left_tz = right_tz = 0; \ |
924 | | } \ |
925 | | v.vector[0] += left_pad * unit_x; \ |
926 | | } \ |
927 | | \ |
928 | | if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ |
929 | | { \ |
930 | | vx = v.vector[0]; \ |
931 | | repeat (PIXMAN_REPEAT_NORMAL, &vx, pixman_int_to_fixed(src_image->bits.width)); \ |
932 | | max_x = pixman_fixed_to_int (vx + (width - 1) * (int64_t)unit_x) + 1; \ |
933 | | \ |
934 | | if (src_image->bits.width < REPEAT_NORMAL_MIN_WIDTH) \ |
935 | | { \ |
936 | | src_width = 0; \ |
937 | | \ |
938 | | while (src_width < REPEAT_NORMAL_MIN_WIDTH && src_width <= max_x) \ |
939 | | src_width += src_image->bits.width; \ |
940 | | \ |
941 | | need_src_extension = TRUE; \ |
942 | | } \ |
943 | | else \ |
944 | | { \ |
945 | | src_width = src_image->bits.width; \ |
946 | | need_src_extension = FALSE; \ |
947 | | } \ |
948 | | \ |
949 | | src_width_fixed = pixman_int_to_fixed (src_width); \ |
950 | | } \ |
951 | | \ |
952 | | while (--height >= 0) \ |
953 | | { \ |
954 | | int weight1, weight2; \ |
955 | | dst = dst_line; \ |
956 | | dst_line += dst_stride; \ |
957 | | vx = v.vector[0]; \ |
958 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
959 | | { \ |
960 | | mask = mask_line; \ |
961 | | mask_line += mask_stride; \ |
962 | | } \ |
963 | | \ |
964 | | y1 = pixman_fixed_to_int (vy); \ |
965 | | weight2 = pixman_fixed_to_bilinear_weight (vy); \ |
966 | | if (weight2) \ |
967 | | { \ |
968 | | /* both weight1 and weight2 are smaller than BILINEAR_INTERPOLATION_RANGE */ \ |
969 | | y2 = y1 + 1; \ |
970 | | weight1 = BILINEAR_INTERPOLATION_RANGE - weight2; \ |
971 | | } \ |
972 | | else \ |
973 | | { \ |
974 | | /* set both top and bottom row to the same scanline and tweak weights */ \ |
975 | | y2 = y1; \ |
976 | | weight1 = weight2 = BILINEAR_INTERPOLATION_RANGE / 2; \ |
977 | | } \ |
978 | | vy += unit_y; \ |
979 | | if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD) \ |
980 | | { \ |
981 | | src_type_t *src1, *src2; \ |
982 | | src_type_t buf1[2]; \ |
983 | | src_type_t buf2[2]; \ |
984 | | repeat (PIXMAN_REPEAT_PAD, &y1, src_image->bits.height); \ |
985 | | repeat (PIXMAN_REPEAT_PAD, &y2, src_image->bits.height); \ |
986 | | src1 = src_first_line + src_stride * y1; \ |
987 | | src2 = src_first_line + src_stride * y2; \ |
988 | | \ |
989 | | if (left_pad > 0) \ |
990 | | { \ |
991 | | buf1[0] = buf1[1] = src1[0]; \ |
992 | | buf2[0] = buf2[1] = src2[0]; \ |
993 | | scanline_func (dst, mask, \ |
994 | | buf1, buf2, left_pad, weight1, weight2, 0, 0, 0, FALSE); \ |
995 | | dst += left_pad; \ |
996 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
997 | | mask += left_pad; \ |
998 | | } \ |
999 | | if (width > 0) \ |
1000 | | { \ |
1001 | | scanline_func (dst, mask, \ |
1002 | | src1, src2, width, weight1, weight2, vx, unit_x, 0, FALSE); \ |
1003 | | dst += width; \ |
1004 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
1005 | | mask += width; \ |
1006 | | } \ |
1007 | | if (right_pad > 0) \ |
1008 | | { \ |
1009 | | buf1[0] = buf1[1] = src1[src_image->bits.width - 1]; \ |
1010 | | buf2[0] = buf2[1] = src2[src_image->bits.width - 1]; \ |
1011 | | scanline_func (dst, mask, \ |
1012 | | buf1, buf2, right_pad, weight1, weight2, 0, 0, 0, FALSE); \ |
1013 | | } \ |
1014 | | } \ |
1015 | | else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ |
1016 | | { \ |
1017 | | src_type_t *src1, *src2; \ |
1018 | | src_type_t buf1[2]; \ |
1019 | | src_type_t buf2[2]; \ |
1020 | | /* handle top/bottom zero padding by just setting weights to 0 if needed */ \ |
1021 | | if (y1 < 0) \ |
1022 | | { \ |
1023 | | weight1 = 0; \ |
1024 | | y1 = 0; \ |
1025 | | } \ |
1026 | | if (y1 >= src_image->bits.height) \ |
1027 | | { \ |
1028 | | weight1 = 0; \ |
1029 | | y1 = src_image->bits.height - 1; \ |
1030 | | } \ |
1031 | | if (y2 < 0) \ |
1032 | | { \ |
1033 | | weight2 = 0; \ |
1034 | | y2 = 0; \ |
1035 | | } \ |
1036 | | if (y2 >= src_image->bits.height) \ |
1037 | | { \ |
1038 | | weight2 = 0; \ |
1039 | | y2 = src_image->bits.height - 1; \ |
1040 | | } \ |
1041 | | src1 = src_first_line + src_stride * y1; \ |
1042 | | src2 = src_first_line + src_stride * y2; \ |
1043 | | \ |
1044 | | if (left_pad > 0) \ |
1045 | | { \ |
1046 | | buf1[0] = buf1[1] = 0; \ |
1047 | | buf2[0] = buf2[1] = 0; \ |
1048 | | scanline_func (dst, mask, \ |
1049 | | buf1, buf2, left_pad, weight1, weight2, 0, 0, 0, TRUE); \ |
1050 | | dst += left_pad; \ |
1051 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
1052 | | mask += left_pad; \ |
1053 | | } \ |
1054 | | if (left_tz > 0) \ |
1055 | | { \ |
1056 | | buf1[0] = 0; \ |
1057 | | buf1[1] = src1[0]; \ |
1058 | | buf2[0] = 0; \ |
1059 | | buf2[1] = src2[0]; \ |
1060 | | scanline_func (dst, mask, \ |
1061 | | buf1, buf2, left_tz, weight1, weight2, \ |
1062 | | pixman_fixed_frac (vx), unit_x, 0, FALSE); \ |
1063 | | dst += left_tz; \ |
1064 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
1065 | | mask += left_tz; \ |
1066 | | vx += left_tz * unit_x; \ |
1067 | | } \ |
1068 | | if (width > 0) \ |
1069 | | { \ |
1070 | | scanline_func (dst, mask, \ |
1071 | | src1, src2, width, weight1, weight2, vx, unit_x, 0, FALSE); \ |
1072 | | dst += width; \ |
1073 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
1074 | | mask += width; \ |
1075 | | vx += width * unit_x; \ |
1076 | | } \ |
1077 | | if (right_tz > 0) \ |
1078 | | { \ |
1079 | | buf1[0] = src1[src_image->bits.width - 1]; \ |
1080 | | buf1[1] = 0; \ |
1081 | | buf2[0] = src2[src_image->bits.width - 1]; \ |
1082 | | buf2[1] = 0; \ |
1083 | | scanline_func (dst, mask, \ |
1084 | | buf1, buf2, right_tz, weight1, weight2, \ |
1085 | | pixman_fixed_frac (vx), unit_x, 0, FALSE); \ |
1086 | | dst += right_tz; \ |
1087 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
1088 | | mask += right_tz; \ |
1089 | | } \ |
1090 | | if (right_pad > 0) \ |
1091 | | { \ |
1092 | | buf1[0] = buf1[1] = 0; \ |
1093 | | buf2[0] = buf2[1] = 0; \ |
1094 | | scanline_func (dst, mask, \ |
1095 | | buf1, buf2, right_pad, weight1, weight2, 0, 0, 0, TRUE); \ |
1096 | | } \ |
1097 | | } \ |
1098 | | else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ |
1099 | | { \ |
1100 | | int32_t num_pixels; \ |
1101 | | int32_t width_remain; \ |
1102 | | src_type_t * src_line_top; \ |
1103 | | src_type_t * src_line_bottom; \ |
1104 | | src_type_t buf1[2]; \ |
1105 | | src_type_t buf2[2]; \ |
1106 | | src_type_t extended_src_line0[REPEAT_NORMAL_MIN_WIDTH*2]; \ |
1107 | | src_type_t extended_src_line1[REPEAT_NORMAL_MIN_WIDTH*2]; \ |
1108 | | int i, j; \ |
1109 | | \ |
1110 | | repeat (PIXMAN_REPEAT_NORMAL, &y1, src_image->bits.height); \ |
1111 | | repeat (PIXMAN_REPEAT_NORMAL, &y2, src_image->bits.height); \ |
1112 | | src_line_top = src_first_line + src_stride * y1; \ |
1113 | | src_line_bottom = src_first_line + src_stride * y2; \ |
1114 | | \ |
1115 | | if (need_src_extension) \ |
1116 | | { \ |
1117 | | for (i=0; i<src_width;) \ |
1118 | | { \ |
1119 | | for (j=0; j<src_image->bits.width; j++, i++) \ |
1120 | | { \ |
1121 | | extended_src_line0[i] = src_line_top[j]; \ |
1122 | | extended_src_line1[i] = src_line_bottom[j]; \ |
1123 | | } \ |
1124 | | } \ |
1125 | | \ |
1126 | | src_line_top = &extended_src_line0[0]; \ |
1127 | | src_line_bottom = &extended_src_line1[0]; \ |
1128 | | } \ |
1129 | | \ |
1130 | | /* Top & Bottom wrap around buffer */ \ |
1131 | | buf1[0] = src_line_top[src_width - 1]; \ |
1132 | | buf1[1] = src_line_top[0]; \ |
1133 | | buf2[0] = src_line_bottom[src_width - 1]; \ |
1134 | | buf2[1] = src_line_bottom[0]; \ |
1135 | | \ |
1136 | | width_remain = width; \ |
1137 | | \ |
1138 | | while (width_remain > 0) \ |
1139 | | { \ |
1140 | | /* We use src_width_fixed because it can make vx in original source range */ \ |
1141 | | repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed); \ |
1142 | | \ |
1143 | | /* Wrap around part */ \ |
1144 | | if (pixman_fixed_to_int (vx) == src_width - 1) \ |
1145 | | { \ |
1146 | | /* for positive unit_x \ |
1147 | | * num_pixels = max(n) + 1, where vx + n*unit_x < src_width_fixed \ |
1148 | | * \ |
1149 | | * vx is in range [0, src_width_fixed - pixman_fixed_e] \ |
1150 | | * So we are safe from overflow. \ |
1151 | | */ \ |
1152 | | num_pixels = ((src_width_fixed - vx - pixman_fixed_e) / unit_x) + 1; \ |
1153 | | \ |
1154 | | if (num_pixels > width_remain) \ |
1155 | | num_pixels = width_remain; \ |
1156 | | \ |
1157 | | scanline_func (dst, mask, buf1, buf2, num_pixels, \ |
1158 | | weight1, weight2, pixman_fixed_frac(vx), \ |
1159 | | unit_x, src_width_fixed, FALSE); \ |
1160 | | \ |
1161 | | width_remain -= num_pixels; \ |
1162 | | vx += num_pixels * unit_x; \ |
1163 | | dst += num_pixels; \ |
1164 | | \ |
1165 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
1166 | | mask += num_pixels; \ |
1167 | | \ |
1168 | | repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed); \ |
1169 | | } \ |
1170 | | \ |
1171 | | /* Normal scanline composite */ \ |
1172 | | if (pixman_fixed_to_int (vx) != src_width - 1 && width_remain > 0) \ |
1173 | | { \ |
1174 | | /* for positive unit_x \ |
1175 | | * num_pixels = max(n) + 1, where vx + n*unit_x < (src_width_fixed - 1) \ |
1176 | | * \ |
1177 | | * vx is in range [0, src_width_fixed - pixman_fixed_e] \ |
1178 | | * So we are safe from overflow here. \ |
1179 | | */ \ |
1180 | | num_pixels = ((src_width_fixed - pixman_fixed_1 - vx - pixman_fixed_e) \ |
1181 | | / unit_x) + 1; \ |
1182 | | \ |
1183 | | if (num_pixels > width_remain) \ |
1184 | | num_pixels = width_remain; \ |
1185 | | \ |
1186 | | scanline_func (dst, mask, src_line_top, src_line_bottom, num_pixels, \ |
1187 | | weight1, weight2, vx, unit_x, src_width_fixed, FALSE); \ |
1188 | | \ |
1189 | | width_remain -= num_pixels; \ |
1190 | | vx += num_pixels * unit_x; \ |
1191 | | dst += num_pixels; \ |
1192 | | \ |
1193 | | if (flags & FLAG_HAVE_NON_SOLID_MASK) \ |
1194 | | mask += num_pixels; \ |
1195 | | } \ |
1196 | | } \ |
1197 | | } \ |
1198 | | else \ |
1199 | | { \ |
1200 | | scanline_func (dst, mask, src_first_line + src_stride * y1, \ |
1201 | | src_first_line + src_stride * y2, width, \ |
1202 | | weight1, weight2, vx, unit_x, max_vx, FALSE); \ |
1203 | | } \ |
1204 | | } \ |
1205 | | } |
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 |