Render gradients from gradient stops directly
Categories
(Core :: Graphics: WebRender, enhancement)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox150 | --- | fixed |
People
(Reporter: nical, Assigned: nical)
References
(Blocks 2 open bugs, Regressed 1 open bug)
Details
(Keywords: perf-alert)
Attachments
(25 files, 2 obsolete files)
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
dmeehan
:
approval-mozilla-beta+
|
Details | Review |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review |
WebRender's gradient shaders work with a fixed size table of something that could be thought of as "quantized evenly-spaced gradient stops". It is very fast to evaluate even when the number of stops is high, but it causes many correctness issues that are fundamentally not fixable using this approach.
In some cases it is because the quantization mises high-frequency details, in other cases it is because it shifts the gradient stops slightly, in a way that is very noticeable for axis-aligned hard stops.
Instead we need a way to render the gradient stops directly in the fragment shader without making any quality compromises, potentially at an extra cost. Hopefully we can offset that cost using one or two fast paths for gradients with few stops.
Skia renders gradients this way, and so should we.
| Assignee | ||
Comment 1•1 year ago
|
||
This patch replaces the quad radial and conic gradient shaders with a single shader that can do all css gradients.
The new shader also has a fast path for gradients with no more than two gradient stops: in this configuration, all of the data needed by the fragment shader is passed via varying, which yields significant speedups over reading them from the gpu buffer for each fragment.
The slow path performs a linear search in the gradient stop offsets to find the pair affecting the current pixel. This starts fairly cheap for 4 stops or less as the first 4 stops are also provded via varyings in the slow path, and gets more expensive for each new quadruplet of gradient stops. The assumption here that the vast majority of gradients use less than 8 stops.
In the slow path, once the pair of gradient stop offsets has been computed, the color pair is read from the gpu buffer.
| Assignee | ||
Updated•1 year ago
|
Comment 2•1 year ago
|
||
The vast majority of gradients do use less than 8 stops except when you consider gradients in the linearRGB (or other non-sRGB) color space. To support those colour spaces we add lots of additional gradient stops.
https://searchfox.org/mozilla-central/source/layout/painting/nsCSSRenderingGradients.h#121
https://searchfox.org/mozilla-central/source/layout/painting/nsCSSRenderingGradients.h#53
| Assignee | ||
Comment 3•1 year ago
|
||
Updated•1 year ago
|
| Assignee | ||
Comment 4•1 year ago
|
||
Updated•1 year ago
|
| Assignee | ||
Comment 5•1 year ago
|
||
That will let us gradually enable it.
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Comment 9•11 months ago
|
||
This change simplifies the followup patch that will implement a tree traversal of stop offsets.
| Assignee | ||
Comment 10•11 months ago
|
||
This patch changes the gradient stop search on the GPU from a linear search to a tree traversal. This drastically reduces the number of gpu buffer reads when there is a lot of gradient stops. An added benefit is that the linear search required non-uniform loop control flow which SWGL currently does not handle (loop that can be exited by some lanes before others). The loop of the tree traversal is uniform which lets SWGL produce correct code.
The tree traversal requires laying out the stops in the gpu buffer in a specific way.
However, the hand-rolled SWGL gradient span shaders benefit enormously from doing an incremental linear search so we keep the linear order of the stops offsets when we know that a span shader will be used.
| Assignee | ||
Comment 11•11 months ago
|
||
| Assignee | ||
Comment 12•11 months ago
|
||
| Assignee | ||
Comment 13•11 months ago
|
||
Updated•11 months ago
|
Comment 14•11 months ago
|
||
Comment 15•11 months ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/59c8e0aa54c7
https://hg.mozilla.org/mozilla-central/rev/732ccd085a20
https://hg.mozilla.org/mozilla-central/rev/f9b3a359e818
https://hg.mozilla.org/mozilla-central/rev/7acb74624df3
https://hg.mozilla.org/mozilla-central/rev/4f168e228a41
https://hg.mozilla.org/mozilla-central/rev/dfa179add631
Comment 16•11 months ago
|
||
Comment 17•11 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 18•11 months ago
|
||
- There were a few leftover comments referring to the merge step which is not needed in this version of the shader.
- Removed a few unused variables also orphaned by the absence of the merge step.
- Renamed radius into startRadius
| Assignee | ||
Comment 19•11 months ago
|
||
This is already covered by wrench tests and makes them pass with the new (currently preffed off) code path.
| Assignee | ||
Comment 20•11 months ago
|
||
The code was incorrectly assuming that one could simply update dotPos and dotPosDelta for partial chunks by dividing by the chunk size and multiplying by the number of pixels in the partial chunk. That's true for dotPosDelta but not for dotPos where there is a compounding effect with each iteration feeding back into the next in a way that makes things non-linear. There has to be a more elegant solution but after many failed attempts I ended up expressing it in terms of a single-pixel step applied multiple times depending on the number of pixels in the partial chunk. It should be pretty fast still and this way the math looks similar to the whole-chunk steps.
In addition, the patch rounds endT up so that we go all the way to the next pixel that is in a different stop pair rather than stopping one pixel before. This removes a lot of unnecessary partial chunks. Before that, we would round endT down which meant that in the next sub-span we would still be in the same gradient stop pair and advance by a pixel before stepping into the next stop pair.
| Assignee | ||
Comment 21•11 months ago
|
||
A followup patch will enable this for SWGL.
| Assignee | ||
Comment 22•11 months ago
|
||
| Assignee | ||
Comment 23•11 months ago
|
||
A followup patch will enable this for SWGL.
| Assignee | ||
Comment 24•11 months ago
|
||
| Assignee | ||
Comment 25•11 months ago
|
||
A followup patch will enable this for SWGL.
Comment 26•11 months ago
|
||
Comment 27•11 months ago
|
||
| bugherder | ||
Comment 28•11 months ago
|
||
Comment 29•11 months ago
|
||
| bugherder | ||
Comment 30•10 months ago
|
||
Comment 31•10 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 32•10 months ago
|
||
| Assignee | ||
Comment 33•10 months ago
|
||
| Assignee | ||
Comment 34•10 months ago
|
||
| Assignee | ||
Comment 35•10 months ago
|
||
The existing function is overly conservative for precise gradients because the latter require less storage per gradient stop.
Comment 36•10 months ago
|
||
Comment 37•10 months ago
|
||
Comment 38•10 months ago
|
||
Backed out for causing wrench failures complaining about atomic.h.
Backout link: https://hg-edge.mozilla.org/integration/autoland/rev/17fb42d96b619d3d8fc124991d798cf24d0f9c91
Comment 39•10 months ago
|
||
| Assignee | ||
Updated•10 months ago
|
Comment 40•10 months ago
|
||
Comment 41•10 months ago
|
||
| bugherder | ||
Comment 42•10 months ago
|
||
Comment 43•10 months ago
|
||
| bugherder | ||
Comment 44•10 months ago
|
||
Comment 45•10 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 46•9 months ago
|
||
Precise gradients have a SWGL-specific optimization to speed up the gradient stop lookup. This was implemented in a way that requires SWGL to use the span shader only, since the fallback code uses a different stop representation (the one that works better on GPU but doesn't allow incrementally searching for stops). Unfortunately I discovered late that span shaders are only run on full sized chunks. The Remaining pixels are always going through the (incompatible) fallback. This was caught by tests on the linear gradients but by the time I got to that, radial and conic gradients had already landed.
Until I have a fix for the partial chunk situation, precise gradients will have to be disabled on SWGL.
| Assignee | ||
Comment 47•9 months ago
|
||
This patch replaces the linear search in the new SWGL gradient paths with the same tree traversal as the GPU version.
The linear version had the advantage of being incremental, so within a span, searches were very fast after the first one. Unfortunately it required the SWGL and GPU paths to use different representations for gradient stop offsets which led to issues when accidentally falling back to the translated glsl code in SWGL.
This version is not incremental so we do the full search each time the span crosses a new gradient stop. This should only matter when the number of gradient stops is high. The tree structure very aggressively converges, though. For example it takes 3 iterations to find a pair in a 124 stops gradient.
Comment 48•9 months ago
|
||
Comment 49•9 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 50•9 months ago
|
||
Comment on attachment 9529020 [details]
Bug 1978773 - Temporarily disable precise gradients in SWGL. r=#gfx-reviewers
Beta/Release Uplift Approval Request
- User impact if declined/Reason for urgency: Incorrect rendering of radial gradients when using software WebRender
- Is this code covered by automated tests?: No
- Has the fix been verified in Nightly?: Yes
- Needs manual test from QE?: No
- If yes, steps to reproduce:
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): It's a backout of a recent pref flip. It reverts to well known code paths.
- String changes made/needed:
- Is Android affected?: Yes
Comment 51•9 months ago
|
||
| Assignee | ||
Comment 52•9 months ago
|
||
Comment 53•9 months ago
•
|
||
:nical, it's tricky to follow the bug meta data since it's in a leave open state.
Can you confirm only that one pref flip is needed for Fx146?
There is only one beta build left for Fx146 and we go to RC next week
Comment 54•9 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 55•9 months ago
|
||
(In reply to Donal Meehan [:dmeehan] from comment #53)
:nical, it's tricky to follow the bug meta data since it's in a leave open state.
Can you confirm only that one pref flip is needed for Fx146?
There is only one beta build left for Fx146 and we go to RC next week
Both gfx.webrender.precise-radial-gradients-swgl and gfx.webrender.precise-conic-gradients-swgl should be set to false in beta.
Comment 56•9 months ago
|
||
Comment on attachment 9529020 [details]
Bug 1978773 - Temporarily disable precise gradients in SWGL. r=#gfx-reviewers
Approved for 146.0b9
Comment 57•9 months ago
|
||
| uplift | ||
Comment 58•9 months ago
|
||
Comment 59•9 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 60•8 months ago
|
||
They can be reenabled now that they are cached.
Comment 61•8 months ago
|
||
Comment 62•8 months ago
|
||
| bugherder | ||
Comment 63•8 months ago
|
||
Comment 64•8 months ago
|
||
Comment 65•8 months ago
|
||
Backed out for causing reftest failures on aja-linear-5a.html
Comment 66•8 months ago
|
||
Comment 67•8 months ago
|
||
Comment 68•8 months ago
|
||
Backed out for causing unexpected passes on aja-linear-5a.html
| Assignee | ||
Comment 69•8 months ago
|
||
| Assignee | ||
Updated•8 months ago
|
Comment 70•8 months ago
|
||
Comment 71•8 months ago
|
||
| bugherder | ||
Comment 72•8 months ago
|
||
(In reply to Pulsebot from comment #58)
Pushed by nsilva@mozilla.com:
https://github.com/mozilla-firefox/firefox/commit/585dadcba78a
https://hg.mozilla.org/integration/autoland/rev/fef66115a015
Reenable precise gradients with SWGL. r=gfx-reviewers,jnicol
Perfherder has detected a talos performance change from push fef66115a015e98adc6b55259774524a8eb07eed.
No action is required from the author; this comment is provided for informational purposes only.
Improvements:
| Ratio | Test | Platform | Options | Absolute values (old vs new) |
|---|---|---|---|---|
| 8% | rasterflood_gradient | linux1804-64-shippable-qr | e10s fission stylo webrender-sw | 1,068.00 -> 1,156.92 |
Need Help or Information?
If you have any questions, please reach out to afinder@mozilla.com. Alternatively, you can find help on Slack by joining #perf-help, and on Matrix you can find help by joining #perftest.
Details of the alert can be found in the alert summary, including links to graphs and comparisons for each of the affected tests.
Updated•8 months ago
|
| Assignee | ||
Comment 73•6 months ago
|
||
This reflects a change that happened in an previous patch in this series.
Comment 74•6 months ago
|
||
Comment on attachment 9543535 [details]
Bug 1978773 - Rename ClipSpace::Raster into ClipSpace::Device. r=gw
Revision D282387 was moved to bug 1998432. Setting attachment 9543535 [details] to obsolete.
Comment 75•6 months ago
|
||
Comment 76•6 months ago
|
||
Comment 77•6 months ago
•
|
||
Backed out for causing failures at border-gradient-nine-patch.yaml.
Backout link: https://hg.mozilla.org/integration/autoland/rev/844fb16c6ad5
Failure log:
https://treeherder.mozilla.org/logviewer?job_id=548830517&repo=autoland&task=Hzru5tr5T4OjJywPd0r7Fw.0&lineNumber=34184
https://treeherder.mozilla.org/logviewer?job_id=548830793&repo=autoland&task=HfIMmpGWQgqCySvdoTyDDQ.0&lineNumber=2357
Updated•6 months ago
|
Comment 78•6 months ago
|
||
Comment 79•6 months ago
|
||
Comment 80•6 months ago
|
||
Backed out for causing build bustages
Backout link: https://hg.mozilla.org/integration/autoland/rev/b434689e8b862bc3b7f528c1653aced071538478
Failure log -> ERROR - error: no rules expected "gfx.webrender.precise-radial-gradients-swgl"
Comment 81•6 months ago
|
||
Comment 82•6 months ago
|
||
| bugherder | ||
| Assignee | ||
Updated•6 months ago
|
Comment 83•6 months ago
|
||
Comment 85•6 months ago
|
||
| bugherder | ||
Comment 87•6 months ago
|
||
This is leave-open but it looks like all of the patches have landed. Maybe this should be closed as FIXED? (unless backing out turns out to be the fix for regression bug 2019872)
| Assignee | ||
Comment 88•6 months ago
|
||
Indeed. Let's close (and potentially reopen later if I can't figure out the bug 2019872 soon enough).
Updated•6 months ago
|
Updated•5 months ago
|
Description
•