Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(738)

Unified Diff: src/opts/SkBlitRow_opts_arm_neon.cpp

Issue 2097883002: revise row blits to keep intermediate precision so that color is preserved when blended against its… (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Fix overflow in destination scale calculation Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/opts/SkBlitRow_opts_arm_neon.cpp
diff --git a/src/opts/SkBlitRow_opts_arm_neon.cpp b/src/opts/SkBlitRow_opts_arm_neon.cpp
index 3cb5a92f86b1d9310a47a62af9582099c6bc770b..3ab00e3fc95ddcca091acff7dc7435466977c8f6 100644
--- a/src/opts/SkBlitRow_opts_arm_neon.cpp
+++ b/src/opts/SkBlitRow_opts_arm_neon.cpp
@@ -909,7 +909,8 @@ void S32_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst,
vdst_wide = vmull_u8(vdst, vdup_n_u8(dst_scale));
// Combine
- vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8);
+ vdst_wide += vsrc_wide;
+ vres = vshrn_n_u16(vdst_wide, 8);
// Store
vst1_u32(dst, vreinterpret_u32_u8(vres));
@@ -931,7 +932,8 @@ void S32_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst,
vsrc_wide = vmovl_u8(vsrc);
vsrc_wide = vmulq_u16(vsrc_wide, vdupq_n_u16(src_scale));
vdst_wide = vmull_u8(vdst, vdup_n_u8(dst_scale));
- vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8);
+ vdst_wide += vsrc_wide;
+ vres = vshrn_n_u16(vdst_wide, 8);
// Store
vst1_lane_u32(dst, vreinterpret_u32_u8(vres), 0);
@@ -964,8 +966,8 @@ void S32A_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst,
// Calc dst_scale
dst_scale = vget_lane_u8(vsrc, 3);
dst_scale *= alpha256;
+ dst_scale = (256<<8) - dst_scale;
dst_scale >>= 8;
- dst_scale = 256 - dst_scale;
// Process src
vsrc_wide = vmovl_u8(vsrc);
@@ -976,7 +978,8 @@ void S32A_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst,
vdst_wide = vmulq_n_u16(vdst_wide, dst_scale);
// Combine
- vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8);
+ vdst_wide += vsrc_wide;
+ vres = vshrn_n_u16(vdst_wide, 8);
vst1_lane_u32(dst, vreinterpret_u32_u8(vres), 0);
dst++;
@@ -1007,9 +1010,8 @@ void S32A_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst,
// Calc dst_scale
vsrc_alphas = vtbl1_u8(vsrc, alpha_mask);
vdst_scale = vmovl_u8(vsrc_alphas);
- vdst_scale *= vsrc_scale;
- vdst_scale = vshrq_n_u16(vdst_scale, 8);
- vdst_scale = vsubq_u16(vdupq_n_u16(256), vdst_scale);
+ vdst_scale = vmlsq_u16(vdupq_n_u16(255<<8), vdst_scale, vsrc_scale);
+ vdst_scale = vsraq_n_u16(vdupq_n_u16(1), vdst_scale, 8);
// Process src
vsrc_wide = vmovl_u8(vsrc);
@@ -1020,7 +1022,8 @@ void S32A_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst,
vdst_wide *= vdst_scale;
// Combine
- vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8);
+ vdst_wide += vsrc_wide;
+ vres = vshrn_n_u16(vdst_wide, 8);
vst1_u32(dst, vreinterpret_u32_u8(vres));

Powered by Google App Engine
This is Rietveld 408576698