blob: fbb2a1e00b5e53834cc06f77d25b113e398bc0a6 [file] [log] [blame]
reedad7ae6c2015-06-04 14:12:25 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +00007
8#include <arm_neon.h>
9
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000010#define SCALE_NOFILTER_NAME MAKENAME(_nofilter_scale)
11#define SCALE_FILTER_NAME MAKENAME(_filter_scale)
12#define AFFINE_NOFILTER_NAME MAKENAME(_nofilter_affine)
13#define AFFINE_FILTER_NAME MAKENAME(_filter_affine)
14#define PERSP_NOFILTER_NAME MAKENAME(_nofilter_persp)
15#define PERSP_FILTER_NAME MAKENAME(_filter_persp)
16
17#define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x)
18#define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y)
19#define PACK_FILTER_X4_NAME MAKENAME(_pack_filter_x4)
20#define PACK_FILTER_Y4_NAME MAKENAME(_pack_filter_y4)
21
22#ifndef PREAMBLE
23 #define PREAMBLE(state)
24 #define PREAMBLE_PARAM_X
25 #define PREAMBLE_PARAM_Y
26 #define PREAMBLE_ARG_X
27 #define PREAMBLE_ARG_Y
28#endif
29
30static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s,
31 uint32_t xy[], int count, int x, int y) {
32 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
33 SkMatrix::kScale_Mask)) == 0);
34
35 PREAMBLE(s);
36
37 // we store y, x, x, x, x, x
reedad7ae6c2015-06-04 14:12:25 -070038 const unsigned maxX = s.fPixmap.width() - 1;
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000039 SkFractionalInt fx;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000040 {
41 SkPoint pt;
42 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
43 SkIntToScalar(y) + SK_ScalarHalf, &pt);
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000044 fx = SkScalarToFractionalInt(pt.fY);
reedad7ae6c2015-06-04 14:12:25 -070045 const unsigned maxY = s.fPixmap.height() - 1;
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000046 *xy++ = TILEY_PROCF(SkFractionalIntToFixed(fx), maxY);
47 fx = SkScalarToFractionalInt(pt.fX);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000048 }
49
50 if (0 == maxX) {
51 // all of the following X values must be 0
52 memset(xy, 0, count * sizeof(uint16_t));
53 return;
54 }
55
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000056 const SkFractionalInt dx = s.fInvSxFractionalInt;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000057
58#ifdef CHECK_FOR_DECAL
59 // test if we don't need to apply the tile proc
60 if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000061 decal_nofilter_scale_neon(xy, SkFractionalIntToFixed(fx),
62 SkFractionalIntToFixed(dx), count);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000063 return;
64 }
65#endif
66
67 if (count >= 8) {
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000068 SkFractionalInt dx2 = dx+dx;
69 SkFractionalInt dx4 = dx2+dx2;
70 SkFractionalInt dx8 = dx4+dx4;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000071
72 // now build fx/fx+dx/fx+2dx/fx+3dx
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000073 SkFractionalInt fx1, fx2, fx3;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000074 int32x4_t lbase, hbase;
75 int16_t *dst16 = (int16_t *)xy;
76
77 fx1 = fx+dx;
78 fx2 = fx1+dx;
79 fx3 = fx2+dx;
80
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000081 lbase = vdupq_n_s32(SkFractionalIntToFixed(fx));
82 lbase = vsetq_lane_s32(SkFractionalIntToFixed(fx1), lbase, 1);
83 lbase = vsetq_lane_s32(SkFractionalIntToFixed(fx2), lbase, 2);
84 lbase = vsetq_lane_s32(SkFractionalIntToFixed(fx3), lbase, 3);
85 hbase = vaddq_s32(lbase, vdupq_n_s32(SkFractionalIntToFixed(dx4)));
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000086
87 // store & bump
88 while (count >= 8) {
89
90 int16x8_t fx8;
91
92 fx8 = TILEX_PROCF_NEON8(lbase, hbase, maxX);
93
94 vst1q_s16(dst16, fx8);
95
96 // but preserving base & on to the next
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +000097 lbase = vaddq_s32 (lbase, vdupq_n_s32(SkFractionalIntToFixed(dx8)));
98 hbase = vaddq_s32 (hbase, vdupq_n_s32(SkFractionalIntToFixed(dx8)));
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +000099 dst16 += 8;
100 count -= 8;
101 fx += dx8;
102 };
103 xy = (uint32_t *) dst16;
104 }
105
106 uint16_t* xx = (uint16_t*)xy;
107 for (int i = count; i > 0; --i) {
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000108 *xx++ = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000109 fx += dx;
110 }
111}
112
113static void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s,
114 uint32_t xy[], int count, int x, int y) {
115 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
116 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
117 SkMatrix::kScale_Mask |
118 SkMatrix::kAffine_Mask)) == 0);
119
120 PREAMBLE(s);
121 SkPoint srcPt;
122 s.fInvProc(s.fInvMatrix,
123 SkIntToScalar(x) + SK_ScalarHalf,
124 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
125
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000126 SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX);
127 SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY);
128 SkFractionalInt dx = s.fInvSxFractionalInt;
129 SkFractionalInt dy = s.fInvKyFractionalInt;
reedad7ae6c2015-06-04 14:12:25 -0700130 int maxX = s.fPixmap.width() - 1;
131 int maxY = s.fPixmap.height() - 1;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000132
133 if (count >= 8) {
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000134 SkFractionalInt dx4 = dx * 4;
135 SkFractionalInt dy4 = dy * 4;
136 SkFractionalInt dx8 = dx * 8;
137 SkFractionalInt dy8 = dy * 8;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000138
139 int32x4_t xbase, ybase;
140 int32x4_t x2base, y2base;
141 int16_t *dst16 = (int16_t *) xy;
142
143 // now build fx, fx+dx, fx+2dx, fx+3dx
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000144 xbase = vdupq_n_s32(SkFractionalIntToFixed(fx));
145 xbase = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx), xbase, 1);
146 xbase = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx), xbase, 2);
147 xbase = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx+dx), xbase, 3);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000148
149 // same for fy
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000150 ybase = vdupq_n_s32(SkFractionalIntToFixed(fy));
151 ybase = vsetq_lane_s32(SkFractionalIntToFixed(fy+dy), ybase, 1);
152 ybase = vsetq_lane_s32(SkFractionalIntToFixed(fy+dy+dy), ybase, 2);
153 ybase = vsetq_lane_s32(SkFractionalIntToFixed(fy+dy+dy+dy), ybase, 3);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000154
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000155 x2base = vaddq_s32(xbase, vdupq_n_s32(SkFractionalIntToFixed(dx4)));
156 y2base = vaddq_s32(ybase, vdupq_n_s32(SkFractionalIntToFixed(dy4)));
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000157
158 // store & bump
159 do {
160 int16x8x2_t hi16;
161
162 hi16.val[0] = TILEX_PROCF_NEON8(xbase, x2base, maxX);
163 hi16.val[1] = TILEY_PROCF_NEON8(ybase, y2base, maxY);
164
165 vst2q_s16(dst16, hi16);
166
167 // moving base and on to the next
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000168 xbase = vaddq_s32(xbase, vdupq_n_s32(SkFractionalIntToFixed(dx8)));
169 ybase = vaddq_s32(ybase, vdupq_n_s32(SkFractionalIntToFixed(dy8)));
170 x2base = vaddq_s32(x2base, vdupq_n_s32(SkFractionalIntToFixed(dx8)));
171 y2base = vaddq_s32(y2base, vdupq_n_s32(SkFractionalIntToFixed(dy8)));
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000172
173 dst16 += 16; // 8x32 aka 16x16
174 count -= 8;
175 fx += dx8;
176 fy += dy8;
177 } while (count >= 8);
178 xy = (uint32_t *) dst16;
179 }
180
181 for (int i = count; i > 0; --i) {
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000182 *xy++ = (TILEY_PROCF(SkFractionalIntToFixed(fy), maxY) << 16) |
183 TILEX_PROCF(SkFractionalIntToFixed(fx), maxX);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000184 fx += dx; fy += dy;
185 }
186}
187
188static void PERSP_NOFILTER_NAME(const SkBitmapProcState& s,
189 uint32_t* SK_RESTRICT xy,
190 int count, int x, int y) {
191 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
192
193 PREAMBLE(s);
194 // max{X,Y} are int here, but later shown/assumed to fit in 16 bits
reedad7ae6c2015-06-04 14:12:25 -0700195 int maxX = s.fPixmap.width() - 1;
196 int maxY = s.fPixmap.height() - 1;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000197
198 SkPerspIter iter(s.fInvMatrix,
199 SkIntToScalar(x) + SK_ScalarHalf,
200 SkIntToScalar(y) + SK_ScalarHalf, count);
201
202 while ((count = iter.next()) != 0) {
203 const SkFixed* SK_RESTRICT srcXY = iter.getXY();
204
205 if (count >= 8) {
206 int32_t *mysrc = (int32_t *) srcXY;
207 int16_t *mydst = (int16_t *) xy;
208 do {
209 int16x8x2_t hi16;
210 int32x4x2_t xy1, xy2;
211
212 xy1 = vld2q_s32(mysrc);
213 xy2 = vld2q_s32(mysrc+8);
214
215 hi16.val[0] = TILEX_PROCF_NEON8(xy1.val[0], xy2.val[0], maxX);
216 hi16.val[1] = TILEY_PROCF_NEON8(xy1.val[1], xy2.val[1], maxY);
217
218 vst2q_s16(mydst, hi16);
219
220 count -= 8; // 8 iterations
221 mysrc += 16; // 16 longs
222 mydst += 16; // 16 shorts, aka 8 longs
223 } while (count >= 8);
224 // get xy and srcXY fixed up
225 srcXY = (const SkFixed *) mysrc;
226 xy = (uint32_t *) mydst;
227 }
228
229 while (--count >= 0) {
230 *xy++ = (TILEY_PROCF(srcXY[1], maxY) << 16) |
231 TILEX_PROCF(srcXY[0], maxX);
232 srcXY += 2;
233 }
234 }
235}
236
237static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
238 SkFixed one PREAMBLE_PARAM_Y) {
239 unsigned i = TILEY_PROCF(f, max);
240 i = (i << 4) | TILEY_LOW_BITS(f, max);
241 return (i << 14) | (TILEY_PROCF((f + one), max));
242}
243
244static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
245 SkFixed one PREAMBLE_PARAM_X) {
246 unsigned i = TILEX_PROCF(f, max);
247 i = (i << 4) | TILEX_LOW_BITS(f, max);
248 return (i << 14) | (TILEX_PROCF((f + one), max));
249}
250
251static inline int32x4_t PACK_FILTER_X4_NAME(int32x4_t f, unsigned max,
252 SkFixed one PREAMBLE_PARAM_X) {
253 int32x4_t ret, res, wide_one;
254
255 // Prepare constants
256 wide_one = vdupq_n_s32(one);
257
258 // Step 1
259 res = TILEX_PROCF_NEON4(f, max);
260
261 // Step 2
262 ret = TILEX_LOW_BITS_NEON4(f, max);
263 ret = vsliq_n_s32(ret, res, 4);
264
265 // Step 3
266 res = TILEX_PROCF_NEON4(f + wide_one, max);
267 ret = vorrq_s32(vshlq_n_s32(ret, 14), res);
268
269 return ret;
270}
271
272static inline int32x4_t PACK_FILTER_Y4_NAME(int32x4_t f, unsigned max,
273 SkFixed one PREAMBLE_PARAM_X) {
274 int32x4_t ret, res, wide_one;
275
276 // Prepare constants
277 wide_one = vdupq_n_s32(one);
278
279 // Step 1
280 res = TILEY_PROCF_NEON4(f, max);
281
282 // Step 2
283 ret = TILEY_LOW_BITS_NEON4(f, max);
284 ret = vsliq_n_s32(ret, res, 4);
285
286 // Step 3
287 res = TILEY_PROCF_NEON4(f + wide_one, max);
288 ret = vorrq_s32(vshlq_n_s32(ret, 14), res);
289
290 return ret;
291}
292
293static void SCALE_FILTER_NAME(const SkBitmapProcState& s,
294 uint32_t xy[], int count, int x, int y) {
295 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
296 SkMatrix::kScale_Mask)) == 0);
297 SkASSERT(s.fInvKy == 0);
298
299 PREAMBLE(s);
300
reedad7ae6c2015-06-04 14:12:25 -0700301 const unsigned maxX = s.fPixmap.width() - 1;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000302 const SkFixed one = s.fFilterOneX;
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000303 const SkFractionalInt dx = s.fInvSxFractionalInt;
304 SkFractionalInt fx;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000305
306 {
307 SkPoint pt;
308 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
309 SkIntToScalar(y) + SK_ScalarHalf, &pt);
310 const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1);
reedad7ae6c2015-06-04 14:12:25 -0700311 const unsigned maxY = s.fPixmap.height() - 1;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000312 // compute our two Y values up front
313 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
314 // now initialize fx
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000315 fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000316 }
317
318#ifdef CHECK_FOR_DECAL
319 // test if we don't need to apply the tile proc
320 if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000321 decal_filter_scale_neon(xy, SkFractionalIntToFixed(fx),
322 SkFractionalIntToFixed(dx), count);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000323 return;
324 }
325#endif
326 {
327
328 if (count >= 4) {
329 int32x4_t wide_fx;
330
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000331 wide_fx = vdupq_n_s32(SkFractionalIntToFixed(fx));
332 wide_fx = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx), wide_fx, 1);
333 wide_fx = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx), wide_fx, 2);
334 wide_fx = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx+dx), wide_fx, 3);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000335
336 while (count >= 4) {
337 int32x4_t res;
338
339 res = PACK_FILTER_X4_NAME(wide_fx, maxX, one PREAMBLE_ARG_X);
340
341 vst1q_u32(xy, vreinterpretq_u32_s32(res));
342
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000343 wide_fx += vdupq_n_s32(SkFractionalIntToFixed(dx+dx+dx+dx));
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000344 fx += dx+dx+dx+dx;
345 xy += 4;
346 count -= 4;
347 }
348 }
349
350 while (--count >= 0) {
commit-bot@chromium.org4012ba52014-02-20 20:13:54 +0000351 *xy++ = PACK_FILTER_X_NAME(SkFractionalIntToFixed(fx), maxX, one PREAMBLE_ARG_X);
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000352 fx += dx;
353 }
354
355 }
356}
357
358static void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
359 uint32_t xy[], int count, int x, int y) {
360 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
361 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
362 SkMatrix::kScale_Mask |
363 SkMatrix::kAffine_Mask)) == 0);
364
365 PREAMBLE(s);
366 SkPoint srcPt;
367 s.fInvProc(s.fInvMatrix,
368 SkIntToScalar(x) + SK_ScalarHalf,
369 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
370
371 SkFixed oneX = s.fFilterOneX;
372 SkFixed oneY = s.fFilterOneY;
373 SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1);
374 SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1);
375 SkFixed dx = s.fInvSx;
376 SkFixed dy = s.fInvKy;
reedad7ae6c2015-06-04 14:12:25 -0700377 unsigned maxX = s.fPixmap.width() - 1;
378 unsigned maxY = s.fPixmap.height() - 1;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000379
380 if (count >= 4) {
381 int32x4_t wide_fy, wide_fx;
382
383 wide_fx = vdupq_n_s32(fx);
384 wide_fx = vsetq_lane_s32(fx+dx, wide_fx, 1);
385 wide_fx = vsetq_lane_s32(fx+dx+dx, wide_fx, 2);
386 wide_fx = vsetq_lane_s32(fx+dx+dx+dx, wide_fx, 3);
387
388 wide_fy = vdupq_n_s32(fy);
389 wide_fy = vsetq_lane_s32(fy+dy, wide_fy, 1);
390 wide_fy = vsetq_lane_s32(fy+dy+dy, wide_fy, 2);
391 wide_fy = vsetq_lane_s32(fy+dy+dy+dy, wide_fy, 3);
392
393 while (count >= 4) {
394 int32x4x2_t vxy;
395
396 // do the X side, then the Y side, then interleave them
397 vxy.val[0] = PACK_FILTER_Y4_NAME(wide_fy, maxY, oneY PREAMBLE_ARG_Y);
398 vxy.val[1] = PACK_FILTER_X4_NAME(wide_fx, maxX, oneX PREAMBLE_ARG_X);
399
400 // interleave as YXYXYXYX as part of the storing
401 vst2q_s32((int32_t*)xy, vxy);
402
403 // prepare next iteration
404 wide_fx += vdupq_n_s32(dx+dx+dx+dx);
405 fx += dx + dx + dx + dx;
406 wide_fy += vdupq_n_s32(dy+dy+dy+dy);
407 fy += dy+dy+dy+dy;
408 xy += 8; // 4 x's, 4 y's
409 count -= 4;
410 }
411 }
412
413 while (--count >= 0) {
414 // NB: writing Y/X
415 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
416 fy += dy;
417 *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
418 fx += dx;
419 }
420}
421
422static void PERSP_FILTER_NAME(const SkBitmapProcState& s,
423 uint32_t* SK_RESTRICT xy, int count,
424 int x, int y) {
425 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
426
427 PREAMBLE(s);
reedad7ae6c2015-06-04 14:12:25 -0700428 unsigned maxX = s.fPixmap.width() - 1;
429 unsigned maxY = s.fPixmap.height() - 1;
commit-bot@chromium.orga96176d2014-01-28 15:18:54 +0000430 SkFixed oneX = s.fFilterOneX;
431 SkFixed oneY = s.fFilterOneY;
432
433 SkPerspIter iter(s.fInvMatrix,
434 SkIntToScalar(x) + SK_ScalarHalf,
435 SkIntToScalar(y) + SK_ScalarHalf, count);
436
437 while ((count = iter.next()) != 0) {
438 const SkFixed* SK_RESTRICT srcXY = iter.getXY();
439
440 while (count >= 4) {
441 int32x4_t wide_x, wide_y;
442 int32x4x2_t vxy, vresyx;
443
444 // load src: x-y-x-y-x-y-x-y
445 vxy = vld2q_s32(srcXY);
446
447 // do the X side, then the Y side, then interleave them
448 wide_x = vsubq_s32(vxy.val[0], vdupq_n_s32(oneX>>1));
449 wide_y = vsubq_s32(vxy.val[1], vdupq_n_s32(oneY>>1));
450
451 vresyx.val[0] = PACK_FILTER_Y4_NAME(wide_y, maxY, oneY PREAMBLE_ARG_Y);
452 vresyx.val[1] = PACK_FILTER_X4_NAME(wide_x, maxX, oneX PREAMBLE_ARG_X);
453
454 // store interleaved as y-x-y-x-y-x-y-x (NB != read order)
455 vst2q_s32((int32_t*)xy, vresyx);
456
457 // on to the next iteration
458 srcXY += 2*4;
459 count -= 4;
460 xy += 2*4;
461 }
462
463 while (--count >= 0) {
464 // NB: we read x/y, we write y/x
465 *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY,
466 oneY PREAMBLE_ARG_Y);
467 *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX,
468 oneX PREAMBLE_ARG_X);
469 srcXY += 2;
470 }
471 }
472}
473
474const SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = {
475 SCALE_NOFILTER_NAME,
476 SCALE_FILTER_NAME,
477 AFFINE_NOFILTER_NAME,
478 AFFINE_FILTER_NAME,
479 PERSP_NOFILTER_NAME,
480 PERSP_FILTER_NAME
481};
482
483#undef TILEX_PROCF_NEON8
484#undef TILEY_PROCF_NEON8
485#undef TILEX_PROCF_NEON4
486#undef TILEY_PROCF_NEON4
487#undef TILEX_LOW_BITS_NEON4
488#undef TILEY_LOW_BITS_NEON4
489
490#undef MAKENAME
491#undef TILEX_PROCF
492#undef TILEY_PROCF
493#ifdef CHECK_FOR_DECAL
494 #undef CHECK_FOR_DECAL
495#endif
496
497#undef SCALE_NOFILTER_NAME
498#undef SCALE_FILTER_NAME
499#undef AFFINE_NOFILTER_NAME
500#undef AFFINE_FILTER_NAME
501#undef PERSP_NOFILTER_NAME
502#undef PERSP_FILTER_NAME
503
504#undef PREAMBLE
505#undef PREAMBLE_PARAM_X
506#undef PREAMBLE_PARAM_Y
507#undef PREAMBLE_ARG_X
508#undef PREAMBLE_ARG_Y
509
510#undef TILEX_LOW_BITS
511#undef TILEY_LOW_BITS