Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: Source/core/rendering/RenderView.cpp

Issue 143323014: *** DO NOT LAND *** Attempt to understand Regions complexity Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderView.h ('k') | Source/core/rendering/RootInlineBox.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 13 matching lines...) Expand all
24 #include "RuntimeEnabledFeatures.h" 24 #include "RuntimeEnabledFeatures.h"
25 #include "core/dom/Document.h" 25 #include "core/dom/Document.h"
26 #include "core/dom/Element.h" 26 #include "core/dom/Element.h"
27 #include "core/html/HTMLDialogElement.h" 27 #include "core/html/HTMLDialogElement.h"
28 #include "core/html/HTMLFrameOwnerElement.h" 28 #include "core/html/HTMLFrameOwnerElement.h"
29 #include "core/html/HTMLIFrameElement.h" 29 #include "core/html/HTMLIFrameElement.h"
30 #include "core/frame/Frame.h" 30 #include "core/frame/Frame.h"
31 #include "core/page/Page.h" 31 #include "core/page/Page.h"
32 #include "core/rendering/ColumnInfo.h" 32 #include "core/rendering/ColumnInfo.h"
33 #include "core/rendering/CompositedLayerMapping.h" 33 #include "core/rendering/CompositedLayerMapping.h"
34 #include "core/rendering/FlowThreadController.h"
35 #include "core/rendering/GraphicsContextAnnotator.h" 34 #include "core/rendering/GraphicsContextAnnotator.h"
36 #include "core/rendering/HitTestResult.h" 35 #include "core/rendering/HitTestResult.h"
37 #include "core/rendering/LayoutRectRecorder.h" 36 #include "core/rendering/LayoutRectRecorder.h"
38 #include "core/rendering/RenderFlowThread.h"
39 #include "core/rendering/RenderGeometryMap.h" 37 #include "core/rendering/RenderGeometryMap.h"
40 #include "core/rendering/RenderLayer.h" 38 #include "core/rendering/RenderLayer.h"
41 #include "core/rendering/RenderLayerCompositor.h" 39 #include "core/rendering/RenderLayerCompositor.h"
42 #include "core/rendering/RenderSelectionInfo.h" 40 #include "core/rendering/RenderSelectionInfo.h"
43 #include "core/svg/SVGDocumentExtensions.h" 41 #include "core/svg/SVGDocumentExtensions.h"
44 #include "platform/geometry/FloatQuad.h" 42 #include "platform/geometry/FloatQuad.h"
45 #include "platform/geometry/TransformState.h" 43 #include "platform/geometry/TransformState.h"
46 #include "platform/graphics/GraphicsContext.h" 44 #include "platform/graphics/GraphicsContext.h"
47 45
48 namespace WebCore { 46 namespace WebCore {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 164
167 LayoutRectRecorder recorder(*this); 165 LayoutRectRecorder recorder(*this);
168 RenderBlock::layout(); 166 RenderBlock::layout();
169 167
170 if (RuntimeEnabledFeatures::dialogElementEnabled()) 168 if (RuntimeEnabledFeatures::dialogElementEnabled())
171 positionDialogs(); 169 positionDialogs();
172 170
173 if (m_frameView->partialLayout().isStopping()) 171 if (m_frameView->partialLayout().isStopping())
174 return; 172 return;
175 173
176 if (hasRenderNamedFlowThreads())
177 flowThreadController()->layoutRenderNamedFlowThreads();
178
179 #ifndef NDEBUG 174 #ifndef NDEBUG
180 checkLayoutState(state); 175 checkLayoutState(state);
181 #endif 176 #endif
182 } 177 }
183 178
184 #ifndef NDEBUG 179 #ifndef NDEBUG
185 void RenderView::checkLayoutState(const LayoutState& state) 180 void RenderView::checkLayoutState(const LayoutState& state)
186 { 181 {
187 ASSERT(layoutDeltaMatches(LayoutSize())); 182 ASSERT(layoutDeltaMatches(LayoutSize()));
188 ASSERT(!m_layoutStateDisableCount); 183 ASSERT(!m_layoutStateDisableCount);
189 ASSERT(m_layoutState == &state); 184 ASSERT(m_layoutState == &state);
190 } 185 }
191 #endif 186 #endif
192 187
193 static RenderBox* enclosingSeamlessRenderer(const Document& doc) 188 static RenderBox* enclosingSeamlessRenderer(const Document& doc)
194 { 189 {
195 Element* ownerElement = doc.seamlessParentIFrame(); 190 Element* ownerElement = doc.seamlessParentIFrame();
196 if (!ownerElement) 191 if (!ownerElement)
197 return 0; 192 return 0;
198 return ownerElement->renderBox(); 193 return ownerElement->renderBox();
199 } 194 }
200 195
201 void RenderView::addChild(RenderObject* newChild, RenderObject* beforeChild)
202 {
203 // Seamless iframes are considered part of an enclosing render flow thread f rom the parent document. This is necessary for them to look
204 // up regions in the parent document during layout.
205 if (newChild && !newChild->isRenderFlowThread()) {
206 RenderBox* seamlessBox = enclosingSeamlessRenderer(document());
207 if (seamlessBox && seamlessBox->flowThreadContainingBlock())
208 newChild->setFlowThreadState(seamlessBox->flowThreadState());
209 }
210 RenderBlock::addChild(newChild, beforeChild);
211 }
212
213 bool RenderView::initializeLayoutState(LayoutState& state) 196 bool RenderView::initializeLayoutState(LayoutState& state)
214 { 197 {
215 bool isSeamlessAncestorInFlowThread = false;
216
217 // FIXME: May be better to push a clip and avoid issuing offscreen repaints. 198 // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
218 state.m_clipped = false; 199 state.m_clipped = false;
219 200
220 // Check the writing mode of the seamless ancestor. It has to match our docu ment's writing mode, or we won't inherit any 201 // Check the writing mode of the seamless ancestor. It has to match our docu ment's writing mode, or we won't inherit any
221 // pagination information. 202 // pagination information.
222 RenderBox* seamlessAncestor = enclosingSeamlessRenderer(document()); 203 RenderBox* seamlessAncestor = enclosingSeamlessRenderer(document());
223 LayoutState* seamlessLayoutState = seamlessAncestor ? seamlessAncestor->view ()->layoutState() : 0; 204 LayoutState* seamlessLayoutState = seamlessAncestor ? seamlessAncestor->view ()->layoutState() : 0;
224 bool shouldInheritPagination = seamlessLayoutState && !m_pageLogicalHeight & & seamlessAncestor->style()->writingMode() == style()->writingMode(); 205 bool shouldInheritPagination = seamlessLayoutState && !m_pageLogicalHeight & & seamlessAncestor->style()->writingMode() == style()->writingMode();
225 206
226 state.m_pageLogicalHeight = shouldInheritPagination ? seamlessLayoutState->m _pageLogicalHeight : m_pageLogicalHeight; 207 state.m_pageLogicalHeight = shouldInheritPagination ? seamlessLayoutState->m _pageLogicalHeight : m_pageLogicalHeight;
227 state.m_pageLogicalHeightChanged = shouldInheritPagination ? seamlessLayoutS tate->m_pageLogicalHeightChanged : m_pageLogicalHeightChanged; 208 state.m_pageLogicalHeightChanged = shouldInheritPagination ? seamlessLayoutS tate->m_pageLogicalHeightChanged : m_pageLogicalHeightChanged;
228 state.m_isPaginated = state.m_pageLogicalHeight; 209 state.m_isPaginated = state.m_pageLogicalHeight;
229 if (state.m_isPaginated && shouldInheritPagination) { 210 if (state.m_isPaginated && shouldInheritPagination) {
230 // Set up the correct pagination offset. We can use a negative offset in order to push the top of the RenderView into its correct place 211 // Set up the correct pagination offset. We can use a negative offset in order to push the top of the RenderView into its correct place
231 // on a page. We can take the iframe's offset from the logical top of th e first page and make the negative into the pagination offset within the child 212 // on a page. We can take the iframe's offset from the logical top of th e first page and make the negative into the pagination offset within the child
232 // view. 213 // view.
233 bool isFlipped = seamlessAncestor->style()->isFlippedBlocksWritingMode() ; 214 bool isFlipped = seamlessAncestor->style()->isFlippedBlocksWritingMode() ;
234 LayoutSize layoutOffset = seamlessLayoutState->layoutOffset(); 215 LayoutSize layoutOffset = seamlessLayoutState->layoutOffset();
235 LayoutSize iFrameOffset(layoutOffset.width() + seamlessAncestor->x() + ( !isFlipped ? seamlessAncestor->borderLeft() + seamlessAncestor->paddingLeft() : 216 LayoutSize iFrameOffset(layoutOffset.width() + seamlessAncestor->x() + ( !isFlipped ? seamlessAncestor->borderLeft() + seamlessAncestor->paddingLeft() :
236 seamlessAncestor->borderRight() + seamlessAncestor->paddingRight()), 217 seamlessAncestor->borderRight() + seamlessAncestor->paddingRight()),
237 layoutOffset.height() + seamlessAncestor->y() + (!isFlipped ? seamle ssAncestor->borderTop() + seamlessAncestor->paddingTop() : 218 layoutOffset.height() + seamlessAncestor->y() + (!isFlipped ? seamle ssAncestor->borderTop() + seamlessAncestor->paddingTop() :
238 seamlessAncestor->borderBottom() + seamlessAncestor->paddingBottom() )); 219 seamlessAncestor->borderBottom() + seamlessAncestor->paddingBottom() ));
239 220
240 LayoutSize offsetDelta = seamlessLayoutState->m_pageOffset - iFrameOffse t; 221 LayoutSize offsetDelta = seamlessLayoutState->m_pageOffset - iFrameOffse t;
241 state.m_pageOffset = offsetDelta; 222 state.m_pageOffset = offsetDelta;
242
243 // Set the current render flow thread to point to our ancestor. This wil l allow the seamless document to locate the correct
244 // regions when doing a layout.
245 if (seamlessAncestor->flowThreadContainingBlock()) {
246 flowThreadController()->setCurrentRenderFlowThread(seamlessAncestor- >view()->flowThreadController()->currentRenderFlowThread());
247 isSeamlessAncestorInFlowThread = true;
248 }
249 } 223 }
250 224
251 // FIXME: We need to make line grids and exclusions work with seamless ifram es as well here. Basically all layout state information needs 225 // FIXME: We need to make line grids and exclusions work with seamless ifram es as well here. Basically all layout state information needs
252 // to propagate here and not just pagination information. 226 // to propagate here and not just pagination information.
253 return isSeamlessAncestorInFlowThread; 227 return false;
254 }
255
256 // The algorithm below assumes this is a full layout. In case there are previous ly computed values for regions, supplemental steps are taken
257 // to ensure the results are the same as those obtained from a full layout (i.e. the auto-height regions from all the flows are marked as needing
258 // layout).
259 // 1. The flows are laid out from the outer flow to the inner flow. This success fully computes the outer non-auto-height regions size so the
260 // inner flows have the necessary information to correctly fragment the content.
261 // 2. The flows are laid out from the inner flow to the outer flow. After an inn er flow is laid out it goes into the constrained layout phase
262 // and marks the auto-height regions they need layout. This means the outer flow s will relayout if they depend on regions with auto-height regions
263 // belonging to inner flows. This step will correctly set the computedAutoHeight for the auto-height regions. It's possible for non-auto-height
264 // regions to relayout if they depend on auto-height regions. This will invalida te the inner flow threads and mark them as needing layout.
265 // 3. The last step is to do one last layout if there are pathological dependenc ies between non-auto-height regions and auto-height regions
266 // as detected in the previous step.
267 void RenderView::layoutContentInAutoLogicalHeightRegions(const LayoutState& stat e)
268 {
269 if (!m_frameView->partialLayout().isStopping()) {
270 // Disable partial layout for any two-pass layout algorithm.
271 m_frameView->partialLayout().reset();
272 }
273
274 // We need to invalidate all the flows with auto-height regions if one such flow needs layout.
275 // If none is found we do a layout a check back again afterwards.
276 if (!flowThreadController()->updateFlowThreadsNeedingLayout()) {
277 // Do a first layout of the content. In some cases more layouts are not needed (e.g. only flows with non-auto-height regions have changed).
278 layoutContent(state);
279
280 // If we find no named flow needing a two step layout after the first la yout, exit early.
281 // Otherwise, initiate the two step layout algorithm and recompute all t he flows.
282 if (!flowThreadController()->updateFlowThreadsNeedingTwoStepLayout())
283 return;
284 }
285
286 // Layout to recompute all the named flows with auto-height regions.
287 layoutContent(state);
288
289 // Propagate the computed auto-height values upwards.
290 // Non-auto-height regions may invalidate the flow thread because they depen ded on auto-height regions, but that's ok.
291 flowThreadController()->updateFlowThreadsIntoConstrainedPhase();
292
293 // Do one last layout that should update the auto-height regions found in th e main flow
294 // and solve pathological dependencies between regions (e.g. a non-auto-heig ht region depending
295 // on an auto-height one).
296 if (needsLayout())
297 layoutContent(state);
298 } 228 }
299 229
300 void RenderView::layout() 230 void RenderView::layout()
301 { 231 {
302 if (!document().paginated()) 232 if (!document().paginated())
303 setPageLogicalHeight(0); 233 setPageLogicalHeight(0);
304 234
305 if (shouldUsePrintingLayout()) 235 if (shouldUsePrintingLayout())
306 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth() ; 236 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth() ;
307 237
(...skipping 16 matching lines...) Expand all
324 254
325 if (document().svgExtensions()) 255 if (document().svgExtensions())
326 document().accessSVGExtensions()->invalidateSVGRootsWithRelativeLeng thDescendents(&layoutScope); 256 document().accessSVGExtensions()->invalidateSVGRootsWithRelativeLeng thDescendents(&layoutScope);
327 } 257 }
328 258
329 ASSERT(!m_layoutState); 259 ASSERT(!m_layoutState);
330 if (!needsLayout()) 260 if (!needsLayout())
331 return; 261 return;
332 262
333 LayoutState state; 263 LayoutState state;
334 bool isSeamlessAncestorInFlowThread = initializeLayoutState(state); 264 initializeLayoutState(state);
335 265
336 m_pageLogicalHeightChanged = false; 266 m_pageLogicalHeightChanged = false;
337 m_layoutState = &state; 267 m_layoutState = &state;
338 268
339 if (checkTwoPassLayoutForAutoHeightRegions()) 269 layoutContent(state);
340 layoutContentInAutoLogicalHeightRegions(state);
341 else
342 layoutContent(state);
343 270
344 if (m_frameView->partialLayout().isStopping()) { 271 if (m_frameView->partialLayout().isStopping()) {
345 m_layoutState = 0; 272 m_layoutState = 0;
346 return; 273 return;
347 } 274 }
348 275
349 #ifndef NDEBUG 276 #ifndef NDEBUG
350 checkLayoutState(state); 277 checkLayoutState(state);
351 #endif 278 #endif
352 m_layoutState = 0; 279 m_layoutState = 0;
353 clearNeedsLayout(); 280 clearNeedsLayout();
354
355 if (isSeamlessAncestorInFlowThread)
356 flowThreadController()->setCurrentRenderFlowThread(0);
357 } 281 }
358 282
359 void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContai ner, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) c onst 283 void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContai ner, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) c onst
360 { 284 {
361 ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == static_cast<bool>(mode & I sFixed)); 285 ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == static_cast<bool>(mode & I sFixed));
362 286
363 if (!repaintContainer && mode & UseTransforms && shouldUseTransformFromConta iner(0)) { 287 if (!repaintContainer && mode & UseTransforms && shouldUseTransformFromConta iner(0)) {
364 TransformationMatrix t; 288 TransformationMatrix t;
365 getTransformFromContainer(0, LayoutSize(), t); 289 getTransformFromContainer(0, LayoutSize(), t);
366 transformState.applyTransform(t); 290 transformState.applyTransform(t);
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 float RenderView::zoomFactor() const 948 float RenderView::zoomFactor() const
1025 { 949 {
1026 return m_frameView->frame().pageZoomFactor(); 950 return m_frameView->frame().pageZoomFactor();
1027 } 951 }
1028 952
1029 void RenderView::pushLayoutState(RenderObject* root) 953 void RenderView::pushLayoutState(RenderObject* root)
1030 { 954 {
1031 ASSERT(m_layoutStateDisableCount == 0); 955 ASSERT(m_layoutStateDisableCount == 0);
1032 ASSERT(m_layoutState == 0); 956 ASSERT(m_layoutState == 0);
1033 957
1034 pushLayoutStateForCurrentFlowThread(root);
1035 m_layoutState = new LayoutState(root); 958 m_layoutState = new LayoutState(root);
1036 } 959 }
1037 960
1038 bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) cons t 961 bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) cons t
1039 { 962 {
1040 RenderObject* o = renderer; 963 RenderObject* o = renderer;
1041 while (o) { 964 while (o) {
1042 if (o->hasColumns() || o->hasTransform() || o->hasReflection()) 965 if (o->hasColumns() || o->hasTransform() || o->hasReflection())
1043 return true; 966 return true;
1044 o = o->container(); 967 o = o->container();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 999
1077 return m_compositor.get(); 1000 return m_compositor.get();
1078 } 1001 }
1079 1002
1080 void RenderView::setIsInWindow(bool isInWindow) 1003 void RenderView::setIsInWindow(bool isInWindow)
1081 { 1004 {
1082 if (m_compositor) 1005 if (m_compositor)
1083 m_compositor->setIsInWindow(isInWindow); 1006 m_compositor->setIsInWindow(isInWindow);
1084 } 1007 }
1085 1008
1086 void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl e)
1087 {
1088 RenderBlock::styleDidChange(diff, oldStyle);
1089 if (hasRenderNamedFlowThreads())
1090 flowThreadController()->styleDidChange();
1091 }
1092
1093 bool RenderView::hasRenderNamedFlowThreads() const
1094 {
1095 return m_flowThreadController && m_flowThreadController->hasRenderNamedFlowT hreads();
1096 }
1097
1098 bool RenderView::checkTwoPassLayoutForAutoHeightRegions() const
1099 {
1100 return hasRenderNamedFlowThreads() && m_flowThreadController->hasFlowThreads WithAutoLogicalHeightRegions();
1101 }
1102
1103 FlowThreadController* RenderView::flowThreadController()
1104 {
1105 if (!m_flowThreadController)
1106 m_flowThreadController = FlowThreadController::create(this);
1107
1108 return m_flowThreadController.get();
1109 }
1110
1111 void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject* object)
1112 {
1113 if (!m_flowThreadController)
1114 return;
1115
1116 RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderF lowThread();
1117 if (!currentFlowThread)
1118 return;
1119
1120 currentFlowThread->pushFlowThreadLayoutState(object);
1121 }
1122
1123 void RenderView::popLayoutStateForCurrentFlowThread()
1124 {
1125 if (!m_flowThreadController)
1126 return;
1127
1128 RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderF lowThread();
1129 if (!currentFlowThread)
1130 return;
1131
1132 currentFlowThread->popFlowThreadLayoutState();
1133 }
1134
1135 IntervalArena* RenderView::intervalArena() 1009 IntervalArena* RenderView::intervalArena()
1136 { 1010 {
1137 if (!m_intervalArena) 1011 if (!m_intervalArena)
1138 m_intervalArena = IntervalArena::create(); 1012 m_intervalArena = IntervalArena::create();
1139 return m_intervalArena.get(); 1013 return m_intervalArena.get();
1140 } 1014 }
1141 1015
1142 bool RenderView::backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const 1016 bool RenderView::backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const
1143 { 1017 {
1144 // FIXME: Remove this main frame check. Same concept applies to subframes to o. 1018 // FIXME: Remove this main frame check. Same concept applies to subframes to o.
1145 if (!m_frameView || !m_frameView->isMainFrame()) 1019 if (!m_frameView || !m_frameView->isMainFrame())
1146 return false; 1020 return false;
1147 1021
1148 return m_frameView->hasOpaqueBackground(); 1022 return m_frameView->hasOpaqueBackground();
1149 } 1023 }
1150 1024
1151 double RenderView::layoutViewportWidth() const 1025 double RenderView::layoutViewportWidth() const
1152 { 1026 {
1153 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1; 1027 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
1154 return viewWidth(ScrollableArea::IncludeScrollbars) / scale; 1028 return viewWidth(ScrollableArea::IncludeScrollbars) / scale;
1155 } 1029 }
1156 1030
1157 double RenderView::layoutViewportHeight() const 1031 double RenderView::layoutViewportHeight() const
1158 { 1032 {
1159 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1; 1033 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
1160 return viewHeight(ScrollableArea::IncludeScrollbars) / scale; 1034 return viewHeight(ScrollableArea::IncludeScrollbars) / scale;
1161 } 1035 }
1162 1036
1163 } // namespace WebCore 1037 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderView.h ('k') | Source/core/rendering/RootInlineBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698