1/*
2 * Copyright 2015 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 */
7
8#ifndef SkMatrix_opts_DEFINED
9#define SkMatrix_opts_DEFINED
10
11#include "SkMatrix.h"
12#include "SkNx.h"
13
14namespace SK_OPTS_NS {
15
16static void matrix_translate(const SkMatrix& m, SkPoint* dst, const SkPoint* src, int count) {
17    SkASSERT(m.getType() <= SkMatrix::kTranslate_Mask);
18    if (count > 0) {
19        SkScalar tx = m.getTranslateX();
20        SkScalar ty = m.getTranslateY();
21        if (count & 1) {
22            dst->fX = src->fX + tx;
23            dst->fY = src->fY + ty;
24            src += 1;
25            dst += 1;
26        }
27        Sk4s trans4(tx, ty, tx, ty);
28        count >>= 1;
29        if (count & 1) {
30            (Sk4s::Load(src) + trans4).store(dst);
31            src += 2;
32            dst += 2;
33        }
34        count >>= 1;
35        for (int i = 0; i < count; ++i) {
36            (Sk4s::Load(src+0) + trans4).store(dst+0);
37            (Sk4s::Load(src+2) + trans4).store(dst+2);
38            src += 4;
39            dst += 4;
40        }
41    }
42}
43
44static void matrix_scale_translate(const SkMatrix& m, SkPoint* dst, const SkPoint* src, int count) {
45    SkASSERT(m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask));
46    if (count > 0) {
47        SkScalar tx = m.getTranslateX();
48        SkScalar ty = m.getTranslateY();
49        SkScalar sx = m.getScaleX();
50        SkScalar sy = m.getScaleY();
51        if (count & 1) {
52            dst->fX = src->fX * sx + tx;
53            dst->fY = src->fY * sy + ty;
54            src += 1;
55            dst += 1;
56        }
57        Sk4s trans4(tx, ty, tx, ty);
58        Sk4s scale4(sx, sy, sx, sy);
59        count >>= 1;
60        if (count & 1) {
61            (Sk4s::Load(src) * scale4 + trans4).store(dst);
62            src += 2;
63            dst += 2;
64        }
65        count >>= 1;
66        for (int i = 0; i < count; ++i) {
67            (Sk4s::Load(src+0) * scale4 + trans4).store(dst+0);
68            (Sk4s::Load(src+2) * scale4 + trans4).store(dst+2);
69            src += 4;
70            dst += 4;
71        }
72    }
73}
74
75static void matrix_affine(const SkMatrix& m, SkPoint* dst, const SkPoint* src, int count) {
76    SkASSERT(m.getType() != SkMatrix::kPerspective_Mask);
77    if (count > 0) {
78        SkScalar tx = m.getTranslateX();
79        SkScalar ty = m.getTranslateY();
80        SkScalar sx = m.getScaleX();
81        SkScalar sy = m.getScaleY();
82        SkScalar kx = m.getSkewX();
83        SkScalar ky = m.getSkewY();
84        if (count & 1) {
85            dst->set(src->fX * sx + src->fY * kx + tx,
86                     src->fX * ky + src->fY * sy + ty);
87            src += 1;
88            dst += 1;
89        }
90        Sk4s trans4(tx, ty, tx, ty);
91        Sk4s scale4(sx, sy, sx, sy);
92        Sk4s  skew4(kx, ky, kx, ky);    // applied to swizzle of src4
93        count >>= 1;
94        for (int i = 0; i < count; ++i) {
95            Sk4s src4 = Sk4s::Load(src);
96            Sk4s swz4 = SkNx_shuffle<1,0,3,2>(src4);  // y0 x0, y1 x1
97            (src4 * scale4 + swz4 * skew4 + trans4).store(dst);
98            src += 2;
99            dst += 2;
100        }
101    }
102}
103
104} // namespace SK_OPTS_NS
105
106#endif//SkMatrix_opts_DEFINED
107