Optimize RGB16 blitH functions with NEON for ARM platform.

Here are some performance resultsi on Nexus 9:
SkRGB16BlitterBlitH_neon:
    +--------+-----------+
    |height  |  C/NEON   |
    +--------+-----------+
    |1       | 0.888531  |
    +--------+-----------+
    |8       | 1.231800  |
    +--------+-----------+
    |18      | 1.073327  |
    +--------+-----------+
    |32      | 1.136991  |
    +--------+-----------+
    |76      | 1.174638  |
    +--------+-----------+
    |85      | 1.188551  |
    +--------+-----------+
    |120     | 1.180261  |
    +--------+-----------+
    |128     | 1.183726  |
    +--------+-----------+
    |512     | 1.220806  |
    +--------+-----------+

BUG=skia:

Review URL: https://codereview.chromium.org/1229673008
diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp
index 8caf908..b481b27 100644
--- a/src/core/SkBlitter_RGB16.cpp
+++ b/src/core/SkBlitter_RGB16.cpp
@@ -27,6 +27,10 @@
                                      size_t deviceRB,
                                      unsigned scale,
                                      uint32_t src32);
+extern void SkRGB16BlitterBlitH_neon(uint16_t* device,
+                                     int width,
+                                     unsigned scale,
+                                     uint32_t src32);
 #else
     // if we don't have neon, then our black blitter is worth the extra code
     #define USE_BLACK_BLITTER
@@ -338,10 +342,14 @@
                 uint32_t src32 = srcExpanded * scale5;
                 scale5 = 32 - scale5; // now we can use it on the device
                 int n = count;
+#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN)
+                SkRGB16BlitterBlitH_neon(device, n, scale5, src32);
+#else
                 do {
                     uint32_t dst32 = SkExpand_rgb_16(*device) * scale5;
                     *device++ = SkCompact_rgb_16((src32 + dst32) >> 5);
                 } while (--n != 0);
+#endif
                 goto DONE;
             }
         }
@@ -601,10 +609,14 @@
             unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3);
             uint32_t src32 =  srcExpanded * scale5;
             scale5 = 32 - scale5;
+#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN)
+            SkRGB16BlitterBlitH_neon(device, count, scale5, src32);
+#else
             do {
                 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5;
                 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5);
             } while (--count != 0);
+#endif
             continue;
         }
         device += count;
diff --git a/src/opts/SkBlitMask_opts_arm_neon.cpp b/src/opts/SkBlitMask_opts_arm_neon.cpp
index 3361a5d..370780c 100644
--- a/src/opts/SkBlitMask_opts_arm_neon.cpp
+++ b/src/opts/SkBlitMask_opts_arm_neon.cpp
@@ -332,3 +332,48 @@
 
 #undef LOAD_LANE_16
 #undef STORE_LANE_16
+
+void SkRGB16BlitterBlitH_neon(uint16_t* device,
+                              int width,
+                              unsigned scale,
+                              uint32_t src32) {
+    if (width >= 8) {
+        // prepare constants
+        uint16x8_t vdev = vdupq_n_u16(0);
+        uint16x8_t vmaskq_g16 = vdupq_n_u16(SK_G16_MASK_IN_PLACE);
+        uint16x8_t vmaskq_ng16 = vdupq_n_u16(~SK_G16_MASK_IN_PLACE);
+        uint32x4_t vsrc32 = vdupq_n_u32(src32);
+        uint32x4_t vscale5 = vdupq_n_u32((uint32_t)scale);
+
+        while (width >= 8) {
+            vdev = vld1q_u16(device);
+
+            // Expand_rgb_16
+            uint16x8x2_t vdst = vzipq_u16((vdev & vmaskq_ng16), (vdev & vmaskq_g16));
+            uint32x4_t vdst32_lo = vmulq_u32(vreinterpretq_u32_u16(vdst.val[0]), vscale5);
+            uint32x4_t vdst32_hi = vmulq_u32(vreinterpretq_u32_u16(vdst.val[1]), vscale5);
+
+            // Compact_rgb_16
+            vdst32_lo = vaddq_u32(vdst32_lo, vsrc32);
+            vdst32_hi = vaddq_u32(vdst32_hi, vsrc32);
+            vdst32_lo = vshrq_n_u32(vdst32_lo, 5);
+            vdst32_hi = vshrq_n_u32(vdst32_hi, 5);
+
+            uint16x4_t vtmp_lo = vmovn_u32(vdst32_lo) & vget_low_u16(vmaskq_ng16);
+            uint16x4_t vtmp_hi = vshrn_n_u32(vdst32_lo, 16) & vget_low_u16(vmaskq_g16);
+            uint16x4_t vdst16_lo = vorr_u16(vtmp_lo, vtmp_hi);
+            vtmp_lo = vmovn_u32(vdst32_hi) & vget_low_u16(vmaskq_ng16);
+            vtmp_hi = vshrn_n_u32(vdst32_hi, 16) & vget_low_u16(vmaskq_g16);
+            uint16x4_t vdst16_hi = vorr_u16(vtmp_lo, vtmp_hi);
+
+            vst1q_u16(device, vcombine_u16(vdst16_lo, vdst16_hi));
+            device += 8;
+            width -= 8;
+        }
+    }
+    while (width != 0) {
+        uint32_t dst32 = SkExpand_rgb_16(*device) * scale;
+        *device++ = SkCompact_rgb_16((src32 + dst32) >> 5);
+        width--;
+    }
+}