1727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*
2727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * Copyright 2013 The Android Open Source Project
3727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *
4727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * Use of this source code is governed by a BSD-style license that can be
5727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * found in the LICENSE file.
6727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
8727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
9727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "SkColorPriv.h"
10727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "SkMorphology_opts.h"
11727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "SkMorphology_opts_neon.h"
12727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
13727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include <arm_neon.h>
14727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
15727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* neon version of dilateX, dilateY, erodeX, erodeY.
16727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * portable versions are in src/effects/SkMorphologyImageFilter.cpp.
17727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease */
18727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
19727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leaseenum MorphType {
20727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    kDilate, kErode
21727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease};
22727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
23727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leaseenum MorphDirection {
24727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    kX, kY
25727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease};
26727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
27727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leasetemplate<MorphType type, MorphDirection direction>
28727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leasestatic void SkMorph_neon(const SkPMColor* src, SkPMColor* dst, int radius,
29727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                         int width, int height, int srcStride, int dstStride)
30727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease{
31727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const int srcStrideX = direction == kX ? 1 : srcStride;
32727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const int dstStrideX = direction == kX ? 1 : dstStride;
33727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const int srcStrideY = direction == kX ? srcStride : 1;
34727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const int dstStrideY = direction == kX ? dstStride : 1;
35727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    radius = SkMin32(radius, width - 1);
36727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const SkPMColor* upperSrc = src + radius * srcStrideX;
37727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for (int x = 0; x < width; ++x) {
38727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        const SkPMColor* lp = src;
39727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        const SkPMColor* up = upperSrc;
40727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        SkPMColor* dptr = dst;
41727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        for (int y = 0; y < height; ++y) {
42727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            uint8x8_t max = vdup_n_u8(type == kDilate ? 0 : 255);
43727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
44727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                uint8x8_t src_pixel = vreinterpret_u8_u32(vdup_n_u32(*p));
45727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                max = type == kDilate ? vmax_u8(src_pixel, max) : vmin_u8(src_pixel, max);
46727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
47727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            *dptr = vget_lane_u32(vreinterpret_u32_u8(max), 0);
48727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            dptr += dstStrideY;
49727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            lp += srcStrideY;
50727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            up += srcStrideY;
51727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
52727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if (x >= radius) src += srcStrideX;
53727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if (x + radius < width - 1) upperSrc += srcStrideX;
54727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        dst += dstStrideX;
55727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
56727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease}
57727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
58727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leasevoid SkDilateX_neon(const SkPMColor* src, SkPMColor* dst, int radius,
59727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    int width, int height, int srcStride, int dstStride)
60727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease{
61727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    SkMorph_neon<kDilate, kX>(src, dst, radius, width, height, srcStride, dstStride);
62727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease}
63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
64727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leasevoid SkErodeX_neon(const SkPMColor* src, SkPMColor* dst, int radius,
65727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   int width, int height, int srcStride, int dstStride)
66727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease{
67727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    SkMorph_neon<kErode, kX>(src, dst, radius, width, height, srcStride, dstStride);
68727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease}
69727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
70727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leasevoid SkDilateY_neon(const SkPMColor* src, SkPMColor* dst, int radius,
71727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    int width, int height, int srcStride, int dstStride)
72727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease{
73727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    SkMorph_neon<kDilate, kY>(src, dst, radius, width, height, srcStride, dstStride);
74727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease}
75727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
76727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Leasevoid SkErodeY_neon(const SkPMColor* src, SkPMColor* dst, int radius,
77727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   int width, int height, int srcStride, int dstStride)
78727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease{
79727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    SkMorph_neon<kErode, kY>(src, dst, radius, width, height, srcStride, dstStride);
80727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease}
81727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease