Changeset 61686 in webkit


Ignore:
Timestamp:
Jun 23, 2010 7:11:26 AM (14 years ago)
Author:
benjamin.poulain@nokia.com
Message:

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

Reviewed by Kenneth Rohde Christiansen.

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::addFixedObject):
(WebCore::FrameView::removeFixedObject):
(WebCore::FrameView::scrollContentsFastPath):

  • page/FrameView.h:
  • platform/ScrollView.cpp:

(WebCore::ScrollView::scrollContents):
(WebCore::ScrollView::scrollContentsFastPath):

  • platform/ScrollView.h:
  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::repaintRectIncludingDescendants):

  • rendering/RenderLayer.h:
  • rendering/RenderObject.cpp:

(WebCore::RenderObject::styleWillChange):

Location:
trunk/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r61682 r61686  
     12010-06-23  Benjamin Poulain  <benjamin.poulain@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     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        Do not render the full frame when there is some elements with fixed positioning
     9        https://bugs.webkit.org/show_bug.cgi?id=33150
     10
     11        The frame view take into acount the list of fixed object when scrolling
     12        the view. If the number of object is lower than a certain threshold, the pixel
     13        are blitted, and the invalidated area updated.
     14
     15        * page/FrameView.cpp:
     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/RenderLayer.cpp:
     25        (WebCore::RenderLayer::repaintRectIncludingDescendants):
     26        * rendering/RenderLayer.h:
     27        * rendering/RenderObject.cpp:
     28        (WebCore::RenderObject::styleWillChange):
     29
    1302010-06-23  Mikhail Naganov  <mnaganov@chromium.org>
    231
  • trunk/WebCore/page/FrameView.cpp

    r61312 r61686  
    915915void FrameView::addFixedObject()
    916916{
     917    if (!m_fixedObjectCount && platformWidget())
     918        setCanBlitOnScroll(false);
    917919    ++m_fixedObjectCount;
    918920}
     
    922924    ASSERT(m_fixedObjectCount > 0);
    923925    --m_fixedObjectCount;
     926    if (!m_fixedObjectCount)
     927        setCanBlitOnScroll(!useSlowRepaints());
     928}
     929
     930bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
     931{
     932    const size_t fixedObjectThreshold = 5;
     933
     934    RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0;
     935    if (RenderView* root = m_frame->contentRenderer())
     936        positionedObjects = root->positionedObjects();
     937
     938    if (!positionedObjects || positionedObjects->isEmpty()) {
     939        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     940        return true;
     941    }
     942
     943    // Get the rects of the fixed objects visible in the rectToScroll
     944    Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
     945    bool updateInvalidatedSubRect = true;
     946    RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
     947    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
     948        RenderBox* renderBox = *it;
     949        if (renderBox->style()->position() != FixedPosition)
     950            continue;
     951        IntRect updateRect = renderBox->layer()->repaintRectIncludingDescendants();
     952        updateRect = contentsToWindow(updateRect);
     953
     954        updateRect.intersect(rectToScroll);
     955        if (!updateRect.isEmpty()) {
     956            if (subRectToUpdate.size() >= fixedObjectThreshold) {
     957                updateInvalidatedSubRect = false;
     958                break;
     959            }
     960            subRectToUpdate.append(updateRect);
     961        }
     962    }
     963
     964    // Scroll the view
     965    if (updateInvalidatedSubRect) {
     966        // 1) scroll
     967        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     968
     969        // 2) update the area of fixed objects that has been invalidated
     970        size_t fixObjectsCount = subRectToUpdate.size();
     971        for (size_t i = 0; i < fixObjectsCount; ++i) {
     972            IntRect updateRect = subRectToUpdate[i];
     973            IntRect scrolledRect = updateRect;
     974            scrolledRect.move(scrollDelta);
     975            updateRect.unite(scrolledRect);
     976            updateRect.intersect(rectToScroll);
     977            hostWindow()->invalidateContentsAndWindow(updateRect, false);
     978        }
     979        return true;
     980    }
     981
     982    // the number of fixed objects exceed the threshold, we cannot use the fast path
     983    return false;
    924984}
    925985
  • trunk/WebCore/page/FrameView.h

    r61360 r61686  
    231231    // On each repaint the delay increses by this amount
    232232    static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p);
     233
     234protected:
     235    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
    233236   
    234237private:
  • trunk/WebCore/platform/ScrollView.cpp

    r60591 r61686  
    514514    if (canBlitOnScroll()) { // The main frame can just blit the WebView window
    515515        // FIXME: Find a way to scroll subframes with this faster path
    516         hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
     516        if (!scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect))
     517            hostWindow()->invalidateContentsForSlowScroll(updateRect, false);
    517518    } else {
    518519       // We need to go ahead and repaint the entire backing store.  Do it now before moving the
     
    526527    // Now blit the backingstore into the window which should be very fast.
    527528    hostWindow()->invalidateWindow(IntRect(), true);
     529}
     530
     531bool ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
     532{
     533    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     534    return true;
    528535}
    529536
  • trunk/WebCore/platform/ScrollView.h

    r60591 r61686  
    259259    virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
    260260
     261    // Scroll the content by blitting the pixels
     262    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
     263
    261264private:
    262265    RefPtr<Scrollbar> m_horizontalScrollbar;
  • trunk/WebCore/rendering/RenderLayer.cpp

    r60753 r61686  
    377377}
    378378
     379IntRect RenderLayer::repaintRectIncludingDescendants() const
     380{
     381    IntRect repaintRect = m_repaintRect;
     382    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
     383        repaintRect.unite(child->repaintRectIncludingDescendants());
     384    return repaintRect;
     385}
     386
    379387void RenderLayer::computeRepaintRects()
    380388{
  • trunk/WebCore/rendering/RenderLayer.h

    r59784 r61686  
    396396    // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint.
    397397    IntRect repaintRect() const { return m_repaintRect; }
     398    IntRect repaintRectIncludingDescendants() const;
    398399    void computeRepaintRects();
    399400    void updateRepaintRectsAfterScroll(bool fixed = false);
  • trunk/WebCore/rendering/RenderObject.cpp

    r60946 r61686  
    16311631
    16321632    if (view()->frameView()) {
    1633         // FIXME: A better solution would be to only invalidate the fixed regions when scrolling.  It's overkill to
    1634         // prevent the entire view from blitting on a scroll.
    1635 
    16361633        bool shouldBlitOnFixedBackgroundImage = false;
    16371634#if ENABLE(FAST_MOBILE_SCROLLING)
     
    16431640#endif
    16441641
    1645         bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition
    1646                                                 || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage()));
    1647         bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition
    1648                                                 || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage()));
    1649 
     1642        bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
     1643        bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
    16501644        if (oldStyleSlowScroll != newStyleSlowScroll) {
    16511645            if (oldStyleSlowScroll)
Note: See TracChangeset for help on using the changeset viewer.