Closed Bug 1480155 Opened 6 years ago Closed 5 years ago

Use set_image_visible_area API to optimize invalidations on large fallback display items

Categories

(Core :: Graphics: WebRender, enhancement, P4)

enhancement

Tracking

()

RESOLVED FIXED
Tracking Status
firefox63 --- affected

People

(Reporter: mstange, Unassigned)

References

Details

If you have a display item that uses fallback, such as a border-image display item, and this item is very tall, then we currently repaint the entire thing over and over as you scroll past it and the display port moves.

Here's an example page with such an item: http://www.twobraids.com/2018/07/things-gateway-bonding-phillips-hue.html

We should optimize this scrolling case so that we only invalidate the parts that are coming into view. On the Gecko side, this means:
 - Create the blob image sized to the entire bounds of the display item (not just to its clipped bounds)
 - Call set_image_visible_area with the item's paint rect.

(It's possible that we're already doing this.)

On the WebRender side, this means:
 - Finish the implementation of retaining + invalidation for blobs + set_image_visible_area.
Priority: -- → P3
Using the pref gfx.webrender.blob.paint-flashing, we can see that this isn't working at the moment. For example, there's a long border image fallback item on jvns.ca, and we seem to be painting the entire thing (even the parts outside the display port) on pageload:

Medium-length page: https://jvns.ca/blog/2018/01/15/should-i-pause-a-ruby-process-to-collect-its-stack/
Long page: https://jvns.ca/blog/2018/01/13/rust-in-2018--way-easier-to-use/

On the medium-length page, I see one paint flashing highlight color covering the entire item, and it never flashes during scrolling. But that item isn't completely contained in the display port. So I would expect parts of it to be repainted as those parts re-enter the display port.

On the long page, the fallback item uses tiling: The different tiles show different paint flashing highlight colors. But tiles that leave the display port never seem to be repainted. If I scroll all the way to the bottom and then back all the way to the top, the tiles at the top still have the same highlight color as before.

Unfortunately there's no APZ minimap with WebRender, so I used a non-WebRender build on the same pages to verify the size of the display port.
Priority: P3 → P4
Markus -- How bad is this in practice?  This sounds like an optimization to me that can move to stage-wr-next.  Am I right or wrong?  Thanks.
Flags: needinfo?(mstange)
I haven't seen any egregiously bad cases yet. Even the page in comment 0 seems to perform mostly fine on my machine; it's a bit janky and it uses about 300MB of memory after scrolling, but the performance is acceptable. However, this bug is a case of unbounded resource usage, and all it takes for it to be a real problem is one page that happens to have a very large element that uses fallback. As such, I think it's still worth blocking on.

For example, with this testcase I can make memory usage go up by two gigabytes just by scrolling up and down a bit:
data:text/html,<div style="border: 10px solid; border-image: linear-gradient(red, black) 10; height: 100000px">
Fortunately the memory usage goes back down after switching tabs.
Flags: needinfo?(mstange)

I fixed this with a patch on bug 1494924

Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.