RESOLVED FIXED 139451
Only when the SVG is inline and only when a shape is referenced before it is defined, this shape will not be drawn
https://bugs.webkit.org/show_bug.cgi?id=139451
Summary Only when the SVG is inline and only when a shape is referenced before it is ...
Said Abou-Hallawa
Reported 2014-12-09 11:06:03 PST
Created attachment 242942 [details] <defs> after <use> (inline) Open the attached test cases in WebKit. Result: When the SVG is inline (included in an HTML) and when a shape is referenced before it is defined, this shape will not be drawn. When the same SVG (the one which has the <defs> comes after the <use>) is opened by itself in WebKit, everything is drawn as expected. Expected: Regardless whether the SVG is inline or not and regardless whether the shapes are defined before they are referenced or after they are referenced, the shapes should be drawn.
Attachments
<defs> after <use> (inline) (432 bytes, text/html)
2014-12-09 11:06 PST, Said Abou-Hallawa
no flags
<defs> after <use> (non inline) (376 bytes, image/svg+xml)
2014-12-09 11:06 PST, Said Abou-Hallawa
no flags
<defs> before <use> (inline) (430 bytes, text/html)
2014-12-09 11:07 PST, Said Abou-Hallawa
no flags
<defs> after <use> (inline - xhtml) (432 bytes, application/xhtml+xml)
2014-12-11 12:10 PST, Said Abou-Hallawa
no flags
Patch (6.62 KB, patch)
2014-12-11 19:14 PST, Said Abou-Hallawa
no flags
Patch (5.43 KB, patch)
2014-12-12 12:11 PST, Said Abou-Hallawa
no flags
Said Abou-Hallawa
Comment 1 2014-12-09 11:06:48 PST
Created attachment 242943 [details] <defs> after <use> (non inline)
Said Abou-Hallawa
Comment 2 2014-12-09 11:07:26 PST
Created attachment 242944 [details] <defs> before <use> (inline)
Said Abou-Hallawa
Comment 3 2014-12-09 11:11:07 PST
NOTE: FireFox and Chrome render the first test case as expected.
Radar WebKit Bug Importer
Comment 4 2014-12-09 11:12:05 PST
Said Abou-Hallawa
Comment 5 2014-12-11 12:10:58 PST
Created attachment 243135 [details] <defs> after <use> (inline - xhtml)
Said Abou-Hallawa
Comment 6 2014-12-11 12:11:55 PST
It looks like this bug is only related to the html parser. It does not happen if the file extension is xhtml
Said Abou-Hallawa
Comment 7 2014-12-11 19:14:11 PST
Dirk Schulze
Comment 8 2014-12-12 04:20:23 PST
Comment on attachment 243173 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=243173&action=review > Source/WebCore/ChangeLog:34 > + This actually might not be the most efficient solution here. This invalidate/ > + update mechanism is very aggressive. While parsing an inline SVG and with > + every child gets appended to a target element we will invalidate/update all > + shadow trees of the referencing elements till all the children elements get > + inserted. If the target SVG element has an 'n' children nodes and there 'm' > + other nodes referencing this target elment then invalidating and updating the > + shadow tree nodes will be O(n*n*m). I do not understand what that has to do with the characterData node? > Source/WebCore/svg/SVGElement.cpp:1099 > + if (hasID() || change.source != ChildChangeSourceParser) > + SVGElementInstance::invalidateAllInstancesOfElement(this); Ok, so if I understand this part and the comment above, we are invalidating more often. Every time a child changes and the element has an id we always mark all instance for invalidation and rebuild the trees, right? To your comment above, this is one of the critical code paths. <use> element is specifically slow in WebKit. If there is a difference between XML and HTML on characterData, why do we fix the issue here? > LayoutTests/svg/in-html/defs-after-use-expected.html:4 > + <g transform="translate(10,10)"> Is the transform needed? just putting x="10" y="10" should work for rectangles. (There might be AA issues on circles and curves though.) > LayoutTests/svg/in-html/defs-after-use.html:16 > + <defs> > + <g id="red-rect"> > + <rect x="0" y="0" width="100" height="50" fill="red"/> > + </g> > + </defs> > + <use x="10" y="10" xlink:href="#red-rect"/> IMO this can just use the rect directly. If that actual test works we don't know if this referencing works. The second <use> overdraws this one.
Said Abou-Hallawa
Comment 9 2014-12-12 12:11:06 PST
Said Abou-Hallawa
Comment 10 2014-12-12 12:41:32 PST
(In reply to comment #8) > Comment on attachment 243173 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=243173&action=review > > > Source/WebCore/ChangeLog:34 > > + This actually might not be the most efficient solution here. This invalidate/ > > + update mechanism is very aggressive. While parsing an inline SVG and with > > + every child gets appended to a target element we will invalidate/update all > > + shadow trees of the referencing elements till all the children elements get > > + inserted. If the target SVG element has an 'n' children nodes and there 'm' > > + other nodes referencing this target elment then invalidating and updating the > > + shadow tree nodes will be O(n*n*m). > > I do not understand what that has to do with the characterData node? When parsing the following SVG: <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000px" height="1000px" viewBox="0 0 1000 1000"> <use x="425" y="80" xlink:href="#helmet"/> <defs> <g id="helmet"> <path d="M 0 0 L 150 0 A75,75 0 0,0 0 0 z" fill="#6E808B"/> <rect x="0" y="0" width="150" height="20" fill="#48565e"/> </g> </defs> </svg> We get the following DOM tree: #document 0x116818600 (renderer 0x11650c7f0) (child needs style recalc) svg 0x119f02460 (renderer 0x10c171670) (child needs style recalc) #text 0x628000080190 "\n " use 0x111204e20 (renderer 0x640000180b60) #document-fragment 0x6480001c0e10 (renderer 0x0) g 0x111009000 (renderer 0x6400001809c0) #text 0x640000080820 "\n " path 0x111014500 (renderer 0x6400001e0100) #text 0x640000080910 "\n " rect 0x11100a190 (renderer 0x11100f170) #text 0x640000080780 "\n " #text 0x648000082670 "\n " defs 0x110705860 (renderer 0x600000105220) (child needs style recalc) #text 0x610000081ea0 "\n " g 0x111311580 (renderer 0x600000185210) #text 0x650000080f50 "\n " path 0x10c176380 (renderer 0x6080001e2f00) #text 0x60000008ef60 "\n " rect 0x10c6259c0 (renderer 0x116517480) #text 0x608000087940 "\n " #text 0x640000080a50 "\n " #text 0x650000080ff0 "\n" The HTML and the XML parsers create a Text element after each SVG element. In the XML code path and when we start processing a new tag, we append the buffered text to the leaf text element which is XMLDocumentParser::m_leafTextNode, see XMLDocumentParser::exitText(). This function causes the following stack of calls: #0 WebCore::SVGElement::childrenChanged() #1 WebCore::CharacterData::dispatchModifiedEvent() #2 WebCore::CharacterData::setDataAndUpdate() #3 WebCore::CharacterData::appendData() #4 WebCore::XMLDocumentParser::exitText() #5 WebCore::XMLDocumentParser::startElementNs() WebCore::CharacterData::dispatchModifiedEvent() sends the source of change as ContainerNode::ChildChangeSourceAPI to SVGElement::childrenChanged() which considers this as a legitimate reason to invalidate the referencing elements because it assumes the children were changed by something but not the parser. This might be a bug but it should not be specific to the SVG shadow tree invalidate/update. > > > Source/WebCore/svg/SVGElement.cpp:1099 > > + if (hasID() || change.source != ChildChangeSourceParser) > > + SVGElementInstance::invalidateAllInstancesOfElement(this); > > Ok, so if I understand this part and the comment above, we are invalidating > more often. Every time a child changes and the element has an id we always > mark all instance for invalidation and rebuild the trees, right? To your > comment above, this is one of the critical code paths. <use> element is > specifically slow in WebKit. > > If there is a difference between XML and HTML on characterData, why do we > fix the issue here? > Fixed: I moved the invalidation to SVGElement::finishParsingChildren() which gets called when all the children are parsed. And for the difference between HTML and XML, I explained above why the bug was not repro in XML code path which, I think, happened accidentally. Although we are doing more invalidation for the XML with this change than we do for the HTML, I think this is the right place to have the invalidation. We should fix the XML Text element issue to not cause any update. But I think this problem should be addressed in a separate bug. > > LayoutTests/svg/in-html/defs-after-use-expected.html:4 > > + <g transform="translate(10,10)"> > > Is the transform needed? just putting x="10" y="10" should work for > rectangles. (There might be AA issues on circles and curves though.) > Done. > > LayoutTests/svg/in-html/defs-after-use.html:16 > > + <defs> > > + <g id="red-rect"> > > + <rect x="0" y="0" width="100" height="50" fill="red"/> > > + </g> > > + </defs> > > + <use x="10" y="10" xlink:href="#red-rect"/> > > IMO this can just use the rect directly. If that actual test works we don't > know if this referencing works. The second <use> overdraws this one. Done. But I changed the test a little to include two <use> elements: 1st: references two <rect>s, the first <rect> comes before the user and the second <rect> comes after the <use>. 2nd: references two <rect>s, the two <rect>s come after the <use>.
Said Abou-Hallawa
Comment 11 2014-12-12 12:58:26 PST
*** Bug 105257 has been marked as a duplicate of this bug. ***
Said Abou-Hallawa
Comment 12 2014-12-12 12:59:42 PST
*** Bug 136128 has been marked as a duplicate of this bug. ***
WebKit Commit Bot
Comment 13 2014-12-19 10:36:36 PST
Comment on attachment 243209 [details] Patch Clearing flags on attachment: 243209 Committed r177576: <http://trac.webkit.org/changeset/177576>
WebKit Commit Bot
Comment 14 2014-12-19 10:36:42 PST
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.