Changeset 21183 in webkit
- Timestamp:
- Apr 29, 2007, 1:09:08 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r21177 r21183 1 2007-04-29 Mitz Pettel <mitz@webkit.org> 2 3 Reviewed by Darin and Hyatt. 4 5 - test and updated results for http://bugs.webkit.org/show_bug.cgi?id=13487 6 Implement O(1) absoluteClippedOverflowRect and absoluteOutlineBox during layout for a possible speed gain 7 8 * fast/repaint/bugzilla-3509-expected.checksum: 9 * fast/repaint/bugzilla-3509-expected.png: 10 * fast/repaint/intermediate-layout-position-clip-expected.checksum: Added. 11 * fast/repaint/intermediate-layout-position-clip-expected.png: Added. 12 * fast/repaint/intermediate-layout-position-clip-expected.txt: Added. 13 * fast/repaint/intermediate-layout-position-clip.html: Added. 14 * fast/repaint/intermediate-layout-position-expected.checksum: 15 * fast/repaint/intermediate-layout-position-expected.png: 16 1 17 2007-04-28 Adele Peterson <adele@apple.com> 2 18 -
trunk/LayoutTests/fast/repaint/bugzilla-3509-expected.checksum
r14089 r21183 1 2af7cd983d67fe56c79c8a968bdaa75d 1 5bd77316c6336bd3dc5382806f5e5a36 -
trunk/LayoutTests/fast/repaint/intermediate-layout-position-expected.checksum
r19492 r21183 1 1e297091caae6dc9b0bb887a590021a6 1 ff2ab8ca87826c939775ba447f3a6d84 -
trunk/WebCore/ChangeLog
r21181 r21183 1 2007-04-29 Mitz Pettel <mitz@webkit.org> 2 3 Reviewed by Darin and Hyatt. 4 5 - http://bugs.webkit.org/show_bug.cgi?id=13487 6 Implement O(1) absoluteClippedOverflowRect and absoluteOutlineBox during layout for a possible speed gain 7 8 Test for a bug fixed by this patch: fast/repaint/intermediate-layout-position-clip.html 9 10 By keeping track of the total translation and clip during layout, absolutePosition and 11 computeAbsoluteRepaintRect become O(1). 12 13 * WebCore.pro: Added LayoutState.cpp 14 * WebCore.vcproj/WebCore/WebCore.vcproj: Added LayoutState.{cpp,h} 15 * WebCore.xcodeproj/project.pbxproj: Added LayoutState.{cpp,h} 16 * WebCoreSources.bkl: Added LayoutState.cpp 17 * page/FrameView.cpp: 18 (WebCore::FrameView::layout): When doing subtree layout, push an initial layout state for the 19 layout root. 20 * rendering/LayoutState.cpp: Added. A LayoutState corresponding to a box consists of the origin of 21 its coordinate system in view coordinates and possibly the clip rect, in view coordinates, which 22 applies to its children. 23 (WebCore::LayoutState::LayoutState): 24 (WebCore::LayoutState::destroy): 25 (WebCore::throw): 26 (WebCore::LayoutState::operator delete): 27 * rendering/LayoutState.h: Added. 28 (WebCore::LayoutState::LayoutState): 29 * rendering/RenderBlock.cpp: 30 (WebCore::RenderBlock::layoutBlock): Factored out the "only positioned objects" case into 31 layoutOnlyPositionedObjects(). Added code to push/pop LayoutState, unless we have columns, in 32 which case we disable/enable LayoutState. Removed the translation by the layout delta 33 of the old absolute rects, since that is now integral to absoluteClippedOverflowRect() and 34 absoluteOutlineBox(). 35 (WebCore::RenderBlock::layoutOnlyPositionedObjects): Added this helper function that checks for 36 and handles the case where only positioned objects need layout. Returns true in that case. 37 (WebCore::RenderBlock::repaintOverhangingFloats): Disabled LayoutState when repainting floats, since 38 they may belong to other containers. 39 (WebCore::RenderBlock::updateFirstLetter): Disabled LayoutState when adding and removing from the 40 first letter container, since it may be different than ourselves. 41 * rendering/RenderBlock.h: 42 * rendering/RenderBox.cpp: 43 (WebCore::RenderBox::setStyle): Minor cleanup: changed element()->document() to the equivalent document(). 44 (WebCore::RenderBox::offsetForPositionedInContainer): Added. Factored out common code from 45 absolutePosition, computeAbsoluteRepaintRect and RenderLayer::updateLayerPosition into this function. 46 (WebCore::RenderBox::absolutePosition): Added an O(1) code path when this function is called during 47 layout (and LayoutState has not been disabled). Factored out some code into 48 offsetForPositionedInContainer. 49 (WebCore::RenderBox::absoluteClippedOverflowRect): Added the layout delta here, so callers don't need 50 to. 51 (WebCore::RenderBox::computeAbsoluteRepaintRect): Added an O(1) code path when this function is called 52 during layout (and LayoutState has not been disabled). Factored out some code into 53 offsetForPositionedInContainer. 54 * rendering/RenderContainer.cpp: 55 (WebCore::RenderContainer::layout): Added LayoutState push/pop. 56 * rendering/RenderFlexibleBox.cpp: 57 (WebCore::RenderFlexibleBox::layoutBlock): Factored out the "only positioned objects" case into 58 layoutOnlyPositionedObjects(). Added LayoutState push/pop. Removed the translation by the layout delta 59 of the old absolute rects, since that is now integral to absoluteClippedOverflowRect() and 60 absoluteOutlineBox(). 61 * rendering/RenderFlow.cpp: 62 (WebCore::RenderFlow::absoluteClippedOverflowRect): Added an ASSERT. 63 * rendering/RenderForeignObject.cpp: 64 (WebCore::RenderForeignObject::layout): Disabled LayoutState because it is incompatible with arbitrary 65 affine transforms. 66 * rendering/RenderHTMLCanvas.cpp: 67 (WebCore::RenderHTMLCanvas::layout): Removed the translation by the layout delta of the old absolute 68 rects, since that is now integral to absoluteClippedOverflowRect() and absoluteOutlineBox(). 69 * rendering/RenderImage.cpp: 70 (WebCore::RenderImage::layout): Ditto. 71 * rendering/RenderLayer.cpp: 72 (WebCore::RenderLayer::updateLayerPositions): Added ASSERTs. Factored out some code into 73 RenderBox::offsetForPositionedInContainer. 74 (WebCore::RenderLayer::updateScrollInfoAfterLayout): Disabled LayoutState around the call to 75 scrollToOffset. 76 * rendering/RenderListItem.cpp: 77 (WebCore::RenderListItem::updateMarkerLocation): Disabled LayoutState when moving the list marker, since 78 it can trigger repainting in other containers. 79 * rendering/RenderObject.cpp: 80 (WebCore::RenderObject::isRoot): Minor cleanup: changed element()->document() to the equivalent 81 document(). 82 (WebCore::RenderObject::computeAbsoluteRepaintRect): Removed 'return' at the end of the function. 83 (WebCore::RenderObject::container): Reordered to avoid calling isText() twice. 84 (WebCore::RenderObject::absoluteOutlineBox): Added the layout delta here, so callers don't need to. 85 * rendering/RenderSVGContainer.cpp: 86 (WebCore::RenderSVGContainer::layout): Disabled LayoutState because it is incompatible with arbitrary 87 affine transforms. 88 * rendering/RenderTable.cpp: 89 (WebCore::RenderTable::layout): Factored out the "only positioned objects" case into 90 layoutOnlyPositionedObjects(). Added LayoutState push/pop. Removed the translation by the layout delta 91 of the old absolute rects, since that is now integral to absoluteClippedOverflowRect() and 92 absoluteOutlineBox(). 93 * rendering/RenderTableCell.cpp: 94 (WebCore::RenderTableCell::absoluteClippedOverflowRect): Added the layout delta here, so callers 95 don't need to. 96 (WebCore::RenderTableCell::computeAbsoluteRepaintRect): For the O(1) code path, skipped the correction 97 for the parent row, because RenderTableRow doesn't push a translation into LayoutState. 98 (WebCore::RenderTableCell::absolutePosition): Ditto. 99 * rendering/RenderTableRow.cpp: 100 (WebCore::RenderTableRow::layout): Added LayoutState push/pop. 101 * rendering/RenderTableSection.cpp: 102 (WebCore::RenderTableSection::setCellWidths): Added LayoutState push/pop if cells are repainted or 103 receive layout. 104 (WebCore::RenderTableSection::calcRowHeight): Ditto. 105 (WebCore::RenderTableSection::layoutRows): Added LayoutState push/pop. 106 * rendering/RenderView.cpp: 107 (WebCore::RenderView::RenderView): 108 (WebCore::RenderView::layout): Added initial LayoutState setup for the layout. 109 (WebCore::RenderView::paintBoxDecorations): Minor cleanup: changed element()->document() to the 110 equivalent document(). 111 (WebCore::RenderView::repaintViewRectangle): Ditto. 112 (WebCore::RenderView::pushLayoutState): Added. Pushes initial layout state for subtree layout. 113 * rendering/RenderView.h: 114 (WebCore::RenderView::pushLayoutState): 115 (WebCore::RenderView::popLayoutState): 116 (WebCore::RenderView::layoutState): 117 (WebCore::RenderView::disableLayoutState): 118 (WebCore::RenderView::enableLayoutState): 119 1 120 2007-04-29 David Hyatt <hyatt@apple.com> 2 121 -
trunk/WebCore/WebCore.pro
r21142 r21183 648 648 rendering/InlineFlowBox.cpp \ 649 649 rendering/InlineTextBox.cpp \ 650 rendering/LayoutState.cpp \ 650 651 rendering/ListMarkerBox.cpp \ 651 652 rendering/RenderApplet.cpp \ -
trunk/WebCore/WebCore.vcproj/WebCore/WebCore.vcproj
r19855 r21183 3372 3372 </File> 3373 3373 <File 3374 RelativePath="..\..\rendering\LayoutState.cpp" 3375 > 3376 </File> 3377 <File 3378 RelativePath="..\..\rendering\LayoutState.h" 3379 > 3380 </File> 3381 <File 3374 3382 RelativePath="..\..\rendering\Length.h" 3375 3383 > -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r20948 r21183 272 272 37919C230B7D188600A56998 /* PositionIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37919C210B7D188600A56998 /* PositionIterator.cpp */; }; 273 273 37919C240B7D188600A56998 /* PositionIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 37919C220B7D188600A56998 /* PositionIterator.h */; settings = {ATTRIBUTES = (); }; }; 274 2D9066060BE141D400956998 /* LayoutState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D9066040BE141D400956998 /* LayoutState.cpp */; }; 275 2D9066070BE141D400956998 /* LayoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D9066050BE141D400956998 /* LayoutState.h */; }; 274 276 448A29BF0A46D9CB0030759F /* JSHTMLOptionsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */; }; 275 277 448A29C00A46D9CB0030759F /* JSHTMLOptionsCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */; }; … … 3383 3385 37919C210B7D188600A56998 /* PositionIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PositionIterator.cpp; sourceTree = "<group>"; }; 3384 3386 37919C220B7D188600A56998 /* PositionIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PositionIterator.h; sourceTree = "<group>"; }; 3387 2D9066040BE141D400956998 /* LayoutState.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutState.cpp; sourceTree = "<group>"; }; 3388 2D9066050BE141D400956998 /* LayoutState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LayoutState.h; sourceTree = "<group>"; }; 3385 3389 448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLOptionsCollection.h; sourceTree = "<group>"; }; 3386 3390 448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOptionsCollection.cpp; sourceTree = "<group>"; }; … … 9467 9471 BCEA481A097D93020094C9E4 /* InlineTextBox.cpp */, 9468 9472 BCEA481B097D93020094C9E4 /* InlineTextBox.h */, 9473 2D9066040BE141D400956998 /* LayoutState.cpp */, 9474 2D9066050BE141D400956998 /* LayoutState.h */, 9469 9475 935C476009AC4CD100A6AAB4 /* Length.h */, 9470 9476 A8EA7A4D0A191A5200A8EF5F /* ListMarkerBox.cpp */, … … 11241 11247 06FC442E0BAE5A9E0090EDE1 /* JavaScriptStatistics.h in Headers */, 11242 11248 E1EC29A00BB04C6B00EA187B /* XPathNodeSet.h in Headers */, 11249 2D9066070BE141D400956998 /* LayoutState.h in Headers */, 11243 11250 ); 11244 11251 runOnlyForDeploymentPostprocessing = 0; … … 12610 12617 E1EC299F0BB04C6B00EA187B /* XPathNodeSet.cpp in Sources */, 12611 12618 51AA3F6F0BD5AA9E00892971 /* ResourceLoaderMac.mm in Sources */, 12619 2D9066060BE141D400956998 /* LayoutState.cpp in Sources */, 12612 12620 ); 12613 12621 runOnlyForDeploymentPostprocessing = 0; -
trunk/WebCore/WebCoreSources.bkl
r20944 r21183 447 447 rendering/InlineFlowBox.cpp 448 448 rendering/InlineTextBox.cpp 449 rendering/LayoutState.cpp 449 450 rendering/ListMarkerBox.cpp 450 451 rendering/RenderApplet.cpp -
trunk/WebCore/page/FrameView.cpp
r21120 r21183 410 410 411 411 pauseScheduledEvents(); 412 413 if (subtree) 414 root->view()->pushLayoutState(root); 412 415 root->layout(); 416 if (subtree) 417 root->view()->popLayoutState(); 413 418 d->layoutRoot = 0; 414 419 -
trunk/WebCore/rendering/RenderBlock.cpp
r21173 r21183 487 487 return; // cause us to come in here. Just bail. 488 488 489 if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) { 490 // All we have to is lay out our positioned objects. 491 layoutPositionedObjects(false); 492 if (hasOverflowClip()) 493 m_layer->updateScrollInfoAfterLayout(); 494 setNeedsLayout(false); 489 if (!relayoutChildren && layoutOnlyPositionedObjects()) 495 490 return; 496 } 497 491 498 492 IntRect oldBounds; 499 493 IntRect oldOutlineBox; … … 501 495 if (checkForRepaint) { 502 496 oldBounds = absoluteClippedOverflowRect(); 503 oldBounds.move(view()->layoutDelta());504 497 oldOutlineBox = absoluteOutlineBox(); 505 oldOutlineBox.move(view()->layoutDelta()); 506 } 498 } 499 500 bool hadColumns = m_hasColumns; 501 if (!hadColumns) 502 view()->pushLayoutState(this, IntSize(xPos(), yPos())); 503 else 504 view()->disableLayoutState(); 507 505 508 506 int oldWidth = m_width; … … 606 604 m_overflowWidth = max(m_overflowWidth, m_width); 607 605 m_overflowHeight = max(m_overflowHeight, m_height); 606 607 if (!hadColumns) 608 view()->popLayoutState(); 609 else 610 view()->enableLayoutState(); 608 611 609 612 // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if … … 1239 1242 } 1240 1243 1244 bool RenderBlock::layoutOnlyPositionedObjects() 1245 { 1246 if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout()) 1247 return false; 1248 1249 // All we have to is lay out our positioned objects. 1250 if (!m_hasColumns) 1251 view()->pushLayoutState(this, IntSize(xPos(), yPos())); 1252 else 1253 view()->disableLayoutState(); 1254 1255 layoutPositionedObjects(false); 1256 if (hasOverflowClip()) 1257 m_layer->updateScrollInfoAfterLayout(); 1258 1259 if (!m_hasColumns) 1260 view()->popLayoutState(); 1261 else 1262 view()->enableLayoutState(); 1263 1264 setNeedsLayout(false); 1265 return true; 1266 } 1267 1241 1268 void RenderBlock::layoutPositionedObjects(bool relayoutChildren) 1242 1269 { … … 1283 1310 FloatingObject* r; 1284 1311 DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); 1312 1313 // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating 1314 // in this block. Better yet would be to push extra state for the containers of other floats. 1315 view()->disableLayoutState(); 1285 1316 for ( ; (r = it.current()); ++it) { 1286 1317 // Only repaint the object if it is overhanging, is not in its own layer, and … … 1292 1323 } 1293 1324 } 1325 view()->enableLayoutState(); 1294 1326 } 1295 1327 } … … 3939 3971 3940 3972 // If the child does not already have style, we create it here. 3941 if (currChild->isText() && !currChild->isBR() && 3942 currChild->parent()->style()->styleType() != RenderStyle::FIRST_LETTER) { 3943 3973 if (currChild->isText() && !currChild->isBR() && currChild->parent()->style()->styleType() != RenderStyle::FIRST_LETTER) { 3974 // Our layout state is not valid for the repaints we are going to trigger by 3975 // adding and removing children of firstLetterContainer. 3976 view()->disableLayoutState(); 3977 3944 3978 RenderText* textObj = static_cast<RenderText*>(currChild); 3945 3979 … … 3995 4029 textObj->destroy(); 3996 4030 } 4031 view()->enableLayoutState(); 3997 4032 } 3998 4033 } -
trunk/WebCore/rendering/RenderBlock.h
r21120 r21183 295 295 void newLine(); 296 296 virtual bool hasLineIfEmpty() const; 297 bool layoutOnlyPositionedObjects(); 297 298 298 299 private: -
trunk/WebCore/rendering/RenderBox.cpp
r21181 r21183 137 137 // Set the text color if we're the body. 138 138 if (isBody()) 139 element()->document()->setTextColor(newStyle->color());139 document()->setTextColor(newStyle->color()); 140 140 141 141 if (style()->outlineWidth() > 0 && style()->outlineSize() > maximalOutlineSize(PaintPhaseOutline)) … … 777 777 } 778 778 779 IntSize RenderBox::offsetForPositionedInContainer(RenderObject* container) const 780 { 781 if (!container->isRelPositioned() || !container->isInlineFlow()) 782 return IntSize(); 783 784 // When we have an enclosing relpositioned inline, we need to add in the offset of the first line 785 // box from the rest of the content, but only in the cases where we know we're positioned 786 // relative to the inline itself. 787 788 IntSize offset; 789 RenderFlow* flow = static_cast<RenderFlow*>(container); 790 int sx; 791 int sy; 792 if (flow->firstLineBox()) { 793 sx = flow->firstLineBox()->xPos(); 794 sy = flow->firstLineBox()->yPos(); 795 } else { 796 sx = flow->staticX(); 797 sy = flow->staticY(); 798 } 799 800 if (!hasStaticX()) 801 offset.setWidth(sx); 802 // This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside 803 // an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct 804 // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers 805 // do. 806 else if (!style()->isOriginalDisplayInlineType()) 807 // Avoid adding in the left border/padding of the containing block twice. Subtract it out. 808 offset.setWidth(sx - (containingBlock()->borderLeft() + containingBlock()->paddingLeft())); 809 810 if (!hasStaticY()) 811 offset.setHeight(sy); 812 813 return offset; 814 } 815 779 816 bool RenderBox::absolutePosition(int& xPos, int& yPos, bool fixed) const 780 817 { 818 if (RenderView* v = view()) { 819 if (LayoutState* layoutState = v->layoutState()) { 820 xPos = layoutState->m_offset.width() + m_x; 821 yPos = layoutState->m_offset.height() + m_y; 822 return true; 823 } 824 } 825 781 826 if (style()->position() == FixedPosition) 782 827 fixed = true; … … 786 831 yPos += o->borderTopExtra(); 787 832 788 if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isInlineFlow()) { 789 // When we have an enclosing relpositioned inline, we need to add in the offset of the first line 790 // box from the rest of the content, but only in the cases where we know we're positioned 791 // relative to the inline itself. 792 RenderFlow* flow = static_cast<RenderFlow*>(o); 793 int sx; 794 int sy; 795 if (flow->firstLineBox()) { 796 sx = flow->firstLineBox()->xPos(); 797 sy = flow->firstLineBox()->yPos(); 798 } else { 799 sx = flow->staticX(); 800 sy = flow->staticY(); 801 } 802 803 bool isInlineType = style()->isOriginalDisplayInlineType(); 804 805 if (!hasStaticX()) 806 xPos += sx; 807 // This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside 808 // an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct 809 // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers 810 // do. 811 if (hasStaticX() && !isInlineType) 812 // Avoid adding in the left border/padding of the containing block twice. Subtract it out. 813 xPos += sx - (containingBlock()->borderLeft() + containingBlock()->paddingLeft()); 814 815 if (!hasStaticY()) 816 yPos += sy; 817 } 833 if (style()->position() == AbsolutePosition) { 834 IntSize offset = offsetForPositionedInContainer(o); 835 xPos += offset.width(); 836 yPos += offset.height(); 837 } 838 818 839 if (o->hasOverflowClip()) 819 840 o->layer()->subtractScrollOffset(xPos, yPos); … … 900 921 { 901 922 IntRect r = overflowRect(false); 923 924 if (RenderView* v = view()) 925 r.move(v->layoutDelta()); 926 902 927 if (style()) { 903 928 if (style()->hasAppearance()) … … 914 939 void RenderBox::computeAbsoluteRepaintRect(IntRect& rect, bool fixed) 915 940 { 941 if (RenderView* v = view()) { 942 if (LayoutState* layoutState = v->layoutState()) { 943 rect.move(m_x, m_y); 944 rect.move(layoutState->m_offset); 945 if (layoutState->m_clipped) 946 rect.intersect(layoutState->m_clipRect); 947 return; 948 } 949 } 950 916 951 int x = rect.x() + m_x; 917 952 int y = rect.y() + m_y; … … 940 975 } 941 976 942 if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isInlineFlow()) { 943 // When we have an enclosing relpositioned inline, we need to add in the offset of the first line 944 // box from the rest of the content, but only in the cases where we know we're positioned 945 // relative to the inline itself. 946 RenderFlow* flow = static_cast<RenderFlow*>(o); 947 int sx; 948 int sy; 949 if (flow->firstLineBox()) { 950 sx = flow->firstLineBox()->xPos(); 951 sy = flow->firstLineBox()->yPos(); 952 } else { 953 sx = flow->staticX(); 954 sy = flow->staticY(); 955 } 956 957 bool isInlineType = style()->isOriginalDisplayInlineType(); 958 959 if (!hasStaticX()) 960 x += sx; 961 // This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside 962 // an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct 963 // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers 964 // do. 965 if (hasStaticX() && !isInlineType) 966 // Avoid adding in the left border/padding of the containing block twice. Subtract it out. 967 x += sx - (containingBlock()->borderLeft() + containingBlock()->paddingLeft()); 968 969 if (!hasStaticY()) 970 y += sy; 977 if (style()->position() == AbsolutePosition) { 978 IntSize offset = offsetForPositionedInContainer(o); 979 x += offset.width(); 980 y += offset.height(); 971 981 } 972 982 -
trunk/WebCore/rendering/RenderBox.h
r21093 r21183 99 99 virtual IntRect absoluteClippedOverflowRect(); 100 100 virtual void computeAbsoluteRepaintRect(IntRect&, bool fixed = false); 101 IntSize offsetForPositionedInContainer(RenderObject*) const; 101 102 102 103 virtual void repaintDuringLayoutIfMoved(const IntRect&); -
trunk/WebCore/rendering/RenderContainer.cpp
r21093 r21183 482 482 ASSERT(needsLayout()); 483 483 484 view()->pushLayoutState(this, IntSize(m_x, m_y)); 485 484 486 RenderObject* child = m_firstChild; 485 487 while (child) { … … 488 490 child = child->nextSibling(); 489 491 } 492 493 view()->popLayoutState(); 490 494 setNeedsLayout(false); 491 495 } -
trunk/WebCore/rendering/RenderFlexibleBox.cpp
r21093 r21183 209 209 ASSERT(needsLayout()); 210 210 211 if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) { 212 // All we have to is lay out our positioned objects. 213 layoutPositionedObjects(false); 214 if (hasOverflowClip()) 215 m_layer->updateScrollInfoAfterLayout(); 216 setNeedsLayout(false); 211 if (!relayoutChildren && layoutOnlyPositionedObjects()) 217 212 return; 218 }219 213 220 214 IntRect oldBounds; … … 223 217 if (checkForRepaint) { 224 218 oldBounds = absoluteClippedOverflowRect(); 225 oldBounds.move(view()->layoutDelta());226 219 oldOutlineBox = absoluteOutlineBox(); 227 oldOutlineBox.move(view()->layoutDelta()); 228 } 220 } 221 222 view()->pushLayoutState(this, IntSize(m_x, m_y)); 229 223 230 224 int previousWidth = m_width; … … 294 288 if (m_overflowWidth < m_width) 295 289 m_overflowWidth = m_width; 290 291 view()->popLayoutState(); 296 292 297 293 // Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if -
trunk/WebCore/rendering/RenderFlow.cpp
r21119 r21183 451 451 { 452 452 if (isInlineFlow()) { 453 // Only compacts and run-ins are allowed in here during layout. 454 ASSERT(!view() || !view()->layoutState() || isCompact() || isRunIn()); 455 453 456 if (!firstLineBox()) 454 457 return IntRect(); -
trunk/WebCore/rendering/RenderForeignObject.cpp
r21093 r21183 87 87 ASSERT(needsLayout()); 88 88 89 // Arbitrary affine transforms are incompatible with LayoutState. 90 view()->disableLayoutState(); 91 89 92 IntRect oldBounds; 90 93 IntRect oldOutlineBox; … … 102 105 repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox); 103 106 107 view()->enableLayoutState(); 104 108 setNeedsLayout(false); 105 109 } -
trunk/WebCore/rendering/RenderHTMLCanvas.cpp
r21093 r21183 86 86 if (checkForRepaint) { 87 87 oldBounds = absoluteClippedOverflowRect(); 88 oldBounds.move(view()->layoutDelta());89 88 oldOutlineBox = absoluteOutlineBox(); 90 oldOutlineBox.move(view()->layoutDelta());91 89 } 92 90 calcWidth(); -
trunk/WebCore/rendering/RenderImage.cpp
r21093 r21183 310 310 if (checkForRepaint) { 311 311 oldBounds = absoluteClippedOverflowRect(); 312 oldBounds.move(view()->layoutDelta());313 312 oldOutlineBox = absoluteOutlineBox(); 314 oldOutlineBox.move(view()->layoutDelta());315 313 } 316 314 -
trunk/WebCore/rendering/RenderLayer.cpp
r21082 r21183 200 200 201 201 if (m_hasVisibleContent) { 202 RenderView* view = m_object->view(); 203 ASSERT(view); 204 // FIXME: Optimize using LayoutState and remove the disableLayoutState() call 205 // from updateScrollInfoAfterLayout(). 206 ASSERT(!view->layoutState()); 207 202 208 IntRect newRect = m_object->absoluteClippedOverflowRect(); 203 209 IntRect newOutlineBox = m_object->absoluteOutlineBox(); 204 210 if (checkForRepaint) { 205 RenderView* view = m_object->view();206 ASSERT(view);207 211 if (view && !view->printing()) { 208 212 bool didMove = newOutlineBox.location() != m_outlineBox.location(); … … 358 362 positionedParent->subtractScrollOffset(x, y); 359 363 360 if (m_object->isPositioned() && positionedParent->renderer()->isRelPositioned() && 361 positionedParent->renderer()->isInlineFlow()) { 362 // When we have an enclosing relpositioned inline, we need to add in the offset of the first line 363 // box from the rest of the content, but only in the cases where we know we're positioned 364 // relative to the inline itself. 365 RenderFlow* flow = static_cast<RenderFlow*>(positionedParent->renderer()); 366 int sx = 0, sy = 0; 367 if (flow->firstLineBox()) { 368 sx = flow->firstLineBox()->xPos(); 369 sy = flow->firstLineBox()->yPos(); 370 } 371 else { 372 sx = flow->staticX(); 373 sy = flow->staticY(); 374 } 375 bool isInlineType = m_object->style()->isOriginalDisplayInlineType(); 376 377 if (!m_object->hasStaticX()) 378 x += sx; 379 380 // This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside 381 // an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct 382 // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers 383 // do. 384 if (m_object->hasStaticX() && !isInlineType) 385 // Avoid adding in the left border/padding of the containing block twice. Subtract it out. 386 x += sx - (m_object->containingBlock()->borderLeft() + m_object->containingBlock()->paddingLeft()); 387 388 if (!m_object->hasStaticY()) 389 y += sy; 390 } 391 } 392 else if (parent()) 364 if (m_object->isPositioned()) { 365 IntSize offset = static_cast<RenderBox*>(m_object)->offsetForPositionedInContainer(positionedParent->renderer()); 366 x += offset.width(); 367 y += offset.height(); 368 } 369 } else if (parent()) 393 370 parent()->subtractScrollOffset(x, y); 394 371 … … 1184 1161 int newX = max(0, min(scrollXOffset(), scrollWidth() - m_object->clientWidth())); 1185 1162 int newY = max(0, min(m_scrollY, scrollHeight() - m_object->clientHeight())); 1186 if (newX != scrollXOffset() || newY != m_scrollY) 1163 if (newX != scrollXOffset() || newY != m_scrollY) { 1164 RenderView* view = m_object->view(); 1165 ASSERT(view); 1166 // scrollToOffset() may call updateLayerPositions(), which doesn't work 1167 // with LayoutState. 1168 // FIXME: Remove the disableLayoutState/enableLayoutState if the above changes. 1169 if (view) 1170 view->disableLayoutState(); 1187 1171 scrollToOffset(newX, newY); 1172 if (view) 1173 view->enableLayoutState(); 1174 } 1188 1175 } 1189 1176 -
trunk/WebCore/rendering/RenderListItem.cpp
r21093 r21183 31 31 #include "HTMLOListElement.h" 32 32 #include "RenderListMarker.h" 33 #include "RenderView.h" 33 34 34 35 using namespace std; … … 201 202 202 203 if (markerPar != lineBoxParent || m_marker->prefWidthsDirty()) { 204 // Removing and adding the marker can trigger repainting in 205 // containers other than ourselves, so we need to disable LayoutState. 206 view()->disableLayoutState(); 203 207 updateFirstLetter(); 204 208 m_marker->remove(); … … 208 212 if (m_marker->prefWidthsDirty()) 209 213 m_marker->calcPrefWidths(); 214 view()->enableLayoutState(); 210 215 } 211 216 } -
trunk/WebCore/rendering/RenderObject.cpp
r21162 r21183 215 215 bool RenderObject::isRoot() const 216 216 { 217 return element() && element()->renderer() == this && element()->document()->documentElement() == element();217 return element() && element()->renderer() == this && document()->documentElement() == element(); 218 218 } 219 219 … … 1894 1894 { 1895 1895 if (parent()) 1896 returnparent()->computeAbsoluteRepaintRect(r, f);1896 parent()->computeAbsoluteRepaintRect(r, f); 1897 1897 } 1898 1898 … … 2422 2422 // calcAbsoluteVertical have to use container(). 2423 2423 RenderObject* o = parent(); 2424 2425 if (isText()) 2426 return o; 2427 2424 2428 EPosition pos = m_style->position(); 2425 if ( !isText() &&pos == FixedPosition) {2429 if (pos == FixedPosition) { 2426 2430 // container() can be called on an object that is not in the 2427 2431 // tree yet. We don't call view() since it will assert if it … … 2432 2436 while (o && o->parent()) 2433 2437 o = o->parent(); 2434 } else if ( !isText() &&pos == AbsolutePosition) {2438 } else if (pos == AbsolutePosition) { 2435 2439 // Same goes here. We technically just want our containing block, but 2436 2440 // we may not have one if we're part of an uninstalled subtree. We'll … … 3026 3030 absolutePosition(x, y); 3027 3031 box.move(x, y); 3032 box.move(view()->layoutDelta()); 3028 3033 box.inflate(style()->outlineSize()); 3029 3034 return box; -
trunk/WebCore/rendering/RenderSVGContainer.cpp
r21093 r21183 27 27 28 28 #include "GraphicsContext.h" 29 #include "RenderView.h" 29 30 #include "SVGLength.h" 30 31 #include "SVGMarkerElement.h" … … 92 93 calcViewport(); 93 94 95 // Arbitrary affine transforms are incompatible with LayoutState. 96 view()->disableLayoutState(); 97 94 98 IntRect oldBounds; 95 99 IntRect oldOutlineBox; … … 118 122 repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox); 119 123 124 view()->enableLayoutState(); 120 125 setNeedsLayout(false); 121 126 } -
trunk/WebCore/rendering/RenderTable.cpp
r21093 r21183 33 33 #include "FrameView.h" 34 34 #include "HTMLNames.h" 35 #include "RenderLayer.h" 35 36 #include "RenderTableCell.h" 36 37 #include "RenderTableCol.h" … … 266 267 ASSERT(needsLayout()); 267 268 268 if (posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) { 269 // All we have to do is lay out our positioned objects. 270 layoutPositionedObjects(false); 271 setNeedsLayout(false); 269 if (layoutOnlyPositionedObjects()) 272 270 return; 273 }274 271 275 272 recalcSectionsIfNeeded(); … … 280 277 if (checkForRepaint) { 281 278 oldBounds = absoluteClippedOverflowRect(); 282 oldBounds.move(view()->layoutDelta());283 279 oldOutlineBox = absoluteOutlineBox(); 284 oldOutlineBox.move(view()->layoutDelta());285 280 } 286 281 282 view()->pushLayoutState(this, IntSize(m_x, m_y)); 283 287 284 m_height = 0; 288 285 m_overflowHeight = 0; … … 424 421 // FIXME: Only pass true if width or height changed. 425 422 layoutPositionedObjects(true); 423 424 view()->popLayoutState(); 426 425 427 426 bool didFullRepaint = true; -
trunk/WebCore/rendering/RenderTableCell.cpp
r21082 r21183 30 30 #include "HTMLTableCellElement.h" 31 31 #include "RenderTableCol.h" 32 #include "RenderView.h" 32 33 #include "TextStream.h" 33 34 … … 176 177 top = max(top, -overflowTop(false) - borderTopExtra()); 177 178 IntRect r(-left, -borderTopExtra() - top, left + max(width() + right, overflowWidth(false)), borderTopExtra() + top + max(height() + bottom + borderBottomExtra(), overflowHeight(false))); 179 180 if (RenderView* v = view()) 181 r.move(v->layoutDelta()); 182 178 183 computeAbsoluteRepaintRect(r); 179 184 return r; … … 185 190 { 186 191 r.setY(r.y() + m_topExtra); 187 r.move(-parent()->xPos(), -parent()->yPos()); // Rows are in the same coordinate space, so don't add their offset in. 192 RenderView* v = view(); 193 if (!v || !v->layoutState()) 194 r.move(-parent()->xPos(), -parent()->yPos()); // Rows are in the same coordinate space, so don't add their offset in. 188 195 RenderBlock::computeAbsoluteRepaintRect(r, fixed); 189 196 } … … 192 199 { 193 200 bool result = RenderBlock::absolutePosition(xPos, yPos, fixed); 194 xPos -= parent()->xPos(); // Rows are in the same coordinate space, so don't add their offset in. 195 yPos -= parent()->yPos(); 201 RenderView* v = view(); 202 if (!v || !v->layoutState()) { 203 xPos -= parent()->xPos(); // Rows are in the same coordinate space, so don't add their offset in. 204 yPos -= parent()->yPos(); 205 } 196 206 return result; 197 207 } -
trunk/WebCore/rendering/RenderTableRow.cpp
r21093 r21183 32 32 #include "HTMLNames.h" 33 33 #include "RenderTableCell.h" 34 #include "RenderView.h" 34 35 35 36 namespace WebCore { … … 114 115 ASSERT(needsLayout()); 115 116 117 // Table rows do not add translation. 118 view()->pushLayoutState(this, IntSize()); 119 116 120 for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { 117 121 if (child->isTableCell()) { … … 123 127 } 124 128 } 129 130 view()->popLayoutState(); 125 131 setNeedsLayout(false); 126 132 } -
trunk/WebCore/rendering/RenderTableSection.cpp
r21120 r21183 35 35 #include "RenderTableCol.h" 36 36 #include "RenderTableRow.h" 37 #include "RenderView.h" 37 38 #include "TextStream.h" 38 39 #include <limits> … … 264 265 { 265 266 Vector<int>& columnPos = table()->columnPositions(); 267 bool pushedLayoutState = false; 266 268 267 269 for (int i = 0; i < m_gridRows; i++) { … … 284 286 if (w != oldWidth) { 285 287 cell->setNeedsLayout(true); 286 if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) 288 if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) { 289 if (!pushedLayoutState) { 290 // Technically, we should also push state for the row, but since 291 // rows don't push a coordinate transform, that's not necessary. 292 view()->pushLayoutState(this, IntSize(m_x, m_y)); 293 pushedLayoutState = true; 294 } 287 295 cell->repaint(); 296 } 288 297 cell->setWidth(w); 289 298 } 290 299 } 291 300 } 301 302 if (pushedLayoutState) 303 view()->popLayoutState(); 292 304 } 293 305 … … 297 309 298 310 int spacing = table()->vBorderSpacing(); 311 bool pushedLayoutState = false; 299 312 300 313 m_rowPos.resize(m_gridRows + 1); … … 325 338 326 339 if (cell->overrideSize() != -1) { 340 if (!pushedLayoutState) { 341 // Technically, we should also push state for the row, but since 342 // rows don't push a coordinate transform, that's not necessary. 343 view()->pushLayoutState(this, IntSize(m_x, m_y)); 344 pushedLayoutState = true; 345 } 327 346 cell->setOverrideSize(-1); 328 347 cell->setChildNeedsLayout(true, false); … … 361 380 m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r]); 362 381 } 382 383 if (pushedLayoutState) 384 view()->popLayoutState(); 363 385 } 364 386 … … 442 464 int vspacing = table()->vBorderSpacing(); 443 465 int nEffCols = table()->numEffCols(); 466 467 view()->pushLayoutState(this, IntSize(m_x, m_y)); 444 468 445 469 for (int r = 0; r < totalRows; r++) { … … 551 575 } 552 576 } 577 578 view()->popLayoutState(); 553 579 554 580 m_height = m_rowPos[totalRows]; -
trunk/WebCore/rendering/RenderView.cpp
r21093 r21183 41 41 , m_printImages(true) 42 42 , m_maximalOutlineSize(0) 43 , m_layoutState(0) 44 , m_layoutStateDisableCount(0) 43 45 { 44 46 // Clear our anonymous bit, set because RenderObject assumes … … 100 102 setChildNeedsLayout(true, false); 101 103 104 ASSERT(!m_layoutState); 105 LayoutState state; 106 // FIXME: May be better to push a clip and avoid issuing offscreen repaints. 107 state.m_clipped = false; 108 m_layoutState = &state; 109 102 110 if (needsLayout()) 103 111 RenderBlock::layout(); … … 110 118 setOverflowHeight(docHeight()); 111 119 120 ASSERT(m_layoutStateDisableCount == 0); 121 ASSERT(m_layoutState == &state); 122 m_layoutState = 0; 112 123 setNeedsLayout(false); 113 124 } … … 140 151 // Check to see if we are enclosed by a transparent layer. If so, we cannot blit 141 152 // when scrolling, and we need to use slow repaints. 142 Element* elt = element()->document()->ownerElement();153 Element* elt = document()->ownerElement(); 143 154 if (view() && elt && elt->renderer()) { 144 155 RenderLayer* layer = elt->renderer()->enclosingLayer(); … … 177 188 // We always just invalidate the root view, since we could be an iframe that is clipped out 178 189 // or even invisible. 179 Element* elt = element()->document()->ownerElement();190 Element* elt = document()->ownerElement(); 180 191 if (!elt) 181 192 m_frameView->repaintRectangle(ur, immediate); … … 525 536 } 526 537 538 void RenderView::pushLayoutState(RenderObject* root) 539 { 540 ASSERT(!m_frameView->needsFullRepaint()); 541 ASSERT(m_layoutStateDisableCount == 0); 542 ASSERT(m_layoutState == 0); 543 544 m_layoutState = new (renderArena()) LayoutState(root); 545 } 546 527 547 } // namespace WebCore -
trunk/WebCore/rendering/RenderView.h
r21079 r21183 25 25 #define RenderView_h 26 26 27 #include "FrameView.h" 28 #include "LayoutState.h" 27 29 #include "RenderBlock.h" 28 30 29 31 namespace WebCore { 30 31 class FrameView;32 32 33 33 class RenderView : public RenderBlock { … … 94 94 void addLayoutDelta(const IntSize& delta) { m_layoutDelta += delta; } 95 95 96 void pushLayoutState(RenderBox* renderer, const IntSize& offset) 97 { 98 if (m_layoutStateDisableCount || m_frameView->needsFullRepaint()) 99 return; 100 m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset); 101 } 102 103 void pushLayoutState(RenderObject*); 104 105 void popLayoutState() 106 { 107 if (m_layoutStateDisableCount || m_frameView->needsFullRepaint()) 108 return; 109 LayoutState* state = m_layoutState; 110 m_layoutState = state->m_next; 111 state->destroy(renderArena()); 112 } 113 114 LayoutState* layoutState() const { return m_layoutStateDisableCount ? 0 : m_layoutState; } 115 116 // Suspends the LayoutState optimization. Used under transforms that cannot be represented by 117 // LayoutState (common in SVG) and when manipulating the render tree during layout in ways 118 // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around). 119 void disableLayoutState() { m_layoutStateDisableCount++; } 120 void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; } 121 96 122 protected: 97 123 FrameView* m_frameView; … … 118 144 bool m_forcedPageBreak; 119 145 IntSize m_layoutDelta; 146 LayoutState* m_layoutState; 147 unsigned m_layoutStateDisableCount; 120 148 }; 121 149
Note:
See TracChangeset
for help on using the changeset viewer.