Changeset 208470 in webkit
- Timestamp:
- Nov 9, 2016 12:38:28 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r208469 r208470 1 2016-11-09 Zalan Bujtas <zalan@apple.com> 2 3 Move RenderNamedFlowThread nextRendererForElement logic to RenderTreeUpdater. 4 https://bugs.webkit.org/show_bug.cgi?id=164503 5 6 Reviewed by Antti Koivisto. 7 8 When we insert a renderer into the render tree, we need to know both its parent 9 and its next sibling. Normally the parent and the sibling are based on the DOM, but 10 when this renderer is part of a flow thread, its insertion sibling is not necessarily the DOM sibling. 11 To find the correct sibling, we call RenderNamedFlowThread's nextRendererForElement(). 12 RenderNamedFlowThread keeps track of its children so that it can compute the next sibling 13 for the insertion point. 14 15 This patch eliminates the need for keeping track of the child renderers of each 16 flow by moving the 'next sibling' logic to RenderTreePosition. 17 18 No change in functionality. 19 20 * rendering/RenderElement.cpp: 21 (WebCore::RenderElement::insertedIntoTree): 22 (WebCore::RenderElement::willBeDestroyed): 23 (WebCore::RenderElement::removeFromRenderFlowThread): 24 (WebCore::RenderElement::renderNamedFlowThreadWrapper): Deleted. 25 * rendering/RenderElement.h: 26 * rendering/RenderNamedFlowThread.cpp: 27 (WebCore::RenderNamedFlowThread::nextRendererForElement): Deleted. 28 (WebCore::RenderNamedFlowThread::addFlowChild): Deleted. 29 (WebCore::RenderNamedFlowThread::removeFlowChild): Deleted. 30 * rendering/RenderNamedFlowThread.h: 31 * style/RenderTreePosition.cpp: 32 (WebCore::RenderTreePosition::previousSiblingRenderer): 33 (WebCore::RenderTreePosition::flowThreadInsertionContext): 34 * style/RenderTreePosition.h: 35 (WebCore::RenderTreePosition::RenderTreePosition): 36 (WebCore::RenderTreePosition::parent): 37 * style/RenderTreeUpdater.cpp: 38 (WebCore::registerElementForFlowThreadIfNeeded): We need to registed the element even when it does not create renderer (display: none). 39 (WebCore::RenderTreeUpdater::createRenderer): 40 (WebCore::moveToFlowThreadIfNeeded): Deleted. 41 1 42 2016-11-09 Per Arne Vollan <pvollan@apple.com> 2 43 -
trunk/Source/WebCore/rendering/RenderElement.cpp
r208460 r208470 1045 1045 void RenderElement::insertedIntoTree() 1046 1046 { 1047 if (auto* containerFlowThread = parent()->renderNamedFlowThreadWrapper())1048 containerFlowThread->addFlowChild(*this);1049 1050 1047 // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children 1051 1048 // and don't have a layer attached to ourselves. … … 1125 1122 // After remove, the object and the associated information should not be in any flow thread. 1126 1123 for (auto& flowThread : *view().flowThreadController().renderNamedFlowThreadList()) { 1127 ASSERT(!flowThread->hasChild(*this));1128 1124 ASSERT(!flowThread->hasChildInfo(this)); 1129 1125 } … … 1524 1520 1525 1521 return true; 1526 }1527 1528 RenderNamedFlowThread* RenderElement::renderNamedFlowThreadWrapper()1529 {1530 auto* renderer = this;1531 while (renderer && renderer->isAnonymousBlock() && !is<RenderNamedFlowThread>(*renderer))1532 renderer = renderer->parent();1533 return is<RenderNamedFlowThread>(renderer) ? downcast<RenderNamedFlowThread>(renderer) : nullptr;1534 1522 } 1535 1523 … … 2208 2196 { 2209 2197 ASSERT(flowThreadState() != NotInsideFlowThread); 2210 if (auto* containerFlowThread = parent()->renderNamedFlowThreadWrapper())2211 containerFlowThread->removeFlowChild(*this);2212 2198 // Sometimes we remove the element from the flow, but it's not destroyed at that time. 2213 2199 // It's only until later when we actually destroy it and remove all the children from it. -
trunk/Source/WebCore/rendering/RenderElement.h
r207499 r208470 200 200 void setHasPausedImageAnimations(bool b) { m_hasPausedImageAnimations = b; } 201 201 202 RenderNamedFlowThread* renderNamedFlowThreadWrapper();203 204 202 void setRenderBoxNeedsLazyRepaint(bool b) { m_renderBoxNeedsLazyRepaint = b; } 205 203 bool renderBoxNeedsLazyRepaint() const { return m_renderBoxNeedsLazyRepaint; } -
trunk/Source/WebCore/rendering/RenderNamedFlowThread.cpp
r206049 r208470 96 96 newStyle.setWritingMode(firstFragment->style().writingMode()); 97 97 setStyle(WTFMove(newStyle)); 98 }99 100 RenderElement* RenderNamedFlowThread::nextRendererForElement(Element& element) const101 {102 for (auto& child : m_flowThreadChildList) {103 ASSERT(!child->isAnonymous());104 ASSERT_WITH_MESSAGE(child->element(), "Can only be null for anonymous renderers");105 106 unsigned short position = element.compareDocumentPosition(*child->element());107 if (position & Node::DOCUMENT_POSITION_FOLLOWING)108 return child;109 }110 111 return nullptr;112 }113 114 void RenderNamedFlowThread::addFlowChild(RenderElement& newChild)115 {116 // The child list is used to sort the flow thread's children render objects117 // based on their corresponding nodes DOM order. The list is needed to avoid searching the whole DOM.118 119 if (newChild.isAnonymous())120 return;121 122 auto* beforeChild = nextRendererForElement(*newChild.element());123 if (beforeChild)124 m_flowThreadChildList.insertBefore(beforeChild, &newChild);125 else126 m_flowThreadChildList.add(&newChild);127 }128 129 void RenderNamedFlowThread::removeFlowChild(RenderElement& child)130 {131 m_flowThreadChildList.remove(&child);132 98 } 133 99 -
trunk/Source/WebCore/rendering/RenderNamedFlowThread.h
r206049 r208470 53 53 54 54 const RenderRegionList& invalidRenderRegionList() const { return m_invalidRegionList; } 55 56 RenderElement* nextRendererForElement(Element&) const;57 58 void addFlowChild(RenderElement&);59 void removeFlowChild(RenderElement&);60 bool hasChildren() const { return !m_flowThreadChildList.isEmpty(); }61 #ifndef NDEBUG62 bool hasChild(RenderElement& child) const { return m_flowThreadChildList.contains(&child); }63 #endif64 55 65 56 static RenderBlock* fragmentFromRenderBoxAsRenderBlock(RenderBox*, const IntPoint& absolutePoint, const RenderBox& flowedBox); … … 142 133 RenderNamedFlowThreadCountedSet m_layoutBeforeThreadsSet; 143 134 144 // Holds the sorted children of a named flow. This is the only way we can get the ordering right.145 ListHashSet<RenderElement*> m_flowThreadChildList;146 147 135 NamedFlowContentElements m_contentElements; 148 136 -
trunk/Source/WebCore/style/RenderTreePosition.cpp
r208112 r208470 28 28 29 29 #include "ComposedTreeIterator.h" 30 #include "FlowThreadController.h" 30 31 #include "PseudoElement.h" 31 32 #include "RenderObject.h" … … 67 68 for (auto it = composedChildren.at(textNode), end = composedChildren.end(); it != end; --it) { 68 69 RenderObject* renderer = it->renderer(); 69 if (renderer && ! RenderTreePosition::isRendererReparented(*renderer))70 if (renderer && !isRendererReparented(*renderer)) 70 71 return renderer; 71 72 } … … 105 106 } 106 107 108 #if ENABLE(CSS_REGIONS) 109 RenderTreePosition RenderTreePosition::insertionPositionForFlowThread(Element* insertionParent, Element& element, const RenderStyle& style) 110 { 111 ASSERT(element.shouldMoveToFlowThread(style)); 112 auto& parentFlowThread = element.document().renderView()->flowThreadController().ensureRenderFlowThreadWithName(style.flowThread()); 113 114 if (!insertionParent) 115 return { parentFlowThread, nullptr }; 116 117 auto composedDescendants = composedTreeDescendants(*insertionParent); 118 auto it = element.isBeforePseudoElement() ? composedDescendants.begin() : composedDescendants.at(element); 119 auto end = composedDescendants.end(); 120 while (it != end) { 121 auto& currentNode = *it; 122 bool hasDisplayContents = is<Element>(currentNode) && downcast<Element>(currentNode).hasDisplayContents(); 123 if (hasDisplayContents) { 124 it.traverseNext(); 125 continue; 126 } 127 128 auto* renderer = currentNode.renderer(); 129 if (!renderer) { 130 it.traverseNextSkippingChildren(); 131 continue; 132 } 133 134 if (!is<RenderElement>(*renderer)) { 135 it.traverseNext(); 136 continue; 137 } 138 139 // We are the last child in this flow. 140 if (!isRendererReparented(*renderer)) 141 return { parentFlowThread, nullptr }; 142 143 if (renderer->style().hasFlowInto() && style.flowThread() == renderer->style().flowThread()) 144 return { parentFlowThread, downcast<RenderElement>(renderer) }; 145 // Nested flows, skip. 146 it.traverseNextSkippingChildren(); 147 } 148 return { parentFlowThread, nullptr }; 149 } 150 #endif 151 107 152 bool RenderTreePosition::isRendererReparented(const RenderObject& renderer) 108 153 { -
trunk/Source/WebCore/style/RenderTreePosition.h
r201393 r208470 28 28 29 29 #include "RenderElement.h" 30 #include "RenderNamedFlowThread.h" 30 31 #include "RenderText.h" 31 32 #include "RenderView.h" … … 46 47 } 47 48 48 RenderTreePosition(RenderElement& parent, RenderObject* nextSibling) 49 : m_parent(parent) 50 , m_nextSibling(nextSibling) 51 , m_hasValidNextSibling(true) 52 { 53 } 49 #if ENABLE(CSS_REGIONS) 50 static RenderTreePosition insertionPositionForFlowThread(Element* insertionParent, Element& child, const RenderStyle&); 51 #endif 54 52 55 53 RenderElement& parent() const { return m_parent; } 56 57 54 void insert(RenderObject&); 58 55 bool canInsert(RenderElement&) const; … … 68 65 69 66 private: 67 #if ENABLE(CSS_REGIONS) 68 RenderTreePosition(RenderFlowThread& parent, RenderObject* nextSibling) 69 : m_parent(parent) 70 , m_nextSibling(nextSibling) 71 , m_hasValidNextSibling(true) 72 { 73 } 74 #endif 75 70 76 RenderElement& m_parent; 71 77 RenderObject* m_nextSibling { nullptr }; -
trunk/Source/WebCore/style/RenderTreeUpdater.cpp
r207458 r208470 307 307 308 308 #if ENABLE(CSS_REGIONS) 309 static RenderNamedFlowThread* moveToFlowThreadIfNeeded(Element& element, const RenderStyle& style)309 static void registerElementForFlowThreadIfNeeded(Element& element, const RenderStyle& style) 310 310 { 311 311 if (!element.shouldMoveToFlowThread(style)) 312 return nullptr; 313 312 return; 314 313 FlowThreadController& flowThreadController = element.document().renderView()->flowThreadController(); 315 RenderNamedFlowThread& parentFlowRenderer = flowThreadController.ensureRenderFlowThreadWithName(style.flowThread()); 316 flowThreadController.registerNamedFlowContentElement(element, parentFlowRenderer); 317 return &parentFlowRenderer; 314 flowThreadController.registerNamedFlowContentElement(element, flowThreadController.ensureRenderFlowThreadWithName(style.flowThread())); 318 315 } 319 316 #endif … … 321 318 void RenderTreeUpdater::createRenderer(Element& element, RenderStyle&& style) 322 319 { 320 auto computeInsertionPosition = [this, &element, &style] () { 321 #if ENABLE(CSS_REGIONS) 322 if (element.shouldMoveToFlowThread(style)) 323 return RenderTreePosition::insertionPositionForFlowThread(renderTreePosition().parent().element(), element, style); 324 #endif 325 renderTreePosition().computeNextSibling(element); 326 return renderTreePosition(); 327 }; 328 323 329 if (!shouldCreateRenderer(element, renderTreePosition().parent())) 324 330 return; 325 331 326 RenderNamedFlowThread* parentFlowRenderer = nullptr;327 332 #if ENABLE(CSS_REGIONS) 328 parentFlowRenderer = moveToFlowThreadIfNeeded(element, style); 333 // Even display: none elements need to be registered in FlowThreadController. 334 registerElementForFlowThreadIfNeeded(element, style); 329 335 #endif 330 336 … … 332 338 return; 333 339 334 renderTreePosition().computeNextSibling(element); 335 336 RenderTreePosition insertionPosition = parentFlowRenderer 337 ? RenderTreePosition(*parentFlowRenderer, parentFlowRenderer->nextRendererForElement(element)) 338 : renderTreePosition(); 339 340 RenderTreePosition insertionPosition = computeInsertionPosition(); 340 341 RenderElement* newRenderer = element.createElementRenderer(WTFMove(style), insertionPosition).leakPtr(); 341 342 if (!newRenderer)
Note: See TracChangeset
for help on using the changeset viewer.