2009-01-05 Simon Fraser <simon.fraser@apple.com>
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Jan 2009 05:37:27 +0000 (05:37 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Jan 2009 05:37:27 +0000 (05:37 +0000)
        Reviewed by Dave Hyatt

        https://bugs.webkit.org/show_bug.cgi?id=22985

        Add an assertion that clip rects are being used when painting with the same
        rootLayer that they were computed with.

        Fix two issues detected by the assertion:

        RenderLayer::updateClipRects() should not unconditionally update the clip rects
        on its parent, but stop when reaching rootLayer (just like calculateClipRects()).

        We need to pass the temporaryClipRects flag down through reflection painting
        to handle the case of nested reflections.

        Also use temporary clip rects in RenderTreeAsText, since that code does not
        reset the painting root for transformed layers, so cached clip rects will not
        match those used for painting.

        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::RenderLayer):
        (WebCore::RenderLayer::paintLayer):
        (WebCore::RenderLayer::updateClipRects):
        (WebCore::RenderLayer::clearClipRects):
        * rendering/RenderLayer.h:
        * rendering/RenderTreeAsText.cpp:
        (WebCore::writeLayers):

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

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

index 8debbc7..a9cc097 100644 (file)
@@ -1,3 +1,33 @@
+2009-01-05  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Dave Hyatt
+
+        https://bugs.webkit.org/show_bug.cgi?id=22985
+        
+        Add an assertion that clip rects are being used when painting with the same
+        rootLayer that they were computed with.
+        
+        Fix two issues detected by the assertion:
+
+        RenderLayer::updateClipRects() should not unconditionally update the clip rects
+        on its parent, but stop when reaching rootLayer (just like calculateClipRects()).
+        
+        We need to pass the temporaryClipRects flag down through reflection painting
+        to handle the case of nested reflections.
+        
+        Also use temporary clip rects in RenderTreeAsText, since that code does not
+        reset the painting root for transformed layers, so cached clip rects will not
+        match those used for painting.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        (WebCore::RenderLayer::paintLayer):
+        (WebCore::RenderLayer::updateClipRects):
+        (WebCore::RenderLayer::clearClipRects):
+        * rendering/RenderLayer.h:
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::writeLayers):
+
 2009-01-05  Adam Treat  <adam.treat@torchmobile.com>
 
         Fix the Qt build
index 5fa42f2..9c9eff0 100644 (file)
@@ -140,6 +140,9 @@ RenderLayer::RenderLayer(RenderObject* object)
     , m_negZOrderList(0)
     , m_overflowList(0)
     , m_clipRects(0) 
+#ifndef NDEBUG    
+    , m_clipRectsRoot(0)
+#endif
     , m_scrollDimensionsDirty(true)
     , m_zOrderListsDirty(true)
     , m_overflowListDirty(true)
@@ -1712,7 +1715,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
     if (m_reflection && !m_paintingInsideReflection && (!m_transform || appliedTransform)) {
         // Mark that we are now inside replica painting.
         m_paintingInsideReflection = true;
-        reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+        reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, false, temporaryClipRects);
         m_paintingInsideReflection = false;
     }
 
@@ -2002,20 +2005,28 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequ
 
 void RenderLayer::updateClipRects(const RenderLayer* rootLayer)
 {
-    if (m_clipRects)
+    if (m_clipRects) {
+        ASSERT(rootLayer == m_clipRectsRoot);
         return; // We have the correct cached value.
-
-    if (parent())
-        parent()->updateClipRects(rootLayer);
+    }
+    
+    // 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.
+    RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
+    if (parentLayer)
+        parentLayer->updateClipRects(rootLayer);
 
     ClipRects clipRects;
     calculateClipRects(rootLayer, clipRects, true);
 
-    if (parent() && parent()->clipRects() && clipRects == *parent()->clipRects())
-        m_clipRects = parent()->clipRects();
+    if (parentLayer && parentLayer->clipRects() && clipRects == *parentLayer->clipRects())
+        m_clipRects = parentLayer->clipRects();
     else
         m_clipRects = new (m_object->renderArena()) ClipRects(clipRects);
     m_clipRects->ref();
+#ifndef NDEBUG
+    m_clipRectsRoot = rootLayer;
+#endif
 }
 
 void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool useCached) const
@@ -2269,6 +2280,9 @@ void RenderLayer::clearClipRects()
     if (m_clipRects) {
         m_clipRects->deref(m_object->renderArena());
         m_clipRects = 0;
+#ifndef NDEBUG
+        m_clipRectsRoot = 0;
+#endif    
     }
 }
 
index 680b246..b2ba48c 100644 (file)
@@ -478,6 +478,9 @@ protected:
     Vector<RenderLayer*>* m_overflowList;
 
     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
 
     bool m_scrollDimensionsDirty : 1;
     bool m_zOrderListsDirty : 1;
index 346968b..f46ff20 100644 (file)
@@ -416,7 +416,7 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
 {
     // Calculate the clip rects we should use.
     IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
-    l->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
+    l->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, true);
 
     // Ensure our lists are up-to-date.
     l->updateZOrderLists();