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