diff options
author | 2016-03-21 13:16:51 -0700 | |
---|---|---|
committer | 2016-03-21 13:16:52 -0700 | |
commit | dc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6 (patch) | |
tree | b072c263452bed811ce7643fa53fb584c997359d /src | |
parent | 66be626f7f3ddda243e51aa8f36398b26769a9b4 (diff) |
Refactor 4f gradients using trait templates
Some 4f gradient housekeeping.
1) replace <DstPtrType, ColorProfile> specialization tuples with an enum covering all dest types
(L32, S32, F16, F32)
2) group various template helpers into dest trait classes, specialized for each dest type
(2a - conflate current dst_swizzle and scale_for_dest ops into one load op)
R=reed@google.com,mtklein@google.com,herb@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1816883002
Review URL: https://codereview.chromium.org/1816883002
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/gradients/Sk4fGradientBase.cpp | 32 | ||||
-rw-r--r-- | src/effects/gradients/Sk4fGradientBase.h | 12 | ||||
-rw-r--r-- | src/effects/gradients/Sk4fGradientPriv.h | 230 | ||||
-rw-r--r-- | src/effects/gradients/Sk4fLinearGradient.cpp | 146 | ||||
-rw-r--r-- | src/effects/gradients/Sk4fLinearGradient.h | 12 |
5 files changed, 211 insertions, 221 deletions
diff --git a/src/effects/gradients/Sk4fGradientBase.cpp b/src/effects/gradients/Sk4fGradientBase.cpp index 43910108ff..e09ba77a04 100644 --- a/src/effects/gradients/Sk4fGradientBase.cpp +++ b/src/effects/gradients/Sk4fGradientBase.cpp @@ -276,56 +276,56 @@ GradientShaderBase4fContext::addMirrorIntervals(const SkGradientShaderBase& shad void SkGradientShaderBase:: GradientShaderBase4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) { if (fColorsArePremul) { - this->shadePremulSpan<SkPMColor, ApplyPremul::False>(x, y, dst, count); + this->shadePremulSpan<DstType::L32, ApplyPremul::False>(x, y, dst, count); } else { - this->shadePremulSpan<SkPMColor, ApplyPremul::True>(x, y, dst, count); + this->shadePremulSpan<DstType::L32, ApplyPremul::True>(x, y, dst, count); } } void SkGradientShaderBase:: GradientShaderBase4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { if (fColorsArePremul) { - this->shadePremulSpan<SkPM4f, ApplyPremul::False>(x, y, dst, count); + this->shadePremulSpan<DstType::F32, ApplyPremul::False>(x, y, dst, count); } else { - this->shadePremulSpan<SkPM4f, ApplyPremul::True>(x, y, dst, count); + this->shadePremulSpan<DstType::F32, ApplyPremul::True>(x, y, dst, count); } } -template<typename DstType, ApplyPremul premul> +template<DstType dstType, ApplyPremul premul> void SkGradientShaderBase:: GradientShaderBase4fContext::shadePremulSpan(int x, int y, - DstType dst[], + typename DstTraits<dstType, premul>::Type dst[], int count) const { const SkGradientShaderBase& shader = static_cast<const SkGradientShaderBase&>(fShader); switch (shader.fTileMode) { case kClamp_TileMode: - this->shadeSpanInternal<DstType, + this->shadeSpanInternal<dstType, premul, kClamp_TileMode>(x, y, dst, count); break; case kRepeat_TileMode: - this->shadeSpanInternal<DstType, + this->shadeSpanInternal<dstType, premul, kRepeat_TileMode>(x, y, dst, count); break; case kMirror_TileMode: - this->shadeSpanInternal<DstType, + this->shadeSpanInternal<dstType, premul, kMirror_TileMode>(x, y, dst, count); break; } } -template<typename DstType, ApplyPremul premul, SkShader::TileMode tileMode> +template<DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode> void SkGradientShaderBase:: GradientShaderBase4fContext::shadeSpanInternal(int x, int y, - DstType dst[], + typename DstTraits<dstType, premul>::Type dst[], int count) const { static const int kBufSize = 128; SkScalar ts[kBufSize]; - TSampler<DstType, tileMode> sampler(*this); + TSampler<dstType, tileMode> sampler(*this); SkASSERT(count > 0); do { @@ -333,14 +333,14 @@ GradientShaderBase4fContext::shadeSpanInternal(int x, int y, this->mapTs(x, y, ts, n); for (int i = 0; i < n; ++i) { const Sk4f c = sampler.sample(ts[i]); - store<DstType, kLinear_SkColorProfileType, premul>(c, dst++); + DstTraits<dstType, premul>::store(c, dst++); } x += n; count -= n; } while (count > 0); } -template<typename DstType, SkShader::TileMode tileMode> +template<DstType dstType, SkShader::TileMode tileMode> class SkGradientShaderBase::GradientShaderBase4fContext::TSampler { public: TSampler(const GradientShaderBase4fContext& ctx) @@ -423,8 +423,8 @@ private: } void loadIntervalData(const Interval* i) { - fCc = scale_for_dest<DstType, kLinear_SkColorProfileType>(dst_swizzle<DstType>(i->fC0)); - fDc = scale_for_dest<DstType, kLinear_SkColorProfileType>(dst_swizzle<DstType>(i->fDc)); + fCc = DstTraits<dstType>::load(i->fC0); + fDc = DstTraits<dstType>::load(i->fDc); } const Interval* fFirstInterval; diff --git a/src/effects/gradients/Sk4fGradientBase.h b/src/effects/gradients/Sk4fGradientBase.h index 03f7e6ef26..ddd0b2bc46 100644 --- a/src/effects/gradients/Sk4fGradientBase.h +++ b/src/effects/gradients/Sk4fGradientBase.h @@ -59,14 +59,16 @@ private: void addMirrorIntervals(const SkGradientShaderBase&, const Sk4f& componentScale, bool reverse); - template<typename DstType, SkShader::TileMode tileMode> + template<DstType, SkShader::TileMode tileMode> class TSampler; - template <typename DstType, ApplyPremul> - void shadePremulSpan(int x, int y, DstType[], int count) const; + template <DstType dstType, ApplyPremul premul> + void shadePremulSpan(int x, int y, typename DstTraits<dstType, premul>::Type[], + int count) const; - template <typename DstType, ApplyPremul, SkShader::TileMode tileMode> - void shadeSpanInternal(int x, int y, DstType[], int count) const; + template <DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode> + void shadeSpanInternal(int x, int y, typename DstTraits<dstType, premul>::Type[], + int count) const; }; #endif // Sk4fGradientBase_DEFINED diff --git a/src/effects/gradients/Sk4fGradientPriv.h b/src/effects/gradients/Sk4fGradientPriv.h index e9bc268b89..4f71d3f14d 100644 --- a/src/effects/gradients/Sk4fGradientPriv.h +++ b/src/effects/gradients/Sk4fGradientPriv.h @@ -14,6 +14,7 @@ #include "SkNx.h" #include "SkPM4f.h" #include "SkPM4fPriv.h" +#include "SkUtils.h" // Templates shared by various 4f gradient flavors. @@ -21,11 +22,12 @@ namespace { enum class ApplyPremul { True, False }; -inline Sk4f premul_4f(const Sk4f& c) { - const float alpha = c[SkPM4f::A]; - // FIXME: portable swizzle? - return c * Sk4f(alpha, alpha, alpha, 1); -} +enum class DstType { + L32, // Linear 32bit. Used for both shader/blitter paths. + S32, // SRGB 32bit. Used for the blitter path only. + F16, // Linear half-float. Used for blitters only. + F32, // Linear float. Used for shaders only. +}; template <ApplyPremul premul> inline SkPMColor trunc_from_4f_255(const Sk4f& c) { @@ -38,106 +40,156 @@ inline SkPMColor trunc_from_4f_255(const Sk4f& c) { return pmc; } -template<typename DstType, SkColorProfileType, ApplyPremul premul> -void store(const Sk4f& color, DstType* dst); +template <ApplyPremul> +struct PremulTraits; -template<> -inline void store<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, SkPM4f* dst) { - c.store(dst); -} +template <> +struct PremulTraits<ApplyPremul::False> { + static Sk4f apply(const Sk4f& c) { return c; } +}; -template<> -inline void store<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, SkPM4f* dst) { - premul_4f(c).store(dst); -} +template <> +struct PremulTraits<ApplyPremul::True> { + static Sk4f apply(const Sk4f& c) { + const float alpha = c[SkPM4f::A]; + // FIXME: portable swizzle? + return c * Sk4f(alpha, alpha, alpha, 1); + } +}; + +// Struct encapsulating various dest-dependent ops: +// +// - load() Load a SkPM4f value into Sk4f. Normally called once per interval +// advance. Also applies a scale and swizzle suitable for DstType. +// +// - store() Store one Sk4f to dest. Optionally handles premul, color space +// conversion, etc. +// +// - store(count) Store the Sk4f value repeatedly to dest, count times. +// +// - store4x() Store 4 Sk4f values to dest (opportunistic optimization). +// +template <DstType, ApplyPremul premul = ApplyPremul::False> +struct DstTraits; -template<> -inline void store<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, SkPMColor* dst) { - *dst = trunc_from_4f_255<ApplyPremul::False>(c); -} +template <ApplyPremul premul> +struct DstTraits<DstType::L32, premul> { + using Type = SkPMColor; -template<> -inline void store<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, SkPMColor* dst) { - *dst = trunc_from_4f_255<ApplyPremul::True>(c); -} + // For L32, we prescale the values by 255 to save a per-pixel multiplication. + static Sk4f load(const SkPM4f& c) { + return c.to4f_pmorder() * Sk4f(255); + } -template<> -inline void store<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, SkPMColor* dst) { - // FIXME: this assumes opaque colors. Handle unpremultiplication. - *dst = Sk4f_toS32(c); -} + static void store(const Sk4f& c, Type* dst) { + *dst = trunc_from_4f_255<premul>(c); + } -template<> -inline void store<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, SkPMColor* dst) { - *dst = Sk4f_toS32(premul_4f(c)); -} + static void store(const Sk4f& c, Type* dst, int n) { + sk_memset32(dst, trunc_from_4f_255<premul>(c), n); + } -template<> -inline void store<uint64_t, kLinear_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, uint64_t* dst) { - *dst = SkFloatToHalf_01(c); -} + static void store4x(const Sk4f& c0, const Sk4f& c1, + const Sk4f& c2, const Sk4f& c3, + Type* dst) { + if (premul == ApplyPremul::False) { + Sk4f_ToBytes((uint8_t*)dst, c0, c1, c2, c3); + } else { + store(c0, dst + 0); + store(c1, dst + 1); + store(c2, dst + 2); + store(c3, dst + 3); + } + } +}; -template<> -inline void store<uint64_t, kLinear_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, uint64_t* dst) { - *dst = SkFloatToHalf_01(premul_4f(c)); -} +template <ApplyPremul premul> +struct DstTraits<DstType::S32, premul> { + using PM = PremulTraits<premul>; + 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(); + } -template<typename DstType, SkColorProfileType profile, ApplyPremul premul> -inline void store4x(const Sk4f& c0, - const Sk4f& c1, - const Sk4f& c2, - const Sk4f& c3, - DstType* dst) { - store<DstType, profile, premul>(c0, dst++); - store<DstType, profile, premul>(c1, dst++); - store<DstType, profile, premul>(c2, dst++); - store<DstType, profile, premul>(c3, dst++); -} + static void store(const Sk4f& c, Type* dst) { + // FIXME: this assumes opaque colors. Handle unpremultiplication. + *dst = Sk4f_toS32(PM::apply(c)); + } -template<> -inline void store4x<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c0, const Sk4f& c1, - const Sk4f& c2, const Sk4f& c3, - SkPMColor* dst) { - Sk4f_ToBytes((uint8_t*)dst, c0, c1, c2, c3); -} + static void store(const Sk4f& c, Type* dst, int n) { + sk_memset32(dst, Sk4f_toS32(PM::apply(c)), n); + } -template<typename DstType, SkColorProfileType> -Sk4f scale_for_dest(const Sk4f& c) { - return c; -} + static void store4x(const Sk4f& c0, const Sk4f& c1, + const Sk4f& c2, const Sk4f& c3, + Type* dst) { + store(c0, dst + 0); + store(c1, dst + 1); + store(c2, dst + 2); + store(c3, dst + 3); + } +}; -template<> -inline Sk4f scale_for_dest<SkPMColor, kLinear_SkColorProfileType>(const Sk4f& c) { - return c * 255; -} +template <ApplyPremul premul> +struct DstTraits<DstType::F16, premul> { + using PM = PremulTraits<premul>; + using Type = uint64_t; -template<typename DstType> -Sk4f dst_swizzle(const SkPM4f&); + static Sk4f load(const SkPM4f& c) { + return c.to4f(); + } -template<> -inline Sk4f dst_swizzle<SkPM4f>(const SkPM4f& c) { - return c.to4f(); -} + static void store(const Sk4f& c, Type* dst) { + *dst = SkFloatToHalf_01(PM::apply(c)); + } -template<> -inline Sk4f dst_swizzle<SkPMColor>(const SkPM4f& c) { - return c.to4f_pmorder(); -} + static void store(const Sk4f& c, Type* dst, int n) { + sk_memset64(dst, SkFloatToHalf_01(PM::apply(c)), n); + } -template<> -inline Sk4f dst_swizzle<uint64_t>(const SkPM4f& c) { - return c.to4f(); -} + static void store4x(const Sk4f& c0, const Sk4f& c1, + const Sk4f& c2, const Sk4f& c3, + Type* dst) { + store(c0, dst + 0); + store(c1, dst + 1); + store(c2, dst + 2); + store(c3, dst + 3); + } +}; -} +template <ApplyPremul premul> +struct DstTraits<DstType::F32, premul> { + using PM = PremulTraits<premul>; + using Type = SkPM4f; + + static Sk4f load(const SkPM4f& c) { + return c.to4f(); + } + + static void store(const Sk4f& c, Type* dst) { + PM::apply(c).store(dst->fVec); + } + + static void store(const Sk4f& c, Type* dst, int n) { + const Sk4f pmc = PM::apply(c); + for (int i = 0; i < n; ++i) { + pmc.store(dst[i].fVec); + } + } + + static void store4x(const Sk4f& c0, const Sk4f& c1, + const Sk4f& c2, const Sk4f& c3, + Type* dst) { + store(c0, dst + 0); + store(c1, dst + 1); + store(c2, dst + 2); + store(c3, dst + 3); + } +}; + +} // anonymous namespace #endif // Sk4fGradientPriv_DEFINED diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp index 84b266accd..f4bb4a7d18 100644 --- a/src/effects/gradients/Sk4fLinearGradient.cpp +++ b/src/effects/gradients/Sk4fLinearGradient.cpp @@ -6,68 +6,12 @@ */ #include "Sk4fLinearGradient.h" -#include "SkUtils.h" #include "SkXfermode.h" namespace { -template<typename DstType, SkColorProfileType, ApplyPremul> -void fill(const Sk4f& c, DstType* dst, int n); - -template<> -void fill<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, SkPM4f* dst, int n) { - while (n > 0) { - c.store(dst++); - n--; - } -} - -template<> -void fill<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, SkPM4f* dst, int n) { - fill<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::False>(premul_4f(c), dst, n); -} - -template<> -void fill<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, SkPMColor* dst, int n) { - sk_memset32(dst, trunc_from_4f_255<ApplyPremul::False>(c), n); -} - -template<> -void fill<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, SkPMColor* dst, int n) { - sk_memset32(dst, trunc_from_4f_255<ApplyPremul::True>(c), n); -} - -template<> -void fill<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, SkPMColor* dst, int n) { - // FIXME: this assumes opaque colors. Handle unpremultiplication. - sk_memset32(dst, Sk4f_toS32(c), n); -} - -template<> -void fill<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, SkPMColor* dst, int n) { - sk_memset32(dst, Sk4f_toS32(premul_4f(c)), n); -} - -template<> -void fill<uint64_t, kLinear_SkColorProfileType, ApplyPremul::False> - (const Sk4f& c, uint64_t* dst, int n) { - sk_memset64(dst, SkFloatToHalf_01(c), n); -} - -template<> -void fill<uint64_t, kLinear_SkColorProfileType, ApplyPremul::True> - (const Sk4f& c, uint64_t* dst, int n) { - sk_memset64(dst, SkFloatToHalf_01(premul_4f(c)), n); -} - -template<typename DstType, SkColorProfileType profile, ApplyPremul premul> -void ramp(const Sk4f& c, const Sk4f& dc, DstType* dst, int n) { +template<DstType dstType, ApplyPremul premul> +void ramp(const Sk4f& c, const Sk4f& dc, typename DstTraits<dstType, premul>::Type dst[], int n) { SkASSERT(n > 0); const Sk4f dc2 = dc + dc; @@ -79,7 +23,7 @@ void ramp(const Sk4f& c, const Sk4f& dc, DstType* dst, int n) { Sk4f c3 = c1 + dc2; while (n >= 4) { - store4x<DstType, profile, premul>(c0, c1, c2, c3, dst); + DstTraits<dstType, premul>::store4x(c0, c1, c2, c3, dst); dst += 4; c0 = c0 + dc4; @@ -89,12 +33,12 @@ void ramp(const Sk4f& c, const Sk4f& dc, DstType* dst, int n) { n -= 4; } if (n & 2) { - store<DstType, profile, premul>(c0, dst++); - store<DstType, profile, premul>(c1, dst++); + DstTraits<dstType, premul>::store(c0, dst++); + DstTraits<dstType, premul>::store(c1, dst++); c0 = c0 + dc2; } if (n & 1) { - store<DstType, profile, premul>(c0, dst); + DstTraits<dstType, premul>::store(c0, dst); } } @@ -193,12 +137,10 @@ LinearGradient4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) { // TODO: plumb dithering SkASSERT(count > 0); if (fColorsArePremul) { - this->shadePremulSpan<SkPMColor, - kLinear_SkColorProfileType, + this->shadePremulSpan<DstType::L32, ApplyPremul::False>(x, y, dst, count); } else { - this->shadePremulSpan<SkPMColor, - kLinear_SkColorProfileType, + this->shadePremulSpan<DstType::L32, ApplyPremul::True>(x, y, dst, count); } } @@ -213,50 +155,44 @@ LinearGradient4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { // TONOTDO: plumb dithering SkASSERT(count > 0); if (fColorsArePremul) { - this->shadePremulSpan<SkPM4f, - kLinear_SkColorProfileType, + this->shadePremulSpan<DstType::F32, ApplyPremul::False>(x, y, dst, count); } else { - this->shadePremulSpan<SkPM4f, - kLinear_SkColorProfileType, + this->shadePremulSpan<DstType::F32, ApplyPremul::True>(x, y, dst, count); } } -template<typename DstType, SkColorProfileType profile, ApplyPremul premul> +template<DstType dstType, ApplyPremul premul> void SkLinearGradient:: LinearGradient4fContext::shadePremulSpan(int x, int y, - DstType dst[], + typename DstTraits<dstType, premul>::Type dst[], int count) const { const SkLinearGradient& shader = static_cast<const SkLinearGradient&>(fShader); switch (shader.fTileMode) { case kClamp_TileMode: - this->shadeSpanInternal<DstType, - profile, + this->shadeSpanInternal<dstType, premul, kClamp_TileMode>(x, y, dst, count); break; case kRepeat_TileMode: - this->shadeSpanInternal<DstType, - profile, + this->shadeSpanInternal<dstType, premul, kRepeat_TileMode>(x, y, dst, count); break; case kMirror_TileMode: - this->shadeSpanInternal<DstType, - profile, + this->shadeSpanInternal<dstType, premul, kMirror_TileMode>(x, y, dst, count); break; } } -template<typename DstType, SkColorProfileType profile, ApplyPremul premul, - SkShader::TileMode tileMode> +template<DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode> void SkLinearGradient:: LinearGradient4fContext::shadeSpanInternal(int x, int y, - DstType dst[], + typename DstTraits<dstType, premul>::Type dst[], int count) const { SkPoint pt; fDstToPosProc(fDstToPos, @@ -265,12 +201,12 @@ LinearGradient4fContext::shadeSpanInternal(int x, int y, &pt); const SkScalar fx = pinFx<tileMode>(pt.x()); const SkScalar dx = fDstToPos.getScaleX(); - LinearIntervalProcessor<DstType, profile, tileMode> proc(fIntervals.begin(), - fIntervals.end() - 1, - this->findInterval(fx), - fx, - dx, - SkScalarNearlyZero(dx * count)); + LinearIntervalProcessor<dstType, tileMode> proc(fIntervals.begin(), + fIntervals.end() - 1, + this->findInterval(fx), + fx, + dx, + SkScalarNearlyZero(dx * count)); while (count > 0) { // What we really want here is SkTPin(advance, 1, count) // but that's a significant perf hit for >> stops; investigate. @@ -285,12 +221,12 @@ LinearGradient4fContext::shadeSpanInternal(int x, int y, || (n == count && proc.currentRampIsZero())); if (proc.currentRampIsZero()) { - fill<DstType, profile, premul>(proc.currentColor(), - dst, n); + DstTraits<dstType, premul>::store(proc.currentColor(), + dst, n); } else { - ramp<DstType, profile, premul>(proc.currentColor(), - proc.currentColorGrad(), - dst, n); + ramp<dstType, premul>(proc.currentColor(), + proc.currentColorGrad(), + dst, n); } proc.advance(SkIntToScalar(n)); @@ -299,7 +235,7 @@ LinearGradient4fContext::shadeSpanInternal(int x, int y, } } -template<typename DstType, SkColorProfileType profile, SkShader::TileMode tileMode> +template<DstType dstType, SkShader::TileMode tileMode> class SkLinearGradient:: LinearGradient4fContext::LinearIntervalProcessor { public: @@ -346,12 +282,11 @@ public: private: void compute_interval_props(SkScalar t) { - fDc = dst_swizzle<DstType>(fInterval->fDc); - fCc = dst_swizzle<DstType>(fInterval->fC0); - fCc = fCc + fDc * Sk4f(t); - fCc = scale_for_dest<DstType, profile>(fCc); - fDcDx = scale_for_dest<DstType, profile>(fDc * Sk4f(fDx)); - fZeroRamp = fIsVertical || fInterval->isZeroRamp(); + const Sk4f dC = DstTraits<dstType>::load(fInterval->fDc); + fCc = DstTraits<dstType>::load(fInterval->fC0); + fCc = fCc + dC * Sk4f(t); + fDcDx = dC * fDx; + fZeroRamp = fIsVertical || fInterval->isZeroRamp(); } const Interval* next_interval(const Interval* i) const { @@ -384,7 +319,6 @@ private: } // Current interval properties. - Sk4f fDc; // local color gradient (dc/dt) Sk4f fDcDx; // dst color gradient (dc/dx) Sk4f fCc; // current color, interpolated in dst SkScalar fAdvX; // remaining interval advance in dst @@ -476,18 +410,18 @@ LinearGradient4fContext::D32_BlitBW(BlitState* state, int x, int y, const SkPixm if (dst.info().isLinear()) { if (ctx->fColorsArePremul) { - ctx->shadePremulSpan<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::False>( + ctx->shadePremulSpan<DstType::L32, ApplyPremul::False>( x, y, dst.writable_addr32(x, y), count); } else { - ctx->shadePremulSpan<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::True>( + ctx->shadePremulSpan<DstType::L32, ApplyPremul::True>( x, y, dst.writable_addr32(x, y), count); } } else { if (ctx->fColorsArePremul) { - ctx->shadePremulSpan<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::False>( + ctx->shadePremulSpan<DstType::S32, ApplyPremul::False>( x, y, dst.writable_addr32(x, y), count); } else { - ctx->shadePremulSpan<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::True>( + ctx->shadePremulSpan<DstType::S32, ApplyPremul::True>( x, y, dst.writable_addr32(x, y), count); } } @@ -501,10 +435,10 @@ LinearGradient4fContext::D64_BlitBW(BlitState* state, int x, int y, const SkPixm static_cast<const LinearGradient4fContext*>(state->fCtx); if (ctx->fColorsArePremul) { - ctx->shadePremulSpan<uint64_t, kLinear_SkColorProfileType, ApplyPremul::False>( + ctx->shadePremulSpan<DstType::F16, ApplyPremul::False>( x, y, dst.writable_addr64(x, y), count); } else { - ctx->shadePremulSpan<uint64_t, kLinear_SkColorProfileType, ApplyPremul::True>( + ctx->shadePremulSpan<DstType::F16, ApplyPremul::True>( x, y, dst.writable_addr64(x, y), count); } } diff --git a/src/effects/gradients/Sk4fLinearGradient.h b/src/effects/gradients/Sk4fLinearGradient.h index 30292c361f..dc7a179583 100644 --- a/src/effects/gradients/Sk4fLinearGradient.h +++ b/src/effects/gradients/Sk4fLinearGradient.h @@ -27,14 +27,16 @@ protected: private: using INHERITED = GradientShaderBase4fContext; - template<typename DstType, SkColorProfileType, TileMode> + template<DstType, TileMode> class LinearIntervalProcessor; - template <typename DstType, SkColorProfileType, ApplyPremul> - void shadePremulSpan(int x, int y, DstType[], int count) const; + template <DstType dstType, ApplyPremul premul> + void shadePremulSpan(int x, int y, typename DstTraits<dstType, premul>::Type[], + int count) const; - template <typename DstType, SkColorProfileType, ApplyPremul, SkShader::TileMode tileMode> - void shadeSpanInternal(int x, int y, DstType[], int count) const; + template <DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode> + void shadeSpanInternal(int x, int y, typename DstTraits<dstType, premul>::Type[], + int count) const; const Interval* findInterval(SkScalar fx) const; |