Bug 1769082 - Avoid divide-by-zero in Skia's luminosity blend mode. r=jrmuizel,gfx-reviewers

This applies a fix that is present in Skia's HW luminosity blend mode to its
CPU pipeline so that the luminosity mode no longer divides by zero, thus avoiding
infs and nans.

Differential Revision: https://phabricator.services.mozilla.com/D149030
This commit is contained in:
Lee Salzman 2022-06-16 03:39:41 +00:00
parent 853b00c6ba
commit 5cf73489a8
5 changed files with 44 additions and 2 deletions

View File

@ -320,7 +320,9 @@ private:
V operator* (const SkNx<N,T>& x, T y) { return x * SkNx<N,T>(y); }
V operator/ (const SkNx<N,T>& x, T y) { return x / SkNx<N,T>(y); }
V operator& (const SkNx<N,T>& x, T y) { return x & SkNx<N,T>(y); }
V operator&&(const SkNx<N,T>& x, const SkNx<N,T>& y) { return x & y; }
V operator| (const SkNx<N,T>& x, T y) { return x | SkNx<N,T>(y); }
V operator||(const SkNx<N,T>& x, const SkNx<N,T>& y) { return x | y; }
V operator^ (const SkNx<N,T>& x, T y) { return x ^ SkNx<N,T>(y); }
V operator==(const SkNx<N,T>& x, T y) { return x == SkNx<N,T>(y); }
V operator!=(const SkNx<N,T>& x, T y) { return x != SkNx<N,T>(y); }

View File

@ -1595,8 +1595,8 @@ SI void clip_color(F* r, F* g, F* b, F a) {
l = lum(*r, *g, *b);
auto clip = [=](F c) {
c = if_then_else(mn >= 0, c, l + (c - l) * ( l) / (l - mn) );
c = if_then_else(mx > a, l + (c - l) * (a - l) / (mx - l), c);
c = if_then_else(mn < 0 && l != mn, l + (c - l) * ( l) / (l - mn), c);
c = if_then_else(mx > a && l != mx, l + (c - l) * (a - l) / (mx - l), c);
c = max(c, 0); // Sometimes without this we may dip just a little negative.
return c;
};

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<div style="width: 100px; height: 100px;">
<canvas id="c" width="100" height="100"></canvas>
</div>
<script>
var ctx = document.getElementById('c').getContext('2d');
var grd = ctx.createLinearGradient(0, 0, 100, 0);
grd.addColorStop(0, 'black');
grd.addColorStop(1, 'white');
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 100, 100);
ctx.globalAlpha = 0.8;
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 100, 100);
</script>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset="utf-8">
<div style="width: 100px; height: 100px;">
<canvas id="c" width="100" height="100"></canvas>
</div>
<script>
var ctx = document.getElementById('c').getContext('2d');
var grd = ctx.createLinearGradient(0, 0, 100, 0);
grd.addColorStop(0, 'black');
grd.addColorStop(1, 'white');
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 100, 100);
ctx.globalCompositeOperation = 'luminosity';
ctx.globalAlpha = 0.8;
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 100, 100);
</script>

View File

@ -2116,6 +2116,7 @@ pref(image.downscale-during-decode.enabled,true) == 1744468-1.html 1744468-1-ref
== 1747272-1.html 1747272-1-ref.html
== 1750146-1.html 1750146-1-ref.html
== 1735265-1.html 1735265-1-ref.html
fuzzy(0-1,0-1000) == 1769082-1.html 1769082-1-ref.html
== 1773484.html 1773484-ref.html
# The following tests are skipped on Android since Android doesn't deal very