Artifacts and flickering when rendering gradients on webrender on android
Categories
(Core :: Graphics: WebRender, defect, P3)
Tracking
()
People
(Reporter: jnicol, Assigned: jnicol)
References
(Blocks 1 open bug)
Details
Attachments
(2 files)
As seen in bug 1499104, there were issues with gradients on webrender on android, noticable in the settings wheel on spiegel.de. This appeared to be fixed by webrender #3352. However, it doesn't seem to have fully fixed them. Since that landed, I can no longer reproduce by visiting spiegel.de on a fresh app launch. But if I visit reddit.com an issue is visible (see vertical stripes next to padlock icon in attachment). And after visiting reddit, it is easy to reproduce back on spiegel or a simple gradient testcase.
Assignee | ||
Comment 1•6 years ago
|
||
In fact, even just reloading spiegel.de is enough to break the gradient again - no need to visit reddit. It does seem to flicker less crazily than before, but it's definitely still broken.
Assignee | ||
Updated•6 years ago
|
Assignee | ||
Comment 2•6 years ago
|
||
The issue occurs when attempting to read gradient stops from the gpu cache at row 32 or greater (ie address >= 2^15). This is because on GLES GLSL ints are 16 bit, so we overflow and read from the wrong location in the gpu cache. If we use a highp int for the address that should fix this problem.
Updated•6 years ago
|
Comment 3•6 years ago
|
||
Assuming this happens on newer Adrenos as well since it sounds like a GLES thing.
Assignee | ||
Comment 4•6 years ago
|
||
Yes, it's a GLES spec thing rather than a device-specific driver bug. Affects most/all devices AFAIK, including the pixel 2.
Assignee | ||
Comment 5•6 years ago
|
||
I was wondering for a while why only gradients were affected and not other primitives, since they all need to fetch data from the gpu cache.
The reason is that linear and radial gradients are the only primitives which fetch data in the fragment shader, all others only do so in the vertex shader. For vertex shaders highp is the default, whereas mediump is the default for fragment shaders.
Assignee | ||
Comment 6•6 years ago
|
||
In GLES 3 GLSL, the default precision for ints is highp (32 bit) in
vertex shaders, but only mediump (16 bit) in fragment shaders.
To render linear and radial gradients the fragment shader must fetch
the gradient stops from the gpu cache, using an address variable. This
variable is a 16 bit int, so if the stops data is located at
too high an address (row 32 or greater) then this value will have
overflown and we fetch from the wrong location. This was resulting in
garbage being drawn instead of the correct gradients.
To fix this, any address used in a fragment shader must be marked as
highp. This includes the varying input which supplies the address, and
the arguments to any functions used for the fetch.
Pushed by jnicol@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/495ee696b110 Ensure address variables in fragment shaders are highp precision. r=gw
Comment 8•6 years ago
|
||
bugherder |
Updated•6 years ago
|
Description
•