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

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

Issue 1767163003: Use float rather than SkFixed for gradient TileProcs. (Closed) Base URL: https://skia.googlesource.com/skia@scalar-pin-to-fixed
Patch Set: Created 4 years, 9 months 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/SkGradientShaderPriv.h ('k') | src/effects/gradients/SkRadialGradient.cpp » ('j') | 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 15d461960dd8f6b97230d989bbce7d497bc7b660..b36c8f62bcf3c25d0fd15ed64f309f8200531738 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -5,6 +5,8 @@
* found in the LICENSE file.
*/
+#include "math.h"
+
#include "Sk4fLinearGradient.h"
#include "SkLinearGradient.h"
@@ -13,8 +15,10 @@
static const float kInv255Float = 1.0f / 255;
-static inline int repeat_8bits(int x) {
- return x & 0xFF;
+static inline int repeat_8bits(float x) {
+ float ignore;
+ const float frac = modff(x, &ignore);
+ return (int)(frac * 256) & 0xFF;
}
// Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly.
@@ -23,11 +27,13 @@ static inline int repeat_8bits(int x) {
#pragma optimize("", off)
#endif
-static inline int mirror_8bits(int x) {
- if (x & 256) {
- x = ~x;
+static inline int mirror_8bits(float x) {
+ const float x_mod_2 = fmod(x, 2.0f);
+ int x_9bits = (int)(x_mod_2 * 256);
+ if (x_9bits & 0x100) {
+ x_9bits = ~x_9bits;
}
- return x & 255;
+ return x_9bits & 0xFF;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
@@ -187,21 +193,21 @@ SkLinearGradient::LinearGradientContext::LinearGradientContext(
namespace {
-typedef void (*LinearShadeProc)(TileProc proc, SkGradFixed dx, SkGradFixed fx,
+typedef void (*LinearShadeProc)(TileProc proc, float dx, float 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, SkGradFixed dx, SkGradFixed fx,
+void shadeSpan_linear_vertical_lerp(TileProc proc, float dx, float 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(SkGradFixedToFixed(fx));
+ unsigned fullIndex = proc(fx);
unsigned fi = fullIndex >> SkGradientShaderBase::kCache32Shift;
unsigned remainder = fullIndex & ((1 << SkGradientShaderBase::kCache32Shift) - 1);
@@ -217,12 +223,12 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkGradFixed dx, SkGradFixed f
sk_memset32_dither(dstC, lerp, dlerp, count);
}
-void shadeSpan_linear_clamp(TileProc proc, SkGradFixed dx, SkGradFixed fx,
+void shadeSpan_linear_clamp(TileProc proc, float float_dx, float float_fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
SkClampRange range;
- range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1);
+ range.init(float_fx, float_dx, count, 0, SkGradientShaderBase::kCache32Count - 1);
range.validate(count);
if ((count = range.fCount0) > 0) {
@@ -234,7 +240,8 @@ void shadeSpan_linear_clamp(TileProc proc, SkGradFixed dx, SkGradFixed fx,
}
if ((count = range.fCount1) > 0) {
int unroll = count >> 3;
- fx = range.fFx1;
+ SkGradFixed fx = range.fFx1;
+ const SkGradFixed dx = SkFloatToGradFixed(float_dx);
for (int i = 0; i < unroll; i++) {
NO_CHECK_ITER; NO_CHECK_ITER;
NO_CHECK_ITER; NO_CHECK_ITER;
@@ -255,12 +262,12 @@ void shadeSpan_linear_clamp(TileProc proc, SkGradFixed dx, SkGradFixed fx,
}
}
-void shadeSpan_linear_mirror(TileProc proc, SkGradFixed dx, SkGradFixed fx,
+void shadeSpan_linear_mirror(TileProc proc, float dx, float fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
do {
- unsigned fi = mirror_8bits(SkGradFixedToFixed(fx) >> 8);
+ unsigned fi = mirror_8bits(fx);
SkASSERT(fi <= 0xFF);
fx += dx;
*dstC++ = cache[toggle + fi];
@@ -268,12 +275,12 @@ void shadeSpan_linear_mirror(TileProc proc, SkGradFixed dx, SkGradFixed fx,
} while (--count != 0);
}
-void shadeSpan_linear_repeat(TileProc proc, SkGradFixed dx, SkGradFixed fx,
+void shadeSpan_linear_repeat(TileProc proc, float dx, float fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
do {
- unsigned fi = repeat_8bits(SkGradFixedToFixed(fx) >> 8);
+ unsigned fi = repeat_8bits(fx);
SkASSERT(fi <= 0xFF);
fx += dx;
*dstC++ = cache[toggle + fi];
@@ -307,19 +314,18 @@ void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkGradFixed dx, fx = SkScalarToGradFixed(srcPt.fX);
+ float dx, fx = SkScalarToFloat(srcPt.fX);
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y));
- // todo: do we need a real/high-precision value for dx here?
- dx = SkScalarToGradFixed(step.fX);
+ dx = SkScalarToFloat(step.fX);
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = SkScalarToGradFixed(fDstToIndex.getScaleX());
+ dx = SkScalarToFloat(fDstToIndex.getScaleX());
}
LinearShadeProc shadeProc = shadeSpan_linear_repeat;
- if (0 == dx) {
+ if (SkScalarNearlyZero(dx)) {
shadeProc = shadeSpan_linear_vertical_lerp;
} else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
shadeProc = shadeSpan_linear_clamp;
@@ -334,7 +340,7 @@ void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
SkScalar dstY = SkIntToScalar(y);
do {
dstProc(fDstToIndex, dstX, dstY, &srcPt);
- unsigned fi = proc(SkScalarToFixed(srcPt.fX));
+ unsigned fi = proc(SkScalarToFloat(srcPt.fX));
SkASSERT(fi <= 0xFFFF);
*dstC++ = cache[toggle + (fi >> kCache32Shift)];
toggle = next_dither_toggle(toggle);
« no previous file with comments | « src/effects/gradients/SkGradientShaderPriv.h ('k') | src/effects/gradients/SkRadialGradient.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698