diff options
author | Florin Malita <fmalita@chromium.org> | 2017-01-27 15:39:32 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-27 21:13:53 +0000 |
commit | 0bd8f36309293720b44af92f113f6ebe96d54779 (patch) | |
tree | 085a099af622bd60fad3420cd1d4a445728e5442 | |
parent | 86cc841e23a81af69269de87224c57be274f40d1 (diff) |
Add missing nextafter() clamping to SkLinearBitmapPipeline tile procs
Fixes the asserts trigered in
https://skia-review.googlesource.com/c/7615
Change-Id: I7e1802bc699becf85396445fe0df4cb110ab69c4
Reviewed-on: https://skia-review.googlesource.com/7720
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Herb Derby <herb@google.com>
-rw-r--r-- | src/core/SkLinearBitmapPipeline_tile.h | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/core/SkLinearBitmapPipeline_tile.h b/src/core/SkLinearBitmapPipeline_tile.h index 716b9bd14c..e18f7a1a5d 100644 --- a/src/core/SkLinearBitmapPipeline_tile.h +++ b/src/core/SkLinearBitmapPipeline_tile.h @@ -143,8 +143,10 @@ private: const SkScalar fYMaxPixel; }; -SkScalar tile_mod(SkScalar x, SkScalar base) { - return x - SkScalarFloorToScalar(x / base) * base; +SkScalar tile_mod(SkScalar x, SkScalar base, SkScalar cap) { + // When x is a negative number *very* close to zero, the difference becomes 0 - (-base) = base + // which is an out of bound value. The min() corrects these problematic values. + return std::min(x - SkScalarFloorToScalar(x / base) * base, cap); } class XRepeatStrategy { @@ -167,7 +169,7 @@ public: SkPoint start; SkScalar length; int count; std::tie(start, length, count) = originalSpan; // Make x and y in range on the tile. - SkScalar x = tile_mod(X(start), fXMax); + SkScalar x = tile_mod(X(start), fXMax, fXCap); SkScalar y = Y(start); SkScalar dx = length / (count - 1); @@ -261,7 +263,7 @@ public: SkPoint start; SkScalar length; int count; std::tie(start, length, count) = originalSpan; // Make x and y in range on the tile. - SkScalar x = tile_mod(X(start), fXMax); + SkScalar x = tile_mod(X(start), fXMax, fXCap); SkScalar y = Y(start); // No need trying to go fast because the steps are larger than a tile or there is one point. @@ -326,23 +328,25 @@ class YRepeatStrategy { public: YRepeatStrategy(int32_t max) : fYMax{SkScalar(max)} + , fYCap{SkScalar(nextafterf(SkScalar(max), 0.0f))} , fYsInvMax{1.0f / SkScalar(max)} { } void tileYPoints(Sk4s* ys) { Sk4s divY = *ys * fYsInvMax; Sk4s modY = *ys - divY.floor() * fYMax; - *ys = modY; + *ys = Sk4s::Min(fYCap, modY); assertTiled(*ys, fYMax); } SkScalar tileY(SkScalar y) { - SkScalar answer = tile_mod(y, fYMax); + SkScalar answer = tile_mod(y, fYMax, fYCap); SkASSERT(0 <= answer && answer < fYMax); return answer; } private: const SkScalar fYMax; + const SkScalar fYCap; const SkScalar fYsInvMax; }; // max = 40 |