REOPENED 230885
[Performance] Optimize RenderLayer::clipCrossesPaintingBoundary
https://bugs.webkit.org/show_bug.cgi?id=230885
Summary [Performance] Optimize RenderLayer::clipCrossesPaintingBoundary
cathiechen
Reported 2021-09-28 02:42:00 PDT
Optimize performance of RenderLayer::clipCrossesPaintingBoundary
Attachments
Patch (3.00 KB, patch)
2021-09-28 02:45 PDT, cathiechen
simon.fraser: review-
screenshot-before-opt (574.19 KB, image/png)
2021-09-28 03:02 PDT, cathiechen
no flags
screenshot-after-opt (603.90 KB, image/png)
2021-09-28 03:03 PDT, cathiechen
no flags
Patch-for-review (4.68 KB, patch)
2021-09-30 03:31 PDT, cathiechen
no flags
screenshot-of-original-clipCrossesPaintingBoundary (807.04 KB, image/png)
2021-09-30 08:53 PDT, cathiechen
no flags
screenshot-of-optimized-clipCrossesPaintingBoundary (762.59 KB, image/png)
2021-09-30 08:54 PDT, cathiechen
no flags
Patch (4.88 KB, patch)
2021-09-30 17:31 PDT, cathiechen
no flags
Patch (5.09 KB, patch)
2021-12-20 00:11 PST, cathiechen
no flags
Patch (8.21 KB, patch)
2021-12-20 00:32 PST, cathiechen
no flags
not-reproducible-with-simulate-wheel-event.html (2.37 KB, text/html)
2021-12-20 04:20 PST, cathiechen
no flags
not-reproducible-with-simulate-wheel-event-expected.html (1.21 KB, text/html)
2021-12-20 04:29 PST, cathiechen
no flags
Patch (5.09 KB, patch)
2021-12-20 04:40 PST, cathiechen
no flags
Patch (6.38 KB, patch)
2021-12-20 22:28 PST, cathiechen
no flags
Patch (11.81 KB, patch)
2021-12-24 02:18 PST, cathiechen
no flags
Patch (12.15 KB, patch)
2021-12-24 03:44 PST, cathiechen
no flags
Patch (12.16 KB, patch)
2021-12-24 04:46 PST, cathiechen
no flags
Patch (12.26 KB, patch)
2022-01-10 01:48 PST, cathiechen
no flags
Patch (12.25 KB, patch)
2022-01-12 20:13 PST, cathiechen
cathiechen: review?
cathiechen
Comment 1 2021-09-28 02:45:59 PDT
cathiechen
Comment 2 2021-09-28 02:58:09 PDT
Tested the case in bug: 229802 locally, this patch will reduce the time cost of RenderLayer::parentClipRects from 8.3% to 2.5%.
cathiechen
Comment 3 2021-09-28 03:02:32 PDT
Created attachment 439448 [details] screenshot-before-opt
cathiechen
Comment 4 2021-09-28 03:03:07 PDT
Created attachment 439449 [details] screenshot-after-opt
cathiechen
Comment 5 2021-09-28 06:55:41 PDT
Comment on attachment 439446 [details] Patch Hi, I think this patch is ready for review. Please take a look, thanks!
Simon Fraser (smfr)
Comment 6 2021-09-29 10:42:53 PDT
Comment on attachment 439446 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=439446&action=review > Source/WebCore/rendering/RenderLayer.cpp:4455 > + if (parentLayer->enclosingPaginationLayer(IncludeCompositedPaginatedLayers) != enclosingPaginationLayer(IncludeCompositedPaginatedLayers)) > + return true; > + > + if (compositedWithOwnBackingStore(*this)) > + return true; > + > + if (paintsIntoProvidedBacking() && backingProviderLayer()) > + return true; > + > + const RenderLayer* paintParent = paintOrderParent(); > + if (parentLayer == paintParent) > + return false; > + > + return paintParent != parentLayer->paintOrderParent(); It's unfortunate that this effectively copies code from enclosingCompositingLayerForRepaint(), and puts in a separate file, so fixes to enclosingCompositingLayerForRepaint() are unlikely to be replicated here. Think it would be better to add `bool RenderLayer::sharesCompositingLayerForRepaint(RenderLayer& otherLayer)` and put it next to RenderLayer::enclosingCompositingLayerForRepaint() so the code is close. Pagination is really rare, so move the pagination check last also.
cathiechen
Comment 7 2021-09-30 03:30:26 PDT
Comment on attachment 439446 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=439446&action=review >> Source/WebCore/rendering/RenderLayer.cpp:4455 >> + return paintParent != parentLayer->paintOrderParent(); > > It's unfortunate that this effectively copies code from enclosingCompositingLayerForRepaint(), and puts in a separate file, so fixes to enclosingCompositingLayerForRepaint() are unlikely to be replicated here. > > Think it would be better to add `bool RenderLayer::sharesCompositingLayerForRepaint(RenderLayer& otherLayer)` and put it next to RenderLayer::enclosingCompositingLayerForRepaint() so the code is close. > > Pagination is really rare, so move the pagination check last also. Done, thanks!
cathiechen
Comment 8 2021-09-30 03:31:11 PDT
Created attachment 439720 [details] Patch-for-review
cathiechen
Comment 9 2021-09-30 08:53:02 PDT
Created attachment 439741 [details] screenshot-of-original-clipCrossesPaintingBoundary
cathiechen
Comment 10 2021-09-30 08:54:24 PDT
Created attachment 439742 [details] screenshot-of-optimized-clipCrossesPaintingBoundary
cathiechen
Comment 11 2021-09-30 08:56:28 PDT
Here are my locally test results. The clipCrossesPaintingBoundary percentage: * Original: 7.1%, 7.8%, 7.0% * With patch in bug 231016: 6.0%, 5.9%, 5.7% * With this patch + patch in bug 231016: 1.6%, 1.4%, 1.2%
cathiechen
Comment 12 2021-09-30 17:31:15 PDT
EWS
Comment 13 2021-09-30 18:23:22 PDT
Committed r283354 (242363@main): <https://commits.webkit.org/242363@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 439801 [details].
Radar WebKit Bug Importer
Comment 14 2021-09-30 18:24:34 PDT
WebKit Commit Bot
Comment 15 2021-12-13 14:30:26 PST
Re-opened since this is blocked by bug 234273
cathiechen
Comment 16 2021-12-20 00:11:07 PST
cathiechen
Comment 17 2021-12-20 00:32:06 PST
cathiechen
Comment 18 2021-12-20 04:20:34 PST
Created attachment 447596 [details] not-reproducible-with-simulate-wheel-event.html Add a test with wheel event simulation, but the issue is not reproducible in run-webkit-tests. It is reproducible by manually scrolling the content.
cathiechen
Comment 19 2021-12-20 04:29:20 PST
Created attachment 447597 [details] not-reproducible-with-simulate-wheel-event-expected.html Add a fake expected.html
cathiechen
Comment 20 2021-12-20 04:40:00 PST
cathiechen
Comment 21 2021-12-20 05:02:08 PST
Comment on attachment 447598 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447598&action=review Hi, This patch also addressed the regression in bug 234269. Let me explain more in the code. > Source/WebCore/rendering/RenderLayer.cpp:1966 > + if (auto* repaintTarget = repaintTargetForLayer(*this); repaintTarget != repaintTargetForLayer(otherLayer)) This change addressed the regression. In the case, the layers "second" and "third" share backing layer, they are not clipCrossesPaintingBoundary, so as the "four" layer, which can get the right clip rects from its parent then.
Tim Nguyen (:ntim)
Comment 22 2021-12-20 11:17:06 PST
Comment on attachment 447598 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447598&action=review >> Source/WebCore/rendering/RenderLayer.cpp:1966 >> + if (auto* repaintTarget = repaintTargetForLayer(*this); repaintTarget != repaintTargetForLayer(otherLayer)) > > This change addressed the regression. > In the case, the layers "second" and "third" share backing layer, they are not clipCrossesPaintingBoundary, so as the "four" layer, which can get the right clip rects from its parent then. Could you add the reftest for the regression? Also, could you please unskip https://webkit-search.igalia.com/webkit/rev/600f4eb35ff0057349a063904f4a89bd0e15abdb/LayoutTests/TestExpectations#5061? Since the revert of the previous version of this patch caused the issue.
cathiechen
Comment 23 2021-12-20 22:12:10 PST
(In reply to Tim Nguyen (:ntim) from comment #22) Hi Tim, thanks for the review! > Could you add the reftest for the regression? > Yeah, I tried to add one. But it seems the regression can not be captured by run-webkit-tests. See the attachment: not-reproducible-with-simulate-wheel-event.html > Also, could you please unskip > https://webkit-search.igalia.com/webkit/rev/ > 600f4eb35ff0057349a063904f4a89bd0e15abdb/LayoutTests/TestExpectations#5061? > Since the revert of the previous version of this patch caused the issue. Will do, thanks!
cathiechen
Comment 24 2021-12-20 22:28:42 PST
Simon Fraser (smfr)
Comment 25 2021-12-23 14:42:03 PST
Comment on attachment 447690 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447690&action=review > Source/WebCore/rendering/RenderLayer.cpp:1938 > +static RenderLayer* repaintTargetForLayer(const RenderLayer& layer) This function has a confusing name now that you've pulled it out from the lambda. You might expect it to return the same thing as enclosingCompositingLayerForRepaint() but all it does is check itself and its backing provider. > Source/WebCore/rendering/RenderLayer.cpp:1973 > + const RenderLayer* paintParent = paintOrderParent(); > + if (&otherLayer == paintParent) > + return true; > + auto* otherPaintParent = otherLayer.paintOrderParent(); > + return paintParent == otherPaintParent || this == otherPaintParent; This code isn't doing any compositing checks. "Paint order" here is really just about z-order, so it's not clear to me that this is correct. For example, what if otherLayer's paintsIntoProvidedBacking() is true?
cathiechen
Comment 26 2021-12-24 01:29:01 PST
Comment on attachment 447690 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447690&action=review Hi Simon, Thanks for the review! >> Source/WebCore/rendering/RenderLayer.cpp:1938 >> +static RenderLayer* repaintTargetForLayer(const RenderLayer& layer) > > This function has a confusing name now that you've pulled it out from the lambda. > > You might expect it to return the same thing as enclosingCompositingLayerForRepaint() but all it does is check itself and its backing provider. Yeah, agree, I will not reuse this function in the new patch. >> Source/WebCore/rendering/RenderLayer.cpp:1973 >> + return paintParent == otherPaintParent || this == otherPaintParent; > > This code isn't doing any compositing checks. "Paint order" here is really just about z-order, so it's not clear to me that this is correct. For example, what if otherLayer's paintsIntoProvidedBacking() is true? Yeah, the approach is not right here, when otherLayer's paintsIntoProvidedBacking() is true. Will fix this is the new patch.
cathiechen
Comment 27 2021-12-24 02:18:25 PST
cathiechen
Comment 28 2021-12-24 02:24:04 PST
(In reply to cathiechen from comment #23) > (In reply to Tim Nguyen (:ntim) from comment #22) > > Hi Tim, thanks for the review! > > > Could you add the reftest for the regression? > > > Yeah, I tried to add one. But it seems the regression can not be captured by > run-webkit-tests. See the attachment: > not-reproducible-with-simulate-wheel-event.html > > > Also, could you please unskip > > https://webkit-search.igalia.com/webkit/rev/ > > 600f4eb35ff0057349a063904f4a89bd0e15abdb/LayoutTests/TestExpectations#5061? > > Since the revert of the previous version of this patch caused the issue. > > Will do, thanks! Hi Tim! Looks like the crash bug was hidden again by the regression of the previous patch. I'll try to explain it in bug 234315.
cathiechen
Comment 29 2021-12-24 02:30:03 PST
Hi, I just added a perf test to the patch. It reveals the improvement of this patch to the pages with lots of deeply nested self-painting layers. The result is improved from 916ms to 714ms. More detailed data: The result with this patch: :Time -> [553, 539.0000000000005, 540, 714, 736, 716, 712.0000000000009, 718, 716, 716, 714, 715, 712, 711.0000000000018, 715, 711.9999999999982, 713, 719.9999999999982, 719.0000000000018, 715.9999999999982] ms mean: 690.3499999999998 ms median: 714.5 ms stdev: 63.343902626851104 ms min: 539.0000000000005 ms max: 736 ms The result without this patch: :Time -> [750, 996, 924, 914, 918, 946, 916, 918, 922, 924, 913, 948, 911, 909, 915, 908, 918, 917, 915, 915] ms mean: 914.85 ms median: 916.5 ms stdev: 43.64000458295116 ms min: 750 ms max: 996 ms
cathiechen
Comment 30 2021-12-24 03:44:13 PST
cathiechen
Comment 31 2021-12-24 04:46:33 PST
Simon Fraser (smfr)
Comment 32 2022-01-05 11:26:06 PST
Comment on attachment 447935 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447935&action=review > Source/WebCore/rendering/RenderLayer.cpp:1971 > + if (compositedWithOwnBackingStore(*layer)) > + return false; > + > + if (!layer->paintsIntoProvidedBacking()) { The way this code uses `layer` makes it look like it's going to loop, but it doesn't. It would be clearer to use `this` in place of `layer`. > Source/WebCore/rendering/RenderLayer.cpp:1975 > + if (layer == parentLayer) How is this ever possible? > Source/WebCore/rendering/RenderLayer.cpp:1979 > + if (compositedWithOwnBackingStore(*parentLayer)) > + return false; But this layer can paint into parentLayer's backing, right? This will be pretty common.
cathiechen
Comment 33 2022-01-06 04:38:24 PST
Comment on attachment 447935 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447935&action=review Hi Simon, Sorry for the confusion. I explained a little, please take a look, thanks! >> Source/WebCore/rendering/RenderLayer.cpp:1971 >> + if (!layer->paintsIntoProvidedBacking()) { > > The way this code uses `layer` makes it look like it's going to loop, but it doesn't. It would be clearer to use `this` in place of `layer`. `layer` could be `this` or `paintOrderParent()`. Inside this constrain, `layer` is set to `paintOrderParent()`. > Source/WebCore/rendering/RenderLayer.cpp:1972 > + layer = paintOrderParent(); Maybe it becomes a little clear, if it uses `layer = layer->paintOrderParent();` here? >> Source/WebCore/rendering/RenderLayer.cpp:1975 >> + if (layer == parentLayer) > > How is this ever possible? `layer` is `paintOrderParent()` now, so it could be `parentLayer`. >> Source/WebCore/rendering/RenderLayer.cpp:1979 >> + return false; > > But this layer can paint into parentLayer's backing, right? This will be pretty common. Here, `this->paintOrderParent()` is not equal to `parentLayer`, so this layer won't paint into parentLayer's backing.
cathiechen
Comment 34 2022-01-10 01:48:38 PST
cathiechen
Comment 35 2022-01-12 20:13:56 PST
Note You need to log in before you can comment on or make changes to this bug.