From 594b5d00cb4924c2d4d8d0d810f8863d96f27cbc Mon Sep 17 00:00:00 2001 From: homm Date: Sun, 19 Jun 2016 15:55:58 +0300 Subject: [PATCH] SIMD AlphaComposite. speedup sse4 by using _mm_mullo_epi16 instead of _mm_mullo_epi32 --- src/libImaging/AlphaComposite.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/libImaging/AlphaComposite.c b/src/libImaging/AlphaComposite.c index 5a78cdf49..716520d4c 100644 --- a/src/libImaging/AlphaComposite.c +++ b/src/libImaging/AlphaComposite.c @@ -34,7 +34,7 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) { int xsize = imDst->xsize; __m128i mm_max_alpha = _mm_set1_epi32(255); __m128i mm_max_alpha2 = _mm_set1_epi32(255 * 255); - __m256i mm_half = _mm_set1_epi32(128); + __m128i mm_half = _mm_set1_epi32(128); __m128i mm_get_lo = _mm_set_epi8( -1,-1, 5,4, 5,4, 5,4, -1,-1, 1,0, 1,0, 1,0); __m128i mm_get_hi = _mm_set_epi8( @@ -131,22 +131,29 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) { _mm_srli_epi16(_mm_add_epi16(src, _mm_srli_epi16(src, 8)), 8) for (; x < xsize - 3; x += 4) { + // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 __m128i mm_dst = _mm_loadu_si128((__m128i *) &dst[x]); + // [16] a1 b1 g1 r1 a0 b0 g0 r0 __m128i mm_dst_lo = _mm_unpacklo_epi8(mm_dst, _mm_setzero_si128()); + // [16] a3 b3 g3 r3 a2 b2 g2 r2 __m128i mm_dst_hi = _mm_unpackhi_epi8(mm_dst, _mm_setzero_si128()); + // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 __m128i mm_src = _mm_loadu_si128((__m128i *) &src[x]); __m128i mm_src_lo = _mm_unpacklo_epi8(mm_src, _mm_setzero_si128()); __m128i mm_src_hi = _mm_unpackhi_epi8(mm_src, _mm_setzero_si128()); + // [32] a3 a2 a1 a0 __m128i mm_dst_a = _mm_srli_epi32(mm_dst, 24); __m128i mm_src_a = _mm_srli_epi32(mm_src, 24); // Compute coefficients - // blend = dst->a * (255 - src->a); 16 bits - __m128i mm_blend = _mm_mullo_epi32(mm_dst_a, _mm_sub_epi32(mm_max_alpha, mm_src_a)); - // outa = src->a * 255 + dst->a * (255 - src->a); 16 bits - __m128i mm_outa = _mm_add_epi32(_mm_mullo_epi32(mm_src_a, mm_max_alpha), mm_blend); - __m128i mm_coef1 = _mm_mullo_epi32(mm_src_a, mm_max_alpha2); + // blend = dst->a * (255 - src->a) + // [16] xx b3 xx b2 xx b1 xx b0 + __m128i mm_blend = _mm_mullo_epi16(mm_dst_a, _mm_sub_epi32(mm_max_alpha, mm_src_a)); + // outa = src->a * 255 + dst->a * 255 - src->a * dst->a + // [16] xx a3 xx a2 xx a1 xx a0 + __m128i mm_outa = _mm_add_epi32(_mm_mullo_epi16(mm_src_a, mm_max_alpha), mm_blend); + __m128i mm_coef1 = _mm_mullo_epi16(mm_src_a, mm_max_alpha2); // 8 bits mm_coef1 = _mm_cvtps_epi32(_mm_div_ps(_mm_cvtepi32_ps(mm_coef1), _mm_cvtepi32_ps(mm_outa))); // 8 bits