Changeset 53693 in webkit


Ignore:
Timestamp:
Jan 22, 2010 4:01:28 AM (14 years ago)
Author:
eric@webkit.org
Message:

2010-01-22 Benjamin Poulain <benjamin.poulain@nokia.com>

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 RenderObjects with fixed position register to the view
to be taken into account while scrolling.
The scrolling code update specifically those elements after blitting the pixels.

  • page/FrameView.cpp: (WebCore::FrameView::registerFixedPositionedObject): (WebCore::FrameView::unregisterFixedPositionedObject): (WebCore::FrameView::scrollContentsFastPath):
  • page/FrameView.h:
  • platform/ScrollView.cpp: (WebCore::ScrollView::scrollContents): (WebCore::ScrollView::scrollContentsFastPath):
  • platform/ScrollView.h:
  • rendering/RenderObject.cpp: (WebCore::RenderObject::styleWillChange): (WebCore::RenderObject::destroy):
Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r53690 r53693  
     12010-01-22  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        The RenderObjects with fixed position register to the view
     9        to be taken into account while scrolling.
     10        The scrolling code update specifically those elements after blitting the pixels.
     11
     12        * page/FrameView.cpp:
     13        (WebCore::FrameView::registerFixedPositionedObject):
     14        (WebCore::FrameView::unregisterFixedPositionedObject):
     15        (WebCore::FrameView::scrollContentsFastPath):
     16        * page/FrameView.h:
     17        * platform/ScrollView.cpp:
     18        (WebCore::ScrollView::scrollContents):
     19        (WebCore::ScrollView::scrollContentsFastPath):
     20        * platform/ScrollView.h:
     21        * rendering/RenderObject.cpp:
     22        (WebCore::RenderObject::styleWillChange):
     23        (WebCore::RenderObject::destroy):
     24
    1252010-01-22  Anton Muhin  <antonm@chromium.org>
    226
  • trunk/WebCore/page/FrameView.cpp

    r53637 r53693  
    814814}
    815815
     816
     817void FrameView::registerFixedPositionedObject(RenderObject* object)
     818{
     819    m_fixedPositionedObjects.add(object);
     820}
     821
     822void FrameView::unregisterFixedPositionedObject(RenderObject* object)
     823{
     824    m_fixedPositionedObjects.remove(object);
     825}
     826
     827void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
     828{
     829    const size_t fixedObjectNumberThreshold = 5;
     830
     831    if (m_fixedPositionedObjects.isEmpty())
     832        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     833    else {
     834        Vector<RenderObject*> fixedObjectsInViewport;
     835        fixedObjectsInViewport.reserveCapacity(m_fixedPositionedObjects.size());
     836
     837        bool updateInvalidatedSubRect = true;
     838        // Get a list of fixed objects that are not in transformations
     839        HashSet<RenderObject*>::const_iterator end = m_fixedPositionedObjects.end();
     840        HashSet<RenderObject*>::const_iterator it = m_fixedPositionedObjects.begin();
     841        for (; it != end; ++it) {
     842            RenderObject* obj = *it;
     843            // make sure the parent layer has not been transformed
     844            if (obj->containingBlock() == obj->view()) {
     845                fixedObjectsInViewport.append(obj);
     846                if (fixedObjectsInViewport.size() > fixedObjectNumberThreshold) {
     847                    updateInvalidatedSubRect = false;
     848                    break;
     849                }
     850            }
     851        }
     852
     853        // scroll the content
     854        if (updateInvalidatedSubRect) {
     855            // 1) scroll
     856            hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
     857
     858            // 2) update the area of fixed objets that has been invalidated
     859            for (size_t i = 0; i < fixedObjectsInViewport.size(); ++i) {
     860                IntRect topLevelRect;
     861                IntRect updateRect = fixedObjectsInViewport[i]->paintingRootRect(topLevelRect);
     862                updateRect.move(-scrollX(), -scrollY());
     863                IntRect scrolledRect = updateRect;
     864                scrolledRect.move(scrollDelta);
     865                updateRect.unite(scrolledRect);
     866                updateRect.intersect(rectToScroll);
     867                hostWindow()->repaint(updateRect, true, false, true);
     868            }
     869        } else {
     870            // the number of fixed objects exceed the threshold, so we repaint everything.
     871            IntRect updateRect = clipRect;
     872            updateRect.intersect(rectToScroll);
     873            hostWindow()->repaint(updateRect, true, false, true);
     874        }
     875    }
     876}
     877
    816878void FrameView::setIsOverlapped(bool isOverlapped)
    817879{
  • trunk/WebCore/page/FrameView.h

    r52947 r53693  
    146146    void removeSlowRepaintObject();
    147147
     148    // Methods to manage the objects that are fixed
     149    // in the view when scrolling
     150    void registerFixedPositionedObject(RenderObject* object);
     151    void unregisterFixedPositionedObject(RenderObject* object);
     152
    148153    void beginDeferredRepaints();
    149154    void endDeferredRepaints();
     
    199204    bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
    200205    void invalidateScrollCorner();
     206
     207protected:
     208    virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
    201209
    202210private:
     
    269277    bool m_contentIsOpaque;
    270278    unsigned m_slowRepaintObjectCount;
     279    HashSet<RenderObject*> m_fixedPositionedObjects;
    271280
    272281    int m_borderX, m_borderY;
  • trunk/WebCore/platform/ScrollView.cpp

    r53259 r53693  
    516516    if (canBlitOnScroll()) { // The main frame can just blit the WebView window
    517517       // FIXME: Find a way to blit subframes without blitting overlapping content
    518        hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
     518       scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect);
    519519    } else {
    520520       // We need to go ahead and repaint the entire backing store.  Do it now before moving the
     
    529529    // be very fast).
    530530    hostWindow()->paint();
     531}
     532
     533void ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
     534{
     535    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
    531536}
    532537
  • trunk/WebCore/platform/ScrollView.h

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

    r53506 r53693  
    16481648        s_affectsParentBlock = false;
    16491649
    1650     if (view()->frameView()) {
    1651         // FIXME: A better solution would be to only invalidate the fixed regions when scrolling.  It's overkill to
    1652         // prevent the entire view from blitting on a scroll.
    1653 
     1650    FrameView* frameView = view()->frameView();
     1651    if (frameView) {
    16541652        bool shouldBlitOnFixedBackgroundImage = false;
    16551653#if ENABLE(FAST_MOBILE_SCROLLING)
     
    16611659#endif
    16621660
    1663         bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition
    1664                                                || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage()));
    1665         bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition
    1666                                                || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage()));
     1661        bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
     1662        bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
     1663
    16671664        if (oldStyleSlowScroll != newStyleSlowScroll) {
    16681665            if (oldStyleSlowScroll)
    1669                 view()->frameView()->removeSlowRepaintObject();
     1666                frameView->removeSlowRepaintObject();
    16701667            if (newStyleSlowScroll)
    1671                 view()->frameView()->addSlowRepaintObject();
     1668                frameView->addSlowRepaintObject();
     1669        }
     1670
     1671        bool newStyleHasTransform = newStyle && (newStyle->hasTransformRelatedProperty());
     1672        if (!newStyleHasTransform) {
     1673            bool newStyleHasFixedPosition = newStyle && (newStyle->position() == FixedPosition);
     1674            bool oldStyleHasFixedPosition = m_style && (m_style->position() == FixedPosition);
     1675
     1676            if (oldStyleHasFixedPosition != newStyleHasFixedPosition) {
     1677                if (newStyleHasFixedPosition)
     1678                    frameView->registerFixedPositionedObject(this);
     1679                else
     1680                    frameView->unregisterFixedPositionedObject(this);
     1681            } else {
     1682                // if previously had a fix position, but had a transform, which has been removed
     1683                bool oldStyleHasTransform = m_style && (m_style->hasTransformRelatedProperty());
     1684                if (oldStyleHasTransform && newStyleHasFixedPosition)
     1685                    frameView->registerFixedPositionedObject(this);
     1686            }
    16721687        }
    16731688    }
     
    19321947void RenderObject::destroy()
    19331948{
     1949    // unregister from the view if the object had a fixed position
     1950    if (m_style && m_style->position() == FixedPosition) {
     1951        FrameView* frameView = document()->view();
     1952        if (frameView)
     1953            frameView->unregisterFixedPositionedObject(this);
     1954    }
     1955
    19341956    // Destroy any leftover anonymous children.
    19351957    RenderObjectChildList* children = virtualChildren();
Note: See TracChangeset for help on using the changeset viewer.