Changeset 53797 in webkit


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

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

Reviewed by Antti Koivisto.

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

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

  • page/FrameView.cpp: (WebCore::FrameView::useSlowRepaints): (WebCore::FrameView::useSlowRepaintsIfNotOverlapped): (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

    r53795 r53797  
     12010-01-25  Benjamin Poulain  <benjamin.poulain@nokia.com>
     2
     3        Reviewed by Antti Koivisto.
     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        * page/FrameView.cpp:
     12        (WebCore::FrameView::useSlowRepaints):
     13        (WebCore::FrameView::useSlowRepaintsIfNotOverlapped):
     14        (WebCore::FrameView::registerFixedPositionedObject):
     15        (WebCore::FrameView::unregisterFixedPositionedObject):
     16        (WebCore::FrameView::scrollContentsFastPath):
     17        * page/FrameView.h:
     18        * platform/ScrollView.cpp:
     19        (WebCore::ScrollView::scrollContents):
     20        (WebCore::ScrollView::scrollContentsFastPath):
     21        * platform/ScrollView.h:
     22        * rendering/RenderObject.cpp:
     23        (WebCore::RenderObject::styleWillChange):
     24        (WebCore::RenderObject::destroy):
     25
    1262010-01-24  Pavel Feldman  <pfeldman@chromium.org>
    227
  • trunk/WebCore/page/FrameView.cpp

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

    r53713 r53797  
    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

    r53718 r53797  
    514514    if (canBlitOnScroll()) { // The main frame can just blit the WebView window
    515515       // FIXME: Find a way to blit subframes without blitting overlapping content
    516        hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
     516       scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect);
    517517    } else {
    518518       // We need to go ahead and repaint the entire backing store.  Do it now before moving the
     
    527527    // be very fast).
    528528    hostWindow()->paint();
     529}
     530
     531void ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
     532{
     533    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
    529534}
    530535
  • trunk/WebCore/platform/ScrollView.h

    r53713 r53797  
    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

    r53713 r53797  
    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.