clamp to [0,1] in all gradient tilers

Today gradient mirror and repeat don't explicitly clamp.  They work fine for
normal float values, but blow up with inputs like infinity and NaN, and
those aren't hard to construct with a combination of a funky matrix and
some squaring for xy -> radius.

So explicitly clamp in each of the three matrix tilers.

This should fix the fuzz at the associated bug.
Bug: skia:7093

Change-Id: Idd44e3c7a1ed95e2b1ace8eb953b62eddeb4e00e
Reviewed-on: https://skia-review.googlesource.com/55702
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
Mike Klein 2017-10-05 13:21:31 -04:00 committed by Skia Commit-Bot
parent eccda1ceca
commit a3b889514f
3 changed files with 8226 additions and 8125 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1073,10 +1073,13 @@ STAGE(repeat_y, const SkJumper_TileCtx* ctx) { g = exclusive_repeat(g, ctx); }
STAGE(mirror_x, const SkJumper_TileCtx* ctx) { r = exclusive_mirror(r, ctx); }
STAGE(mirror_y, const SkJumper_TileCtx* ctx) { g = exclusive_mirror(g, ctx); }
// Clamp x to [0,1], both sides exclusive (think, gradients).
STAGE( clamp_x_1, Ctx::None) { r = min(max(0, r), 1.0f); }
STAGE(repeat_x_1, Ctx::None) { r = r - floor_(r); }
STAGE(mirror_x_1, Ctx::None) { r = abs_( (r-1.0f) - two(floor_((r-1.0f)*0.5f)) - 1.0f ); }
// Clamp x to [0,1], both sides inclusive (think, gradients).
// Even repeat and mirror funnel through a clamp to handle bad inputs like +Inf, NaN.
SI F clamp_01(F v) { return min(max(0, v), 1); }
STAGE( clamp_x_1, Ctx::None) { r = clamp_01(r); }
STAGE(repeat_x_1, Ctx::None) { r = clamp_01(r - floor_(r)); }
STAGE(mirror_x_1, Ctx::None) { r = clamp_01(abs_( (r-1.0f) - two(floor_((r-1.0f)*0.5f)) - 1.0f )); }
STAGE(luminance_to_alpha, Ctx::None) {
a = r*0.2126f + g*0.7152f + b*0.0722f;