aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/gradients
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-01 12:59:40 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-01 12:59:40 +0000
commit3c2102c2d2cdad328a0d87329e1a973f12775836 (patch)
treebfabda50bccc07e57b0a0851f380f3a717638814 /src/effects/gradients
parenta63389843dd18003382d61c2e4610af09ed07d38 (diff)
restore cache-count for gradients to p.o.2. so we can perform fancier dithering
in the future. Review URL: https://codereview.appspot.com/7254043 git-svn-id: http://skia.googlecode.com/svn/trunk@7506 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects/gradients')
-rw-r--r--src/effects/gradients/SkGradientShader.cpp37
-rw-r--r--src/effects/gradients/SkGradientShaderPriv.h17
-rw-r--r--src/effects/gradients/SkLinearGradient.cpp26
-rw-r--r--src/effects/gradients/SkRadialGradient.cpp6
4 files changed, 26 insertions, 60 deletions
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 81a6659fbc..de9ae9e48b 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -364,14 +364,6 @@ static inline U16CPU bitsTo16(unsigned x, const unsigned bits) {
return 0;
}
-/** We duplicate the last value in each half of the cache so that
- interpolation doesn't have to special-case being at the last point.
-*/
-static void complete_16bit_cache(uint16_t* cache, int stride) {
- cache[stride - 1] = cache[stride - 2];
- cache[2 * stride - 1] = cache[2 * stride - 2];
-}
-
const uint16_t* SkGradientShaderBase::getCache16() const {
if (fCache16 == NULL) {
// double the count for dither entries
@@ -384,7 +376,7 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
fCache16 = fCache16Storage;
if (fColorCount == 2) {
Build16bitCache(fCache16, fOrigColors[0], fOrigColors[1],
- kGradient16Length);
+ kCache16Count);
} else {
Rec* rec = fRecs;
int prevIndex = 0;
@@ -396,8 +388,6 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
Build16bitCache(fCache16 + prevIndex, fOrigColors[i-1], fOrigColors[i], nextIndex - prevIndex + 1);
prevIndex = nextIndex;
}
- // one extra space left over at the end for complete_16bit_cache()
- SkASSERT(prevIndex == kGradient16Length - 1);
}
if (fMapper) {
@@ -405,7 +395,7 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
uint16_t* linear = fCache16; // just computed linear data
uint16_t* mapped = fCache16Storage; // storage for mapped data
SkUnitMapper* map = fMapper;
- for (int i = 0; i < kGradient16Length; i++) {
+ for (int i = 0; i < kCache16Count; i++) {
int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache16Shift;
mapped[i] = linear[index];
mapped[i + kCache16Count] = linear[index + kCache16Count];
@@ -413,19 +403,10 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
sk_free(fCache16);
fCache16 = fCache16Storage;
}
- complete_16bit_cache(fCache16, kCache16Count);
}
return fCache16;
}
-/** We duplicate the last value in each half of the cache so that
- interpolation doesn't have to special-case being at the last point.
-*/
-static void complete_32bit_cache(SkPMColor* cache, int stride) {
- cache[stride - 1] = cache[stride - 2];
- cache[2 * stride - 1] = cache[2 * stride - 2];
-}
-
const SkPMColor* SkGradientShaderBase::getCache32() const {
if (fCache32 == NULL) {
// double the count for dither entries
@@ -439,13 +420,13 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
if (fColorCount == 2) {
Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
- kGradient32Length, fCacheAlpha);
+ kCache32Count, fCacheAlpha);
} else {
Rec* rec = fRecs;
int prevIndex = 0;
for (int i = 1; i < fColorCount; i++) {
int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift;
- SkASSERT(nextIndex < kGradient32Length);
+ SkASSERT(nextIndex < kCache32Count);
if (nextIndex > prevIndex)
Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1],
@@ -453,7 +434,6 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
nextIndex - prevIndex + 1, fCacheAlpha);
prevIndex = nextIndex;
}
- SkASSERT(prevIndex == kGradient32Length - 1);
}
if (fMapper) {
@@ -462,7 +442,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
SkPMColor* linear = fCache32; // just computed linear data
SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
SkUnitMapper* map = fMapper;
- for (int i = 0; i < kGradient32Length; i++) {
+ for (int i = 0; i < kCache32Count; i++) {
int index = map->mapUnit16((i << 8) | i) >> 8;
mapped[i] = linear[index];
mapped[i + kCache32Count] = linear[index + kCache32Count];
@@ -471,7 +451,6 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
fCache32PixelRef = newPR;
fCache32 = (SkPMColor*)newPR->getAddr();
}
- complete_32bit_cache(fCache32, kCache32Count);
}
return fCache32;
}
@@ -493,7 +472,7 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
if (fMapper) {
// force our cahce32pixelref to be built
(void)this->getCache32();
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, kGradient32Length, 1);
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
bitmap->setPixelRef(fCache32PixelRef);
return;
}
@@ -533,9 +512,7 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
if (!gCache->find(storage.get(), size, bitmap)) {
// force our cahce32pixelref to be built
(void)this->getCache32();
- // Only expose the linear section of the cache; don't let the caller
- // know about the padding at the end to make interpolation faster.
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, kGradient32Length, 1);
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
bitmap->setPixelRef(fCache32PixelRef);
gCache->add(storage.get(), size, *bitmap);
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 954acb2e45..d35fb1c596 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -101,26 +101,14 @@ public:
/// Seems like enough for visual accuracy. TODO: if pos[] deserves
/// it, use a larger cache.
kCache16Bits = 8,
- kGradient16Length = (1 << kCache16Bits),
- /// Each cache gets 1 extra entry at the end so we don't have to
- /// test for end-of-cache in lerps. This is also the value used
- /// to stride *writes* into the dither cache; it must not be zero.
- /// Total space for a cache is 2x kCache16Count entries: one
- /// regular cache, one for dithering.
- kCache16Count = kGradient16Length + 1,
+ kCache16Count = (1 << kCache16Bits),
kCache16Shift = 16 - kCache16Bits,
kSqrt16Shift = 8 - kCache16Bits,
/// Seems like enough for visual accuracy. TODO: if pos[] deserves
/// it, use a larger cache.
kCache32Bits = 8,
- kGradient32Length = (1 << kCache32Bits),
- /// Each cache gets 1 extra entry at the end so we don't have to
- /// test for end-of-cache in lerps. This is also the value used
- /// to stride *writes* into the dither cache; it must not be zero.
- /// Total space for a cache is 2x kCache32Count entries: one
- /// regular cache, one for dithering.
- kCache32Count = kGradient32Length + 1,
+ kCache32Count = (1 << kCache32Bits),
kCache32Shift = 16 - kCache32Bits,
kSqrt32Shift = 8 - kCache32Bits,
@@ -132,7 +120,6 @@ public:
kDitherStride32 = 0,
#endif
kDitherStride16 = kCache16Count,
- kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1
};
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 1848571386..b194d50a84 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -131,16 +131,18 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
// If colors change sharply across the gradient, dithering is
// insufficient (it subsamples the color space) and we need to lerp.
unsigned fullIndex = proc(fx);
- unsigned fi = fullIndex >> (16 - SkGradientShaderBase::kCache32Bits);
- unsigned remainder = fullIndex & SkGradientShaderBase::kLerpRemainderMask32;
- SkPMColor lerp =
- SkFastFourByteInterp(
- cache[toggle + fi + 1],
- cache[toggle + fi], remainder);
- SkPMColor dlerp =
- SkFastFourByteInterp(
- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + fi + 1],
- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + fi], remainder);
+ unsigned fi = fullIndex >> SkGradientShaderBase::kCache32Shift;
+ unsigned remainder = fullIndex & ((1 << SkGradientShaderBase::kCache32Shift) - 1);
+
+ int index0 = fi + toggle;
+ int index1 = index0;
+ if (fi < SkGradientShaderBase::kCache32Count - 1) {
+ index1 += 1;
+ }
+ SkPMColor lerp = SkFastFourByteInterp(cache[index1], cache[index0], remainder);
+ index0 ^= SkGradientShaderBase::kDitherStride32;
+ index1 ^= SkGradientShaderBase::kDitherStride32;
+ SkPMColor dlerp = SkFastFourByteInterp(cache[index1], cache[index0], remainder);
sk_memset32_dither(dstC, lerp, dlerp, count);
}
@@ -149,7 +151,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
SkClampRange range;
- range.init(fx, dx, count, 0, SkGradientShaderBase::kGradient32Length);
+ range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1);
if ((count = range.fCount0) > 0) {
sk_memset32_dither(dstC,
@@ -334,7 +336,7 @@ void shadeSpan16_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
const uint16_t* SK_RESTRICT cache,
int toggle, int count) {
SkClampRange range;
- range.init(fx, dx, count, 0, SkGradientShaderBase::kGradient16Length);
+ range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1);
if ((count = range.fCount0) > 0) {
dither_memset16(dstC,
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index 3062105ee3..6945d5a8cc 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -227,8 +227,8 @@ SkShader::BitmapType SkRadialGradient::asABitmap(SkBitmap* bitmap,
this->getGradientTableBitmap(bitmap);
}
if (matrix) {
- matrix->setScale(SkIntToScalar(kGradient32Length),
- SkIntToScalar(kGradient32Length));
+ matrix->setScale(SkIntToScalar(kCache32Count),
+ SkIntToScalar(kCache32Count));
matrix->preConcat(fPtsToUnit);
}
if (xy) {
@@ -318,7 +318,7 @@ void shadeSpan_radial_clamp(SkScalar sfx, SkScalar sdx,
SkFixed fy = SkScalarToFixed(sfy) >> 1;
SkFixed dy = SkScalarToFixed(sdy) >> 1;
if ((count > 4) && radial_completely_pinned(fx, dx, fy, dy)) {
- unsigned fi = SkGradientShaderBase::kGradient32Length;
+ unsigned fi = SkGradientShaderBase::kCache32Count - 1;
sk_memset32_dither(dstC,
cache[toggle + fi],
cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + fi],