Chromium Code Reviews

Unified Diff: src/opts/SkSwizzler_opts.h

Issue 1618603003: SSSE3 opts for RGB -> RGB(FF) or BGR(FF) (Closed) Base URL: https://skia.googlesource.com/skia.git@rgb
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/opts/SkSwizzler_opts.h
diff --git a/src/opts/SkSwizzler_opts.h b/src/opts/SkSwizzler_opts.h
index ad121cfafecc42d33fddaa2227ed9fd0693e659b..1d1328d05e836746a292b43d5d70cb7319187be1 100644
--- a/src/opts/SkSwizzler_opts.h
+++ b/src/opts/SkSwizzler_opts.h
@@ -358,12 +358,47 @@ static void RGBA_to_BGRA(uint32_t* dst, const void* vsrc, int count) {
RGBA_to_BGRA_portable(dst, src, count);
}
+template <bool kSwapRB>
+static void insert_alpha_should_swaprb(uint32_t dst[], const void* vsrc, int count) {
+ const uint8_t* src = (const uint8_t*) vsrc;
+
+ const __m128i alphaMask = _mm_set1_epi32(0xFF000000);
+ __m128i expand;
+ const uint8_t X = 0xFF; // Used a placeholder. The value of X is irrelevant.
mtklein 2016/01/22 17:51:50 Because X > 127, this actually sets those lanes to
msarett 2016/01/22 18:20:08 Agreed. I was hoping there was something that wou
+ if (kSwapRB) {
+ expand = _mm_setr_epi8(2,1,0,X, 5,4,3,X, 8,7,6,X, 11,10,9,X);
+ } else {
+ expand = _mm_setr_epi8(0,1,2,X, 3,4,5,X, 6,7,8,X, 9,10,11,X);
+ }
+
+ while (count >= 4) {
+ // Load a vector. While this actually contains 5 pixels plus an
mtklein 2016/01/22 17:51:50 So isn't this only safe while (count >= 6) ?
mtklein 2016/01/22 18:00:30 Alternatively, since only the load is weird and th
msarett 2016/01/22 18:20:08 I don't understand why it's not always safe? At t
+ // extra component, we will discard all but the first four pixels on
+ // this iteration.
+ __m128i rgb = _mm_loadu_si128((const __m128i*) src);
+
+ // Expand the first four pixels to RGBX and then mask to RGB(FF).
+ __m128i rgba = _mm_or_si128(_mm_shuffle_epi8(rgb, expand), alphaMask);
+
+ // Store 4 pixels.
+ _mm_storeu_si128((__m128i*) dst, rgba);
+
+ src += 4*3;
+ dst += 4;
+ count -= 4;
+ }
+
+ // Call portable code to finish up the tail of [0,4) pixels.
+ auto proc = kSwapRB ? RGB_to_BGR1_portable : RGB_to_RGB1_portable;
+ proc(dst, src, count);
+}
+
static void RGB_to_RGB1(uint32_t dst[], const void* src, int count) {
- RGB_to_RGB1_portable(dst, src, count);
+ insert_alpha_should_swaprb<false>(dst, src, count);
}
static void RGB_to_BGR1(uint32_t dst[], const void* src, int count) {
- RGB_to_BGR1_portable(dst, src, count);
+ insert_alpha_should_swaprb<true>(dst, src, count);
}
#else
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine