Title: [117313] trunk/Source/WebCore
Revision
117313
Author
timothy_hor...@apple.com
Date
2012-05-16 11:41:38 -0700 (Wed, 16 May 2012)

Log Message

FrameView::scrollContentsFastPath should use painted area to determine whether to drop out of the fast path
https://bugs.webkit.org/show_bug.cgi?id=86651
<rdar://problem/11459243>

Reviewed by Simon Fraser.

Previously, we decided to fall out of the fast scrolling path by the number of fixed-position elements
on the page. This was less than ideal if a single fixed position element took up a significant portion
of the page, or if there were many small, cheap-to-paint fixed elements.

Instead, we should use the fast path if less than 50% of the page will be repainted by fixed-position
elements, and otherwise fall back to the slow path.

I've tested a few different thresholds with an internal test; 50% seems to work relatively well,
but the ideal value is hard to determine and likely depends on hardware.

No new tests, performance improvement with few large fixed-position objects or many small ones.

* page/FrameView.cpp:
(WebCore::FrameView::scrollContentsFastPath):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (117312 => 117313)


--- trunk/Source/WebCore/ChangeLog	2012-05-16 18:31:53 UTC (rev 117312)
+++ trunk/Source/WebCore/ChangeLog	2012-05-16 18:41:38 UTC (rev 117313)
@@ -1,3 +1,26 @@
+2012-05-16  Tim Horton  <timothy_hor...@apple.com>
+
+        FrameView::scrollContentsFastPath should use painted area to determine whether to drop out of the fast path
+        https://bugs.webkit.org/show_bug.cgi?id=86651
+        <rdar://problem/11459243>
+
+        Reviewed by Simon Fraser.
+
+        Previously, we decided to fall out of the fast scrolling path by the number of fixed-position elements
+        on the page. This was less than ideal if a single fixed position element took up a significant portion
+        of the page, or if there were many small, cheap-to-paint fixed elements.
+
+        Instead, we should use the fast path if less than 50% of the page will be repainted by fixed-position
+        elements, and otherwise fall back to the slow path.
+
+        I've tested a few different thresholds with an internal test; 50% seems to work relatively well,
+        but the ideal value is hard to determine and likely depends on hardware.
+
+        No new tests, performance improvement with few large fixed-position objects or many small ones.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollContentsFastPath):
+
 2012-05-16  David Reveman  <reve...@chromium.org>
 
         [Chromium] Use ThrottledTextureUploader with threaded compositing.

Modified: trunk/Source/WebCore/page/FrameView.cpp (117312 => 117313)


--- trunk/Source/WebCore/page/FrameView.cpp	2012-05-16 18:31:53 UTC (rev 117312)
+++ trunk/Source/WebCore/page/FrameView.cpp	2012-05-16 18:41:38 UTC (rev 117313)
@@ -1454,8 +1454,6 @@
 
 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
 {
-    const size_t fixedObjectThreshold = 5;
-
     RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0;
     if (RenderView* root = rootRenderer(this))
         positionedObjects = root->positionedObjects();
@@ -1468,8 +1466,7 @@
     const bool isCompositedContentLayer = contentsInCompositedLayer();
 
     // Get the rects of the fixed objects visible in the rectToScroll
-    Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
-    bool updateInvalidatedSubRect = true;
+    Region regionToUpdate;
     RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
     for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
         RenderBox* renderBox = *it;
@@ -1483,45 +1480,40 @@
         updateRect = contentsToRootView(updateRect);
         if (!isCompositedContentLayer && clipsRepaints())
             updateRect.intersect(rectToScroll);
-        if (!updateRect.isEmpty()) {
-            if (subRectToUpdate.size() >= fixedObjectThreshold) {
-                updateInvalidatedSubRect = false;
-                break;
-            }
-            subRectToUpdate.append(updateRect);
-        }
+        if (!updateRect.isEmpty())
+            regionToUpdate.unite(updateRect);
     }
 
-    // Scroll the view
-    if (updateInvalidatedSubRect) {
-        // 1) scroll
-        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+    // The area to be painted by fixed objects exceeds 50% of the area of the view, we cannot use the fast path.
+    if (regionToUpdate.totalArea() > (clipRect.width() * clipRect.height() * 0.5))
+        return false;
 
-        // 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);
+    // 1) scroll
+    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+
+    // 2) update the area of fixed objects that has been invalidated
+    Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
+    size_t fixObjectsCount = subRectsToUpdate.size();
+    for (size_t i = 0; i < fixObjectsCount; ++i) {
+        IntRect updateRect = subRectsToUpdate[i];
+        IntRect scrolledRect = updateRect;
+        scrolledRect.move(scrollDelta);
+        updateRect.unite(scrolledRect);
 #if USE(ACCELERATED_COMPOSITING)
-            if (isCompositedContentLayer) {
-                updateRect = rootViewToContents(updateRect);
-                RenderView* root = rootRenderer(this);
-                ASSERT(root);
-                root->layer()->setBackingNeedsRepaintInRect(updateRect);
-                continue;
-            }
-#endif
-            if (clipsRepaints())
-                updateRect.intersect(rectToScroll);
-            hostWindow()->invalidateContentsAndRootView(updateRect, false);
+        if (isCompositedContentLayer) {
+            updateRect = rootViewToContents(updateRect);
+            RenderView* root = rootRenderer(this);
+            ASSERT(root);
+            root->layer()->setBackingNeedsRepaintInRect(updateRect);
+            continue;
         }
-        return true;
+#endif
+        if (clipsRepaints())
+            updateRect.intersect(rectToScroll);
+        hostWindow()->invalidateContentsAndRootView(updateRect, false);
     }
 
-    // the number of fixed objects exceed the threshold, we cannot use the fast path
-    return false;
+    return true;
 }
 
 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to