aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/SkRasterPipelineTest.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-08-01 14:51:44 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-01 19:15:33 +0000
commit249ee1f985b4bad78db2d5cfdd14ce38edb2c23a (patch)
tree3043344800e697bc29005d2e3a1b04b1c4c8fd09 /tests/SkRasterPipelineTest.cpp
parentdff5d4368dde7f27870b30c3724a4acc702f879c (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.cpp28
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);
+}