Open Bug 1439292 Opened 7 years ago Updated 2 years ago

Find a more generic way to handle flattening of container display items

Categories

(Core :: Web Painting, enhancement, P3)

enhancement

Tracking

()

Tracking Status
firefox60 --- affected

People

(Reporter: mattwoodrow, Unassigned)

References

(Blocks 1 open bug)

Details

Flattening away inactive opacity items improves performance considerably, as can be seen by comparing these two testcases: https://mattwoodrow.github.io/dl-test/dl-test.html?count=5000&layer=inactive https://mattwoodrow.github.io/dl-test/dl-test.html?count=5000&layer=flattened The overhead of recursing into FrameLayerBuilder is considerable, and we're much better off when we can avoid it. The current approach checks for an inactive opacity item with 3 or less children, no intersections between the children and all children support rendering with a supplied opacity value. If that succeeds, we remove the opacity item, and tell the children to draw using the required opacity. I think instead of that, we could replace the opacity item with a new 'push opacity' and 'pop opacity item', and bring the children up into the outer list between the two new items. We'd also want to make sure the whole sequence gets assigned to the same PaintedLayer. That would be much more generic, as it would work with any number of children, and would work with all types of child display items, without needing to implement opacity overriding per-type. It's also much easier to extend to other container types, like masking, filtering and blend mode, so that we can do those cheaper as well. Finding a solution that works for transform as well would be nice, but the change in coordinate spaces makes it much more difficult. It's possible that we could handle translation-only transforms by telling FLB to apply an offset to every operation it does on a display item.
(In reply to Matt Woodrow (:mattwoodrow) from comment #0) > That would be much more generic, as it would work with any number of > children, and would work with all types of child display items, without > needing to implement opacity overriding per-type. Wouldn't we still need to have something like ApplyOpacity on e.g. nsDisplayBackgroundColor so that we can reap the painting benefits of not having an intermediate surface? (In reply to Matt Woodrow (:mattwoodrow) from comment #0) > Flattening away inactive opacity items improves performance considerably I assume this is just looking at the time spent in FrameLayerBuilder? I'm curious; instead of comparing inactive flattened opacity to inactive transforms, have you also compared it to inactive *non*-flattened opacity, e.g. by disabling the flattening code manually? Then we'd know what part of the difference comes from flattening vs what part comes from differences between transform and opacity.
(In reply to Markus Stange [:mstange] from comment #1) > (In reply to Matt Woodrow (:mattwoodrow) from comment #0) > > That would be much more generic, as it would work with any number of > > children, and would work with all types of child display items, without > > needing to implement opacity overriding per-type. > > Wouldn't we still need to have something like ApplyOpacity on e.g. > nsDisplayBackgroundColor so that we can reap the painting benefits of not > having an intermediate surface? Right, this proposal would give us a more generic way to skip the FrameLayerBuilder overhead of recursing into in inactive layer. We'd probably still want PaintItems to have the same logic for detecting when we have non-intersecting items that support ApplyOpacity, and using it to avoid the PushGroup. > > (In reply to Matt Woodrow (:mattwoodrow) from comment #0) > > Flattening away inactive opacity items improves performance considerably > > I assume this is just looking at the time spent in FrameLayerBuilder? > > I'm curious; instead of comparing inactive flattened opacity to inactive > transforms, have you also compared it to inactive *non*-flattened opacity, > e.g. by disabling the flattening code manually? Then we'd know what part of > the difference comes from flattening vs what part comes from differences > between transform and opacity. That's a good point, I'll test this out locally and put results up after my next meeting.
(In reply to Matt Woodrow (:mattwoodrow) from comment #2) > We'd probably still want PaintItems to have the same logic for detecting > when we have non-intersecting items that support ApplyOpacity, and using it > to avoid the PushGroup. Alternatively we could make gfxContext detect the PushGroup, <some non intersecting draw calls>, PopGroup pattern, and optimize it away, but that might be harder.
From a local build (with my patch queue of perf improvements): Flattening enabled: 60fps, 3.2ms DL, 6.4ms FLB, 1.0ms Raster Flattening disabled: 20fps, 3.2ms DL, 42ms FLB, 1.5ms Raster
What a massive difference!
Depends on: 1442190
Depends on: 1462672
Depends on: 1479091
Depends on: 1479092
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.