aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2016-03-21 13:16:51 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-21 13:16:52 -0700
commitdc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6 (patch)
treeb072c263452bed811ce7643fa53fb584c997359d /src
parent66be626f7f3ddda243e51aa8f36398b26769a9b4 (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.cpp32
-rw-r--r--src/effects/gradients/Sk4fGradientBase.h12
-rw-r--r--src/effects/gradients/Sk4fGradientPriv.h230
-rw-r--r--src/effects/gradients/Sk4fLinearGradient.cpp146
-rw-r--r--src/effects/gradients/Sk4fLinearGradient.h12
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;