Bug 1624468 - Add a fast path for more gradient types in WR

2020-03-30

Today's list...

Hardstop support

Allow gradients with hard stops to be cached.

Setup

testcases/linear-hardstops.yaml

 1     - type: gradient
 2       bounds: 0 0 1920 1080
 3       start: 0 0
 4       end: 1920 0
 5       stops: [0.0, red,
 6               0.2, [100,  50,  50, 1],
 7               0.4, red,
 8               0.4, green,
 9               0.5, [ 50, 100,  50, 1],
10               0.6, green,
11               0.6, blue,
12               0.8, [ 50,  50, 100, 1],
13               1.0, blue ]
testcases/linear-hardstops.png

RenderDoc

Cache:

cached_hardstops_gradient.png

Drawcalls:

cached_hardstops_drawcalls.png

Hardstop clipping

Support and verify that invisible segments don't go into the gradient cache and don't emit a blit.

Setup

testcases/linear-hardstops-zoomed.yaml

 1     - type: gradient
 2       bounds: 0 0 1920 1080
 3       start: -4000 0
 4       end: 5920 0
 5       stops: [0.0, red,
 6               0.2, [100,  50,  50, 1],
 7               0.4, red,
 8               0.4, green,
 9               0.5, [ 50, 100,  50, 1],
10               0.6, green,
11               0.6, blue,
12               0.8, [ 50,  50, 100, 1],
13               1.0, blue ]
testcases/linear-hardstops-zoomed.png

RenderDoc

Cache:

cached_hardstops_zoomed_gradient.png

Drawcalls:

cached_hardstops_zoomed_drawcalls.png

Removing hacks -- vertical gradient test

Remove hardcoded hacks assuming horizontal gradient etc.

Setup

testcases/linear-smooth-too-many-stops-non-uniform-vertical.yaml

 1     - type: gradient
 2       bounds: 0 0 1920 1080
 3       start: 0 -300
 4       end:  0 1380
 5       stops: [0.0, red,
 6               0.4, green,
 7               0.5, blue,
 8               0.6, [140,40,40,1],
 9               1.0, [10,200,190,1]]

Result:

testcases/linear-smooth-too-many-stops-non-uniform-vertical.png

(Remove blue for comparison):

testcases/vertical_4stop_ref.png

RenderDoc

Cache:

cached_smooth_vertical_gradient.png

Drawcalls:

cached_smooth_vertical_drawcalls.png

Clipping test

Add a clipping test to verify this seems to work.

testcases/linear-smooth-too-many-stops-non-uniform-vertical-clip.yaml

 1     - type: gradient
 2       bounds: 0 0 1920 1080
 3       start: 0 -300
 4       end:  0 1380
 5       stops: [0.0, red,
 6               0.4, green,
 7               0.5, blue,
 8               0.6, [140,40,40,1],
 9               1.0, [10,200,190,1]]
10       complex-clip:
11         rect: [200, 200, 1520, 680]
12         radius: [64, 64]
testcases/linear-smooth-too-many-stops-non-uniform-vertical-clip.png

RefTests

5 stops

reftest/gradient_cache_5stops.yaml

Test Reference
 1     - type: gradient
 2       bounds: 0 0 1980 1080
 3       start: 0 0
 4       end: 1980 0
 5       stops: [0.0, red,
 6               0.25, green,
 7               0.5, blue,
 8               0.75, [40,40,40,1],
 9               1.0, [100,200,50,1]]
 1     - type: gradient
 2       bounds: 0 0 960 1080
 3       start: 0 0
 4       end: 960 0
 5       stops: [0.0, red,
 6               0.5, green,
 7               1.0, blue]
 8     - type: gradient
 9       bounds: 960 0 960 1080
10       start: 0 0
11       end: 960 0
12       stops: [ 0.0, blue,
13               0.5, [40,40,40,1],
14               1.0, [100,200,50,1]]
reftest/gradient_cache_5stops.png reftest/gradient_cache_5stops_ref.png

(TODO extract and make standalone and add the WebGL diff viewer I did for reftest analyzer)

Hardstops

reftest/gradient_cache_hardstop.yaml

Test Reference
 1     - type: gradient
 2       bounds: 0 0 1920 1080
 3       start: 0 0
 4       end: 1920 0
 5       stops: [0.0, red,
 6               0.125, yellow,
 7               0.25, red,
 8               0.25, green,
 9               0.375, yellow,
10               0.5, green,
11               0.5, blue,
12               0.625, yellow,
13               0.75, blue,
14               0.75, white,
15               1.0, [100,200,50,1]]
 1     - type: gradient
 2       bounds: 0 0 960 1080
 3       start: 0 0
 4       end: 960 0
 5       stops: [0.0, red,
 6               0.25, yellow,
 7               0.5, red,
 8               0.5, green,
 9               0.75, yellow,
10               1.0, green]
11     - type: gradient
12       bounds: 960 0 960 1080
13       start: 0 0
14       end: 960 0
15       stops: [0.0, blue,
16               0.25, yellow,
17               0.5, blue,
18               0.5, white,
19               1.0, [100,200,50,1]]
reftest/gradient_cache_hardstop.png reftest/gradient_cache_hardstop_ref.png

5 stops Vertical

reftest/gradient_cache_5stops_vertical.yaml

Test Reference
 1     - type: gradient
 2       bounds: 0 0 1980 1080
 3       start: 0 0
 4       end: 0 1080
 5       stops: [0.0, red,
 6               0.25, green,
 7               0.5, blue,
 8               0.75, [40,40,40,1],
 9               1.0, [100,200,50,1]]
 1     - type: gradient
 2       bounds: 0 0 1920 540
 3       start: 0 0
 4       end: 0 540
 5       stops: [0.0, red,
 6               0.5, green,
 7               1.0, blue]
 8     - type: gradient
 9       bounds: 0 540 1920 1080
10       start: 0 0
11       end: 0 540
12       stops: [ 0.0, blue,
13               0.5, [40,40,40,1],
14               1.0, [100,200,50,1]]
reftest/gradient_cache_5stops_vertical.png reftest/gradient_cache_5stops_vertical_ref.png

Hardstops Clipped

reftest/gradient_cache_hardstop_clip.yaml

Test Reference
 1     - type: gradient
 2       bounds: 0 0 1920 1080
 3       start: 0 0
 4       end: 1920 0
 5       stops: [0.0, red,
 6               0.125, yellow,
 7               0.25, red,
 8               0.25, green,
 9               0.375, yellow,
10               0.5, green,
11               0.5, blue,
12               0.625, yellow,
13               0.75, blue,
14               0.75, white,
15               1.0, [100,200,50,1]]
16       complex-clip:
17         rect: [200, 200, 1520, 680]
18         radius: [64, 64]
 1     - type: gradient
 2       bounds: 0 0 960 1080
 3       start: 0 0
 4       end: 960 0
 5       stops: [0.0, red,
 6               0.25, yellow,
 7               0.5, red,
 8               0.5, green,
 9               0.75, yellow,
10               1.0, green]
11       complex-clip:
12         rect: [200, 200, 1520, 680]
13         radius: [64, 64]
14     - type: gradient
15       bounds: 960 0 960 1080
16       start: 0 0
17       end: 960 0
18       stops: [0.0, blue,
19               0.25, yellow,
20               0.5, blue,
21               0.5, white,
22               1.0, [100,200,50,1]]
23       complex-clip:
24         rect: [200, 200, 1520, 680]
25         radius: [64, 64]
reftest/gradient_cache_hardstop_clip.png reftest/gradient_cache_hardstop_clip_ref.png

Other

Reftests caught a regression in gradient\linear-clamp-1a.yaml. Final stop needs to be repeated infinitely apparently. Adding more reftests (same problem likely to exist when clamping before offset 0):

reftest/gradient_cache_clamp.yaml

Test Reference
 1     - type: gradient
 2       bounds: 0 0 400 200
 3       start: 0 100
 4       end: 100 100
 5       stops: [0.0, blue, 1.0, blue, 1.0, red]
 6     - type: gradient
 7       bounds: 0 300 400 200
 8       start: 100 100
 9       end: 200 100
10       stops: [0.0, blue, 1.0, blue, 1.0, red]
11     - type: gradient
12       bounds: 0 600 200 400
13       start: 0 100
14       end: 0 300
15       stops: [
16           0.0,  blue,
17           1.0,  red]
 1     - type: gradient
 2       bounds: 0 0 400 200
 3       start: 0 100
 4       end: 400 100
 5       stops: [
 6           0.0,  blue,
 7           0.25, blue,
 8           0.25, red,
 9           1.0,  red]
10     - type: gradient
11       bounds: 0 300 400 200
12       start: 0 100
13       end: 400 100
14       stops: [
15             0.0, blue,
16             0.5, blue,
17             0.5, red,
18             1.0, red]
19     - type: gradient
20       bounds: 0 600 200 400
21       start: 0 0
22       end: 0 400
23       stops: [
24           0.0,  blue,
25           0.25,  blue,
26           0.75,  red,
27           1.0,  red]
reftest/gradient_cache_clamp.png reftest/gradient_cache_clamp_ref.png

Benchmarks

Quadro P400

Above reftests, all but clip is repeated 10 times (clip is slow enough as it is).

benchmarks/2.out_p400/timings.svg

.