Changeset 21183 in webkit


Ignore:
Timestamp:
Apr 29, 2007, 1:09:08 PM (18 years ago)
Author:
weinig
Message:

LayoutTests:

Reviewed by Darin and Hyatt.

  • fast/repaint/bugzilla-3509-expected.checksum:
  • fast/repaint/bugzilla-3509-expected.png:
  • fast/repaint/intermediate-layout-position-clip-expected.checksum: Added.
  • fast/repaint/intermediate-layout-position-clip-expected.png: Added.
  • fast/repaint/intermediate-layout-position-clip-expected.txt: Added.
  • fast/repaint/intermediate-layout-position-clip.html: Added.
  • fast/repaint/intermediate-layout-position-expected.checksum:
  • fast/repaint/intermediate-layout-position-expected.png:

WebCore:

Reviewed by Darin and Hyatt.

Test for a bug fixed by this patch: fast/repaint/intermediate-layout-position-clip.html

By keeping track of the total translation and clip during layout, absolutePosition and
computeAbsoluteRepaintRect become O(1).

  • WebCore.pro: Added LayoutState.cpp
  • WebCore.vcproj/WebCore/WebCore.vcproj: Added LayoutState.{cpp,h}
  • WebCore.xcodeproj/project.pbxproj: Added LayoutState.{cpp,h}
  • WebCoreSources.bkl: Added LayoutState.cpp
  • page/FrameView.cpp: (WebCore::FrameView::layout): When doing subtree layout, push an initial layout state for the layout root.
  • rendering/LayoutState.cpp: Added. A LayoutState corresponding to a box consists of the origin of its coordinate system in view coordinates and possibly the clip rect, in view coordinates, which applies to its children. (WebCore::LayoutState::LayoutState): (WebCore::LayoutState::destroy): (WebCore::throw): (WebCore::LayoutState::operator delete):
  • rendering/LayoutState.h: Added. (WebCore::LayoutState::LayoutState):
  • rendering/RenderBlock.cpp: (WebCore::RenderBlock::layoutBlock): Factored out the "only positioned objects" case into layoutOnlyPositionedObjects(). Added code to push/pop LayoutState, unless we have columns, in which case we disable/enable LayoutState. Removed the translation by the layout delta of the old absolute rects, since that is now integral to absoluteClippedOverflowRect() and absoluteOutlineBox(). (WebCore::RenderBlock::layoutOnlyPositionedObjects): Added this helper function that checks for and handles the case where only positioned objects need layout. Returns true in that case. (WebCore::RenderBlock::repaintOverhangingFloats): Disabled LayoutState when repainting floats, since they may belong to other containers. (WebCore::RenderBlock::updateFirstLetter): Disabled LayoutState when adding and removing from the first letter container, since it may be different than ourselves.
  • rendering/RenderBlock.h:
  • rendering/RenderBox.cpp: (WebCore::RenderBox::setStyle): Minor cleanup: changed element()->document() to the equivalent document(). (WebCore::RenderBox::offsetForPositionedInContainer): Added. Factored out common code from absolutePosition, computeAbsoluteRepaintRect and RenderLayer::updateLayerPosition into this function. (WebCore::RenderBox::absolutePosition): Added an O(1) code path when this function is called during layout (and LayoutState has not been disabled). Factored out some code into offsetForPositionedInContainer. (WebCore::RenderBox::absoluteClippedOverflowRect): Added the layout delta here, so callers don't need to. (WebCore::RenderBox::computeAbsoluteRepaintRect): Added an O(1) code path when this function is called during layout (and LayoutState has not been disabled). Factored out some code into offsetForPositionedInContainer.
  • rendering/RenderContainer.cpp: (WebCore::RenderContainer::layout): Added LayoutState push/pop.
  • rendering/RenderFlexibleBox.cpp: (WebCore::RenderFlexibleBox::layoutBlock): Factored out the "only positioned objects" case into layoutOnlyPositionedObjects(). Added LayoutState push/pop. Removed the translation by the layout delta of the old absolute rects, since that is now integral to absoluteClippedOverflowRect() and absoluteOutlineBox().
  • rendering/RenderFlow.cpp: (WebCore::RenderFlow::absoluteClippedOverflowRect): Added an ASSERT.
  • rendering/RenderForeignObject.cpp: (WebCore::RenderForeignObject::layout): Disabled LayoutState because it is incompatible with arbitrary affine transforms.
  • rendering/RenderHTMLCanvas.cpp: (WebCore::RenderHTMLCanvas::layout): Removed the translation by the layout delta of the old absolute rects, since that is now integral to absoluteClippedOverflowRect() and absoluteOutlineBox().
  • rendering/RenderImage.cpp: (WebCore::RenderImage::layout): Ditto.
  • rendering/RenderLayer.cpp: (WebCore::RenderLayer::updateLayerPositions): Added ASSERTs. Factored out some code into RenderBox::offsetForPositionedInContainer. (WebCore::RenderLayer::updateScrollInfoAfterLayout): Disabled LayoutState around the call to scrollToOffset.
  • rendering/RenderListItem.cpp: (WebCore::RenderListItem::updateMarkerLocation): Disabled LayoutState when moving the list marker, since it can trigger repainting in other containers.
  • rendering/RenderObject.cpp: (WebCore::RenderObject::isRoot): Minor cleanup: changed element()->document() to the equivalent document(). (WebCore::RenderObject::computeAbsoluteRepaintRect): Removed 'return' at the end of the function. (WebCore::RenderObject::container): Reordered to avoid calling isText() twice. (WebCore::RenderObject::absoluteOutlineBox): Added the layout delta here, so callers don't need to.
  • rendering/RenderSVGContainer.cpp: (WebCore::RenderSVGContainer::layout): Disabled LayoutState because it is incompatible with arbitrary affine transforms.
  • rendering/RenderTable.cpp: (WebCore::RenderTable::layout): Factored out the "only positioned objects" case into layoutOnlyPositionedObjects(). Added LayoutState push/pop. Removed the translation by the layout delta of the old absolute rects, since that is now integral to absoluteClippedOverflowRect() and absoluteOutlineBox().
  • rendering/RenderTableCell.cpp: (WebCore::RenderTableCell::absoluteClippedOverflowRect): Added the layout delta here, so callers don't need to. (WebCore::RenderTableCell::computeAbsoluteRepaintRect): For the O(1) code path, skipped the correction for the parent row, because RenderTableRow doesn't push a translation into LayoutState. (WebCore::RenderTableCell::absolutePosition): Ditto.
  • rendering/RenderTableRow.cpp: (WebCore::RenderTableRow::layout): Added LayoutState push/pop.
  • rendering/RenderTableSection.cpp: (WebCore::RenderTableSection::setCellWidths): Added LayoutState push/pop if cells are repainted or receive layout. (WebCore::RenderTableSection::calcRowHeight): Ditto. (WebCore::RenderTableSection::layoutRows): Added LayoutState push/pop.
  • rendering/RenderView.cpp: (WebCore::RenderView::RenderView): (WebCore::RenderView::layout): Added initial LayoutState setup for the layout. (WebCore::RenderView::paintBoxDecorations): Minor cleanup: changed element()->document() to the equivalent document(). (WebCore::RenderView::repaintViewRectangle): Ditto. (WebCore::RenderView::pushLayoutState): Added. Pushes initial layout state for subtree layout.
  • rendering/RenderView.h: (WebCore::RenderView::pushLayoutState): (WebCore::RenderView::popLayoutState): (WebCore::RenderView::layoutState): (WebCore::RenderView::disableLayoutState): (WebCore::RenderView::enableLayoutState):
Location:
trunk
Files:
6 added
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r21177 r21183  
     12007-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
    1172007-04-28  Adele Peterson  <adele@apple.com>
    218
  • trunk/LayoutTests/fast/repaint/bugzilla-3509-expected.checksum

    r14089 r21183  
    1 2af7cd983d67fe56c79c8a968bdaa75d
     15bd77316c6336bd3dc5382806f5e5a36
  • trunk/LayoutTests/fast/repaint/intermediate-layout-position-expected.checksum

    r19492 r21183  
    1 1e297091caae6dc9b0bb887a590021a6
     1ff2ab8ca87826c939775ba447f3a6d84
  • trunk/WebCore/ChangeLog

    r21181 r21183  
     12007-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
    11202007-04-29  David Hyatt  <hyatt@apple.com>
    2121
  • trunk/WebCore/WebCore.pro

    r21142 r21183  
    648648    rendering/InlineFlowBox.cpp \
    649649    rendering/InlineTextBox.cpp \
     650    rendering/LayoutState.cpp \
    650651    rendering/ListMarkerBox.cpp \
    651652    rendering/RenderApplet.cpp \
  • trunk/WebCore/WebCore.vcproj/WebCore/WebCore.vcproj

    r19855 r21183  
    33723372                        </File>
    33733373                        <File
     3374                                RelativePath="..\..\rendering\LayoutState.cpp"
     3375                                >
     3376                        </File>
     3377                        <File
     3378                                RelativePath="..\..\rendering\LayoutState.h"
     3379                                >
     3380                        </File>
     3381                        <File
    33743382                                RelativePath="..\..\rendering\Length.h"
    33753383                                >
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r20948 r21183  
    272272                37919C230B7D188600A56998 /* PositionIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37919C210B7D188600A56998 /* PositionIterator.cpp */; };
    273273                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 */; };
    274276                448A29BF0A46D9CB0030759F /* JSHTMLOptionsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */; };
    275277                448A29C00A46D9CB0030759F /* JSHTMLOptionsCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */; };
     
    33833385                37919C210B7D188600A56998 /* PositionIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PositionIterator.cpp; sourceTree = "<group>"; };
    33843386                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>"; };
    33853389                448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLOptionsCollection.h; sourceTree = "<group>"; };
    33863390                448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOptionsCollection.cpp; sourceTree = "<group>"; };
     
    94679471                                BCEA481A097D93020094C9E4 /* InlineTextBox.cpp */,
    94689472                                BCEA481B097D93020094C9E4 /* InlineTextBox.h */,
     9473                                2D9066040BE141D400956998 /* LayoutState.cpp */,
     9474                                2D9066050BE141D400956998 /* LayoutState.h */,
    94699475                                935C476009AC4CD100A6AAB4 /* Length.h */,
    94709476                                A8EA7A4D0A191A5200A8EF5F /* ListMarkerBox.cpp */,
     
    1124111247                                06FC442E0BAE5A9E0090EDE1 /* JavaScriptStatistics.h in Headers */,
    1124211248                                E1EC29A00BB04C6B00EA187B /* XPathNodeSet.h in Headers */,
     11249                                2D9066070BE141D400956998 /* LayoutState.h in Headers */,
    1124311250                        );
    1124411251                        runOnlyForDeploymentPostprocessing = 0;
     
    1261012617                                E1EC299F0BB04C6B00EA187B /* XPathNodeSet.cpp in Sources */,
    1261112618                                51AA3F6F0BD5AA9E00892971 /* ResourceLoaderMac.mm in Sources */,
     12619                                2D9066060BE141D400956998 /* LayoutState.cpp in Sources */,
    1261212620                        );
    1261312621                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/WebCore/WebCoreSources.bkl

    r20944 r21183  
    447447        rendering/InlineFlowBox.cpp
    448448        rendering/InlineTextBox.cpp
     449        rendering/LayoutState.cpp
    449450        rendering/ListMarkerBox.cpp
    450451        rendering/RenderApplet.cpp
  • trunk/WebCore/page/FrameView.cpp

    r21120 r21183  
    410410
    411411    pauseScheduledEvents();
     412
     413    if (subtree)
     414        root->view()->pushLayoutState(root);
    412415    root->layout();
     416    if (subtree)
     417        root->view()->popLayoutState();
    413418    d->layoutRoot = 0;
    414419
  • trunk/WebCore/rendering/RenderBlock.cpp

    r21173 r21183  
    487487        return;                                      // cause us to come in here.  Just bail.
    488488
    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())
    495490        return;
    496     }
    497    
     491
    498492    IntRect oldBounds;
    499493    IntRect oldOutlineBox;
     
    501495    if (checkForRepaint) {
    502496        oldBounds = absoluteClippedOverflowRect();
    503         oldBounds.move(view()->layoutDelta());
    504497        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();
    507505
    508506    int oldWidth = m_width;
     
    606604    m_overflowWidth = max(m_overflowWidth, m_width);
    607605    m_overflowHeight = max(m_overflowHeight, m_height);
     606
     607    if (!hadColumns)
     608        view()->popLayoutState();
     609    else
     610        view()->enableLayoutState();
    608611
    609612    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
     
    12391242}
    12401243
     1244bool 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
    12411268void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
    12421269{
     
    12831310        FloatingObject* r;
    12841311        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();
    12851316        for ( ; (r = it.current()); ++it) {
    12861317            // Only repaint the object if it is overhanging, is not in its own layer, and
     
    12921323            }
    12931324        }
     1325        view()->enableLayoutState();
    12941326    }
    12951327}
     
    39393971
    39403972    // 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
    39443978        RenderText* textObj = static_cast<RenderText*>(currChild);
    39453979       
     
    39954029            textObj->destroy();
    39964030        }
     4031        view()->enableLayoutState();
    39974032    }
    39984033}
  • trunk/WebCore/rendering/RenderBlock.h

    r21120 r21183  
    295295    void newLine();
    296296    virtual bool hasLineIfEmpty() const;
     297    bool layoutOnlyPositionedObjects();
    297298
    298299private:
  • trunk/WebCore/rendering/RenderBox.cpp

    r21181 r21183  
    137137    // Set the text color if we're the body.
    138138    if (isBody())
    139         element()->document()->setTextColor(newStyle->color());
     139        document()->setTextColor(newStyle->color());
    140140
    141141    if (style()->outlineWidth() > 0 && style()->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
     
    777777}
    778778
     779IntSize 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
    779816bool RenderBox::absolutePosition(int& xPos, int& yPos, bool fixed) const
    780817{
     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
    781826    if (style()->position() == FixedPosition)
    782827        fixed = true;
     
    786831        yPos += o->borderTopExtra();
    787832
    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
    818839        if (o->hasOverflowClip())
    819840            o->layer()->subtractScrollOffset(xPos, yPos);
     
    900921{
    901922    IntRect r = overflowRect(false);
     923
     924    if (RenderView* v = view())
     925        r.move(v->layoutDelta());
     926
    902927    if (style()) {
    903928        if (style()->hasAppearance())
     
    914939void RenderBox::computeAbsoluteRepaintRect(IntRect& rect, bool fixed)
    915940{
     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
    916951    int x = rect.x() + m_x;
    917952    int y = rect.y() + m_y;
     
    940975        }
    941976
    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();
    971981        }
    972982
  • trunk/WebCore/rendering/RenderBox.h

    r21093 r21183  
    9999    virtual IntRect absoluteClippedOverflowRect();
    100100    virtual void computeAbsoluteRepaintRect(IntRect&, bool fixed = false);
     101    IntSize offsetForPositionedInContainer(RenderObject*) const;
    101102
    102103    virtual void repaintDuringLayoutIfMoved(const IntRect&);
  • trunk/WebCore/rendering/RenderContainer.cpp

    r21093 r21183  
    482482    ASSERT(needsLayout());
    483483
     484    view()->pushLayoutState(this, IntSize(m_x, m_y));
     485
    484486    RenderObject* child = m_firstChild;
    485487    while (child) {
     
    488490        child = child->nextSibling();
    489491    }
     492
     493    view()->popLayoutState();
    490494    setNeedsLayout(false);
    491495}
  • trunk/WebCore/rendering/RenderFlexibleBox.cpp

    r21093 r21183  
    209209    ASSERT(needsLayout());
    210210
    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())
    217212        return;
    218     }
    219213
    220214    IntRect oldBounds;
     
    223217    if (checkForRepaint) {
    224218        oldBounds = absoluteClippedOverflowRect();
    225         oldBounds.move(view()->layoutDelta());
    226219        oldOutlineBox = absoluteOutlineBox();
    227         oldOutlineBox.move(view()->layoutDelta());
    228     }
     220    }
     221
     222    view()->pushLayoutState(this, IntSize(m_x, m_y));
    229223
    230224    int previousWidth = m_width;
     
    294288    if (m_overflowWidth < m_width)
    295289        m_overflowWidth = m_width;
     290
     291    view()->popLayoutState();
    296292
    297293    // Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
  • trunk/WebCore/rendering/RenderFlow.cpp

    r21119 r21183  
    451451{
    452452    if (isInlineFlow()) {
     453        // Only compacts and run-ins are allowed in here during layout.
     454        ASSERT(!view() || !view()->layoutState() || isCompact() || isRunIn());
     455
    453456        if (!firstLineBox())
    454457            return IntRect();
  • trunk/WebCore/rendering/RenderForeignObject.cpp

    r21093 r21183  
    8787    ASSERT(needsLayout());
    8888
     89    // Arbitrary affine transforms are incompatible with LayoutState.
     90    view()->disableLayoutState();
     91
    8992    IntRect oldBounds;
    9093    IntRect oldOutlineBox;
     
    102105        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
    103106
     107    view()->enableLayoutState();
    104108    setNeedsLayout(false);
    105109}
  • trunk/WebCore/rendering/RenderHTMLCanvas.cpp

    r21093 r21183  
    8686    if (checkForRepaint) {
    8787        oldBounds = absoluteClippedOverflowRect();
    88         oldBounds.move(view()->layoutDelta());
    8988        oldOutlineBox = absoluteOutlineBox();
    90         oldOutlineBox.move(view()->layoutDelta());
    9189    }
    9290    calcWidth();
  • trunk/WebCore/rendering/RenderImage.cpp

    r21093 r21183  
    310310    if (checkForRepaint) {
    311311        oldBounds = absoluteClippedOverflowRect();
    312         oldBounds.move(view()->layoutDelta());
    313312        oldOutlineBox = absoluteOutlineBox();
    314         oldOutlineBox.move(view()->layoutDelta());
    315313    }
    316314
  • trunk/WebCore/rendering/RenderLayer.cpp

    r21082 r21183  
    200200       
    201201    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
    202208        IntRect newRect = m_object->absoluteClippedOverflowRect();
    203209        IntRect newOutlineBox = m_object->absoluteOutlineBox();
    204210        if (checkForRepaint) {
    205             RenderView* view = m_object->view();
    206             ASSERT(view);
    207211            if (view && !view->printing()) {
    208212                bool didMove = newOutlineBox.location() != m_outlineBox.location();
     
    358362        positionedParent->subtractScrollOffset(x, y);
    359363       
    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())
    393370        parent()->subtractScrollOffset(x, y);
    394371   
     
    11841161        int newX = max(0, min(scrollXOffset(), scrollWidth() - m_object->clientWidth()));
    11851162        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();
    11871171            scrollToOffset(newX, newY);
     1172            if (view)
     1173                view->enableLayoutState();
     1174        }
    11881175    }
    11891176
  • trunk/WebCore/rendering/RenderListItem.cpp

    r21093 r21183  
    3131#include "HTMLOListElement.h"
    3232#include "RenderListMarker.h"
     33#include "RenderView.h"
    3334
    3435using namespace std;
     
    201202
    202203        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();
    203207            updateFirstLetter();
    204208            m_marker->remove();
     
    208212            if (m_marker->prefWidthsDirty())
    209213                m_marker->calcPrefWidths();
     214            view()->enableLayoutState();
    210215        }
    211216    }
  • trunk/WebCore/rendering/RenderObject.cpp

    r21162 r21183  
    215215bool RenderObject::isRoot() const
    216216{
    217     return element() && element()->renderer() == this && element()->document()->documentElement() == element();
     217    return element() && element()->renderer() == this && document()->documentElement() == element();
    218218}
    219219
     
    18941894{
    18951895    if (parent())
    1896         return parent()->computeAbsoluteRepaintRect(r, f);
     1896        parent()->computeAbsoluteRepaintRect(r, f);
    18971897}
    18981898
     
    24222422    // calcAbsoluteVertical have to use container().
    24232423    RenderObject* o = parent();
     2424
     2425    if (isText())
     2426        return o;
     2427
    24242428    EPosition pos = m_style->position();
    2425     if (!isText() && pos == FixedPosition) {
     2429    if (pos == FixedPosition) {
    24262430        // container() can be called on an object that is not in the
    24272431        // tree yet.  We don't call view() since it will assert if it
     
    24322436        while (o && o->parent())
    24332437            o = o->parent();
    2434     } else if (!isText() && pos == AbsolutePosition) {
     2438    } else if (pos == AbsolutePosition) {
    24352439        // Same goes here.  We technically just want our containing block, but
    24362440        // we may not have one if we're part of an uninstalled subtree.  We'll
     
    30263030    absolutePosition(x, y);
    30273031    box.move(x, y);
     3032    box.move(view()->layoutDelta());
    30283033    box.inflate(style()->outlineSize());
    30293034    return box;
  • trunk/WebCore/rendering/RenderSVGContainer.cpp

    r21093 r21183  
    2727
    2828#include "GraphicsContext.h"
     29#include "RenderView.h"
    2930#include "SVGLength.h"
    3031#include "SVGMarkerElement.h"
     
    9293    calcViewport();
    9394
     95    // Arbitrary affine transforms are incompatible with LayoutState.
     96    view()->disableLayoutState();
     97
    9498    IntRect oldBounds;
    9599    IntRect oldOutlineBox;
     
    118122        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
    119123
     124    view()->enableLayoutState();
    120125    setNeedsLayout(false);
    121126}
  • trunk/WebCore/rendering/RenderTable.cpp

    r21093 r21183  
    3333#include "FrameView.h"
    3434#include "HTMLNames.h"
     35#include "RenderLayer.h"
    3536#include "RenderTableCell.h"
    3637#include "RenderTableCol.h"
     
    266267    ASSERT(needsLayout());
    267268
    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())
    272270        return;
    273     }
    274271
    275272    recalcSectionsIfNeeded();
     
    280277    if (checkForRepaint) {
    281278        oldBounds = absoluteClippedOverflowRect();
    282         oldBounds.move(view()->layoutDelta());
    283279        oldOutlineBox = absoluteOutlineBox();
    284         oldOutlineBox.move(view()->layoutDelta());
    285280    }
    286281   
     282    view()->pushLayoutState(this, IntSize(m_x, m_y));
     283
    287284    m_height = 0;
    288285    m_overflowHeight = 0;
     
    424421    // FIXME: Only pass true if width or height changed.
    425422    layoutPositionedObjects(true);
     423
     424    view()->popLayoutState();
    426425
    427426    bool didFullRepaint = true;
  • trunk/WebCore/rendering/RenderTableCell.cpp

    r21082 r21183  
    3030#include "HTMLTableCellElement.h"
    3131#include "RenderTableCol.h"
     32#include "RenderView.h"
    3233#include "TextStream.h"
    3334
     
    176177        top = max(top, -overflowTop(false) - borderTopExtra());
    177178        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
    178183        computeAbsoluteRepaintRect(r);
    179184        return r;
     
    185190{
    186191    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.
    188195    RenderBlock::computeAbsoluteRepaintRect(r, fixed);
    189196}
     
    192199{
    193200    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    }
    196206    return result;
    197207}
  • trunk/WebCore/rendering/RenderTableRow.cpp

    r21093 r21183  
    3232#include "HTMLNames.h"
    3333#include "RenderTableCell.h"
     34#include "RenderView.h"
    3435
    3536namespace WebCore {
     
    114115    ASSERT(needsLayout());
    115116
     117    // Table rows do not add translation.
     118    view()->pushLayoutState(this, IntSize());
     119
    116120    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    117121        if (child->isTableCell()) {
     
    123127        }
    124128    }
     129
     130    view()->popLayoutState();
    125131    setNeedsLayout(false);
    126132}
  • trunk/WebCore/rendering/RenderTableSection.cpp

    r21120 r21183  
    3535#include "RenderTableCol.h"
    3636#include "RenderTableRow.h"
     37#include "RenderView.h"
    3738#include "TextStream.h"
    3839#include <limits>
     
    264265{
    265266    Vector<int>& columnPos = table()->columnPositions();
     267    bool pushedLayoutState = false;
    266268
    267269    for (int i = 0; i < m_gridRows; i++) {
     
    284286            if (w != oldWidth) {
    285287                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                    }
    287295                    cell->repaint();
     296                }
    288297                cell->setWidth(w);
    289298            }
    290299        }
    291300    }
     301   
     302    if (pushedLayoutState)
     303        view()->popLayoutState();
    292304}
    293305
     
    297309
    298310    int spacing = table()->vBorderSpacing();
     311    bool pushedLayoutState = false;
    299312
    300313    m_rowPos.resize(m_gridRows + 1);
     
    325338
    326339            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                }
    327346                cell->setOverrideSize(-1);
    328347                cell->setChildNeedsLayout(true, false);
     
    361380        m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r]);
    362381    }
     382
     383    if (pushedLayoutState)
     384        view()->popLayoutState();
    363385}
    364386
     
    442464    int vspacing = table()->vBorderSpacing();
    443465    int nEffCols = table()->numEffCols();
     466
     467    view()->pushLayoutState(this, IntSize(m_x, m_y));
    444468
    445469    for (int r = 0; r < totalRows; r++) {
     
    551575        }
    552576    }
     577
     578    view()->popLayoutState();
    553579
    554580    m_height = m_rowPos[totalRows];
  • trunk/WebCore/rendering/RenderView.cpp

    r21093 r21183  
    4141    , m_printImages(true)
    4242    , m_maximalOutlineSize(0)
     43    , m_layoutState(0)
     44    , m_layoutStateDisableCount(0)
    4345{
    4446    // Clear our anonymous bit, set because RenderObject assumes
     
    100102        setChildNeedsLayout(true, false);
    101103   
     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
    102110    if (needsLayout())
    103111        RenderBlock::layout();
     
    110118    setOverflowHeight(docHeight());
    111119
     120    ASSERT(m_layoutStateDisableCount == 0);
     121    ASSERT(m_layoutState == &state);
     122    m_layoutState = 0;
    112123    setNeedsLayout(false);
    113124}
     
    140151    // Check to see if we are enclosed by a transparent layer.  If so, we cannot blit
    141152    // when scrolling, and we need to use slow repaints.
    142     Element* elt = element()->document()->ownerElement();
     153    Element* elt = document()->ownerElement();
    143154    if (view() && elt && elt->renderer()) {
    144155        RenderLayer* layer = elt->renderer()->enclosingLayer();
     
    177188    // We always just invalidate the root view, since we could be an iframe that is clipped out
    178189    // or even invisible.
    179     Element* elt = element()->document()->ownerElement();
     190    Element* elt = document()->ownerElement();
    180191    if (!elt)
    181192        m_frameView->repaintRectangle(ur, immediate);
     
    525536}
    526537
     538void 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
    527547} // namespace WebCore
  • trunk/WebCore/rendering/RenderView.h

    r21079 r21183  
    2525#define RenderView_h
    2626
     27#include "FrameView.h"
     28#include "LayoutState.h"
    2729#include "RenderBlock.h"
    2830
    2931namespace WebCore {
    30 
    31 class FrameView;
    3232
    3333class RenderView : public RenderBlock {
     
    9494    void addLayoutDelta(const IntSize& delta) { m_layoutDelta += delta; }
    9595
     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
    96122protected:
    97123    FrameView* m_frameView;
     
    118144    bool m_forcedPageBreak;
    119145    IntSize m_layoutDelta;
     146    LayoutState* m_layoutState;
     147    unsigned m_layoutStateDisableCount;
    120148};
    121149
Note: See TracChangeset for help on using the changeset viewer.