epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2011 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
tfarina@chromium.org | e4fafb1 | 2013-12-12 21:11:12 +0000 | [diff] [blame] | 7 | |
tfarina@chromium.org | 8f6884a | 2014-01-24 20:56:26 +0000 | [diff] [blame] | 8 | #include "SkRandom.h" |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 9 | #include "Test.h" |
rileya@google.com | 589708b | 2012-07-26 20:04:23 +0000 | [diff] [blame] | 10 | #include "gradients/SkClampRange.h" |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 11 | |
| 12 | static skiatest::Reporter* gReporter; |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 13 | #define R_ASSERT(cond) if (!(cond)) { \ |
| 14 | SkDebugf("%d: %s\n", __LINE__, #cond); \ |
| 15 | REPORTER_ASSERT(gReporter, cond); \ |
reed@google.com | 13659f1 | 2011-04-18 19:59:38 +0000 | [diff] [blame] | 16 | } |
| 17 | |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 18 | // Arbitrary sentinel values outside [0, 0xFFFF]. |
| 19 | static const int kV0 = -42, kV1 = -53, kRamp = -64; |
reed@google.com | 13659f1 | 2011-04-18 19:59:38 +0000 | [diff] [blame] | 20 | |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 21 | static void check_value(int64_t bigfx, int expected) { |
| 22 | if (bigfx < 0) { |
| 23 | R_ASSERT(expected == kV0); |
reed | 438b0d7 | 2014-12-19 07:40:26 -0800 | [diff] [blame] | 24 | } else if (bigfx > kFracMax_SkGradFixed) { |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 25 | R_ASSERT(expected == kV1); |
reed | 438b0d7 | 2014-12-19 07:40:26 -0800 | [diff] [blame] | 26 | } else if (bigfx == kFracMax_SkGradFixed) { |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 27 | // Either one is fine (and we do see both). |
| 28 | R_ASSERT(expected == kV1 || expected == kRamp); |
| 29 | } else { |
| 30 | R_ASSERT(expected == kRamp); |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 31 | } |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 32 | } |
| 33 | |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 34 | static void slow_check(const SkClampRange& range, |
reed | 438b0d7 | 2014-12-19 07:40:26 -0800 | [diff] [blame] | 35 | const SkGradFixed fx, SkGradFixed dx, int count) { |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 36 | SkASSERT(range.fCount0 + range.fCount1 + range.fCount2 == count); |
reed@google.com | 13659f1 | 2011-04-18 19:59:38 +0000 | [diff] [blame] | 37 | |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 38 | // If dx is large, fx will overflow if updated naively. So we use more bits. |
| 39 | int64_t bigfx = fx; |
| 40 | |
reed@google.com | 33a94e2 | 2014-04-18 19:36:22 +0000 | [diff] [blame] | 41 | for (int i = 0; i < range.fCount0; i++) { |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 42 | check_value(bigfx, range.fV0); |
| 43 | bigfx += dx; |
reed@google.com | 33a94e2 | 2014-04-18 19:36:22 +0000 | [diff] [blame] | 44 | } |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 45 | |
reed@google.com | 33a94e2 | 2014-04-18 19:36:22 +0000 | [diff] [blame] | 46 | for (int i = 0; i < range.fCount1; i++) { |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 47 | check_value(bigfx, kRamp); |
| 48 | bigfx += dx; |
reed@google.com | 33a94e2 | 2014-04-18 19:36:22 +0000 | [diff] [blame] | 49 | } |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 50 | |
reed@google.com | 33a94e2 | 2014-04-18 19:36:22 +0000 | [diff] [blame] | 51 | for (int i = 0; i < range.fCount2; i++) { |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 52 | check_value(bigfx, range.fV1); |
| 53 | bigfx += dx; |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 54 | } |
| 55 | } |
| 56 | |
tfarina@chromium.org | e4fafb1 | 2013-12-12 21:11:12 +0000 | [diff] [blame] | 57 | |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 58 | static void test_range(SkFixed fx, SkFixed dx, int count) { |
reed | 438b0d7 | 2014-12-19 07:40:26 -0800 | [diff] [blame] | 59 | const SkGradFixed gfx = SkFixedToGradFixed(fx); |
| 60 | const SkGradFixed gdx = SkFixedToGradFixed(dx); |
| 61 | |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 62 | SkClampRange range; |
reed | 438b0d7 | 2014-12-19 07:40:26 -0800 | [diff] [blame] | 63 | range.init(gfx, gdx, count, kV0, kV1); |
| 64 | slow_check(range, gfx, gdx, count); |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | #define ff(x) SkIntToFixed(x) |
| 68 | |
tfarina@chromium.org | e4fafb1 | 2013-12-12 21:11:12 +0000 | [diff] [blame] | 69 | DEF_TEST(ClampRange, reporter) { |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 70 | gReporter = reporter; |
| 71 | |
| 72 | test_range(0, 0, 20); |
| 73 | test_range(0xFFFF, 0, 20); |
| 74 | test_range(-ff(2), 0, 20); |
| 75 | test_range( ff(2), 0, 20); |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 76 | |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 77 | test_range(-10, 1, 20); |
| 78 | test_range(10, -1, 20); |
| 79 | test_range(-10, 3, 20); |
| 80 | test_range(10, -3, 20); |
reed@google.com | 13659f1 | 2011-04-18 19:59:38 +0000 | [diff] [blame] | 81 | |
| 82 | test_range(ff(1), ff(16384), 100); |
| 83 | test_range(ff(-1), ff(-16384), 100); |
| 84 | test_range(ff(1)/2, ff(16384), 100); |
benjaminwagner | 0b2a189 | 2015-11-11 08:46:34 -0800 | [diff] [blame] | 85 | test_range(ff(1)/2, ff(-16384), 100); |
reed@google.com | 13659f1 | 2011-04-18 19:59:38 +0000 | [diff] [blame] | 86 | |
commit-bot@chromium.org | e0e7cfe | 2013-09-09 20:09:12 +0000 | [diff] [blame] | 87 | SkRandom rand; |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 88 | |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 89 | // test non-overflow cases |
| 90 | for (int i = 0; i < 1000000; i++) { |
| 91 | SkFixed fx = rand.nextS() >> 1; |
| 92 | SkFixed sx = rand.nextS() >> 1; |
| 93 | int count = rand.nextU() % 1000 + 1; |
| 94 | SkFixed dx = (sx - fx) / count; |
| 95 | test_range(fx, dx, count); |
| 96 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 97 | |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 98 | // TODO(reed): skia:2481, fix whatever bug this is, then uncomment |
| 99 | /* |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 100 | // test overflow cases |
reed@google.com | 13659f1 | 2011-04-18 19:59:38 +0000 | [diff] [blame] | 101 | for (int i = 0; i < 100000; i++) { |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 102 | SkFixed fx = rand.nextS(); |
reed@google.com | 13659f1 | 2011-04-18 19:59:38 +0000 | [diff] [blame] | 103 | SkFixed dx = rand.nextS(); |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 104 | int count = rand.nextU() % 1000 + 1; |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 105 | test_range(fx, dx, count); |
| 106 | } |
commit-bot@chromium.org | 86398e5 | 2014-04-30 16:51:51 +0000 | [diff] [blame] | 107 | */ |
reed@google.com | 63c1ad8 | 2011-04-18 14:15:36 +0000 | [diff] [blame] | 108 | } |