[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

eric at webkit.org eric at webkit.org
Thu Feb 4 21:27:09 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 4644ecca4204b7e9f8de9df8175f5ae6160dd132
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Jan 25 12:37:37 2010 +0000

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

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d5c8773..3c49245 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,28 @@
+2010-01-25  Benjamin Poulain  <benjamin.poulain at 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):
+
 2010-01-24  Pavel Feldman  <pfeldman at chromium.org>
 
         Reviewed by Timothy Hatcher.
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 21666ae..efc6c69 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -784,12 +784,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_fixedPositionedObjects.isEmpty()) || m_isOverlapped || !m_contentIsOpaque;
 }
 
 bool FrameView::useSlowRepaintsIfNotOverlapped() const
 {
-    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
+    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && !m_fixedPositionedObjects.isEmpty()) || !m_contentIsOpaque;
 }
 
 void FrameView::setUseSlowRepaints()
@@ -813,6 +813,73 @@ void FrameView::removeSlowRepaintObject()
         setCanBlitOnScroll(!useSlowRepaints());
 }
 
+
+void FrameView::registerFixedPositionedObject(RenderObject* object)
+{
+    if (platformWidget() && m_fixedPositionedObjects.isEmpty())
+        setCanBlitOnScroll(false);
+    m_fixedPositionedObjects.add(object);
+}
+
+void FrameView::unregisterFixedPositionedObject(RenderObject* object)
+{
+    bool wasEmpty = m_fixedPositionedObjects.isEmpty();
+    m_fixedPositionedObjects.remove(object);
+    if (platformWidget() && !wasEmpty && m_fixedPositionedObjects.isEmpty())
+        setCanBlitOnScroll(!useSlowRepaints());
+}
+
+void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+    const size_t fixedObjectNumberThreshold = 5;
+
+    if (m_fixedPositionedObjects.isEmpty())
+        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+    else {
+        Vector<RenderObject*, fixedObjectNumberThreshold> fixedObjectsInViewport;
+
+        bool updateInvalidatedSubRect = true;
+        // Get a list of fixed objects that are not in transformations
+        HashSet<RenderObject*>::const_iterator end = m_fixedPositionedObjects.end();
+        HashSet<RenderObject*>::const_iterator it = m_fixedPositionedObjects.begin();
+        for (; it != end; ++it) {
+            RenderObject* obj = *it;
+            // make sure the parent layer has not been transformed
+            if (obj->containingBlock() == obj->view()) {
+                if (fixedObjectsInViewport.size() >= fixedObjectNumberThreshold) {
+                    updateInvalidatedSubRect = false;
+                    break;
+                }
+                fixedObjectsInViewport.append(obj);
+            }
+        }
+
+        // scroll the content
+        if (updateInvalidatedSubRect) {
+            // 1) scroll
+            hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+
+            // 2) update the area of fixed objets that has been invalidated
+            size_t fixObjectsCount = fixedObjectsInViewport.size();
+            for (size_t i = 0; i < fixObjectsCount; ++i) {
+                IntRect topLevelRect;
+                IntRect updateRect = fixedObjectsInViewport[i]->paintingRootRect(topLevelRect);
+                updateRect.move(-scrollX(), -scrollY());
+                IntRect scrolledRect = updateRect;
+                scrolledRect.move(scrollDelta);
+                updateRect.unite(scrolledRect);
+                updateRect.intersect(rectToScroll);
+                hostWindow()->repaint(updateRect, true, false, true);
+            }
+        } else {
+            // the number of fixed objects exceed the threshold, so we repaint everything.
+            IntRect updateRect = clipRect;
+            updateRect.intersect(rectToScroll);
+            hostWindow()->repaint(updateRect, true, false, true);
+        }
+    }
+}
+
 void FrameView::setIsOverlapped(bool isOverlapped)
 {
     if (isOverlapped == m_isOverlapped)
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index b27ffd8..c3de05b 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -145,6 +145,11 @@ public:
     void addSlowRepaintObject();
     void removeSlowRepaintObject();
 
+    // Methods to manage the objects that are fixed
+    // in the view when scrolling
+    void registerFixedPositionedObject(RenderObject* object);
+    void unregisterFixedPositionedObject(RenderObject* object);
+
     void beginDeferredRepaints();
     void endDeferredRepaints();
     void checkStopDelayingDeferredRepaints();
@@ -199,6 +204,9 @@ public:
     bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
     void invalidateScrollCorner();
 
+protected:
+    virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+
 private:
     FrameView(Frame*);
 
@@ -268,6 +276,7 @@ private:
     bool m_isOverlapped;
     bool m_contentIsOpaque;
     unsigned m_slowRepaintObjectCount;
+    HashSet<RenderObject*> m_fixedPositionedObjects;
 
     int m_borderX, m_borderY;
 
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index e4291cc..0156680 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -513,7 +513,7 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
 
     if (canBlitOnScroll()) { // The main frame can just blit the WebView window
        // FIXME: Find a way to blit subframes without blitting overlapping content
-       hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
+       scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect);
     } else { 
        // We need to go ahead and repaint the entire backing store.  Do it now before moving the
        // windowed plugins.
@@ -528,6 +528,11 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
     hostWindow()->paint();
 }
 
+void ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+}
+
 IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
 {
     IntPoint viewPoint = convertFromContainingWindow(windowPoint);
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index a7173a7..6ca2581 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 void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
     
 private:
     RefPtr<Scrollbar> m_horizontalScrollbar;
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 5ddb882..c6c015a 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -1647,10 +1647,8 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
     } else
         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.
-
+    FrameView* frameView = view()->frameView();
+    if (frameView) {
         bool shouldBlitOnFixedBackgroundImage = false;
 #if ENABLE(FAST_MOBILE_SCROLLING)
         // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
@@ -1660,15 +1658,32 @@ 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();
+                frameView->removeSlowRepaintObject();
             if (newStyleSlowScroll)
-                view()->frameView()->addSlowRepaintObject();
+                frameView->addSlowRepaintObject();
+        }
+
+        bool newStyleHasTransform = newStyle && (newStyle->hasTransformRelatedProperty());
+        if (!newStyleHasTransform) {
+            bool newStyleHasFixedPosition = newStyle && (newStyle->position() == FixedPosition);
+            bool oldStyleHasFixedPosition = m_style && (m_style->position() == FixedPosition);
+
+            if (oldStyleHasFixedPosition != newStyleHasFixedPosition) {
+                if (newStyleHasFixedPosition)
+                    frameView->registerFixedPositionedObject(this);
+                else
+                    frameView->unregisterFixedPositionedObject(this);
+            } else {
+                // if previously had a fix position, but had a transform, which has been removed
+                bool oldStyleHasTransform = m_style && (m_style->hasTransformRelatedProperty());
+                if (oldStyleHasTransform && newStyleHasFixedPosition)
+                    frameView->registerFixedPositionedObject(this);
+            }
         }
     }
 }
@@ -1931,6 +1946,13 @@ bool RenderObject::isSelectionBorder() const
 
 void RenderObject::destroy()
 {
+    // unregister from the view if the object had a fixed position
+    if (m_style && m_style->position() == FixedPosition) {
+        FrameView* frameView = document()->view();
+        if (frameView)
+            frameView->unregisterFixedPositionedObject(this);
+    }
+
     // Destroy any leftover anonymous children.
     RenderObjectChildList* children = virtualChildren();
     if (children)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list