diff options
author | Mike Klein <mtklein@chromium.org> | 2017-08-01 14:51:44 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-08-01 19:15:33 +0000 |
commit | 249ee1f985b4bad78db2d5cfdd14ce38edb2c23a (patch) | |
tree | 3043344800e697bc29005d2e3a1b04b1c4c8fd09 /tests/SkRasterPipelineTest.cpp | |
parent | dff5d4368dde7f27870b30c3724a4acc702f879c (diff) |
clamp to 0 in repeat and mirror image tilers
If we were doing this math with real numbers or even just doubles, these
clamps wouldn't be necessary. But we're favoring speed over accuracy
here when we emulate fmod() and some of those inaccuracies end up with
values outside the [0,tile) range, negative!
To keep the spirit of fast over 100% accurate, I've just added a safety
clamp to 0. The case in the unit test now returns 0 where it should
really return something like 7 or 8, but at least we won't try to read
_way_ outside the image buffer.
BUG=chromium:749260
Change-Id: Ifc5cfe69798beccbb2a16547510158576e06eb3a
Reviewed-on: https://skia-review.googlesource.com/29580
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'tests/SkRasterPipelineTest.cpp')
-rw-r--r-- | tests/SkRasterPipelineTest.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/tests/SkRasterPipelineTest.cpp b/tests/SkRasterPipelineTest.cpp index bab3d5b63b..33e8b4fe15 100644 --- a/tests/SkRasterPipelineTest.cpp +++ b/tests/SkRasterPipelineTest.cpp @@ -262,3 +262,31 @@ DEF_TEST(SkRasterPipeline_2d, r) { REPORTER_ASSERT(r, ((rgba[2] >> 8) & 0xff) == 128); REPORTER_ASSERT(r, ((rgba[3] >> 8) & 0xff) == 128); } + +DEF_TEST(SkRasterPipeline_repeat_tiling, r) { + // Repeat tiling works roughly like + // v' = v - floor(v / limit) * limit + // + // If v = 19133558.0f and limit = 9.0f, that's + // + // v' = 19133558.0f - floor(19133558.0f / 9.0f) * 9.0f + // + // The problem comes with that division term. In infinite precision, + // that'd be 2125950 + 8/9, but the nearest float is 2125951.0f. + // + // Then 2125951.0f * 9.0f = 19133559.0f, which is greater than v, + // so v' becomes negative. :'( + + // Here's a regression test to make sure this doesn't happen. + float in [4] = {19133558.0f,0,0,0}; + float out[4 * SkJumper_kMaxStride]; + SkJumper_TileCtx tile = { 9.0f, 1/9.0f }; + + SkRasterPipeline_<256> p; + p.append(SkRasterPipeline::uniform_color, in); + p.append(SkRasterPipeline::repeat_x, &tile); + p.append(SkRasterPipeline::store_rgba, out); + p.run(0,0,1,1); + + REPORTER_ASSERT(r, 0.0f <= out[0] && out[0] < 9.0f); +} |