Bug 229802 - [Performance] Self painting layers spend too much time in RenderLayer::collectFragments
Summary: [Performance] Self painting layers spend too much time in RenderLayer::collec...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: WebKit Local Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: cathiechen
URL:
Keywords: InRadar
Depends on: 233684
Blocks:
  Show dependency treegraph
 
Reported: 2021-09-02 05:52 PDT by cathiechen
Modified: 2021-12-13 01:09 PST (History)
15 users (show)

See Also:


Attachments
screen-shot-collectFragments-cost (1.11 MB, image/png)
2021-09-02 05:58 PDT, cathiechen
no flags Details
test-change-first-child-height.html (1.67 KB, text/html)
2021-09-02 06:00 PDT, cathiechen
no flags Details
Patch (4.64 KB, patch)
2021-09-02 10:11 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch (4.61 KB, patch)
2021-09-05 20:36 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch (9.29 KB, patch)
2021-09-08 00:46 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch (9.41 KB, patch)
2021-09-09 09:41 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch (9.47 KB, patch)
2021-09-09 19:04 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch (8.53 KB, patch)
2021-09-11 09:11 PDT, cathiechen
no flags Details | Formatted Diff | Diff
screenshot-of-optimized-collectFragments (1.09 MB, image/png)
2021-09-11 09:18 PDT, cathiechen
no flags Details
screenshot-of-original-collectFragments (1.10 MB, image/png)
2021-09-11 09:18 PDT, cathiechen
no flags Details
Patch (8.56 KB, patch)
2021-09-15 02:49 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch (13.57 KB, patch)
2021-09-24 10:45 PDT, cathiechen
no flags Details | Formatted Diff | Diff
screenshot-of-optimized-collectFragments (1.57 MB, image/png)
2021-09-27 01:18 PDT, cathiechen
no flags Details
Patch (12.06 KB, patch)
2021-09-27 01:24 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch-for-review (9.92 KB, patch)
2021-09-28 03:25 PDT, cathiechen
no flags Details | Formatted Diff | Diff
Patch (3.90 KB, patch)
2021-10-05 00:39 PDT, cathiechen
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description cathiechen 2021-09-02 05:52:54 PDT
RenderLayer::collectFragments costs around 20% time in RenderLayer::collectFragments for this test.
Comment 1 cathiechen 2021-09-02 05:58:29 PDT
Created attachment 437140 [details]
screen-shot-collectFragments-cost
Comment 2 cathiechen 2021-09-02 06:00:12 PDT
Created attachment 437142 [details]
test-change-first-child-height.html
Comment 3 cathiechen 2021-09-02 10:11:27 PDT
Created attachment 437162 [details]
Patch
Comment 4 Simon Fraser (smfr) 2021-09-02 10:42:11 PDT
Comment on attachment 437162 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=437162&action=review

> Source/WebCore/rendering/RenderLayer.cpp:4591
> +    if (!paintDirtyRect.intersects(m_repaintRects.outlineBoundsRect))

This needs to check m_repaintRectsValid
Comment 5 cathiechen 2021-09-05 20:35:51 PDT
Comment on attachment 437162 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=437162&action=review

>> Source/WebCore/rendering/RenderLayer.cpp:4591
>> +    if (!paintDirtyRect.intersects(m_repaintRects.outlineBoundsRect))
> 
> This needs to check m_repaintRectsValid

Done, thanks!
Comment 6 cathiechen 2021-09-05 20:36:56 PDT
Created attachment 437376 [details]
Patch
Comment 7 cathiechen 2021-09-08 00:46:23 PDT
Created attachment 437606 [details]
Patch
Comment 8 Radar WebKit Bug Importer 2021-09-09 05:53:18 PDT
<rdar://problem/82921321>
Comment 9 cathiechen 2021-09-09 09:41:13 PDT
Created attachment 437754 [details]
Patch
Comment 10 cathiechen 2021-09-09 19:04:52 PDT
Created attachment 437822 [details]
Patch
Comment 11 Rob Buis 2021-09-10 00:17:56 PDT
Comment on attachment 437822 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=437822&action=review

> Source/WebCore/rendering/RenderLayer.cpp:3553
> +        return true;

With a transform in place there could still be no intersection I think? If so it is probably best to keep this check out of hasIntersections. Or rename to something like hasSimpleIntersections.
Comment 12 cathiechen 2021-09-11 09:03:03 PDT
Comment on attachment 437822 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=437822&action=review

>> Source/WebCore/rendering/RenderLayer.cpp:3553
>> +        return true;
> 
> With a transform in place there could still be no intersection I think? If so it is probably best to keep this check out of hasIntersections. Or rename to something like hasSimpleIntersections.

Thanks, looks like this can be removed.
Comment 13 cathiechen 2021-09-11 09:11:11 PDT
Created attachment 437952 [details]
Patch
Comment 14 cathiechen 2021-09-11 09:18:07 PDT
Created attachment 437954 [details]
screenshot-of-optimized-collectFragments
Comment 15 cathiechen 2021-09-11 09:18:53 PDT
Created attachment 437955 [details]
screenshot-of-original-collectFragments
Comment 16 cathiechen 2021-09-11 09:30:11 PDT
Hi,

I think the patch is ready for review.

According to the tests on my local Mac.
The function RenderLayer::collectFragments costs about 20% less (from 27% to 6.2%) while loading the test page.

A performance test has been added, which is based on requestAnimationFrame. The result is about 10% better.

Please take a look. Thanks:)
Comment 17 cathiechen 2021-09-15 02:49:32 PDT
Created attachment 438231 [details]
Patch
Comment 18 Simon Fraser (smfr) 2021-09-15 09:27:57 PDT
Comment on attachment 438231 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=438231&action=review

> Source/WebCore/rendering/RenderLayer.cpp:3552
> +    if (auto* box = renderBox(); box && box->hasRenderOverflow()) {

If a box has overflow, why can't we just check against m_repaintRects.clippedOverflowRect?
Comment 19 cathiechen 2021-09-24 10:14:21 PDT
Comment on attachment 438231 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=438231&action=review

>> Source/WebCore/rendering/RenderLayer.cpp:3552
>> +    if (auto* box = renderBox(); box && box->hasRenderOverflow()) {
> 
> If a box has overflow, why can't we just check against m_repaintRects.clippedOverflowRect?

Yes, we can remove this. I was trying to collect all the rects, including the descendants' which is not needed.

And it seems this approach will change the return value of collectFragments when there is backgroundClipRect.
I will try to upload a new patch that should not change the return value.
Comment 20 cathiechen 2021-09-24 10:45:47 PDT
Created attachment 439162 [details]
Patch
Comment 21 cathiechen 2021-09-24 10:51:12 PDT
The time is reduced from 27% to 15.2% with the new optimization.
Comment 22 cathiechen 2021-09-27 01:18:00 PDT
Created attachment 439328 [details]
screenshot-of-optimized-collectFragments
Comment 23 cathiechen 2021-09-27 01:24:19 PDT
Created attachment 439330 [details]
Patch
Comment 24 cathiechen 2021-09-27 20:17:01 PDT
Comment on attachment 439330 [details]
Patch

Hi,
I think the patch is ready for review now. Please take a look, thanks!
Comment 25 cathiechen 2021-09-28 03:10:18 PDT
The intersection check and the parentClipRects part are not very relevant, so I've split the parentClipRects changes to a new bug. (230885)
Comment 26 cathiechen 2021-09-28 03:25:06 PDT
Created attachment 439451 [details]
Patch-for-review
Comment 27 cathiechen 2021-10-05 00:39:06 PDT
Created attachment 440179 [details]
Patch
Comment 28 Rob Buis 2021-12-13 00:39:53 PST
Comment on attachment 439451 [details]
Patch-for-review

View in context: https://bugs.webkit.org/attachment.cgi?id=439451&action=review

> Source/WebCore/rendering/RenderLayer.cpp:4625
> +                foregroundRect = LayoutRect();

It seems at this point we can just return? Also is it possible to add a single block to handle the !intersectsBackgroundRect, rather than in three areas?
Comment 29 cathiechen 2021-12-13 01:09:49 PST
Comment on attachment 439451 [details]
Patch-for-review

View in context: https://bugs.webkit.org/attachment.cgi?id=439451&action=review

>> Source/WebCore/rendering/RenderLayer.cpp:4625
>> +                foregroundRect = LayoutRect();
> 
> It seems at this point we can just return? Also is it possible to add a single block to handle the !intersectsBackgroundRect, rather than in three areas?

Yeah, indeed, we can return here.
BTW, we moved this fix to bug: 231169