Index: src/effects/gradients/Sk4fLinearGradient.cpp |
diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp |
index 84b266accdf144c26003b49e0118fc0fc86f27fb..f4bb4a7d1829d67598855354ead50a3b85dfae00 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); |
} |
} |