OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> | 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> |
3 * 1999 Lars Knoll <knoll@kde.org> | 3 * 1999 Lars Knoll <knoll@kde.org> |
4 * 1999 Antti Koivisto <koivisto@kde.org> | 4 * 1999 Antti Koivisto <koivisto@kde.org> |
5 * 2000 Dirk Mueller <mueller@kde.org> | 5 * 2000 Dirk Mueller <mueller@kde.org> |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) | 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) |
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
9 * Copyright (C) 2009 Google Inc. All rights reserved. | 9 * Copyright (C) 2009 Google Inc. All rights reserved. |
10 * | 10 * |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 // The maximum number of updateWidgets iterations that should be done before ret
urning. | 101 // The maximum number of updateWidgets iterations that should be done before ret
urning. |
102 static const unsigned maxUpdateWidgetsIterations = 2; | 102 static const unsigned maxUpdateWidgetsIterations = 2; |
103 static const double resourcePriorityUpdateDelayAfterScroll = 0.250; | 103 static const double resourcePriorityUpdateDelayAfterScroll = 0.250; |
104 | 104 |
105 FrameView::FrameView(LocalFrame* frame) | 105 FrameView::FrameView(LocalFrame* frame) |
106 : m_frame(frame) | 106 : m_frame(frame) |
107 , m_displayMode(WebDisplayModeBrowser) | 107 , m_displayMode(WebDisplayModeBrowser) |
108 , m_canHaveScrollbars(true) | 108 , m_canHaveScrollbars(true) |
109 , m_slowRepaintObjectCount(0) | 109 , m_slowRepaintObjectCount(0) |
110 , m_hasPendingLayout(false) | 110 , m_hasPendingLayout(false) |
111 , m_layoutSubtreeRoot(0) | |
112 , m_inSynchronousPostLayout(false) | 111 , m_inSynchronousPostLayout(false) |
113 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) | 112 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) |
114 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) | 113 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) |
115 , m_isTransparent(false) | 114 , m_isTransparent(false) |
116 , m_baseBackgroundColor(Color::white) | 115 , m_baseBackgroundColor(Color::white) |
117 , m_mediaType(MediaTypeNames::screen) | 116 , m_mediaType(MediaTypeNames::screen) |
118 , m_overflowStatusDirty(true) | 117 , m_overflowStatusDirty(true) |
119 , m_viewportRenderer(0) | 118 , m_viewportRenderer(0) |
120 , m_wasScrolledByUser(false) | 119 , m_wasScrolledByUser(false) |
121 , m_inProgrammaticScroll(false) | 120 , m_inProgrammaticScroll(false) |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 visitor->trace(m_horizontalScrollbar); | 219 visitor->trace(m_horizontalScrollbar); |
221 visitor->trace(m_verticalScrollbar); | 220 visitor->trace(m_verticalScrollbar); |
222 visitor->trace(m_children); | 221 visitor->trace(m_children); |
223 #endif | 222 #endif |
224 Widget::trace(visitor); | 223 Widget::trace(visitor); |
225 } | 224 } |
226 | 225 |
227 void FrameView::reset() | 226 void FrameView::reset() |
228 { | 227 { |
229 m_hasPendingLayout = false; | 228 m_hasPendingLayout = false; |
230 m_layoutSubtreeRoot = nullptr; | |
231 m_doFullPaintInvalidation = false; | 229 m_doFullPaintInvalidation = false; |
232 m_layoutSchedulingEnabled = true; | 230 m_layoutSchedulingEnabled = true; |
233 m_inPerformLayout = false; | 231 m_inPerformLayout = false; |
234 m_inSynchronousPostLayout = false; | 232 m_inSynchronousPostLayout = false; |
235 m_layoutCount = 0; | 233 m_layoutCount = 0; |
236 m_nestedLayoutCount = 0; | 234 m_nestedLayoutCount = 0; |
237 m_postLayoutTasksTimer.stop(); | 235 m_postLayoutTasksTimer.stop(); |
238 m_updateWidgetsTimer.stop(); | 236 m_updateWidgetsTimer.stop(); |
239 m_firstLayout = true; | 237 m_firstLayout = true; |
240 m_firstLayoutCallbackPending = false; | 238 m_firstLayoutCallbackPending = false; |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 | 748 |
751 bool FrameView::isEnclosedInCompositingLayer() const | 749 bool FrameView::isEnclosedInCompositingLayer() const |
752 { | 750 { |
753 // FIXME: It's a bug that compositing state isn't always up to date when thi
s is called. crbug.com/366314 | 751 // FIXME: It's a bug that compositing state isn't always up to date when thi
s is called. crbug.com/366314 |
754 DisableCompositingQueryAsserts disabler; | 752 DisableCompositingQueryAsserts disabler; |
755 | 753 |
756 LayoutObject* frameOwnerRenderer = m_frame->ownerRenderer(); | 754 LayoutObject* frameOwnerRenderer = m_frame->ownerRenderer(); |
757 return frameOwnerRenderer && frameOwnerRenderer->enclosingLayer()->enclosing
LayerForPaintInvalidationCrossingFrameBoundaries(); | 755 return frameOwnerRenderer && frameOwnerRenderer->enclosingLayer()->enclosing
LayerForPaintInvalidationCrossingFrameBoundaries(); |
758 } | 756 } |
759 | 757 |
760 LayoutObject* FrameView::layoutRoot(bool onlyDuringLayout) const | 758 static inline void countObjectsNeedingLayoutInRoot(const LayoutObject* root, uns
igned& needsLayoutObjects, unsigned& totalObjects) |
761 { | 759 { |
762 return onlyDuringLayout && layoutPending() ? nullptr : m_layoutSubtreeRoot; | 760 for (const LayoutObject* o = root; o; o = o->nextInPreOrder(root)) { |
| 761 ++totalObjects; |
| 762 if (o->needsLayout()) |
| 763 ++needsLayoutObjects; |
| 764 } |
| 765 } |
| 766 |
| 767 void FrameView::countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned
& totalObjects, bool& isSubtree) |
| 768 { |
| 769 needsLayoutObjects = 0; |
| 770 totalObjects = 0; |
| 771 isSubtree = isSubtreeLayout(); |
| 772 if (isSubtree) { |
| 773 for (auto& subtreeRoot : m_layoutSubtreeRoots) |
| 774 countObjectsNeedingLayoutInRoot(subtreeRoot, needsLayoutObjects, tot
alObjects); |
| 775 } else { |
| 776 countObjectsNeedingLayoutInRoot(layoutView(), needsLayoutObjects, totalO
bjects); |
| 777 } |
| 778 } |
| 779 |
| 780 bool FrameView::isLayoutRoot(const LayoutObject& object) const |
| 781 { |
| 782 return m_layoutSubtreeRoots.contains(const_cast<LayoutObject*>(&object)); |
763 } | 783 } |
764 | 784 |
765 inline void FrameView::forceLayoutParentViewIfNeeded() | 785 inline void FrameView::forceLayoutParentViewIfNeeded() |
766 { | 786 { |
767 LayoutPart* ownerRenderer = m_frame->ownerRenderer(); | 787 LayoutPart* ownerRenderer = m_frame->ownerRenderer(); |
768 if (!ownerRenderer || !ownerRenderer->frame()) | 788 if (!ownerRenderer || !ownerRenderer->frame()) |
769 return; | 789 return; |
770 | 790 |
771 LayoutBox* contentBox = embeddedContentBox(); | 791 LayoutBox* contentBox = embeddedContentBox(); |
772 if (!contentBox) | 792 if (!contentBox) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 | 841 |
822 document->updateRenderTreeIfNeeded(); | 842 document->updateRenderTreeIfNeeded(); |
823 lifecycle().advanceTo(DocumentLifecycle::StyleClean); | 843 lifecycle().advanceTo(DocumentLifecycle::StyleClean); |
824 } | 844 } |
825 | 845 |
826 void FrameView::lineLayoutTime(double ms) | 846 void FrameView::lineLayoutTime(double ms) |
827 { | 847 { |
828 m_lineLayoutMs += ms; | 848 m_lineLayoutMs += ms; |
829 } | 849 } |
830 | 850 |
831 void FrameView::performLayout(LayoutObject* rootForThisLayout, bool inSubtreeLay
out) | 851 static void gatherDebugLayoutRects(LayoutObject& layoutRoot) |
832 { | 852 { |
| 853 bool isTracing; |
| 854 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("blink.debug.la
yout"), &isTracing); |
| 855 if (!isTracing) |
| 856 return; |
| 857 if (!layoutRoot.enclosingLayer()->hasCompositedLayerMapping()) |
| 858 return; |
| 859 // For access to compositedLayerMapping(). |
| 860 DisableCompositingQueryAsserts disabler; |
| 861 GraphicsLayer* graphicsLayer = layoutRoot.enclosingLayer()->compositedLayerM
apping()->mainGraphicsLayer(); |
| 862 if (!graphicsLayer) |
| 863 return; |
| 864 |
| 865 GraphicsLayerDebugInfo& debugInfo = graphicsLayer->debugInfo(); |
| 866 |
| 867 debugInfo.currentLayoutRects().clear(); |
| 868 for (LayoutObject* renderer = &layoutRoot; renderer; renderer = renderer->ne
xtInPreOrder()) { |
| 869 if (renderer->layoutDidGetCalledSinceLastFrame()) { |
| 870 FloatQuad quad = renderer->localToAbsoluteQuad(FloatQuad(renderer->p
reviousPaintInvalidationRect())); |
| 871 LayoutRect rect = LayoutRect(quad.enclosingBoundingBox()); |
| 872 debugInfo.currentLayoutRects().append(rect); |
| 873 } |
| 874 } |
| 875 } |
| 876 |
| 877 static inline void layoutFromRootObject(LayoutObject& root) |
| 878 { |
| 879 LayoutState layoutState(root); |
| 880 root.layout(); |
| 881 gatherDebugLayoutRects(root); |
| 882 } |
| 883 |
| 884 void FrameView::performLayout(bool inSubtreeLayout) |
| 885 { |
| 886 ASSERT(inSubtreeLayout || m_layoutSubtreeRoots.isEmpty()); |
| 887 |
833 m_lineLayoutMs = 0; | 888 m_lineLayoutMs = 0; |
834 TRACE_EVENT0("blink,benchmark", "FrameView::performLayout"); | 889 TRACE_EVENT0("blink,benchmark", "FrameView::performLayout"); |
835 double start = WTF::currentTimeMS(); | 890 double start = WTF::currentTimeMS(); |
836 | 891 |
837 ScriptForbiddenScope forbidScript; | 892 ScriptForbiddenScope forbidScript; |
838 | 893 |
839 ASSERT(!isInPerformLayout()); | 894 ASSERT(!isInPerformLayout()); |
840 lifecycle().advanceTo(DocumentLifecycle::InPerformLayout); | 895 lifecycle().advanceTo(DocumentLifecycle::InPerformLayout); |
841 | 896 |
842 TemporaryChange<bool> changeInPerformLayout(m_inPerformLayout, true); | 897 TemporaryChange<bool> changeInPerformLayout(m_inPerformLayout, true); |
843 | 898 |
844 // performLayout is the actual guts of layout(). | 899 // performLayout is the actual guts of layout(). |
845 // FIXME: The 300 other lines in layout() probably belong in other helper fu
nctions | 900 // FIXME: The 300 other lines in layout() probably belong in other helper fu
nctions |
846 // so that a single human could understand what layout() is actually doing. | 901 // so that a single human could understand what layout() is actually doing. |
847 | 902 |
848 LayoutState layoutState(*rootForThisLayout); | |
849 | |
850 forceLayoutParentViewIfNeeded(); | 903 forceLayoutParentViewIfNeeded(); |
851 | 904 |
852 rootForThisLayout->layout(); | 905 if (inSubtreeLayout) { |
853 gatherDebugLayoutRects(rootForThisLayout); | 906 while (m_layoutSubtreeRoots.size()) { |
| 907 LayoutObject& root = *m_layoutSubtreeRoots.takeAny(); |
| 908 if (!root.needsLayout()) |
| 909 continue; |
| 910 layoutFromRootObject(root); |
| 911 |
| 912 // We need to ensure that we mark up all renderers up to the LayoutV
iew |
| 913 // for paint invalidation. This simplifies our code as we just alway
s |
| 914 // do a full tree walk. |
| 915 if (LayoutObject* container = root.container()) |
| 916 container->setMayNeedPaintInvalidation(); |
| 917 } |
| 918 } else { |
| 919 layoutFromRootObject(*layoutView()); |
| 920 } |
854 | 921 |
855 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllIma
geResourcePriorities(); | 922 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllIma
geResourcePriorities(); |
856 | 923 |
857 lifecycle().advanceTo(DocumentLifecycle::AfterPerformLayout); | 924 lifecycle().advanceTo(DocumentLifecycle::AfterPerformLayout); |
858 int layoutMs = (WTF::currentTimeMS() - start); | 925 int layoutMs = (WTF::currentTimeMS() - start); |
859 Platform::current()->histogramCustomCounts("Renderer.LayoutMs", layoutMs, 0,
1000 * 60, 50); | 926 Platform::current()->histogramCustomCounts("Renderer.LayoutMs", layoutMs, 0,
1000 * 60, 50); |
860 // TODO(benjhayden): re-enable when safe | 927 // TODO(benjhayden): re-enable when safe |
861 // Platform::current()->histogramCustomCounts("Renderer.LineLayoutMs", m_lin
eLayoutMs, 0, 1000 * 60, 50); | 928 // Platform::current()->histogramCustomCounts("Renderer.LineLayoutMs", m_lin
eLayoutMs, 0, 1000 * 60, 50); |
862 } | 929 } |
863 | 930 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 | 986 |
920 #if !ENABLE(OILPAN) | 987 #if !ENABLE(OILPAN) |
921 // If there is only one ref to this view left, then its going to be destroye
d as soon as we exit, | 988 // If there is only one ref to this view left, then its going to be destroye
d as soon as we exit, |
922 // so there's no point to continuing to layout | 989 // so there's no point to continuing to layout |
923 if (protector->hasOneRef()) | 990 if (protector->hasOneRef()) |
924 return; | 991 return; |
925 #endif | 992 #endif |
926 | 993 |
927 Document* document = m_frame->document(); | 994 Document* document = m_frame->document(); |
928 bool inSubtreeLayout = isSubtreeLayout(); | 995 bool inSubtreeLayout = isSubtreeLayout(); |
929 LayoutObject* rootForThisLayout = inSubtreeLayout ? m_layoutSubtreeRoot : do
cument->layoutView(); | 996 |
| 997 // FIXME: The notion of a single root for layout is no longer applicable. Re
move or update this code. crbug.com/460596 |
| 998 LayoutObject* rootForThisLayout = inSubtreeLayout ? *(m_layoutSubtreeRoots.b
egin()) : layoutView(); |
930 if (!rootForThisLayout) { | 999 if (!rootForThisLayout) { |
931 // FIXME: Do we need to set m_size here? | 1000 // FIXME: Do we need to set m_size here? |
932 ASSERT_NOT_REACHED(); | 1001 ASSERT_NOT_REACHED(); |
933 return; | 1002 return; |
934 } | 1003 } |
935 | 1004 |
936 FontCachePurgePreventer fontCachePurgePreventer; | 1005 FontCachePurgePreventer fontCachePurgePreventer; |
937 Layer* layer; | |
938 { | 1006 { |
939 TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled,
false); | 1007 TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled,
false); |
940 | 1008 |
941 m_nestedLayoutCount++; | 1009 m_nestedLayoutCount++; |
942 if (!inSubtreeLayout) { | 1010 if (!inSubtreeLayout) { |
943 Document* document = m_frame->document(); | 1011 clearLayoutSubtreeRootsAndMarkContainingBlocks(); |
944 Node* body = document->body(); | 1012 Node* body = document->body(); |
945 if (body && body->renderer()) { | 1013 if (body && body->renderer()) { |
946 if (isHTMLFrameSetElement(*body)) { | 1014 if (isHTMLFrameSetElement(*body)) { |
947 body->renderer()->setChildNeedsLayout(); | 1015 body->renderer()->setChildNeedsLayout(); |
948 } else if (isHTMLBodyElement(*body)) { | 1016 } else if (isHTMLBodyElement(*body)) { |
949 if (!m_firstLayout && m_size.height() != layoutSize().height
() && body->renderer()->enclosingBox()->stretchesToViewport()) | 1017 if (!m_firstLayout && m_size.height() != layoutSize().height
() && body->renderer()->enclosingBox()->stretchesToViewport()) |
950 body->renderer()->setChildNeedsLayout(); | 1018 body->renderer()->setChildNeedsLayout(); |
951 } | 1019 } |
952 } | 1020 } |
953 } | 1021 } |
954 updateCounters(); | 1022 updateCounters(); |
955 | 1023 |
956 ScrollbarMode hMode; | 1024 ScrollbarMode hMode; |
957 ScrollbarMode vMode; | 1025 ScrollbarMode vMode; |
958 calculateScrollbarModesForLayoutAndSetViewportRenderer(hMode, vMode); | 1026 calculateScrollbarModesForLayoutAndSetViewportRenderer(hMode, vMode); |
959 | 1027 |
960 if (!inSubtreeLayout) { | 1028 if (!inSubtreeLayout) { |
961 // Now set our scrollbar state for the layout. | 1029 // Now set our scrollbar state for the layout. |
962 ScrollbarMode currentHMode = horizontalScrollbarMode(); | 1030 ScrollbarMode currentHMode = horizontalScrollbarMode(); |
963 ScrollbarMode currentVMode = verticalScrollbarMode(); | 1031 ScrollbarMode currentVMode = verticalScrollbarMode(); |
964 | 1032 |
965 if (m_firstLayout) { | 1033 if (m_firstLayout) { |
966 setScrollbarsSuppressed(true); | 1034 setScrollbarsSuppressed(true); |
967 | 1035 |
968 m_doFullPaintInvalidation = true; | 1036 m_doFullPaintInvalidation = true; |
969 m_firstLayout = false; | 1037 m_firstLayout = false; |
970 m_firstLayoutCallbackPending = true; | 1038 m_firstLayoutCallbackPending = true; |
971 m_lastViewportSize = layoutSize(IncludeScrollbars); | 1039 m_lastViewportSize = layoutSize(IncludeScrollbars); |
972 m_lastZoomFactor = rootForThisLayout->style()->zoom(); | 1040 m_lastZoomFactor = layoutView()->style()->zoom(); |
973 | 1041 |
974 // Set the initial vMode to AlwaysOn if we're auto. | 1042 // Set the initial vMode to AlwaysOn if we're auto. |
975 if (vMode == ScrollbarAuto) | 1043 if (vMode == ScrollbarAuto) |
976 setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes
a vertical scrollbar to appear. | 1044 setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes
a vertical scrollbar to appear. |
977 // Set the initial hMode to AlwaysOff if we're auto. | 1045 // Set the initial hMode to AlwaysOff if we're auto. |
978 if (hMode == ScrollbarAuto) | 1046 if (hMode == ScrollbarAuto) |
979 setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This caus
es a horizontal scrollbar to disappear. | 1047 setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This caus
es a horizontal scrollbar to disappear. |
980 | 1048 |
981 setScrollbarModes(hMode, vMode); | 1049 setScrollbarModes(hMode, vMode); |
982 setScrollbarsSuppressed(false, true); | 1050 setScrollbarsSuppressed(false, true); |
(...skipping 15 matching lines...) Expand all Loading... |
998 bodyRenderer->setChildNeedsLayout(); | 1066 bodyRenderer->setChildNeedsLayout(); |
999 else if (rootRenderer && rootRenderer->stretchesToViewport()) | 1067 else if (rootRenderer && rootRenderer->stretchesToViewport()) |
1000 rootRenderer->setChildNeedsLayout(); | 1068 rootRenderer->setChildNeedsLayout(); |
1001 } | 1069 } |
1002 | 1070 |
1003 // We need to set m_doFullPaintInvalidation before triggering layout
as LayoutObject::checkForPaintInvalidation | 1071 // We need to set m_doFullPaintInvalidation before triggering layout
as LayoutObject::checkForPaintInvalidation |
1004 // checks the boolean to disable local paint invalidations. | 1072 // checks the boolean to disable local paint invalidations. |
1005 m_doFullPaintInvalidation |= layoutView()->shouldDoFullPaintInvalida
tionForNextLayout(); | 1073 m_doFullPaintInvalidation |= layoutView()->shouldDoFullPaintInvalida
tionForNextLayout(); |
1006 } | 1074 } |
1007 | 1075 |
1008 layer = rootForThisLayout->enclosingLayer(); | 1076 performLayout(inSubtreeLayout); |
1009 | 1077 |
1010 performLayout(rootForThisLayout, inSubtreeLayout); | 1078 ASSERT(m_layoutSubtreeRoots.isEmpty()); |
1011 | |
1012 m_layoutSubtreeRoot = nullptr; | |
1013 // We need to ensure that we mark up all renderers up to the LayoutView | |
1014 // for paint invalidation. This simplifies our code as we just always | |
1015 // do a full tree walk. | |
1016 if (LayoutObject* container = rootForThisLayout->container()) | |
1017 container->setMayNeedPaintInvalidation(); | |
1018 } // Reset m_layoutSchedulingEnabled to its previous value. | 1079 } // Reset m_layoutSchedulingEnabled to its previous value. |
1019 | 1080 |
1020 if (!inSubtreeLayout && !toLayoutView(rootForThisLayout)->document().printin
g()) | 1081 if (!inSubtreeLayout && !document->printing()) |
1021 adjustViewSize(); | 1082 adjustViewSize(); |
1022 | 1083 |
1023 layer->updateLayerPositionsAfterLayout(); | 1084 // FIXME: Could find the common ancestor layer of all dirty subtrees and mar
k from there. crbug.com/462719 |
| 1085 layoutView()->enclosingLayer()->updateLayerPositionsAfterLayout(); |
1024 | 1086 |
1025 layoutView()->compositor()->didLayout(); | 1087 layoutView()->compositor()->didLayout(); |
1026 | 1088 |
1027 m_layoutCount++; | 1089 m_layoutCount++; |
1028 | 1090 |
1029 if (AXObjectCache* cache = rootForThisLayout->document().axObjectCache()) { | 1091 if (AXObjectCache* cache = document->axObjectCache()) { |
1030 const KURL& url = rootForThisLayout->document().url(); | 1092 const KURL& url = document->url(); |
1031 if (url.isValid() && !url.isAboutBlankURL()) | 1093 if (url.isValid() && !url.isAboutBlankURL()) |
1032 cache->handleLayoutComplete(rootForThisLayout); | 1094 cache->handleLayoutComplete(document); |
1033 } | 1095 } |
1034 updateAnnotatedRegions(); | 1096 updateAnnotatedRegions(); |
1035 | 1097 |
1036 ASSERT(!rootForThisLayout->needsLayout()); | |
1037 | |
1038 if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) | 1098 if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) |
1039 updateOverflowStatus(layoutSize().width() < contentsWidth(), layoutSize(
).height() < contentsHeight()); | 1099 updateOverflowStatus(layoutSize().width() < contentsWidth(), layoutSize(
).height() < contentsHeight()); |
1040 | 1100 |
1041 scheduleOrPerformPostLayoutTasks(); | 1101 scheduleOrPerformPostLayoutTasks(); |
1042 | 1102 |
| 1103 // FIXME: The notion of a single root for layout is no longer applicable. Re
move or update this code. crbug.com/460596 |
1043 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Layout", "
endData", InspectorLayoutEvent::endData(rootForThisLayout)); | 1104 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Layout", "
endData", InspectorLayoutEvent::endData(rootForThisLayout)); |
1044 InspectorInstrumentation::didLayout(m_frame.get(), rootForThisLayout); | 1105 InspectorInstrumentation::didLayout(m_frame.get()); |
1045 | 1106 |
1046 m_nestedLayoutCount--; | 1107 m_nestedLayoutCount--; |
1047 if (m_nestedLayoutCount) | 1108 if (m_nestedLayoutCount) |
1048 return; | 1109 return; |
1049 | 1110 |
1050 #if ENABLE(ASSERT) | 1111 #if ENABLE(ASSERT) |
1051 // Post-layout assert that nobody was re-marked as needing layout during lay
out. | 1112 // Post-layout assert that nobody was re-marked as needing layout during lay
out. |
1052 document->layoutView()->assertSubtreeIsLaidOut(); | 1113 layoutView()->assertSubtreeIsLaidOut(); |
1053 #endif | 1114 #endif |
1054 | 1115 |
1055 // FIXME: It should be not possible to remove the FrameView from the frame/p
age during layout | 1116 // FIXME: It should be not possible to remove the FrameView from the frame/p
age during layout |
1056 // however m_inPerformLayout is not set for most of this function, so none o
f our RELEASE_ASSERTS | 1117 // however m_inPerformLayout is not set for most of this function, so none o
f our RELEASE_ASSERTS |
1057 // in LocalFrame/Page will fire. One of the post-layout tasks is disconnecti
ng the LocalFrame from | 1118 // in LocalFrame/Page will fire. One of the post-layout tasks is disconnecti
ng the LocalFrame from |
1058 // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.ht
ml | 1119 // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.ht
ml |
1059 // necessitating this check here. | 1120 // necessitating this check here. |
1060 // ASSERT(frame()->page()); | 1121 // ASSERT(frame()->page()); |
1061 if (frame().page()) | 1122 if (frame().page()) |
1062 frame().page()->chrome().client().layoutUpdated(m_frame.get()); | 1123 frame().page()->chrome().client().layoutUpdated(m_frame.get()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 | 1157 |
1097 if (m_frame->selection().isCaretBoundsDirty()) | 1158 if (m_frame->selection().isCaretBoundsDirty()) |
1098 m_frame->selection().invalidateCaretRect(); | 1159 m_frame->selection().invalidateCaretRect(); |
1099 } | 1160 } |
1100 | 1161 |
1101 DocumentLifecycle& FrameView::lifecycle() const | 1162 DocumentLifecycle& FrameView::lifecycle() const |
1102 { | 1163 { |
1103 return m_frame->document()->lifecycle(); | 1164 return m_frame->document()->lifecycle(); |
1104 } | 1165 } |
1105 | 1166 |
1106 void FrameView::gatherDebugLayoutRects(LayoutObject* layoutRoot) | |
1107 { | |
1108 bool isTracing; | |
1109 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("blink.debug.la
yout"), &isTracing); | |
1110 if (!isTracing) | |
1111 return; | |
1112 if (!layoutRoot->enclosingLayer()->hasCompositedLayerMapping()) | |
1113 return; | |
1114 // For access to compositedLayerMapping(). | |
1115 DisableCompositingQueryAsserts disabler; | |
1116 GraphicsLayer* graphicsLayer = layoutRoot->enclosingLayer()->compositedLayer
Mapping()->mainGraphicsLayer(); | |
1117 if (!graphicsLayer) | |
1118 return; | |
1119 | |
1120 GraphicsLayerDebugInfo& debugInfo = graphicsLayer->debugInfo(); | |
1121 | |
1122 debugInfo.currentLayoutRects().clear(); | |
1123 for (LayoutObject* renderer = layoutRoot; renderer; renderer = renderer->nex
tInPreOrder()) { | |
1124 if (renderer->layoutDidGetCalledSinceLastFrame()) { | |
1125 FloatQuad quad = renderer->localToAbsoluteQuad(FloatQuad(renderer->p
reviousPaintInvalidationRect())); | |
1126 LayoutRect rect = LayoutRect(quad.enclosingBoundingBox()); | |
1127 debugInfo.currentLayoutRects().append(rect); | |
1128 } | |
1129 } | |
1130 } | |
1131 | |
1132 LayoutBox* FrameView::embeddedContentBox() const | 1167 LayoutBox* FrameView::embeddedContentBox() const |
1133 { | 1168 { |
1134 LayoutView* layoutView = this->layoutView(); | 1169 LayoutView* layoutView = this->layoutView(); |
1135 if (!layoutView) | 1170 if (!layoutView) |
1136 return nullptr; | 1171 return nullptr; |
1137 | 1172 |
1138 LayoutObject* firstChild = layoutView->firstChild(); | 1173 LayoutObject* firstChild = layoutView->firstChild(); |
1139 if (!firstChild || !firstChild->isBox()) | 1174 if (!firstChild || !firstChild->isBox()) |
1140 return nullptr; | 1175 return nullptr; |
1141 | 1176 |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1796 | 1831 |
1797 void FrameView::handleLoadCompleted() | 1832 void FrameView::handleLoadCompleted() |
1798 { | 1833 { |
1799 // Once loading has completed, allow autoSize one last opportunity to | 1834 // Once loading has completed, allow autoSize one last opportunity to |
1800 // reduce the size of the frame. | 1835 // reduce the size of the frame. |
1801 if (m_autoSizeInfo) | 1836 if (m_autoSizeInfo) |
1802 m_autoSizeInfo->autoSizeIfNeeded(); | 1837 m_autoSizeInfo->autoSizeIfNeeded(); |
1803 maintainScrollPositionAtAnchor(0); | 1838 maintainScrollPositionAtAnchor(0); |
1804 } | 1839 } |
1805 | 1840 |
| 1841 void FrameView::clearLayoutSubtreeRoot(const LayoutObject& root) |
| 1842 { |
| 1843 m_layoutSubtreeRoots.remove(const_cast<LayoutObject*>(&root)); |
| 1844 } |
| 1845 |
| 1846 void FrameView::clearLayoutSubtreeRootsAndMarkContainingBlocks() |
| 1847 { |
| 1848 for (auto& iter : m_layoutSubtreeRoots) |
| 1849 iter->markContainingBlocksForLayout(false); |
| 1850 m_layoutSubtreeRoots.clear(); |
| 1851 } |
| 1852 |
1806 void FrameView::scheduleRelayout() | 1853 void FrameView::scheduleRelayout() |
1807 { | 1854 { |
1808 ASSERT(m_frame->view() == this); | 1855 ASSERT(m_frame->view() == this); |
1809 | 1856 |
1810 if (isSubtreeLayout()) { | |
1811 m_layoutSubtreeRoot->markContainingBlocksForLayout(false); | |
1812 m_layoutSubtreeRoot = nullptr; | |
1813 } | |
1814 if (!m_layoutSchedulingEnabled) | 1857 if (!m_layoutSchedulingEnabled) |
1815 return; | 1858 return; |
1816 if (!needsLayout()) | 1859 if (!needsLayout()) |
1817 return; | 1860 return; |
1818 if (!m_frame->document()->shouldScheduleLayout()) | 1861 if (!m_frame->document()->shouldScheduleLayout()) |
1819 return; | 1862 return; |
1820 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali
dateLayout", "data", InspectorInvalidateLayoutEvent::data(m_frame.get())); | 1863 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali
dateLayout", "data", InspectorInvalidateLayoutEvent::data(m_frame.get())); |
1821 | 1864 |
| 1865 clearLayoutSubtreeRootsAndMarkContainingBlocks(); |
| 1866 |
1822 if (m_hasPendingLayout) | 1867 if (m_hasPendingLayout) |
1823 return; | 1868 return; |
1824 m_hasPendingLayout = true; | 1869 m_hasPendingLayout = true; |
1825 | 1870 |
1826 page()->animator().scheduleVisualUpdate(m_frame.get()); | 1871 page()->animator().scheduleVisualUpdate(m_frame.get()); |
1827 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); | 1872 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); |
1828 } | 1873 } |
1829 | 1874 |
1830 static bool isObjectAncestorContainerOf(LayoutObject* ancestor, LayoutObject* de
scendant) | |
1831 { | |
1832 for (LayoutObject* r = descendant; r; r = r->container()) { | |
1833 if (r == ancestor) | |
1834 return true; | |
1835 } | |
1836 return false; | |
1837 } | |
1838 | |
1839 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot) | 1875 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot) |
1840 { | 1876 { |
1841 ASSERT(m_frame->view() == this); | 1877 ASSERT(m_frame->view() == this); |
1842 | 1878 |
1843 // FIXME: Should this call shouldScheduleLayout instead? | 1879 // FIXME: Should this call shouldScheduleLayout instead? |
1844 if (!m_frame->document()->isActive()) | 1880 if (!m_frame->document()->isActive()) |
1845 return; | 1881 return; |
1846 | 1882 |
1847 LayoutView* layoutView = this->layoutView(); | 1883 LayoutView* layoutView = this->layoutView(); |
1848 if (layoutView && layoutView->needsLayout()) { | 1884 if (layoutView && layoutView->needsLayout()) { |
1849 if (relayoutRoot) | 1885 if (relayoutRoot) |
1850 relayoutRoot->markContainingBlocksForLayout(false); | 1886 relayoutRoot->markContainingBlocksForLayout(false); |
1851 return; | 1887 return; |
1852 } | 1888 } |
1853 | 1889 |
1854 if (layoutPending() || !m_layoutSchedulingEnabled) { | 1890 if (relayoutRoot == layoutView) |
1855 if (m_layoutSubtreeRoot != relayoutRoot) { | 1891 clearLayoutSubtreeRootsAndMarkContainingBlocks(); |
1856 if (isObjectAncestorContainerOf(m_layoutSubtreeRoot, relayoutRoot))
{ | 1892 else |
1857 // Keep the current root | 1893 m_layoutSubtreeRoots.add(relayoutRoot); |
1858 relayoutRoot->markContainingBlocksForLayout(false, m_layoutSubtr
eeRoot); | 1894 if (m_layoutSchedulingEnabled) { |
1859 ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot
->container()->needsLayout()); | |
1860 } else if (isSubtreeLayout() && isObjectAncestorContainerOf(relayout
Root, m_layoutSubtreeRoot)) { | |
1861 // Re-root at relayoutRoot | |
1862 m_layoutSubtreeRoot->markContainingBlocksForLayout(false, relayo
utRoot); | |
1863 m_layoutSubtreeRoot = relayoutRoot; | |
1864 ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot
->container()->needsLayout()); | |
1865 } else { | |
1866 // Just do a full relayout | |
1867 if (isSubtreeLayout()) | |
1868 m_layoutSubtreeRoot->markContainingBlocksForLayout(false); | |
1869 m_layoutSubtreeRoot = nullptr; | |
1870 relayoutRoot->markContainingBlocksForLayout(false); | |
1871 } | |
1872 } | |
1873 } else if (m_layoutSchedulingEnabled) { | |
1874 m_layoutSubtreeRoot = relayoutRoot; | |
1875 ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->contai
ner()->needsLayout()); | |
1876 m_hasPendingLayout = true; | 1895 m_hasPendingLayout = true; |
1877 | 1896 |
1878 page()->animator().scheduleVisualUpdate(m_frame.get()); | 1897 page()->animator().scheduleVisualUpdate(m_frame.get()); |
1879 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); | 1898 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); |
1880 } | 1899 } |
1881 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali
dateLayout", "data", InspectorInvalidateLayoutEvent::data(m_frame.get())); | 1900 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali
dateLayout", "data", InspectorInvalidateLayoutEvent::data(m_frame.get())); |
1882 } | 1901 } |
1883 | 1902 |
1884 bool FrameView::layoutPending() const | 1903 bool FrameView::layoutPending() const |
1885 { | 1904 { |
(...skipping 2194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4080 { | 4099 { |
4081 Settings* settings = frame().settings(); | 4100 Settings* settings = frame().settings(); |
4082 if (!settings || !settings->rootLayerScrolls()) | 4101 if (!settings || !settings->rootLayerScrolls()) |
4083 return this; | 4102 return this; |
4084 | 4103 |
4085 LayoutView* layoutView = this->layoutView(); | 4104 LayoutView* layoutView = this->layoutView(); |
4086 return layoutView ? layoutView->scrollableArea() : nullptr; | 4105 return layoutView ? layoutView->scrollableArea() : nullptr; |
4087 } | 4106 } |
4088 | 4107 |
4089 } // namespace blink | 4108 } // namespace blink |
OLD | NEW |