Bug 228125

Summary: [SVG] Attribute change triggers redundant (and out of order) setNeedsLayout call
Product: WebKit Reporter: zalan <zalan>
Component: SVGAssignee: Rob Buis <rbuis>
Status: RESOLVED FIXED    
Severity: Normal CC: bfulgham, darin, dino, ews-watchlist, fmalita, gyuyoung.kim, pdr, rbuis, sabouhallawa, schenney, sergio, simon.fraser, svillar, webkit-bug-importer, zalan, zimmermann
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=230296
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

zalan
Reported 2021-07-20 13:58:02 PDT
<svg id=changeThis></svg> <script> document.body.offsetHeight; changeThis.setAttribute("width","100px"); </script> The RenderObject::setNeedsLayout(MarkContainingBlockChain) triggered by the SVGElement::attributeChanged (SVGElement::attributeChanged -> SVGSVGElement::svgAttributeChanged -> RenderSVGResource::markForLayoutAndParentResourceInvalidation()) is incorrect and redundant. Incorrect in the context of how the dirty bits on the render tree should be populated. It is out of order i.e we have to have all the ancestors resolved first when marking descendant renderers dirty. Redundant because this attribute change on the SVG element also triggers style invalidation as part of the "presentational hints" flow (which applies to pretty much all the valid SVG attributes see SVGElement::hasPresentationalHintsForAttribute) and this style invalidation path would properly update the associated renderer's dirty bit through the normal RenderTreeUpdater process (as if it was just yet another non-svg style update e.g. <div dir=ltr <-changing it to rtl).
Attachments
Patch (1.71 KB, patch)
2021-08-07 07:57 PDT, Rob Buis
no flags
Patch (1.85 KB, patch)
2021-08-07 13:29 PDT, Rob Buis
no flags
Patch (1.92 KB, patch)
2021-08-09 02:31 PDT, Rob Buis
no flags
Radar WebKit Bug Importer
Comment 1 2021-07-20 14:20:19 PDT
Sergio Villar Senin
Comment 2 2021-08-02 03:38:12 PDT
(In reply to zalan from comment #0) > <svg id=changeThis></svg> > <script> > document.body.offsetHeight; > changeThis.setAttribute("width","100px"); > </script> > > The RenderObject::setNeedsLayout(MarkContainingBlockChain) triggered by the > SVGElement::attributeChanged (SVGElement::attributeChanged -> > SVGSVGElement::svgAttributeChanged -> > RenderSVGResource::markForLayoutAndParentResourceInvalidation()) is > incorrect and redundant. > Incorrect in the context of how the dirty bits on the render tree should be > populated. It is out of order i.e we have to have all the ancestors resolved > first when marking descendant renderers dirty. > Redundant because this attribute change on the SVG element also triggers > style invalidation as part of the "presentational hints" flow (which applies > to pretty much all the valid SVG attributes see > SVGElement::hasPresentationalHintsForAttribute) and this style invalidation > path would properly update the associated renderer's dirty bit through the > normal RenderTreeUpdater process (as if it was just yet another non-svg > style update e.g. <div dir=ltr <-changing it to rtl). Removing the RenderSVGResource::markForLayoutAndParentResourceInvalidation call in SVGSVGElement::svgAttributeChanged is not harmless though as it makes the test LayoutTests/svg/as-object/embedded-svg-size-changes.html fail.
zalan
Comment 3 2021-08-02 07:51:22 PDT
(In reply to Sergio Villar Senin from comment #2) > (In reply to zalan from comment #0) > > <svg id=changeThis></svg> > > <script> > > document.body.offsetHeight; > > changeThis.setAttribute("width","100px"); > > </script> > > > > The RenderObject::setNeedsLayout(MarkContainingBlockChain) triggered by the > > SVGElement::attributeChanged (SVGElement::attributeChanged -> > > SVGSVGElement::svgAttributeChanged -> > > RenderSVGResource::markForLayoutAndParentResourceInvalidation()) is > > incorrect and redundant. > > Incorrect in the context of how the dirty bits on the render tree should be > > populated. It is out of order i.e we have to have all the ancestors resolved > > first when marking descendant renderers dirty. > > Redundant because this attribute change on the SVG element also triggers > > style invalidation as part of the "presentational hints" flow (which applies > > to pretty much all the valid SVG attributes see > > SVGElement::hasPresentationalHintsForAttribute) and this style invalidation > > path would properly update the associated renderer's dirty bit through the > > normal RenderTreeUpdater process (as if it was just yet another non-svg > > style update e.g. <div dir=ltr <-changing it to rtl). > > Removing the RenderSVGResource::markForLayoutAndParentResourceInvalidation > call in SVGSVGElement::svgAttributeChanged is not harmless though as it > makes the test LayoutTests/svg/as-object/embedded-svg-size-changes.html fail. Yup and that's what someone (preferably with WebKit SVG background) needs to figure out and adjust some other part of the code accordingly.
Rob Buis
Comment 4 2021-08-07 07:57:57 PDT
Rob Buis
Comment 5 2021-08-07 13:29:21 PDT
Rob Buis
Comment 6 2021-08-09 02:31:55 PDT
EWS
Comment 7 2021-08-11 00:43:49 PDT
Committed r280887 (240424@main): <https://commits.webkit.org/240424@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 435178 [details].
Note You need to log in before you can comment on or make changes to this bug.