aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-08 19:48:12 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-08 19:48:12 +0000
commitd8e0d6a87d56ece202cc529ec9269da3dcd3d6a8 (patch)
treedcf392cd1e7cb51d89d8897a0183f4bf84ec691d /src/effects
parent0556ea0ede7066b9b3ed9f03f5a6eb72cd718897 (diff)
Optimize building gradient cache for when we know alpha is always 0xFF.
remove old build guard for dithering. Review URL: https://codereview.appspot.com/7309064 git-svn-id: http://skia.googlecode.com/svn/trunk@7678 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/gradients/SkGradientShader.cpp163
-rw-r--r--src/effects/gradients/SkGradientShaderPriv.h4
2 files changed, 85 insertions, 82 deletions
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index aa03ecb208..6c953741cd 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -289,24 +289,6 @@ void SkGradientShaderBase::Build16bitCache(uint16_t cache[], SkColor c0, SkColor
} while (--count != 0);
}
-/*
- * 2x2 dither a fixed-point color component (8.16) down to 8, matching the
- * semantics of how we 2x2 dither 32->16
- */
-static inline U8CPU dither_fixed_to_8(SkFixed n) {
- n >>= 8;
- return ((n << 1) - ((n >> 8 << 8) | (n >> 8))) >> 8;
-}
-
-/*
- * For dithering with premultiply, we want to ceiling the alpha component,
- * to ensure that it is always >= any color component.
- */
-static inline U8CPU dither_ceil_fixed_to_8(SkFixed n) {
- n >>= 8;
- return ((n << 1) - (n | (n >> 8))) >> 8;
-}
-
void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1,
int count, U8CPU paintAlpha) {
SkASSERT(count > 1);
@@ -319,67 +301,94 @@ void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColo
da = SkIntToFixed(tmp - a) / (count - 1);
}
- SkFixed r = SkColorGetR(c0);
- SkFixed g = SkColorGetG(c0);
- SkFixed b = SkColorGetB(c0);
+ /*
+ * r,g,b used to be SkFixed, but on gcc (4.2.1 mac and 4.6.3 goobuntu) in
+ * release builds, we saw a compiler error where the 0xFF parameter in
+ * SkPackARGB32() was being totally ignored whenever it was called with
+ * a non-zero add (e.g. 0x8000).
+ *
+ * We found two work-arounds:
+ * 1. change r,g,b to unsigned (or just one of them)
+ * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead
+ * of using |
+ *
+ * We chose #1 just because it was more localized.
+ * See http://code.google.com/p/skia/issues/detail?id=1113
+ */
+ uint32_t r = SkColorGetR(c0);
+ uint32_t g = SkColorGetG(c0);
+ uint32_t b = SkColorGetB(c0);
+
SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1);
SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1);
SkFixed db = SkIntToFixed(SkColorGetB(c1) - b) / (count - 1);
-#ifdef SK_IGNORE_GRADIENT_DITHER_FIX
- a = SkIntToFixed(a) + 0x8000;
- r = SkIntToFixed(r) + 0x8000;
- g = SkIntToFixed(g) + 0x8000;
- b = SkIntToFixed(b) + 0x8000;
-#else
- a = SkIntToFixed(a);
- r = SkIntToFixed(r);
- g = SkIntToFixed(g);
- b = SkIntToFixed(b);
-#endif
+ /* We pre-add 1/8 to avoid having to add this to our [0] value each time
+ in the loop. Without this, the bias for each would be
+ 0x2000 0xA000 0xE000 0x6000
+ With this trick, we can add 0 for the first (no-op) and just adjust the
+ others.
+ */
+ r = SkIntToFixed(r) + 0x2000;
+ g = SkIntToFixed(g) + 0x2000;
+ b = SkIntToFixed(b) + 0x2000;
+
+ /*
+ * Our dither-cell (spatially) is
+ * 0 2
+ * 3 1
+ * Where
+ * [0] -> [-1/8 ... 1/8 ) values near 0
+ * [1] -> [ 1/8 ... 3/8 ) values near 1/4
+ * [2] -> [ 3/8 ... 5/8 ) values near 1/2
+ * [3] -> [ 5/8 ... 7/8 ) values near 3/4
+ */
- do {
-#ifdef SK_IGNORE_GRADIENT_DITHER_FIX
- cache[0] = SkPremultiplyARGBInline(a >> 16, r >> 16, g >> 16, b >> 16);
- cache[kCache32Count] =
- SkPremultiplyARGBInline(dither_ceil_fixed_to_8(a),
- dither_fixed_to_8(r),
- dither_fixed_to_8(g),
- dither_fixed_to_8(b));
-#else
- /*
- * Our dither-cell (spatially) is
- * 0 2
- * 3 1
- * Where
- * [0] -> [-1/8 ... 1/8 ) values near 0
- * [1] -> [ 1/8 ... 3/8 ) values near 1/4
- * [2] -> [ 3/8 ... 5/8 ) values near 1/2
- * [3] -> [ 5/8 ... 7/8 ) values near 3/4
- */
- cache[kCache32Count*0] = SkPremultiplyARGBInline((a + 0x2000) >> 16,
- (r + 0x2000) >> 16,
- (g + 0x2000) >> 16,
- (b + 0x2000) >> 16);
- cache[kCache32Count*3] = SkPremultiplyARGBInline((a + 0x6000) >> 16,
- (r + 0x6000) >> 16,
- (g + 0x6000) >> 16,
- (b + 0x6000) >> 16);
- cache[kCache32Count*1] = SkPremultiplyARGBInline((a + 0xA000) >> 16,
- (r + 0xA000) >> 16,
- (g + 0xA000) >> 16,
- (b + 0xA000) >> 16);
- cache[kCache32Count*2] = SkPremultiplyARGBInline((a + 0xE000) >> 16,
- (r + 0xE000) >> 16,
- (g + 0xE000) >> 16,
- (b + 0xE000) >> 16);
-#endif
- cache += 1;
- a += da;
- r += dr;
- g += dg;
- b += db;
- } while (--count != 0);
+ if (0xFF == a && 0 == da) {
+ do {
+ cache[kCache32Count*0] = SkPackARGB32(0xFF, (r + 0 ) >> 16,
+ (g + 0 ) >> 16,
+ (b + 0 ) >> 16);
+ cache[kCache32Count*1] = SkPackARGB32(0xFF, (r + 0x8000) >> 16,
+ (g + 0x8000) >> 16,
+ (b + 0x8000) >> 16);
+ cache[kCache32Count*2] = SkPackARGB32(0xFF, (r + 0xC000) >> 16,
+ (g + 0xC000) >> 16,
+ (b + 0xC000) >> 16);
+ cache[kCache32Count*3] = SkPackARGB32(0xFF, (r + 0x4000) >> 16,
+ (g + 0x4000) >> 16,
+ (b + 0x4000) >> 16);
+ cache += 1;
+ r += dr;
+ g += dg;
+ b += db;
+ } while (--count != 0);
+ } else {
+ a = SkIntToFixed(a) + 0x2000;
+ do {
+ cache[kCache32Count*0] = SkPremultiplyARGBInline((a + 0 ) >> 16,
+ (r + 0 ) >> 16,
+ (g + 0 ) >> 16,
+ (b + 0 ) >> 16);
+ cache[kCache32Count*1] = SkPremultiplyARGBInline((a + 0x8000) >> 16,
+ (r + 0x8000) >> 16,
+ (g + 0x8000) >> 16,
+ (b + 0x8000) >> 16);
+ cache[kCache32Count*2] = SkPremultiplyARGBInline((a + 0xC000) >> 16,
+ (r + 0xC000) >> 16,
+ (g + 0xC000) >> 16,
+ (b + 0xC000) >> 16);
+ cache[kCache32Count*3] = SkPremultiplyARGBInline((a + 0x4000) >> 16,
+ (r + 0x4000) >> 16,
+ (g + 0x4000) >> 16,
+ (b + 0x4000) >> 16);
+ cache += 1;
+ a += da;
+ r += dr;
+ g += dg;
+ b += db;
+ } while (--count != 0);
+ }
}
static inline int SkFixedToFFFF(SkFixed x) {
@@ -479,12 +488,10 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
SkUnitMapper* map = fMapper;
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];
-#ifndef SK_IGNORE_GRADIENT_DITHER_FIX
+ mapped[i + kCache32Count*0] = linear[index + kCache32Count*0];
+ mapped[i + kCache32Count*1] = linear[index + kCache32Count*1];
mapped[i + kCache32Count*2] = linear[index + kCache32Count*2];
mapped[i + kCache32Count*3] = linear[index + kCache32Count*3];
-#endif
}
fCache32PixelRef->unref();
fCache32PixelRef = newPR;
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index e796d7d2f8..7bcda14738 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -167,13 +167,9 @@ private:
};
static inline int init_dither_toggle(int x, int y) {
-#ifdef SK_IGNORE_GRADIENT_DITHER_FIX
- return ((x ^ y) & 1) * SkGradientShaderBase::kDitherStride32;
-#else
x &= 1;
y = (y & 1) << 1;
return (x | y) * SkGradientShaderBase::kDitherStride32;
-#endif
}
static inline int next_dither_toggle(int toggle) {