Changeset 159218 in webkit
- Timestamp:
- Nov 13, 2013, 12:03:53 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r159214 r159218 1 2013-11-13 Simon Fraser <simon.fraser@apple.com> 2 3 ASSERTION FAILED: m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint()) after r135816 4 https://bugs.webkit.org/show_bug.cgi?id=103432 5 6 Reviewed by Dave Hyatt. 7 8 RenderLayer caches repaint rects in m_repaintRect, and on updating layer 9 positions after scrolling, asserts that the cached rect is correct. However, 10 this assertion would sometimes fail if we were scrolling as a result of 11 doing adjustViewSize() in the middle of layout, because we haven't updated 12 layer positions post-layout yet. 13 14 Fix by having the poorly named FrameView::repaintFixedElementsAfterScrolling() 15 skip the layer updating if this FrameView is inside of adjusetViewSize() in 16 layout. 17 18 In order to know if we're inside view size adjusting, add a LayoutPhase 19 member to FrameView, replacing two existing bools that track laying out state. 20 21 Investigative work showed that there are many, many ways to re-enter FrameView::layout(), 22 which makes it hard (but desirable) to more assertions about state changes, but 23 indicated that saving and restoring the state (via TemporaryChange<LayoutPhase>) 24 was a good idea. 25 26 * page/FrameView.cpp: 27 (WebCore::FrameView::FrameView): 28 (WebCore::FrameView::reset): 29 (WebCore::FrameView::updateCompositingLayersAfterStyleChange): 30 (WebCore::FrameView::layout): 31 (WebCore::FrameView::repaintFixedElementsAfterScrolling): 32 * page/FrameView.h: 33 1 34 2013-11-13 Myles C. Maxfield <mmaxfield@apple.com> 2 35 -
trunk/Source/WebCore/page/FrameView.cpp
r158655 r159218 174 174 , m_layoutTimer(this, &FrameView::layoutTimerFired) 175 175 , m_layoutRoot(0) 176 , m_layoutPhase(OutsideLayout) 176 177 , m_inSynchronousPostLayout(false) 177 178 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) … … 260 261 m_needsFullRepaint = true; 261 262 m_layoutSchedulingEnabled = true; 262 m_inLayout = false; 263 m_doingPreLayoutStyleUpdate = false; 263 m_layoutPhase = OutsideLayout; 264 264 m_inSynchronousPostLayout = false; 265 265 m_layoutCount = 0; … … 732 732 733 733 // If we expect to update compositing after an incipient layout, don't do so here. 734 if ( m_doingPreLayoutStyleUpdate|| layoutPending() || renderView->needsLayout())734 if (inPreLayoutStyleUpdate() || layoutPending() || renderView->needsLayout()) 735 735 return; 736 736 … … 1066 1066 void FrameView::layout(bool allowSubtree) 1067 1067 { 1068 if (m_inLayout) 1069 return; 1068 if (isInLayout()) 1069 return; 1070 1071 // Many of the tasks performed during layout can cause this function to be re-entered, 1072 // so save the layout phase now and restore it on exit. 1073 TemporaryChange<LayoutPhase> layoutPhaseRestorer(m_layoutPhase, InPreLayout); 1070 1074 1071 1075 // Protect the view from being deleted during layout (in recalcStyle) … … 1113 1117 // This is a new top-level layout. If there are any remaining tasks from the previous 1114 1118 // layout, finish them now. 1115 m_inSynchronousPostLayout = true;1119 TemporaryChange<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true); 1116 1120 performPostLayoutTasks(); 1117 m_inSynchronousPostLayout = false; 1118 } 1121 } 1122 1123 m_layoutPhase = InPreLayoutStyleUpdate; 1119 1124 1120 1125 // Viewport-dependent media queries may cause us to need completely different style information. … … 1133 1138 // Always ensure our style info is up-to-date. This can happen in situations where 1134 1139 // the layout beats any sort of style recalc update that needs to occur. 1135 TemporaryChange<bool> changeDoingPreLayoutStyleUpdate(m_doingPreLayoutStyleUpdate, true);1136 1140 document.updateStyleIfNeeded(); 1141 m_layoutPhase = InPreLayout; 1137 1142 1138 1143 subtree = m_layoutRoot; … … 1198 1203 else 1199 1204 m_lastViewportSize = visibleContentRect(IncludeScrollbars).size(); 1205 1200 1206 m_lastZoomFactor = root->style().zoom(); 1201 1207 … … 1228 1234 } 1229 1235 } 1236 1237 m_layoutPhase = InPreLayout; 1230 1238 } 1231 1239 … … 1241 1249 LayoutStateDisabler layoutStateDisabler(disableLayoutState ? &root->view() : 0); 1242 1250 1243 m_inLayout = true; 1251 ASSERT(m_layoutPhase == InPreLayout); 1252 m_layoutPhase = InLayout; 1253 1244 1254 beginDeferredRepaints(); 1245 1255 forceLayoutParentViewIfNeeded(); 1256 1257 ASSERT(m_layoutPhase == InLayout); 1258 1246 1259 root->layout(); 1247 1260 #if ENABLE(IOS_TEXT_AUTOSIZING) … … 1260 1273 #endif 1261 1274 endDeferredRepaints(); 1262 m_inLayout = false; 1275 1276 ASSERT(m_layoutPhase == InLayout); 1263 1277 1264 1278 if (subtree) … … 1270 1284 } 1271 1285 1286 m_layoutPhase = InViewSizeAdjust; 1287 1272 1288 bool neededFullRepaint = m_needsFullRepaint; 1273 1289 1274 1290 if (!subtree && !toRenderView(*root).printing()) 1275 1291 adjustViewSize(); 1292 1293 m_layoutPhase = InPostLayout; 1276 1294 1277 1295 m_needsFullRepaint = neededFullRepaint; … … 1315 1333 updateWidgetPositions(); 1316 1334 else { 1317 m_inSynchronousPostLayout = true;1335 TemporaryChange<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true); 1318 1336 performPostLayoutTasks(); // Calls resumeScheduledEvents(). 1319 m_inSynchronousPostLayout = false;1320 1337 } 1321 1338 } … … 1948 1965 void FrameView::repaintFixedElementsAfterScrolling() 1949 1966 { 1967 // If we're scrolling as a result of updating the view size after layout, we'll update widgets and layer positions soon anyway. 1968 if (m_layoutPhase == InViewSizeAdjust) 1969 return; 1970 1950 1971 // For fixed position elements, update widget positions and compositing layers after scrolling, 1951 1972 // but only if we're not inside of layout. -
trunk/Source/WebCore/page/FrameView.h
r159023 r159218 110 110 void unscheduleRelayout(); 111 111 bool layoutPending() const; 112 bool isInLayout() const { return m_ inLayout; }112 bool isInLayout() const { return m_layoutPhase == InLayout; } 113 113 114 114 RenderObject* layoutRoot(bool onlyDuringLayout = false) const; … … 447 447 void init(); 448 448 449 enum LayoutPhase { 450 OutsideLayout, 451 InPreLayout, 452 InPreLayoutStyleUpdate, 453 InLayout, 454 InViewSizeAdjust, 455 InPostLayout, 456 }; 457 LayoutPhase layoutPhase() const { return m_layoutPhase; } 458 459 bool inPreLayoutStyleUpdate() const { return m_layoutPhase == InPreLayoutStyleUpdate; } 460 449 461 virtual bool isFrameView() const OVERRIDE { return true; } 450 462 … … 564 576 bool m_delayedLayout; 565 577 RenderElement* m_layoutRoot; 566 578 579 LayoutPhase m_layoutPhase; 567 580 bool m_layoutSchedulingEnabled; 568 bool m_inLayout;569 bool m_doingPreLayoutStyleUpdate;570 581 bool m_inSynchronousPostLayout; 571 582 int m_layoutCount;
Note:
See TracChangeset
for help on using the changeset viewer.