diff options
author | Mike Klein <mtklein@chromium.org> | 2016-11-28 09:33:02 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-28 15:10:32 +0000 |
commit | d5de013643789950aef09a9f081ac65c4c965900 (patch) | |
tree | 32ad5a5264dffa8e7e36f9c31dfb40101e3642dc /src/opts | |
parent | 3b66ab6f9fdc6eacdf0ee1921da28751de30c018 (diff) |
Some simple pipeline refactoring.
This is a batch of little tweaks that all preserve the existing logical behavior:
- rename dst to move_dst_src to parallel move_src_dst
- remove unused swap_src_dst
- move swap_rb up with the other utility stages
- factor out from_8888() to parallel from_565() and from_4444()
- factor out gather() from the accum_* stages
This changes the order of the math in accum_8888[_srgb] ever so slightly, from (scale * C) * (1/255.0f) to scale * (1/255.0f * C). It causes a few pixel diffs, but nothing noticeable. This makes the 8888 bilerp logic consistent with the other formats, which all convert to [0,1] float first before being scaled.
CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD
Change-Id: Id37857b91be3086565169dcc9b1a537574e532aa
Reviewed-on: https://skia-review.googlesource.com/5226
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/opts')
-rw-r--r-- | src/opts/SkRasterPipeline_opts.h | 157 |
1 files changed, 61 insertions, 96 deletions
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h index c6fbe6938a..6033952ea8 100644 --- a/src/opts/SkRasterPipeline_opts.h +++ b/src/opts/SkRasterPipeline_opts.h @@ -30,7 +30,8 @@ namespace { #endif using SkNf = SkNx<N, float>; - using SkNi = SkNx<N, int>; + using SkNi = SkNx<N, int32_t>; + using SkNu = SkNx<N, uint32_t>; using SkNh = SkNx<N, uint16_t>; using SkNb = SkNx<N, uint8_t>; @@ -184,6 +185,14 @@ SI void store(size_t tail, const SkNx<N,T>& v, T* dst) { v.store(dst); } +SI void from_8888(const SkNu& _8888, SkNf* r, SkNf* g, SkNf* b, SkNf* a) { + auto to_float = [](const SkNu& v) { return SkNx_cast<float>(SkNi::Load(&v)); }; + *r = (1/255.0f)*to_float((_8888 >> 0) & 0xff); + *g = (1/255.0f)*to_float((_8888 >> 8) & 0xff); + *b = (1/255.0f)*to_float((_8888 >> 16) & 0xff); + *a = (1/255.0f)*to_float( _8888 >> 24 ); +} + SI void from_4444(const SkNh& _4444, SkNf* r, SkNf* g, SkNf* b, SkNf* a) { auto _32_bit = SkNx_cast<int>(_4444); @@ -271,13 +280,18 @@ STAGE(move_src_dst, true) { da = a; } -STAGE(swap_src_dst, true) { - SkTSwap(r, dr); - SkTSwap(g, dg); - SkTSwap(b, db); - SkTSwap(a, da); +STAGE(move_dst_src, true) { + r = dr; + g = dg; + b = db; + a = da; } +STAGE(swap_rb, true) { + SkTSwap(r, b); +} + + // The default shader produces a constant color (from the SkPaint). STAGE(constant_color, true) { auto color = (const SkPM4f*)ctx; @@ -483,13 +497,7 @@ STAGE(store_srgb, false) { STAGE(load_s_8888, true) { auto ptr = *(const uint32_t**)ctx + x; - - auto px = load<kIsTail>(tail, ptr); - auto to_int = [](const SkNx<N, uint32_t>& v) { return SkNi::Load(&v); }; - r = (1/255.0f)*SkNx_cast<float>(to_int((px >> 0) & 0xff)); - g = (1/255.0f)*SkNx_cast<float>(to_int((px >> 8) & 0xff)); - b = (1/255.0f)*SkNx_cast<float>(to_int((px >> 16) & 0xff)); - a = (1/255.0f)*SkNx_cast<float>(to_int(px >> 24)); + from_8888(load<kIsTail>(tail, ptr), &r, &g, &b, &a); } STAGE(store_8888, false) { @@ -689,10 +697,6 @@ STAGE(lab_to_xyz, true) { b = Z; } -STAGE(swap_rb, true) { - SkTSwap(r, b); -} - SI SkNf assert_in_tile(const SkNf& v, float limit) { for (int i = 0; i < N; i++) { SkASSERT(0 <= v[i] && v[i] < limit); @@ -786,6 +790,13 @@ SI SkNi offset_and_ptr(T** ptr, const void* ctx, const SkNf& x, const SkNf& y) { return offset; } +template <typename T> +SI void gather(T (&dst)[N], const T* src, const SkNi& offset, size_t tail) { + size_t n = tail ? tail : N; + for (size_t i = 0; i < n; i++) { dst[i] = src[offset[i]]; } + for (size_t i = n; i < N; i++) { dst[i] = 0; } +} + STAGE(accum_a8, true) {} // TODO STAGE(accum_i8, true) {} // TODO @@ -796,13 +807,7 @@ STAGE(accum_g8, true) { SkNi offset = offset_and_ptr(&p, ctx, r, g); uint8_t px[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - px[i] = 0; - continue; - } - px[i] = p[offset[i]]; - } + gather(px, p, offset, tail); SkNf gray = SkNx_cast<float>(SkNb::Load(px)) * (1/255.0f); @@ -817,13 +822,7 @@ STAGE(accum_g8_srgb, true) { SkNi offset = offset_and_ptr(&p, ctx, r, g); uint8_t px[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - px[i] = 0; - continue; - } - px[i] = p[offset[i]]; - } + gather(px, p, offset, tail); SkNf gray = sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(px))); @@ -839,13 +838,8 @@ STAGE(accum_565, true) { SkNi offset = offset_and_ptr(&p, ctx, r, g); uint16_t px[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - px[i] = 0; - continue; - } - px[i] = p[offset[i]]; - } + gather(px, p, offset, tail); + SkNf R,G,B; from_565(SkNh::Load(px), &R, &G, &B); @@ -860,13 +854,8 @@ STAGE(accum_565_srgb, true) { SkNi offset = offset_and_ptr(&p, ctx, r, g); uint16_t px[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - px[i] = 0; - continue; - } - px[i] = p[offset[i]]; - } + gather(px, p, offset, tail); + SkNf R,G,B; from_565(SkNh::Load(px), &R, &G, &B); @@ -882,13 +871,7 @@ STAGE(accum_4444, true) { SkNi offset = offset_and_ptr(&p, ctx, r, g); uint16_t px[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - px[i] = 0; - continue; - } - px[i] = p[offset[i]]; - } + gather(px, p, offset, tail); SkNf R,G,B,A; from_4444(SkNh::Load(px), &R, &G, &B, &A); @@ -904,13 +887,7 @@ STAGE(accum_4444_srgb, true) { SkNi offset = offset_and_ptr(&p, ctx, r, g); uint16_t px[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - px[i] = 0; - continue; - } - px[i] = p[offset[i]]; - } + gather(px, p, offset, tail); SkNf R,G,B,A; from_4444(SkNh::Load(px), &R, &G, &B, &A); @@ -926,65 +903,53 @@ STAGE(accum_8888, true) { const uint32_t* p; SkNi offset = offset_and_ptr(&p, ctx, r, g); - uint8_t R[N], G[N], B[N], A[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - R[i] = G[i] = B[i] = A[i] = 0; - continue; - } - uint32_t rgba = p[offset[i]]; - R[i] = rgba >> 0; - G[i] = rgba >> 8; - B[i] = rgba >> 16; - A[i] = rgba >> 24; - } + uint32_t px[N]; + gather(px, p, offset, tail); + + SkNf R,G,B,A; + from_8888(SkNu::Load(px), &R, &G, &B, &A); SkNf scale = b; - dr += scale * SkNx_cast<float>(SkNb::Load(R)) * (1/255.0f); - dg += scale * SkNx_cast<float>(SkNb::Load(G)) * (1/255.0f); - db += scale * SkNx_cast<float>(SkNb::Load(B)) * (1/255.0f); - da += scale * SkNx_cast<float>(SkNb::Load(A)) * (1/255.0f); + dr += scale * R; + dg += scale * G; + db += scale * B; + da += scale * A; } STAGE(accum_8888_srgb, true) { const uint32_t* p; SkNi offset = offset_and_ptr(&p, ctx, r, g); - uint8_t R[N], G[N], B[N], A[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - R[i] = G[i] = B[i] = A[i] = 0; - continue; - } - uint32_t rgba = p[offset[i]]; - R[i] = rgba >> 0; - G[i] = rgba >> 8; - B[i] = rgba >> 16; - A[i] = rgba >> 24; - } + uint32_t px[N]; + gather(px, p, offset, tail); + + SkNf R,G,B,A; + from_8888(SkNu::Load(px), &R, &G, &B, &A); SkNf scale = b; - dr += scale * sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(R))); - dg += scale * sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(G))); - db += scale * sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(B))); - da += scale * SkNx_cast<float>(SkNb::Load(A)) * (1/255.0f); + dr += scale * sk_linear_from_srgb_math(R); + dg += scale * sk_linear_from_srgb_math(G); + db += scale * sk_linear_from_srgb_math(B); + da += scale * A; } STAGE(accum_f16, true) { const uint64_t* p; SkNi offset = offset_and_ptr(&p, ctx, r, g); + // f16 -> f32 conversion works best with tightly packed f16s, + // so we gather each component rather than using gather(). uint16_t R[N], G[N], B[N], A[N]; - for (size_t i = 0; i < N; i++) { - if (kIsTail && i >= tail) { - R[i] = G[i] = B[i] = A[i] = 0; - continue; - } + size_t n = tail ? tail : N; + for (size_t i = 0; i < n; i++) { uint64_t rgba = p[offset[i]]; R[i] = rgba >> 0; G[i] = rgba >> 16; B[i] = rgba >> 32; A[i] = rgba >> 48; } + for (size_t i = n; i < N; i++) { + R[i] = G[i] = B[i] = A[i] = 0; + } SkNf scale = b; dr += scale * SkHalfToFloat_finite_ftz(SkNh::Load(R)); dg += scale * SkHalfToFloat_finite_ftz(SkNh::Load(G)); |