RenderLayer subtrees without any self-painting layer shouldn't be walked during hit...
authorjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Oct 2012 23:33:51 +0000 (23:33 +0000)
committerjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Oct 2012 23:33:51 +0000 (23:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=89393

Reviewed by Eric Seidel.

Performance optimization, covered by existing tests.

Bug 88888 added an peformance optimization for painting. As hit testing is very similar to
painting, it would benefit from the same optimization.

On http://dglazkov.github.com/performance-tests/biggrid.html, with a 10,000 * 100 tables,
it reduces the time to select some text inside a cell from 1-2 seconds to a usable time
(I didn't measure the exact timing).

Note that as in bug 88888, the multi-column code is not covered by this optimization.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::hitTest):
This is the entrance to the hit testing code so we check if we can bail out early.

(WebCore::RenderLayer::hitTestList):
If we have no self-painting descendant layers, we can bail out.

(WebCore::RenderLayer::hitTestContents):
(WebCore::RenderLayer::hitTestLayer):
hitTest should filter the layers that call these functions. Added some ASSERT to
make sure we don't mistakenly call them when could avoid it.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@131665 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp

index 1d4063f..4d51802 100644 (file)
@@ -1,3 +1,33 @@
+2012-10-17  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        RenderLayer subtrees without any self-painting layer shouldn't be walked during hit testing
+        https://bugs.webkit.org/show_bug.cgi?id=89393
+
+        Reviewed by Eric Seidel.
+
+        Performance optimization, covered by existing tests.
+
+        Bug 88888 added an peformance optimization for painting. As hit testing is very similar to
+        painting, it would benefit from the same optimization.
+
+        On http://dglazkov.github.com/performance-tests/biggrid.html, with a 10,000 * 100 tables,
+        it reduces the time to select some text inside a cell from 1-2 seconds to a usable time
+        (I didn't measure the exact timing).
+
+        Note that as in bug 88888, the multi-column code is not covered by this optimization.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::hitTest):
+        This is the entrance to the hit testing code so we check if we can bail out early.
+
+        (WebCore::RenderLayer::hitTestList):
+        If we have no self-painting descendant layers, we can bail out.
+
+        (WebCore::RenderLayer::hitTestContents):
+        (WebCore::RenderLayer::hitTestLayer):
+        hitTest should filter the layers that call these functions. Added some ASSERT to
+        make sure we don't mistakenly call them when could avoid it.
+
 2012-10-17  Allan Sandfeld Jensen  <allan.jensen@digia.com>
 
         [Qt] Certain SVG content freezes QtWebKit
index 0a9cf91..62606f1 100644 (file)
@@ -3504,6 +3504,8 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
 
 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result)
 {
+    ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
+
     renderer()->document()->updateLayout();
     
     LayoutRect hitTestArea = renderer()->isRenderFlowThread() ? toRenderFlowThread(renderer())->borderBoxRect() : renderer()->view()->documentRect();
@@ -3624,6 +3626,9 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
                                        const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform,
                                        const HitTestingTransformState* transformState, double* zOffset)
 {
+    if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
+        return 0;
+
     // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
 
     bool useTemporaryClipRects = renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
@@ -3795,6 +3800,8 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
 
 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const
 {
+    ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
+
     if (!renderer()->hitTest(request, result, hitTestLocation,
                             toLayoutPoint(layerBounds.location() - renderBoxLocation()),
                             hitTestFilter)) {
@@ -3829,7 +3836,10 @@ RenderLayer* RenderLayer::hitTestList(Vector<RenderLayer*>* list, RenderLayer* r
 {
     if (!list)
         return 0;
-    
+
+    if (!hasSelfPaintingLayerDescendant())
+        return 0;
+
     RenderLayer* resultLayer = 0;
     for (int i = list->size() - 1; i >= 0; --i) {
         RenderLayer* childLayer = list->at(i);