From 83aa9208dab96f1b6affa8167522e9a94afd70a5 Mon Sep 17 00:00:00 2001 From: fmalita Date: Wed, 23 Mar 2016 12:28:14 -0700 Subject: [PATCH] Planar ramp() for S32 linear gradients R=mtklein@google.com,reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1825333003 Review URL: https://codereview.chromium.org/1825333003 --- src/effects/gradients/Sk4fGradientPriv.h | 10 ++++---- src/effects/gradients/Sk4fLinearGradient.cpp | 36 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/effects/gradients/Sk4fGradientPriv.h b/src/effects/gradients/Sk4fGradientPriv.h index 4f71d3f..ae6fe7c 100644 --- a/src/effects/gradients/Sk4fGradientPriv.h +++ b/src/effects/gradients/Sk4fGradientPriv.h @@ -108,19 +108,19 @@ struct DstTraits { using PM = PremulTraits; using Type = SkPMColor; - // TODO: prescale by something like (255^2, 255^2, 255^2, 255) and use - // linear_to_srgb to save a mult in store? static Sk4f load(const SkPM4f& c) { - return c.to4f_pmorder(); + // Prescaling by (255^2, 255^2, 255^2, 255) on load, to avoid a 255 multiply on + // each store (S32 conversion yields a uniform 255 factor). + return c.to4f_pmorder() * Sk4f(255 * 255, 255 * 255, 255 * 255, 255); } static void store(const Sk4f& c, Type* dst) { // FIXME: this assumes opaque colors. Handle unpremultiplication. - *dst = Sk4f_toS32(PM::apply(c)); + *dst = to_4b(linear_to_srgb(PM::apply(c))); } static void store(const Sk4f& c, Type* dst, int n) { - sk_memset32(dst, Sk4f_toS32(PM::apply(c)), n); + sk_memset32(dst, to_4b(linear_to_srgb(PM::apply(c))), n); } static void store4x(const Sk4f& c0, const Sk4f& c1, diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp index f4bb4a7..4ea025d 100644 --- a/src/effects/gradients/Sk4fLinearGradient.cpp +++ b/src/effects/gradients/Sk4fLinearGradient.cpp @@ -6,6 +6,7 @@ */ #include "Sk4fLinearGradient.h" +#include "Sk4x4f.h" #include "SkXfermode.h" namespace { @@ -42,6 +43,41 @@ void ramp(const Sk4f& c, const Sk4f& dc, typename DstTraits::Ty } } +// Planar version of ramp (S32 no-premul only). +template<> +void ramp(const Sk4f& c, const Sk4f& dc, SkPMColor dst[], int n) { + SkASSERT(n > 0); + + const Sk4f dc4 = dc * 4; + const Sk4x4f dc4x = { Sk4f(dc4[0]), Sk4f(dc4[1]), Sk4f(dc4[2]), Sk4f(dc4[3]) }; + Sk4x4f c4x = Sk4x4f::Transpose(c, c + dc, c + dc * 2, c + dc * 3); + + while (n >= 4) { + const Sk4x4f cx4s32 = { c4x.r.sqrt(), c4x.g.sqrt(), c4x.b.sqrt(), c4x.a }; + cx4s32.transpose((uint8_t*)dst); + + c4x.r += dc4x.r; + c4x.g += dc4x.g; + c4x.b += dc4x.b; + c4x.a += dc4x.a; + + dst += 4; + n -= 4; + } + + if (n & 2) { + DstTraits + ::store(Sk4f(c4x.r[0], c4x.g[0], c4x.b[0], c4x.a[0]), dst++); + DstTraits + ::store(Sk4f(c4x.r[1], c4x.g[1], c4x.b[1], c4x.a[1]), dst++); + } + + if (n & 1) { + DstTraits + ::store(Sk4f(c4x.r[n & 2], c4x.g[n & 2], c4x.b[n & 2], c4x.a[n & 2]), dst); + } +} + template SkScalar pinFx(SkScalar); -- 2.7.4