aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jumper/SkJumper_stages.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-06-22 11:00:17 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-22 19:46:51 +0000
commit0cc60b8bbd251efbeb374815395ea3e5fb62e184 (patch)
tree9c8cf5bd9610027a660ec5f34a5f4343a57f1176 /src/jumper/SkJumper_stages.cpp
parent915893167e69f79677b17f3f388072e65d80d083 (diff)
fix repeat/mirror sampling bleed
I think this has been broken since we tried to simplify this in https://skia-review.googlesource.com/16547 The HSW backend does still look a little wrong, but improved, and the others seem fixed. Can you see how this affects your test cases, layout tests, etc? BUG=skia:6783 Change-Id: I17957ac8100331bea5b64d674bf43105048b72f6 Reviewed-on: https://skia-review.googlesource.com/20548 Commit-Queue: Mike Klein <mtklein@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org> Reviewed-by: Herb Derby <herb@google.com>
Diffstat (limited to 'src/jumper/SkJumper_stages.cpp')
-rw-r--r--src/jumper/SkJumper_stages.cpp46
1 files changed, 28 insertions, 18 deletions
diff --git a/src/jumper/SkJumper_stages.cpp b/src/jumper/SkJumper_stages.cpp
index eae3cd84f1..44af125449 100644
--- a/src/jumper/SkJumper_stages.cpp
+++ b/src/jumper/SkJumper_stages.cpp
@@ -940,24 +940,34 @@ STAGE(store_f32) {
store4(ptr,tail, r,g,b,a);
}
-SI F clamp(F v, float limit) {
- return min(max(0, v), limit);
-}
-SI F repeat(F v, float limit) {
- return v - floor_(v/limit)*limit;
-}
-SI F mirror(F v, float limit) {
- return abs_( (v-limit) - (limit+limit)*floor_((v-limit)/(limit+limit)) - limit );
-}
-STAGE(clamp_x) { r = clamp (r, *(const float*)ctx); }
-STAGE(clamp_y) { g = clamp (g, *(const float*)ctx); }
-STAGE(repeat_x) { r = repeat(r, *(const float*)ctx); }
-STAGE(repeat_y) { g = repeat(g, *(const float*)ctx); }
-STAGE(mirror_x) { r = mirror(r, *(const float*)ctx); }
-STAGE(mirror_y) { g = mirror(g, *(const float*)ctx); }
-
-STAGE( clamp_x_1) { r = clamp (r, 1.0f); }
-STAGE(repeat_x_1) { r = repeat(r, 1.0f); }
+SI F ulp_before(F f) {
+ U32 bits = -1 + unaligned_load<U32>(&f);
+ return unaligned_load<F>(&bits);
+}
+
+SI F exclusive_clamp(F v, float limit) {
+ v = max(0,v);
+ return min(v, ulp_before(limit));
+}
+SI F exclusive_repeat(F v, float limit) {
+ v = v - floor_(v/limit)*limit;
+ return min(v, ulp_before(limit));
+}
+SI F exclusive_mirror(F v, float limit) {
+ v = abs_( (v-limit) - (limit+limit)*floor_((v-limit)/(limit+limit)) - limit );
+ return min(v, ulp_before(limit));
+}
+// Clamp x or y to [0,limit) == [0,limit - 1 ulp] (think, sampling from images).
+STAGE(clamp_x) { r = exclusive_clamp (r, *(const float*)ctx); }
+STAGE(clamp_y) { g = exclusive_clamp (g, *(const float*)ctx); }
+STAGE(repeat_x) { r = exclusive_repeat(r, *(const float*)ctx); }
+STAGE(repeat_y) { g = exclusive_repeat(g, *(const float*)ctx); }
+STAGE(mirror_x) { r = exclusive_mirror(r, *(const float*)ctx); }
+STAGE(mirror_y) { g = exclusive_mirror(g, *(const float*)ctx); }
+
+// Clamp x to [0,1], both sides exclusive (think, gradients).
+STAGE( clamp_x_1) { r = min(max(0, r), 1.0f); }
+STAGE(repeat_x_1) { r = r - floor_(r); }
STAGE(mirror_x_1) { r = abs_( (r-1.0f) - two(floor_((r-1.0f)*0.5f)) - 1.0f ); }
STAGE(luminance_to_alpha) {