Title: [134705] branches/safari-536.28-branch/Source/WebCore
Revision
134705
Author
simon.fra...@apple.com
Date
2012-11-14 18:06:58 -0800 (Wed, 14 Nov 2012)

Log Message

<rdar://problem/12705261> Cache absolute clip rects on RenderLayer for compositing overlap testing (87212)

Merge r119458.

    2012-05-25  Simon Fraser  <simon.fra...@apple.com>

    Cache absolute clip rects on RenderLayer for compositing overlap testing
    https://bugs.webkit.org/show_bug.cgi?id=87212

    Reviewed by Dave Hyatt.

    Enhance the cache of ClipRects on RenderLayers to store three
    different types of ClipRects, rather than just one.

    We need to compute clip rects relative to different layers
    for different purposes. For painting, we compute relative to
    the compositing layer which is acting as a painting root.
    For hit testing, we compute relative to the root, except
    for transformed layers. For composting overlap testing, we
    compute relative to the root ("absolute"). At other times, we do one-off
    computation which we never want to cache ("temporary clip rects").

    This change allows us to cache rects for hit testing, and for
    compositing overlap testing. This has huge performance benefits
    on some pages (bug 84410).

    This change also makes ClipRects not arena-allocated, so we
    can use RefPtr<ClipRect>.

    No testable behavior change.

    * rendering/RenderBoxModelObject.cpp:
    (WebCore::RenderBoxModelObject::willBeDestroyed): No need for the
    explicit clipRects teardown, since clipRects don't need a live
    RenderObject for arena-based destruction.

    * rendering/RenderLayer.cpp: Remove arena-related new and delete.
    (WebCore::RenderLayer::RenderLayer): No need to explicitly initialize m_clipRects,
    since it's an OwnPtr now.
    (WebCore::RenderLayer::~RenderLayer): No explicit clipRect teardown required.
    (WebCore::RenderLayer::clippingRootForPainting): Renamed to make its purpose
    more obvious.
    (WebCore::RenderLayer::paintLayer): Use the TemporaryClipRects type when necessary.
    (WebCore::RenderLayer::paintLayerContents): Ditto
    (WebCore::RenderLayer::hitTestLayer): No longer need to use temporary clipRects when
    hit testing since we cache clip rects for hit testing.
    (WebCore::RenderLayer::updateClipRects): Take a ClipRectsType and pass it through.
    (WebCore::RenderLayer::calculateClipRects): Ditto
    (WebCore::RenderLayer::parentClipRects): Ditto
    (WebCore::RenderLayer::backgroundClipRect): Ditto
    (WebCore::RenderLayer::calculateRects): Take ClipRectsType, which obviates temporaryClipRects.
    (WebCore::RenderLayer::childrenClipRect): Use clippingRootForPainting().
    (WebCore::RenderLayer::selfClipRect): Ditto
    (WebCore::RenderLayer::localClipRect): Ditto
    (WebCore::RenderLayer::clearClipRectsIncludingDescendants): Take a type of clip rect to clear
    (include all). Allows us to just clear painting clip rects.
    (WebCore::RenderLayer::clearClipRects):

    * rendering/RenderLayer.h:
    (WebCore::ClipRects::create): We don't use RefCounted<> in order to use a bit in
    the refCount for a flag. Add create() method.
    (WebCore::ClipRects::deref): No longer arena-allocated.
    (WebCore::ClipRectsCache::ClipRectsCache): Struct that holds a small
    array of the 3 types of clipRects (and, in debug, the layer relative
    to which they were computed).
    (WebCore::RenderLayer::clipRects):

    * rendering/RenderLayerBacking.cpp:
    (WebCore::RenderLayerBacking::updateCompositedBounds): Use AbsoluteClipRects; rootLayer
    is always the RenderView's layer here.
    (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Use TemporaryClipRects.
    (WebCore::RenderLayerBacking::setRequiresOwnBackingStore): When this variable changes,
    we need to invalidate painting clipRects, since it affects the ancestor relative to which
    those rects are computed.

    * rendering/RenderLayerBacking.h:
    * rendering/RenderLayerCompositor.cpp:
    (WebCore::RenderLayerCompositor::updateBacking): When the composited state
    of a layer changes, we have to clear all descendant clip rects, since this
    can affect the layers relative to which clip rects are computed.
    (WebCore::RenderLayerCompositor::addToOverlapMap): Use AbsoluteClipRects.
    (WebCore::RenderLayerCompositor::computeCompositingRequirements): No need
    to call updateLayerPosition(), since that should have always happened after
    layout. That call cleared clip rects, so removing it is very beneficial.
    (WebCore::RenderLayerCompositor::clippedByAncestor): Use TemporaryClipRects.

    * rendering/RenderTreeAsText.cpp:
    (WebCore::writeLayers): Use TemporaryClipRects.

Modified Paths

Diff

Modified: branches/safari-536.28-branch/Source/WebCore/ChangeLog (134704 => 134705)


--- branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-15 02:06:52 UTC (rev 134704)
+++ branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-15 02:06:58 UTC (rev 134705)
@@ -1,5 +1,96 @@
 2012-11-13  Simon Fraser  <simon.fra...@apple.com>
 
+        <rdar://problem/12705261> Cache absolute clip rects on RenderLayer for compositing overlap testing (87212)
+
+        Merge r119458.
+
+    2012-05-25  Simon Fraser  <simon.fra...@apple.com>
+    
+            Cache absolute clip rects on RenderLayer for compositing overlap testing
+            https://bugs.webkit.org/show_bug.cgi?id=87212
+    
+            Reviewed by Dave Hyatt.
+            
+            Enhance the cache of ClipRects on RenderLayers to store three
+            different types of ClipRects, rather than just one.
+            
+            We need to compute clip rects relative to different layers
+            for different purposes. For painting, we compute relative to
+            the compositing layer which is acting as a painting root.
+            For hit testing, we compute relative to the root, except
+            for transformed layers. For composting overlap testing, we
+            compute relative to the root ("absolute"). At other times, we do one-off
+            computation which we never want to cache ("temporary clip rects").
+            
+            This change allows us to cache rects for hit testing, and for
+            compositing overlap testing. This has huge performance benefits
+            on some pages (bug 84410).
+            
+            This change also makes ClipRects not arena-allocated, so we
+            can use RefPtr<ClipRect>.
+    
+            No testable behavior change.
+    
+            * rendering/RenderBoxModelObject.cpp:
+            (WebCore::RenderBoxModelObject::willBeDestroyed): No need for the
+            explicit clipRects teardown, since clipRects don't need a live
+            RenderObject for arena-based destruction.
+    
+            * rendering/RenderLayer.cpp: Remove arena-related new and delete.
+            (WebCore::RenderLayer::RenderLayer): No need to explicitly initialize m_clipRects,
+            since it's an OwnPtr now.
+            (WebCore::RenderLayer::~RenderLayer): No explicit clipRect teardown required.
+            (WebCore::RenderLayer::clippingRootForPainting): Renamed to make its purpose
+            more obvious.
+            (WebCore::RenderLayer::paintLayer): Use the TemporaryClipRects type when necessary.
+            (WebCore::RenderLayer::paintLayerContents): Ditto
+            (WebCore::RenderLayer::hitTestLayer): No longer need to use temporary clipRects when
+            hit testing since we cache clip rects for hit testing.
+            (WebCore::RenderLayer::updateClipRects): Take a ClipRectsType and pass it through.
+            (WebCore::RenderLayer::calculateClipRects): Ditto
+            (WebCore::RenderLayer::parentClipRects): Ditto
+            (WebCore::RenderLayer::backgroundClipRect): Ditto
+            (WebCore::RenderLayer::calculateRects): Take ClipRectsType, which obviates temporaryClipRects.
+            (WebCore::RenderLayer::childrenClipRect): Use clippingRootForPainting().
+            (WebCore::RenderLayer::selfClipRect): Ditto
+            (WebCore::RenderLayer::localClipRect): Ditto
+            (WebCore::RenderLayer::clearClipRectsIncludingDescendants): Take a type of clip rect to clear
+            (include all). Allows us to just clear painting clip rects.
+            (WebCore::RenderLayer::clearClipRects):
+    
+            * rendering/RenderLayer.h:
+            (WebCore::ClipRects::create): We don't use RefCounted<> in order to use a bit in
+            the refCount for a flag. Add create() method.
+            (WebCore::ClipRects::deref): No longer arena-allocated.
+            (WebCore::ClipRectsCache::ClipRectsCache): Struct that holds a small
+            array of the 3 types of clipRects (and, in debug, the layer relative
+            to which they were computed).
+            (WebCore::RenderLayer::clipRects):
+    
+            * rendering/RenderLayerBacking.cpp:
+            (WebCore::RenderLayerBacking::updateCompositedBounds): Use AbsoluteClipRects; rootLayer
+            is always the RenderView's layer here.
+            (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Use TemporaryClipRects.
+            (WebCore::RenderLayerBacking::setRequiresOwnBackingStore): When this variable changes,
+            we need to invalidate painting clipRects, since it affects the ancestor relative to which
+            those rects are computed.
+    
+            * rendering/RenderLayerBacking.h:
+            * rendering/RenderLayerCompositor.cpp:
+            (WebCore::RenderLayerCompositor::updateBacking): When the composited state
+            of a layer changes, we have to clear all descendant clip rects, since this
+            can affect the layers relative to which clip rects are computed.
+            (WebCore::RenderLayerCompositor::addToOverlapMap): Use AbsoluteClipRects.
+            (WebCore::RenderLayerCompositor::computeCompositingRequirements): No need
+            to call updateLayerPosition(), since that should have always happened after
+            layout. That call cleared clip rects, so removing it is very beneficial.
+            (WebCore::RenderLayerCompositor::clippedByAncestor): Use TemporaryClipRects.
+    
+            * rendering/RenderTreeAsText.cpp:
+            (WebCore::writeLayers): Use TemporaryClipRects.
+
+2012-11-13  Simon Fraser  <simon.fra...@apple.com>
+
         <rdar://problem/12705190> Terrible performance on http://alliances.commandandconquer.com/ and http://www.lordofultima.com/ and App Store (84410)
 
         Merge r118567, r118617, r118957, r119172, r121124, r121130, r121306, r121446, r122376, r122653 (partial), r122802 (partial),

Modified: branches/safari-536.28-branch/Source/WebCore/rendering/RenderBoxModelObject.cpp (134704 => 134705)


--- branches/safari-536.28-branch/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-11-15 02:06:52 UTC (rev 134704)
+++ branches/safari-536.28-branch/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-11-15 02:06:58 UTC (rev 134705)
@@ -345,10 +345,6 @@
 
 void RenderBoxModelObject::willBeDestroyed()
 {
-    // This must be done before we destroy the RenderObject.
-    if (m_layer)
-        m_layer->clearClipRects();
-
     // A continuation of this RenderObject should be destroyed at subclasses.
     ASSERT(!continuation());
 

Modified: branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.cpp (134704 => 134705)


--- branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.cpp	2012-11-15 02:06:52 UTC (rev 134704)
+++ branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.cpp	2012-11-15 02:06:58 UTC (rev 134705)
@@ -127,25 +127,6 @@
 const int MinimumWidthWhileResizing = 100;
 const int MinimumHeightWhileResizing = 40;
 
-void* ClipRects::operator new(size_t sz, RenderArena* renderArena)
-{
-    return renderArena->allocate(sz);
-}
-
-void ClipRects::operator delete(void* ptr, size_t sz)
-{
-    // Stash size where destroy can find it.
-    *(size_t *)ptr = sz;
-}
-
-void ClipRects::destroy(RenderArena* renderArena)
-{
-    delete this;
-    
-    // Recover the size left there for us by operator delete and free the memory.
-    renderArena->free(*(size_t *)this, this);
-}
-
 RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
     : m_inResizeMode(false)
     , m_scrollDimensionsDirty(true)
@@ -183,10 +164,6 @@
     , m_posZOrderList(0)
     , m_negZOrderList(0)
     , m_normalFlowList(0)
-    , m_clipRects(0)
-#ifndef NDEBUG
-    , m_clipRectsRoot(0)
-#endif
     , m_marquee(0)
     , m_staticInlinePosition(0)
     , m_staticBlockPosition(0)
@@ -254,9 +231,6 @@
     clearBacking(true);
 #endif
     
-    // Make sure we have no lingering clip rects.
-    ASSERT(!m_clipRects);
-    
     if (m_scrollCorner)
         m_scrollCorner->destroy();
     if (m_resizer)
@@ -1068,7 +1042,7 @@
 }
 #endif
     
-RenderLayer* RenderLayer::clippingRoot() const
+RenderLayer* RenderLayer::clippingRootForPainting() const
 {
 #if USE(ACCELERATED_COMPOSITING)
     if (isComposited())
@@ -2930,7 +2904,7 @@
         // Make sure the parent's clip rects have been calculated.
         ClipRect clipRect = paintDirtyRect;
         if (parent()) {
-            clipRect = backgroundClipRect(rootLayer, region, paintFlags & PaintLayerTemporaryClipRects);
+            clipRect = backgroundClipRect(rootLayer, region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects);
             clipRect.intersect(paintDirtyRect);
         
             // Push the parent coordinate space's clip.
@@ -3059,7 +3033,7 @@
 #endif
     
     if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
-        calculateRects(rootLayer, region, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, localPaintFlags & PaintLayerTemporaryClipRects);
+        calculateRects(rootLayer, region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
         paintOffset = toPoint(layerBounds.location() - renderBoxLocation());
     }
 
@@ -3472,11 +3446,7 @@
 {
     // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
 
-    bool useTemporaryClipRects = false;
-#if USE(ACCELERATED_COMPOSITING)
-    useTemporaryClipRects = compositor()->inCompositingMode();
-#endif
-    useTemporaryClipRects |= renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
+    bool useTemporaryClipRects = renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
 
     LayoutRect hitTestArea = result.rectForPoint(hitTestPoint);
 
@@ -3484,7 +3454,7 @@
     if (transform() && !appliedTransform) {
         // Make sure the parent's clip rects have been calculated.
         if (parent()) {
-            ClipRect clipRect = backgroundClipRect(rootLayer, result.region(), useTemporaryClipRects, IncludeOverlayScrollbarSize);
+            ClipRect clipRect = backgroundClipRect(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, IncludeOverlayScrollbarSize);
             // Go ahead and test the enclosing clip now.
             if (!clipRect.intersects(hitTestArea))
                 return 0;
@@ -3545,7 +3515,7 @@
     ClipRect bgRect;
     ClipRect fgRect;
     ClipRect outlineRect;
-    calculateRects(rootLayer, result.region(), hitTestRect, layerBounds, bgRect, fgRect, outlineRect, useTemporaryClipRects, IncludeOverlayScrollbarSize);
+    calculateRects(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, IncludeOverlayScrollbarSize);
     
     // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
     // descendants.
@@ -3816,10 +3786,11 @@
     return 0;
 }
 
-void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy)
+void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy relevancy)
 {
-    if (m_clipRects) {
-        ASSERT(rootLayer == m_clipRectsRoot);
+    ASSERT(clipRectsType < NumCachedClipRectsTypes);
+    if (m_clipRectsCache && m_clipRectsCache->m_clipRects[clipRectsType]) {
+        ASSERT(rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
         return; // We have the correct cached value.
     }
     
@@ -3827,29 +3798,34 @@
     // examine the parent.  We want to cache clip rects with us as the root.
     RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
     if (parentLayer)
-        parentLayer->updateClipRects(rootLayer, region, relevancy);
+        parentLayer->updateClipRects(rootLayer, region, clipRectsType, relevancy);
 
     ClipRects clipRects;
-    calculateClipRects(rootLayer, region, clipRects, true, relevancy);
+    calculateClipRects(rootLayer, region, clipRectsType, clipRects, relevancy);
 
-    if (parentLayer && parentLayer->clipRects() && clipRects == *parentLayer->clipRects())
-        m_clipRects = parentLayer->clipRects();
+    if (!m_clipRectsCache)
+        m_clipRectsCache = adoptPtr(new ClipRectsCache);
+
+    if (parentLayer && parentLayer->clipRects(clipRectsType) && clipRects == *parentLayer->clipRects(clipRectsType))
+        m_clipRectsCache->m_clipRects[clipRectsType] = parentLayer->clipRects(clipRectsType);
     else
-        m_clipRects = new (renderer()->renderArena()) ClipRects(clipRects);
-    m_clipRects->ref();
+        m_clipRectsCache->m_clipRects[clipRectsType] = ClipRects::create(clipRects);
+
+    m_clipRectsCache->m_clipRects[clipRectsType]->ref();
 #ifndef NDEBUG
-    m_clipRectsRoot = rootLayer;
+    m_clipRectsCache->m_clipRectsRoot[clipRectsType] = rootLayer;
 #endif
 }
 
-void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRects& clipRects,
-    bool useCached, OverlayScrollbarSizeRelevancy relevancy) const
+void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, ClipRects& clipRects, OverlayScrollbarSizeRelevancy relevancy) const
 {
     if (!parent()) {
         // The root layer's clip rect is always infinite.
         clipRects.reset(PaintInfo::infiniteRect());
         return;
     }
+    
+    bool useCached = clipRectsType != TemporaryClipRects;
 
     // For transformed layers, the root layer was shifted to be us, so there is no need to
     // examine the parent.  We want to cache clip rects with us as the root.
@@ -3857,10 +3833,10 @@
     
     // Ensure that our parent's clip has been calculated so that we can examine the values.
     if (parentLayer) {
-        if (useCached && parentLayer->clipRects())
-            clipRects = *parentLayer->clipRects();
+        if (useCached && parentLayer->clipRects(clipRectsType))
+            clipRects = *parentLayer->clipRects(clipRectsType);
         else
-            parentLayer->calculateClipRects(rootLayer, region, clipRects);
+            parentLayer->calculateClipRects(rootLayer, region, clipRectsType, clipRects);
     } else
         clipRects.reset(PaintInfo::infiniteRect());
 
@@ -3908,16 +3884,16 @@
     }
 }
 
-void RenderLayer::parentClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRects& clipRects, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
+void RenderLayer::parentClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, ClipRects& clipRects, OverlayScrollbarSizeRelevancy relevancy) const
 {
     ASSERT(parent());
-    if (temporaryClipRects) {
-        parent()->calculateClipRects(rootLayer, region, clipRects, false, relevancy);
+    if (clipRectsType == TemporaryClipRects) {
+        parent()->calculateClipRects(rootLayer, region, clipRectsType, clipRects, relevancy);
         return;
     }
 
-    parent()->updateClipRects(rootLayer, region, relevancy);
-    clipRects = *parent()->clipRects();
+    parent()->updateClipRects(rootLayer, region, clipRectsType, relevancy);
+    clipRects = *parent()->clipRects(clipRectsType);
 }
 
 static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position)
@@ -3931,11 +3907,11 @@
     return parentRects.overflowClipRect();
 }
 
-ClipRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, RenderRegion* region, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
+ClipRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy relevancy) const
 {
     ASSERT(parent());
     ClipRects parentRects;
-    parentClipRects(rootLayer, region, parentRects, temporaryClipRects, relevancy);
+    parentClipRects(rootLayer, region, clipRectsType, parentRects, relevancy);
     ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer()->style()->position());
     RenderView* view = renderer()->view();
     ASSERT(view);
@@ -3947,12 +3923,11 @@
     return backgroundClipRect;
 }
 
-void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
-                                 ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, bool temporaryClipRects,
-                                 OverlayScrollbarSizeRelevancy relevancy) const
+void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
+                                 ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, OverlayScrollbarSizeRelevancy relevancy) const
 {
     if (rootLayer != this && parent()) {
-        backgroundRect = backgroundClipRect(rootLayer, region, temporaryClipRects, relevancy);
+        backgroundRect = backgroundClipRect(rootLayer, region, clipRectsType, relevancy);
         backgroundRect.intersect(paintDirtyRect);
     } else
         backgroundRect = paintDirtyRect;
@@ -4005,10 +3980,10 @@
     // FIXME: border-radius not accounted for.
     // FIXME: Regions not accounted for.
     RenderView* renderView = renderer()->view();
-    RenderLayer* clippingRootLayer = clippingRoot();
+    RenderLayer* clippingRootLayer = clippingRootForPainting();
     LayoutRect layerBounds;
     ClipRect backgroundRect, foregroundRect, outlineRect;
-    calculateRects(clippingRootLayer, 0, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+    calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
     return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
 }
 
@@ -4017,10 +3992,10 @@
     // FIXME: border-radius not accounted for.
     // FIXME: Regions not accounted for.
     RenderView* renderView = renderer()->view();
-    RenderLayer* clippingRootLayer = clippingRoot();
+    RenderLayer* clippingRootLayer = clippingRootForPainting();
     LayoutRect layerBounds;
     ClipRect backgroundRect, foregroundRect, outlineRect;
-    calculateRects(clippingRootLayer, 0, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+    calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
     return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
 }
 
@@ -4028,10 +4003,10 @@
 {
     // FIXME: border-radius not accounted for.
     // FIXME: Regions not accounted for.
-    RenderLayer* clippingRootLayer = clippingRoot();
+    RenderLayer* clippingRootLayer = clippingRootForPainting();
     LayoutRect layerBounds;
     ClipRect backgroundRect, foregroundRect, outlineRect;
-    calculateRects(clippingRootLayer, 0, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+    calculateRects(clippingRootLayer, 0, PaintingClipRects, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
 
     LayoutRect clipRect = backgroundRect.rect();
     if (clipRect == PaintInfo::infiniteRect())
@@ -4279,25 +4254,25 @@
     return pixelSnappedIntRect(unionBounds);
 }
 
-void RenderLayer::clearClipRectsIncludingDescendants()
+void RenderLayer::clearClipRectsIncludingDescendants(ClipRectsType typeToClear)
 {
-    if (!m_clipRects)
+    // FIXME: it's not clear how this layer not having clip rects guarantees that no descendants have any.
+    if (!m_clipRectsCache)
         return;
 
-    clearClipRects();
+    clearClipRects(typeToClear);
     
     for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
-        l->clearClipRectsIncludingDescendants();
+        l->clearClipRectsIncludingDescendants(typeToClear);
 }
 
-void RenderLayer::clearClipRects()
+void RenderLayer::clearClipRects(ClipRectsType typeToClear)
 {
-    if (m_clipRects) {
-        m_clipRects->deref(renderer()->renderArena());
-        m_clipRects = 0;
-#ifndef NDEBUG
-        m_clipRectsRoot = 0;
-#endif    
+    if (typeToClear == AllClipRectTypes)
+        m_clipRectsCache = nullptr;
+    else {
+        ASSERT(typeToClear < NumCachedClipRectsTypes);
+        m_clipRectsCache->m_clipRects[typeToClear] = nullptr;
     }
 }
 

Modified: branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.h (134704 => 134705)


--- branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.h	2012-11-15 02:06:52 UTC (rev 134704)
+++ branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.h	2012-11-15 02:06:58 UTC (rev 134705)
@@ -128,27 +128,19 @@
 
 class ClipRects {
 public:
-    ClipRects()
-        : m_refCnt(0)
-        , m_fixed(false)
+    static PassRefPtr<ClipRects> create()
     {
+        return adoptRef(new ClipRects);
     }
 
-    ClipRects(const LayoutRect& r)
-        : m_overflowClipRect(r)
-        , m_fixedClipRect(r)
-        , m_posClipRect(r)
-        , m_refCnt(0)
-        , m_fixed(false)
+    static PassRefPtr<ClipRects> create(const ClipRects& other)
     {
+        return adoptRef(new ClipRects(other));
     }
 
-    ClipRects(const ClipRects& other)
-        : m_overflowClipRect(other.overflowClipRect())
-        , m_fixedClipRect(other.fixedClipRect())
-        , m_posClipRect(other.posClipRect())
-        , m_refCnt(0)
-        , m_fixed(other.fixed())
+    ClipRects()
+        : m_refCnt(0)
+        , m_fixed(false)
     {
     }
 
@@ -173,16 +165,12 @@
     void setFixed(bool fixed) { m_fixed = fixed; }
 
     void ref() { m_refCnt++; }
-    void deref(RenderArena* renderArena) { if (--m_refCnt == 0) destroy(renderArena); }
+    void deref()
+    {
+        if (!--m_refCnt)
+            delete this;
+    }
 
-    void destroy(RenderArena*);
-
-    // Overloaded new operator.
-    void* operator new(size_t, RenderArena*);
-
-    // Overridden to prevent the normal delete from being called.
-    void operator delete(void*, size_t);
-
     bool operator==(const ClipRects& other) const
     {
         return m_overflowClipRect == other.overflowClipRect() &&
@@ -201,10 +189,24 @@
     }
 
 private:
-    // The normal operator new is disallowed on all render objects.
-    void* operator new(size_t) throw();
+    ClipRects(const LayoutRect& r)
+        : m_overflowClipRect(r)
+        , m_fixedClipRect(r)
+        , m_posClipRect(r)
+        , m_refCnt(0)
+        , m_fixed(false)
+    {
+    }
 
-private:
+    ClipRects(const ClipRects& other)
+        : m_overflowClipRect(other.overflowClipRect())
+        , m_fixedClipRect(other.fixedClipRect())
+        , m_posClipRect(other.posClipRect())
+        , m_refCnt(0)
+        , m_fixed(other.fixed())
+    {
+    }
+
     ClipRect m_overflowClipRect;
     ClipRect m_fixedClipRect;
     ClipRect m_posClipRect;
@@ -212,6 +214,30 @@
     bool m_fixed : 1;
 };
 
+enum ClipRectsType {
+    PaintingClipRects, // Relative to painting ancestor. Used for painting.
+    RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
+    AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
+    NumCachedClipRectsTypes,
+    AllClipRectTypes,
+    TemporaryClipRects
+};
+
+struct ClipRectsCache {
+    ClipRectsCache()
+    {
+#ifndef NDEBUG
+        for (int i = 0; i < NumCachedClipRectsTypes; ++i)
+            m_clipRectsRoot[i] = 0;
+#endif
+    }
+
+    RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes];
+#ifndef NDEBUG
+    const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
+#endif
+};
+
 class RenderLayer : public ScrollableArea {
 public:
     friend class RenderReplica;
@@ -371,8 +397,8 @@
     void relativePositionOffset(LayoutUnit& relX, LayoutUnit& relY) const { relX += m_relativeOffset.width(); relY += m_relativeOffset.height(); }
     const LayoutSize& relativePositionOffset() const { return m_relativeOffset; }
 
-    void clearClipRectsIncludingDescendants();
-    void clearClipRects();
+    void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes);
+    void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes);
 
     void addBlockSelectionGapsBounds(const LayoutRect&);
     void clearBlockSelectionGapsBounds();
@@ -421,7 +447,7 @@
     RenderLayer* enclosingScrollableLayer() const;
 
     // The layer relative to which clipping rects for this layer are computed.
-    RenderLayer* clippingRoot() const;
+    RenderLayer* clippingRootForPainting() const;
 
 #if USE(ACCELERATED_COMPOSITING)
     // Enclosing compositing layer; if includeSelf is true, may return this.
@@ -470,17 +496,18 @@
     // This method figures out our layerBounds in coordinates relative to
     // |rootLayer}.  It also computes our background and foreground clip rects
     // for painting/event handling.
-    void calculateRects(const RenderLayer* rootLayer, RenderRegion*, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
+    void calculateRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
                         ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect,
-                        bool temporaryClipRects = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
+                        OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
 
     // Compute and cache clip rects computed with the given layer as the root
-    void updateClipRects(const RenderLayer* rootLayer, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
+    void updateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
     // Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors
     // (rather than computing them all from scratch up the parent chain).
-    void calculateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRects&, bool useCached = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
-    ClipRects* clipRects() const { return m_clipRects; }
+    void calculateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, ClipRects&, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
 
+    ClipRects* clipRects(ClipRectsType type) const { ASSERT(type < NumCachedClipRectsTypes); return m_clipRectsCache ? m_clipRectsCache->m_clipRects[type].get() : 0; }
+
     LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
     LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
     LayoutRect localClipRect() const; // Returns the background clip rect of the layer in the local coordinate space.
@@ -763,8 +790,8 @@
     void updateOrRemoveFilterEffect();
 #endif
 
-    void parentClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRects&, bool temporaryClipRects = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
-    ClipRect backgroundClipRect(const RenderLayer* rootLayer, RenderRegion*, bool temporaryClipRects, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
+    void parentClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, ClipRects&, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
+    ClipRect backgroundClipRect(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
     LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior);
 
     RenderLayer* enclosingTransformedAncestor() const;
@@ -903,11 +930,8 @@
     // overflow layers, but that may change in the future.
     Vector<RenderLayer*>* m_normalFlowList;
 
-    ClipRects* m_clipRects;      // Cached clip rects used when painting and hit testing.
-#ifndef NDEBUG
-    const RenderLayer* m_clipRectsRoot;   // Root layer used to compute clip rects.
-#endif
-
+    OwnPtr<ClipRectsCache> m_clipRectsCache;
+    
     IntPoint m_cachedOverlayScrollbarOffset;
 
     RenderMarquee* m_marquee; // Used by layers with overflow:marquee

Modified: branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayerBacking.cpp (134704 => 134705)


--- branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayerBacking.cpp	2012-11-15 02:06:52 UTC (rev 134704)
+++ branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayerBacking.cpp	2012-11-15 02:06:58 UTC (rev 134705)
@@ -282,7 +282,7 @@
         LayoutRect clippingBounds = view->unscaledDocumentRect();
 
         if (m_owningLayer != rootLayer)
-            clippingBounds.intersect(m_owningLayer->backgroundClipRect(rootLayer, 0, true).rect()); // FIXME: Incorrect for CSS regions.
+            clippingBounds.intersect(m_owningLayer->backgroundClipRect(rootLayer, 0, AbsoluteClipRects).rect()); // FIXME: Incorrect for CSS regions.
 
         LayoutPoint delta;
         m_owningLayer->convertToLayerCoords(rootLayer, delta);
@@ -482,7 +482,7 @@
         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
         // for a compositing layer, rootLayer is the layer itself.
-        IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(compAncestor, 0, true).rect()); // FIXME: Incorrect for CSS regions.
+        IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(compAncestor, 0, TemporaryClipRects).rect()); // FIXME: Incorrect for CSS regions.
         ASSERT(parentClipRect != PaintInfo::infiniteRect());
         m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation));
         m_ancestorClippingLayer->setSize(parentClipRect.size());

Modified: branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayerCompositor.cpp (134704 => 134705)


--- branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-11-15 02:06:52 UTC (rev 134704)
+++ branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-11-15 02:06:58 UTC (rev 134705)
@@ -539,6 +539,9 @@
             innerCompositor->updateRootLayerAttachment();
     }
     
+    if (layerChanged)
+        layer->clearClipRectsIncludingDescendants(PaintingClipRects);
+
     return layerChanged;
 }
 
@@ -638,7 +641,7 @@
         boundsComputed = true;
     }
 
-    IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(rootRenderLayer(), 0, true).rect()); // FIXME: Incorrect for CSS regions.
+    IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(rootRenderLayer(), 0, AbsoluteClipRects).rect()); // FIXME: Incorrect for CSS regions.
     clipRect.scale(pageScaleFactor());
     clipRect.intersect(layerBounds);
     overlapMap.add(layer, clipRect);
@@ -1525,7 +1528,7 @@
     if (!computeClipRoot || computeClipRoot == layer)
         return false;
 
-    return layer->backgroundClipRect(computeClipRoot, 0, true).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
+    return layer->backgroundClipRect(computeClipRoot, 0, TemporaryClipRects).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
 }
 
 // Return true if the given layer is a stacking context and has compositing child

Modified: branches/safari-536.28-branch/Source/WebCore/rendering/RenderTreeAsText.cpp (134704 => 134705)


--- branches/safari-536.28-branch/Source/WebCore/rendering/RenderTreeAsText.cpp	2012-11-15 02:06:52 UTC (rev 134704)
+++ branches/safari-536.28-branch/Source/WebCore/rendering/RenderTreeAsText.cpp	2012-11-15 02:06:58 UTC (rev 134705)
@@ -705,7 +705,7 @@
     // Calculate the clip rects we should use.
     IntRect layerBounds;
     ClipRect damageRect, clipRectToApply, outlineRect;
-    l->calculateRects(rootLayer, 0, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, true);
+    l->calculateRects(rootLayer, 0, TemporaryClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
 
     // Ensure our lists are up-to-date.
     l->updateLayerListsIfNeeded();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to