[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Thu Apr 8 02:20:25 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 3754c523e347b7b8b5d37b5fa8de382c30f49f00
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Mar 12 07:07:06 2010 +0000

    2010-03-11  Benjamin Poulain  <benjamin.poulain at 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):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55890 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4cf6bf6..fe1bbe3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,33 @@
+2010-03-11  Benjamin Poulain  <benjamin.poulain at 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):
+
 2010-03-11  Aaron Boodman  <aa at chromium.org>
 
         Kill WebDocument::applicationID() (part 1).
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 2e9908a..0d9d07f 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -108,6 +108,7 @@ FrameView::FrameView(Frame* frame)
     : m_frame(frame)
     , m_canHaveScrollbars(true)
     , m_slowRepaintObjectCount(0)
+    , m_fixedObjectCount(0)
     , m_layoutTimer(this, &FrameView::layoutTimerFired)
     , m_layoutRoot(0)
     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
@@ -799,12 +800,12 @@ String FrameView::mediaType() const
 
 bool FrameView::useSlowRepaints() const
 {
-    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;
+    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
 }
 
 bool FrameView::useSlowRepaintsIfNotOverlapped() const
 {
-    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
+    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque;
 }
 
 void FrameView::setUseSlowRepaints()
@@ -828,6 +829,77 @@ void FrameView::removeSlowRepaintObject()
         setCanBlitOnScroll(!useSlowRepaints());
 }
 
+void FrameView::addFixedObject()
+{
+    if (!m_fixedObjectCount && platformWidget())
+        setCanBlitOnScroll(false);
+    ++m_fixedObjectCount;
+}
+
+void FrameView::removeFixedObject()
+{
+    ASSERT(m_fixedObjectCount > 0);
+    --m_fixedObjectCount;
+    if (!m_fixedObjectCount)
+        setCanBlitOnScroll(!useSlowRepaints());
+}
+
+bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+    const size_t fixedObjectThreshold = 5;
+
+    ListHashSet<RenderBox*>* positionedObjects = 0;
+    if (RenderView* root = m_frame->contentRenderer())
+        positionedObjects = root->positionedObjects();
+
+    if (!positionedObjects || positionedObjects->isEmpty()) {
+        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+        return true;
+    }
+
+    // Get the rects of the fixed objects visible in the rectToScroll
+    Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
+    bool updateInvalidatedSubRect = true;
+    ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
+    for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
+        RenderBox* renderBox = *it;
+        if (renderBox->style()->position() != FixedPosition)
+            continue;
+        IntRect topLevelRect;
+        IntRect updateRect = renderBox->paintingRootRect(topLevelRect);
+        updateRect.move(-scrollX(), -scrollY());
+        updateRect.intersect(rectToScroll);
+        if (!updateRect.isEmpty()) {
+            if (subRectToUpdate.size() >= fixedObjectThreshold) {
+                updateInvalidatedSubRect = false;
+                break;
+            }
+            subRectToUpdate.append(updateRect);
+        }
+    }
+
+    // Scroll the view
+    if (updateInvalidatedSubRect) {
+        // 1) scroll
+        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+
+        // 2) update the area of fixed objects that has been invalidated
+        size_t fixObjectsCount = subRectToUpdate.size();
+        for (size_t i = 0; i < fixObjectsCount; ++i) {
+            IntRect updateRect = subRectToUpdate[i];
+            IntRect scrolledRect = updateRect;
+            scrolledRect.move(scrollDelta);
+            updateRect.unite(scrolledRect);
+            updateRect.intersect(rectToScroll);
+            hostWindow()->invalidateContentsAndWindow(updateRect, false);
+        }
+        return true;
+    }
+
+    // the number of fixed objects exceed the threshold, we cannot use the fast path
+    return false;
+}
+
 void FrameView::setIsOverlapped(bool isOverlapped)
 {
     if (isOverlapped == m_isOverlapped)
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 1d5a312..15058a6 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -149,6 +149,9 @@ public:
     void addSlowRepaintObject();
     void removeSlowRepaintObject();
 
+    void addFixedObject();
+    void removeFixedObject();
+
     void beginDeferredRepaints();
     void endDeferredRepaints();
     void checkStopDelayingDeferredRepaints();
@@ -203,6 +206,9 @@ public:
     bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
     void invalidateScrollCorner();
 
+protected:
+    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+
 private:
     FrameView(Frame*);
 
@@ -272,6 +278,7 @@ private:
     bool m_isOverlapped;
     bool m_contentIsOpaque;
     unsigned m_slowRepaintObjectCount;
+    unsigned m_fixedObjectCount;
 
     int m_borderX, m_borderY;
 
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 4fd5cfd..c2a0adf 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -510,8 +510,9 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
     }
 
     if (canBlitOnScroll()) { // The main frame can just blit the WebView window
-       // FIXME: Find a way to scroll subframes with this faster path
-       hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
+        // FIXME: Find a way to scroll subframes with this faster path
+        if (!scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect))
+            hostWindow()->invalidateContentsForSlowScroll(updateRect, false);
     } else { 
        // We need to go ahead and repaint the entire backing store.  Do it now before moving the
        // windowed plugins.
@@ -525,6 +526,12 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
     hostWindow()->invalidateWindow(IntRect(), true);
 }
 
+bool ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+    return true;
+}
+
 IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
 {
     IntPoint viewPoint = convertFromContainingWindow(windowPoint);
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 111d6b6..f5bb169 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -249,6 +249,9 @@ protected:
     IntRect scrollCornerRect() const;
     virtual void updateScrollCorner();
     virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
+
+    // Scroll the content by blitting the pixels
+    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
     
 private:
     RefPtr<Scrollbar> m_horizontalScrollbar;
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 510a311..184f983 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -74,6 +74,7 @@ public:
     void insertPositionedObject(RenderBox*);
     void removePositionedObject(RenderBox*);
     void removePositionedObjects(RenderBlock*);
+    ListHashSet<RenderBox*>* positionedObjects() const { return m_positionedObjects; }
 
     void addPercentHeightDescendant(RenderBox*);
     static void removePercentHeightDescendant(RenderBox*);
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 1d8fb12..1c0e837 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -146,6 +146,16 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl
                 removeFloatingOrPositionedChildFromBlockLists();
         }
     }
+    if (FrameView *frameView = view()->frameView()) {
+        bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition;
+        bool oldStyleIsFixed = style() && style()->position() == FixedPosition;
+        if (newStyleIsFixed != oldStyleIsFixed) {
+            if (newStyleIsFixed)
+                frameView->addFixedObject();
+            else
+                frameView->removeFixedObject();
+        }
+    }
 
     RenderBoxModelObject::styleWillChange(diff, newStyle);
 }
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 3f39c15..8212dca 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -1652,9 +1652,6 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
         s_affectsParentBlock = false;
 
     if (view()->frameView()) {
-        // FIXME: A better solution would be to only invalidate the fixed regions when scrolling.  It's overkill to
-        // prevent the entire view from blitting on a scroll.
-
         bool shouldBlitOnFixedBackgroundImage = false;
 #if ENABLE(FAST_MOBILE_SCROLLING)
         // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
@@ -1664,10 +1661,8 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
         shouldBlitOnFixedBackgroundImage = true;
 #endif
 
-        bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition
-                                               || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage()));
-        bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition
-                                               || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage()));
+        bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
+        bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
         if (oldStyleSlowScroll != newStyleSlowScroll) {
             if (oldStyleSlowScroll)
                 view()->frameView()->removeSlowRepaintObject();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list