Go from a 1x2 to a 2x2 dither cell, and change/simplify the logic for how we
compute the "dithered" version of a color to just a graduated fixed-point-round.
Also, add this new dither to conical and sweep, which before had no dithering.
Disabled for now using SK_IGNORE_GRADIENT_DITHER_FIX. Will enable this and
and rebaseline skia.
http://code.google.com/p/skia/issues/detail?id=1098
Review URL: https://codereview.appspot.com/7248046
git-svn-id: http://skia.googlecode.com/svn/trunk@7549 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index e239530..f1acd55 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -113,11 +113,12 @@
return SkFloatToFixed(t);
}
-typedef void (*TwoPointRadialProc)(TwoPtRadial* rec, SkPMColor* dstC,
- const SkPMColor* cache, int count);
+typedef void (*TwoPointConicalProc)(TwoPtRadial* rec, SkPMColor* dstC,
+ const SkPMColor* cache, int toggle, int count);
static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
- const SkPMColor* SK_RESTRICT cache, int count) {
+ const SkPMColor* SK_RESTRICT cache, int toggle,
+ int count) {
for (; count > 0; --count) {
SkFixed t = rec->nextT();
if (TwoPtRadial::DontDrawT(t)) {
@@ -125,13 +126,18 @@
} else {
SkFixed index = SkClampMax(t, 0xFFFF);
SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
+ *dstC++ = cache[toggle +
+ (index >> SkGradientShaderBase::kCache32Shift)];
}
+#ifndef SK_IGNORE_GRADIENT_DITHER_FIX
+ toggle = next_dither_toggle(toggle);
+#endif
}
}
static void twopoint_repeat(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
- const SkPMColor* SK_RESTRICT cache, int count) {
+ const SkPMColor* SK_RESTRICT cache, int toggle,
+ int count) {
for (; count > 0; --count) {
SkFixed t = rec->nextT();
if (TwoPtRadial::DontDrawT(t)) {
@@ -139,13 +145,18 @@
} else {
SkFixed index = repeat_tileproc(t);
SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
+ *dstC++ = cache[toggle +
+ (index >> SkGradientShaderBase::kCache32Shift)];
}
+#ifndef SK_IGNORE_GRADIENT_DITHER_FIX
+ toggle = next_dither_toggle(toggle);
+#endif
}
}
static void twopoint_mirror(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
- const SkPMColor* SK_RESTRICT cache, int count) {
+ const SkPMColor* SK_RESTRICT cache, int toggle,
+ int count) {
for (; count > 0; --count) {
SkFixed t = rec->nextT();
if (TwoPtRadial::DontDrawT(t)) {
@@ -153,8 +164,12 @@
} else {
SkFixed index = mirror_tileproc(t);
SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
+ *dstC++ = cache[toggle +
+ (index >> SkGradientShaderBase::kCache32Shift)];
}
+#ifndef SK_IGNORE_GRADIENT_DITHER_FIX
+ toggle = next_dither_toggle(toggle);
+#endif
}
}
@@ -183,6 +198,12 @@
void SkTwoPointConicalGradient::shadeSpan(int x, int y, SkPMColor* dstCParam,
int count) {
+#ifndef SK_IGNORE_GRADIENT_DITHER_FIX
+ int toggle = init_dither_toggle(x, y);
+#else
+ int toggle = 0;
+#endif
+
SkASSERT(count > 0);
SkPMColor* SK_RESTRICT dstC = dstCParam;
@@ -191,7 +212,7 @@
const SkPMColor* SK_RESTRICT cache = this->getCache32();
- TwoPointRadialProc shadeProc = twopoint_repeat;
+ TwoPointConicalProc shadeProc = twopoint_repeat;
if (SkShader::kClamp_TileMode == fTileMode) {
shadeProc = twopoint_clamp;
} else if (SkShader::kMirror_TileMode == fTileMode) {
@@ -219,7 +240,7 @@
}
fRec.setup(fx, fy, dx, dy);
- (*shadeProc)(&fRec, dstC, cache, count);
+ (*shadeProc)(&fRec, dstC, cache, toggle, count);
} else { // perspective case
SkScalar dstX = SkIntToScalar(x);
SkScalar dstY = SkIntToScalar(y);
@@ -229,7 +250,10 @@
dstX += SK_Scalar1;
fRec.setup(srcPt.fX, srcPt.fY, 0, 0);
- (*shadeProc)(&fRec, dstC, cache, 1);
+ (*shadeProc)(&fRec, dstC, cache, toggle, 1);
+#ifndef SK_IGNORE_GRADIENT_DITHER_FIX
+ toggle = next_dither_toggle(toggle);
+#endif
}
}
}