Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(617)

Unified Diff: src/effects/gradients/SkLinearGradient.cpp

Issue 815623004: improve precision of gradients (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/effects/gradients/SkClampRange.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/gradients/SkLinearGradient.cpp
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 4e7a6c729d5c014b89b319a45624f1040266c041..885a1b56c8e28d1b034cc726c465f80ffae73afa 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -104,7 +104,7 @@ SkLinearGradient::LinearGradientContext::LinearGradientContext(
#define NO_CHECK_ITER \
do { \
- unsigned fi = fx >> SkGradientShaderBase::kCache32Shift; \
+ unsigned fi = SkGradFixedToFixed(fx) >> SkGradientShaderBase::kCache32Shift; \
SkASSERT(fi <= 0xFF); \
fx += dx; \
*dstC++ = cache[toggle + fi]; \
@@ -113,21 +113,21 @@ SkLinearGradient::LinearGradientContext::LinearGradientContext(
namespace {
-typedef void (*LinearShadeProc)(TileProc proc, SkFixed dx, SkFixed fx,
+typedef void (*LinearShadeProc)(TileProc proc, SkGradFixed dx, SkGradFixed fx,
SkPMColor* dstC, const SkPMColor* cache,
int toggle, int count);
// Linear interpolation (lerp) is unnecessary if there are no sharp
// discontinuities in the gradient - which must be true if there are
// only 2 colors - but it's cheap.
-void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan_linear_vertical_lerp(TileProc proc, SkGradFixed dx, SkGradFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
// We're a vertical gradient, so no change in a span.
// 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 fullIndex = proc(SkGradFixedToFixed(fx));
unsigned fi = fullIndex >> SkGradientShaderBase::kCache32Shift;
unsigned remainder = fullIndex & ((1 << SkGradientShaderBase::kCache32Shift) - 1);
@@ -143,7 +143,7 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
sk_memset32_dither(dstC, lerp, dlerp, count);
}
-void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan_linear_clamp(TileProc proc, SkGradFixed dx, SkGradFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
@@ -180,12 +180,12 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
}
}
-void shadeSpan_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan_linear_mirror(TileProc proc, SkGradFixed dx, SkGradFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
do {
- unsigned fi = mirror_8bits(fx >> 8);
+ unsigned fi = mirror_8bits(SkGradFixedToFixed(fx) >> 8);
SkASSERT(fi <= 0xFF);
fx += dx;
*dstC++ = cache[toggle + fi];
@@ -193,12 +193,12 @@ void shadeSpan_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx,
} while (--count != 0);
}
-void shadeSpan_linear_repeat(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan_linear_repeat(TileProc proc, SkGradFixed dx, SkGradFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
do {
- unsigned fi = repeat_8bits(fx >> 8);
+ unsigned fi = repeat_8bits(SkGradFixedToFixed(fx) >> 8);
SkASSERT(fi <= 0xFF);
fx += dx;
*dstC++ = cache[toggle + fi];
@@ -223,15 +223,16 @@ void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
+ SkGradFixed dx, fx = SkScalarToGradFixed(srcPt.fX);
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed dxStorage[1];
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL);
- dx = dxStorage[0];
+ // todo: do we need a real/high-precision value for dx here?
+ dx = SkFixedToGradFixed(dxStorage[0]);
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = SkScalarToFixed(fDstToIndex.getScaleX());
+ dx = SkScalarToGradFixed(fDstToIndex.getScaleX());
}
LinearShadeProc shadeProc = shadeSpan_linear_repeat;
@@ -301,7 +302,7 @@ static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other,
#define NO_CHECK_ITER_16 \
do { \
- unsigned fi = fx >> SkGradientShaderBase::kCache16Shift; \
+ unsigned fi = SkGradFixedToFixed(fx) >> SkGradientShaderBase::kCache16Shift; \
SkASSERT(fi < SkGradientShaderBase::kCache16Count); \
fx += dx; \
*dstC++ = cache[toggle + fi]; \
@@ -310,22 +311,22 @@ static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other,
namespace {
-typedef void (*LinearShade16Proc)(TileProc proc, SkFixed dx, SkFixed fx,
+typedef void (*LinearShade16Proc)(TileProc proc, SkGradFixed dx, SkGradFixed fx,
uint16_t* dstC, const uint16_t* cache,
int toggle, int count);
-void shadeSpan16_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan16_linear_vertical(TileProc proc, SkGradFixed dx, SkGradFixed fx,
uint16_t* SK_RESTRICT dstC,
const uint16_t* SK_RESTRICT cache,
int toggle, int count) {
// we're a vertical gradient, so no change in a span
- unsigned fi = proc(fx) >> SkGradientShaderBase::kCache16Shift;
+ unsigned fi = proc(SkGradFixedToFixed(fx)) >> SkGradientShaderBase::kCache16Shift;
SkASSERT(fi < SkGradientShaderBase::kCache16Count);
dither_memset16(dstC, cache[toggle + fi],
cache[next_dither_toggle16(toggle) + fi], count);
}
-void shadeSpan16_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan16_linear_clamp(TileProc proc, SkGradFixed dx, SkGradFixed fx,
uint16_t* SK_RESTRICT dstC,
const uint16_t* SK_RESTRICT cache,
int toggle, int count) {
@@ -362,12 +363,12 @@ void shadeSpan16_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
}
}
-void shadeSpan16_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan16_linear_mirror(TileProc proc, SkGradFixed dx, SkGradFixed fx,
uint16_t* SK_RESTRICT dstC,
const uint16_t* SK_RESTRICT cache,
int toggle, int count) {
do {
- unsigned fi = mirror_bits(fx >> SkGradientShaderBase::kCache16Shift,
+ unsigned fi = mirror_bits(SkGradFixedToFixed(fx) >> SkGradientShaderBase::kCache16Shift,
SkGradientShaderBase::kCache16Bits);
SkASSERT(fi < SkGradientShaderBase::kCache16Count);
fx += dx;
@@ -376,12 +377,12 @@ void shadeSpan16_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx,
} while (--count != 0);
}
-void shadeSpan16_linear_repeat(TileProc proc, SkFixed dx, SkFixed fx,
+void shadeSpan16_linear_repeat(TileProc proc, SkGradFixed dx, SkGradFixed fx,
uint16_t* SK_RESTRICT dstC,
const uint16_t* SK_RESTRICT cache,
int toggle, int count) {
do {
- unsigned fi = repeat_bits(fx >> SkGradientShaderBase::kCache16Shift,
+ unsigned fi = repeat_bits(SkGradFixedToFixed(fx) >> SkGradientShaderBase::kCache16Shift,
SkGradientShaderBase::kCache16Bits);
SkASSERT(fi < SkGradientShaderBase::kCache16Count);
fx += dx;
@@ -410,19 +411,20 @@ void SkLinearGradient::LinearGradientContext::shadeSpan16(int x, int y,
if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
+ SkGradFixed dx, fx = SkScalarToGradFixed(srcPt.fX);
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed dxStorage[1];
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL);
- dx = dxStorage[0];
+ // todo: do we need a real/high-precision value for dx here?
+ dx = SkFixedToGradFixed(dxStorage[0]);
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = SkScalarToFixed(fDstToIndex.getScaleX());
+ dx = SkScalarToGradFixed(fDstToIndex.getScaleX());
}
LinearShade16Proc shadeProc = shadeSpan16_linear_repeat;
- if (fixed_nearly_zero(dx)) {
+ if (fixed_nearly_zero(SkGradFixedToFixed(dx))) {
shadeProc = shadeSpan16_linear_vertical;
} else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
shadeProc = shadeSpan16_linear_clamp;
« no previous file with comments | « src/effects/gradients/SkClampRange.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698