Cache RenderLayer::isRootLayer for better performance
authorjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2012 22:27:32 +0000 (22:27 +0000)
committerjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2012 22:27:32 +0000 (22:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=88570

Reviewed by Ojan Vafai.

Caching covered by existing tests.

RenderLayer::isRootLayer()'s answer will be the same during the RenderLayer's
lifetime as a RenderLayer is tied to a RenderBoxModelObject. This change caches
isRootLayer value in the constructor.

On http://dglazkov.github.com/performance-tests/biggrid.html with a 100,000 rows
by 100 columns table, it saves about 10% on the paint time during scrolling on
my machine (going from 50ms to 45ms). It would expect all code paths to see some
improvement as checking renderer()->isRenderView() was pretty common.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
Added code to cache the result of renderer()->isRenderView() here.

(WebCore::RenderLayer::stackingContext):
(WebCore::isPositionedContainer):
(WebCore::isFixedPositionedContainer):
(WebCore::RenderLayer::enclosingTransformedAncestor):
(WebCore::RenderLayer::clippingRootForPainting):
(WebCore::shouldSuppressPaintingLayer):
(WebCore::RenderLayer::hitTest):
(WebCore::RenderLayer::intersectsDamageRect):
* rendering/RenderLayer.h:
(WebCore::RenderLayer::isStackingContext):
Updated all the call sites to use isRootLayer() instead of renderer()->isRenderView()
as it is faster.

(WebCore::RenderLayer::isRootLayer):
Added our caching here. Also made m_canSkipRepaintRectsUpdateOnScroll to follow
m_isRootLayer example.

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

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

index eb7c4d6ec6e9eefdcd8463d4f1fb5041d6a9ef92..f3a85685e0716edf086e1dbb625d914eb5aeb1e5 100644 (file)
@@ -1,3 +1,42 @@
+2012-06-07  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        Cache RenderLayer::isRootLayer for better performance
+        https://bugs.webkit.org/show_bug.cgi?id=88570
+
+        Reviewed by Ojan Vafai.
+
+        Caching covered by existing tests.
+
+        RenderLayer::isRootLayer()'s answer will be the same during the RenderLayer's
+        lifetime as a RenderLayer is tied to a RenderBoxModelObject. This change caches
+        isRootLayer value in the constructor.
+
+        On http://dglazkov.github.com/performance-tests/biggrid.html with a 100,000 rows
+        by 100 columns table, it saves about 10% on the paint time during scrolling on
+        my machine (going from 50ms to 45ms). It would expect all code paths to see some
+        improvement as checking renderer()->isRenderView() was pretty common.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        Added code to cache the result of renderer()->isRenderView() here.
+
+        (WebCore::RenderLayer::stackingContext):
+        (WebCore::isPositionedContainer):
+        (WebCore::isFixedPositionedContainer):
+        (WebCore::RenderLayer::enclosingTransformedAncestor):
+        (WebCore::RenderLayer::clippingRootForPainting):
+        (WebCore::shouldSuppressPaintingLayer):
+        (WebCore::RenderLayer::hitTest):
+        (WebCore::RenderLayer::intersectsDamageRect):
+        * rendering/RenderLayer.h:
+        (WebCore::RenderLayer::isStackingContext):
+        Updated all the call sites to use isRootLayer() instead of renderer()->isRenderView()
+        as it is faster.
+
+        (WebCore::RenderLayer::isRootLayer):
+        Added our caching here. Also made m_canSkipRepaintRectsUpdateOnScroll to follow
+        m_isRootLayer example.
+
 2012-06-07  Takashi Sakamoto  <tasak@google.com>
 
         Incorrect border rendering when border radius is above 2px.
index c51d8444489a3979fc185dd6f16f5c0d2f9197b6..d5e4fcbd86afb139a2ea9d07256d489162eeda74 100644 (file)
@@ -129,6 +129,7 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
     : m_inResizeMode(false)
     , m_scrollDimensionsDirty(true)
     , m_normalFlowListDirty(true)
+    , m_isRootLayer(renderer->isRenderView())
     , m_usedTransparency(false)
     , m_paintingInsideReflection(false)
     , m_inOverflowRelayout(false)
@@ -865,21 +866,20 @@ FloatPoint RenderLayer::perspectiveOrigin() const
 RenderLayer* RenderLayer::stackingContext() const
 {
     RenderLayer* layer = parent();
-    while (layer && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
+    while (layer && !layer->isRootLayer() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
         layer = layer->parent();
     return layer;
 }
 
 static inline bool isPositionedContainer(RenderLayer* layer)
 {
-    RenderObject* o = layer->renderer();
-    return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform();
+    RenderBoxModelObject* layerRenderer = layer->renderer();
+    return layer->isRootLayer() || layerRenderer->isPositioned() || layerRenderer->isRelPositioned() || layer->hasTransform();
 }
 
 static inline bool isFixedPositionedContainer(RenderLayer* layer)
 {
-    RenderObject* o = layer->renderer();
-    return o->isRenderView() || layer->hasTransform();
+    return layer->isRootLayer() || layer->hasTransform();
 }
 
 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
@@ -909,7 +909,7 @@ IntRect RenderLayer::scrollableAreaBoundingBox() const
 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
 {
     RenderLayer* curr = parent();
-    while (curr && !curr->renderer()->isRenderView() && !curr->transform())
+    while (curr && !curr->isRootLayer() && !curr->transform())
         curr = curr->parent();
 
     return curr;
@@ -1058,7 +1058,7 @@ RenderLayer* RenderLayer::clippingRootForPainting() const
 
     const RenderLayer* current = this;
     while (current) {
-        if (current->renderer()->isRenderView())
+        if (current->isRootLayer())
             return const_cast<RenderLayer*>(current);
 
         current = compositingContainer(current);
@@ -2851,7 +2851,7 @@ static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
     // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
     // will do a full repaint().
-    if (layer->renderer()->document()->didLayoutWithPendingStylesheets() && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot())
+    if (layer->renderer()->document()->didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isRoot())
         return true;
 
     // Avoid painting all layers if the document is in a state where visual updates aren't allowed.
@@ -3317,7 +3317,7 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
         // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 
         // return ourselves. We do this so mouse events continue getting delivered after a drag has 
         // exited the WebView, and so hit testing over a scrollbar hits the content document.
-        if ((request.active() || request.release()) && renderer()->isRenderView()) {
+        if ((request.active() || request.release()) && isRootLayer()) {
             renderer()->updateHitTestResult(result, result.point());
             insideLayer = this;
         }
@@ -4038,7 +4038,7 @@ bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo
     // Always examine the canvas and the root.
     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
     // paints the root's background.
-    if (renderer()->isRenderView() || renderer()->isRoot())
+    if (isRootLayer() || renderer()->isRoot())
         return true;
 
     // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we 
index 73f55b853d185383d04e197a11095c283e1c7c9e..bd81c95105ef5ea4d9a3c9d9282597ee2a468dc0 100644 (file)
@@ -368,8 +368,8 @@ public:
     bool inResizeMode() const { return m_inResizeMode; }
     void setInResizeMode(bool b) { m_inResizeMode = b; }
 
-    bool isRootLayer() const { return renderer()->isRenderView(); }
-    
+    bool isRootLayer() const { return m_isRootLayer; }
+
 #if USE(ACCELERATED_COMPOSITING)
     RenderLayerCompositor* compositor() const;
     
@@ -646,7 +646,7 @@ private:
 
     void updateNormalFlowList();
 
-    bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || renderer()->isRenderView(); }
+    bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || isRootLayer(); }
     bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
 
     void computeRepaintRects(LayoutPoint* offsetFromRoot = 0);
@@ -871,6 +871,8 @@ protected:
 
     bool m_isSelfPaintingLayer : 1;
 
+    const bool m_isRootLayer : 1;
+
     bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
                                  // we ended up painting this layer or any descendants (and therefore need to
                                  // blend).
@@ -900,7 +902,7 @@ protected:
     // This is an optimization added for <table>.
     // Currently cells do not need to update their repaint rectangles when scrolling. This also
     // saves a lot of time when scrolling on a table.
-    bool m_canSkipRepaintRectsUpdateOnScroll : 1;
+    const bool m_canSkipRepaintRectsUpdateOnScroll : 1;
 
 #if ENABLE(CSS_FILTERS)
     bool m_hasFilterInfo : 1;