Changeset 55890 in webkit


Ignore:
Timestamp:
Mar 11, 2010 11:07:06 PM (14 years ago)
Author:
eric@webkit.org
Message:

2010-03-11 Benjamin Poulain <benjamin.poulain@nokia.com>

Reviewed by Adam Treat.

Do not render the full frame when there is some elements with fixed positioning
https://bugs.webkit.org/show_bug.cgi?id=33150

The frame view take into acount the list of fixed object when scrolling
the view. If the number of object is lower than a certain threshold, the pixel
are blitted, and the invalidated area updated.

  • page/FrameView.cpp: (WebCore::FrameView::FrameView): (WebCore::FrameView::useSlowRepaints): (WebCore::FrameView::useSlowRepaintsIfNotOverlapped): (WebCore::FrameView::addFixedObject): (WebCore::FrameView::removeFixedObject): (WebCore::FrameView::scrollContentsFastPath):
  • page/FrameView.h:
  • platform/ScrollView.cpp: (WebCore::ScrollView::scrollContents): (WebCore::ScrollView::scrollContentsFastPath):
  • platform/ScrollView.h:
  • rendering/RenderBlock.h: (WebCore::RenderBlock::positionedObjects):
  • rendering/RenderBox.cpp: (WebCore::RenderBox::styleWillChange):
  • rendering/RenderObject.cpp: (WebCore::RenderObject::styleWillChange):
Location:
trunk/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r55888 r55890  
     12010-03-11  Benjamin Poulain  <benjamin.poulain@nokia.com>
     2
     3        Reviewed by Adam Treat.
     4
     5        Do not render the full frame when there is some elements with fixed positioning
     6        https://bugs.webkit.org/show_bug.cgi?id=33150
     7
     8        The frame view take into acount the list of fixed object when scrolling
     9        the view. If the number of object is lower than a certain threshold, the pixel
     10        are blitted, and the invalidated area updated.
     11
     12        * page/FrameView.cpp:
     13        (WebCore::FrameView::FrameView):
     14        (WebCore::FrameView::useSlowRepaints):
     15        (WebCore::FrameView::useSlowRepaintsIfNotOverlapped):
     16        (WebCore::FrameView::addFixedObject):
     17        (WebCore::FrameView::removeFixedObject):
     18        (WebCore::FrameView::scrollContentsFastPath):
     19        * page/FrameView.h:
     20        * platform/ScrollView.cpp:
     21        (WebCore::ScrollView::scrollContents):
     22        (WebCore::ScrollView::scrollContentsFastPath):
     23        * platform/ScrollView.h:
     24        * rendering/RenderBlock.h:
     25        (WebCore::RenderBlock::positionedObjects):
     26        * rendering/RenderBox.cpp:
     27        (WebCore::RenderBox::styleWillChange):
     28        * rendering/RenderObject.cpp:
     29        (WebCore::RenderObject::styleWillChange):
     30
    1312010-03-11  Aaron Boodman  <aa@chromium.org>
    232
  • trunk/WebCore/page/FrameView.cpp

    r55675 r55890  
    109109    , m_canHaveScrollbars(true)
    110110    , m_slowRepaintObjectCount(0)
     111    , m_fixedObjectCount(0)
    111112    , m_layoutTimer(this, &FrameView::layoutTimerFired)
    112113    , m_layoutRoot(0)
     
    800801bool FrameView::useSlowRepaints() const
    801802{
    802     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;
     803    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
    803804}
    804805
    805806bool FrameView::useSlowRepaintsIfNotOverlapped() const
    806807{
    807     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
     808    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque;
    808809}
    809810
     
    827828    if (!m_slowRepaintObjectCount)
    828829        setCanBlitOnScroll(!useSlowRepaints());
     830}
     831
     832void FrameView::addFixedObject()
     833{
     834    if (!m_fixedObjectCount && platformWidget())
     835        setCanBlitOnScroll(false);
     836    ++m_fixedObjectCount;
     837}
     838
     839void FrameView::removeFixedObject()
     840{
     841    ASSERT(m_fixedObjectCount > 0);
     842    --m_fixedObjectCount;
     843    if (!m_fixedObjectCount)
     844        setCanBlitOnScroll(!useSlowRepaints());
     845}
     846
     847bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
     848{
     849    const size_t fixedObjectThreshold = 5;
     850
     851    ListHashSet<RenderBox*>* positionedObjects = 0;
     852    if (RenderView* root = m_frame->contentRenderer())
     853        positionedObjects = root->positionedObjects();
     854
     855    if (!positionedObjects || positionedObjects->isEmpty()) {
     856        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     857        return true;
     858    }
     859
     860    // Get the rects of the fixed objects visible in the rectToScroll
     861    Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
     862    bool updateInvalidatedSubRect = true;
     863    ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
     864    for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
     865        RenderBox* renderBox = *it;
     866        if (renderBox->style()->position() != FixedPosition)
     867            continue;
     868        IntRect topLevelRect;
     869        IntRect updateRect = renderBox->paintingRootRect(topLevelRect);
     870        updateRect.move(-scrollX(), -scrollY());
     871        updateRect.intersect(rectToScroll);
     872        if (!updateRect.isEmpty()) {
     873            if (subRectToUpdate.size() >= fixedObjectThreshold) {
     874                updateInvalidatedSubRect = false;
     875                break;
     876            }
     877            subRectToUpdate.append(updateRect);
     878        }
     879    }
     880
     881    // Scroll the view
     882    if (updateInvalidatedSubRect) {
     883        // 1) scroll
     884        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     885
     886        // 2) update the area of fixed objects that has been invalidated
     887        size_t fixObjectsCount = subRectToUpdate.size();
     888        for (size_t i = 0; i < fixObjectsCount; ++i) {
     889            IntRect updateRect = subRectToUpdate[i];
     890            IntRect scrolledRect = updateRect;
     891            scrolledRect.move(scrollDelta);
     892            updateRect.unite(scrolledRect);
     893            updateRect.intersect(rectToScroll);
     894            hostWindow()->invalidateContentsAndWindow(updateRect, false);
     895        }
     896        return true;
     897    }
     898
     899    // the number of fixed objects exceed the threshold, we cannot use the fast path
     900    return false;
    829901}
    830902
  • trunk/WebCore/page/FrameView.h

    r54994 r55890  
    150150    void removeSlowRepaintObject();
    151151
     152    void addFixedObject();
     153    void removeFixedObject();
     154
    152155    void beginDeferredRepaints();
    153156    void endDeferredRepaints();
     
    203206    bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
    204207    void invalidateScrollCorner();
     208
     209protected:
     210    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
    205211
    206212private:
     
    273279    bool m_contentIsOpaque;
    274280    unsigned m_slowRepaintObjectCount;
     281    unsigned m_fixedObjectCount;
    275282
    276283    int m_borderX, m_borderY;
  • trunk/WebCore/platform/ScrollView.cpp

    r55675 r55890  
    511511
    512512    if (canBlitOnScroll()) { // The main frame can just blit the WebView window
    513        // FIXME: Find a way to scroll subframes with this faster path
    514        hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
     513        // FIXME: Find a way to scroll subframes with this faster path
     514        if (!scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect))
     515            hostWindow()->invalidateContentsForSlowScroll(updateRect, false);
    515516    } else {
    516517       // We need to go ahead and repaint the entire backing store.  Do it now before moving the
     
    524525    // Now blit the backingstore into the window which should be very fast.
    525526    hostWindow()->invalidateWindow(IntRect(), true);
     527}
     528
     529bool ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
     530{
     531    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     532    return true;
    526533}
    527534
  • trunk/WebCore/platform/ScrollView.h

    r54620 r55890  
    250250    virtual void updateScrollCorner();
    251251    virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
     252
     253    // Scroll the content by blitting the pixels
     254    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
    252255   
    253256private:
  • trunk/WebCore/rendering/RenderBlock.h

    r55636 r55890  
    7575    void removePositionedObject(RenderBox*);
    7676    void removePositionedObjects(RenderBlock*);
     77    ListHashSet<RenderBox*>* positionedObjects() const { return m_positionedObjects; }
    7778
    7879    void addPercentHeightDescendant(RenderBox*);
  • trunk/WebCore/rendering/RenderBox.cpp

    r54784 r55890  
    145145            if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
    146146                removeFloatingOrPositionedChildFromBlockLists();
     147        }
     148    }
     149    if (FrameView *frameView = view()->frameView()) {
     150        bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition;
     151        bool oldStyleIsFixed = style() && style()->position() == FixedPosition;
     152        if (newStyleIsFixed != oldStyleIsFixed) {
     153            if (newStyleIsFixed)
     154                frameView->addFixedObject();
     155            else
     156                frameView->removeFixedObject();
    147157        }
    148158    }
  • trunk/WebCore/rendering/RenderObject.cpp

    r55090 r55890  
    16531653
    16541654    if (view()->frameView()) {
    1655         // FIXME: A better solution would be to only invalidate the fixed regions when scrolling.  It's overkill to
    1656         // prevent the entire view from blitting on a scroll.
    1657 
    16581655        bool shouldBlitOnFixedBackgroundImage = false;
    16591656#if ENABLE(FAST_MOBILE_SCROLLING)
     
    16651662#endif
    16661663
    1667         bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition
    1668                                                || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage()));
    1669         bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition
    1670                                                || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage()));
     1664        bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
     1665        bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
    16711666        if (oldStyleSlowScroll != newStyleSlowScroll) {
    16721667            if (oldStyleSlowScroll)
Note: See TracChangeset for help on using the changeset viewer.