diff options
author | Mike Klein <mtklein@chromium.org> | 2016-12-13 15:44:23 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-13 22:09:57 +0000 |
commit | 04e10da8362a0dcabd795a4ad53f617719ca0d20 (patch) | |
tree | 203575b49fb941990f0a19b288b6c6cc1eef9388 /src/opts | |
parent | 21f783829619186442041de6008f7f58f4f6250d (diff) |
clamp to premul when reading premul sRGB
It's pretty easy to start with sound premultiplied linear floats, pack those to sRGB encoded bytes, then read them back to linear floats and find them not quite premultiplied, with a color channel just a smidge greater than the alpha channel. This can happen basically any time we have different transfer functions for alpha and colors... sRGB being the only one we draw into.
This is an annoying problem with no known good solution. So apply the clamp hammer.
These new calls on SkRasterPipeline should make it impossible to get wrong.
CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD
Change-Id: I4c974f4a7b151f3f684946f1e83d06b1b288fd01
Reviewed-on: https://skia-review.googlesource.com/5945
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/opts')
-rw-r--r-- | src/opts/SkRasterPipeline_opts.h | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h index 3cc3f2f01a..135d927b85 100644 --- a/src/opts/SkRasterPipeline_opts.h +++ b/src/opts/SkRasterPipeline_opts.h @@ -301,17 +301,23 @@ STAGE(clamp_0) { g = SkNf::Max(g, 0.0f); b = SkNf::Max(b, 0.0f); } +STAGE(clamp_1) { + a = SkNf::Min(a, 1.0f); + r = SkNf::Min(r, 1.0f); + g = SkNf::Min(g, 1.0f); + b = SkNf::Min(b, 1.0f); +} STAGE(clamp_a) { a = SkNf::Min(a, 1.0f); r = SkNf::Min(r, a); g = SkNf::Min(g, a); b = SkNf::Min(b, a); } -STAGE(clamp_1) { - a = SkNf::Min(a, 1.0f); - r = SkNf::Min(r, 1.0f); - g = SkNf::Min(g, 1.0f); - b = SkNf::Min(b, 1.0f); +STAGE(clamp_a_d) { + da = SkNf::Min(da, 1.0f); + dr = SkNf::Min(dr, da); + dg = SkNf::Min(dg, da); + db = SkNf::Min(db, da); } STAGE(unpremul) { |