Title: [112436] trunk
Revision
112436
Author
[email protected]
Date
2012-03-28 13:42:19 -0700 (Wed, 28 Mar 2012)

Log Message

[chromium] layer->clipRect() is not initialized for layers that create a renderSurface.
https://bugs.webkit.org/show_bug.cgi?id=74147

Reviewed by Adrienne Walker.

Source/WebCore:

Added 3 additional unit tests; Modified existing unit tests and layout tests.

The layer's clipRect and usesLayerClipping information was not
being initialized for layers that created a renderSurface. (It
was, however, being initialized for the renderSurface itself.)
This patch adds a unit test that reproduces that this is an error,
other unit tests to tightly test the value of clipRect being
initialized, and adds the logic to properly initialize the
clipRect.

Before this patch, this bug was causing flashing on tab-switch on
the apple iphone page. Even worse, with partial swap enabled, the
layers would simply disappear, because the first frame the
clipRect is uninitialized and the layer is not drawn, and the
second frame onwards, the damage tracker correctly things nothing
is damaged, so it doesn't draw that layer again until other damage
causes it to be redrawn.

* platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
(WebCore::calculateDrawTransformsAndVisibilityInternal):

Source/WebKit/chromium:

Added 3 more unit tests. One reproduces the clipRect problem in an
integrated manner, the other two directly test that clipRects are
properly initialized.

* tests/CCLayerTreeHostCommonTest.cpp:
(WebCore::TEST):
(WebCore):
* tests/CCLayerTreeTestCommon.h:
(WebKitTests):

LayoutTests:

* platform/chromium/test_expectations.txt: marked test as needing rebaselining

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (112435 => 112436)


--- trunk/LayoutTests/ChangeLog	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/LayoutTests/ChangeLog	2012-03-28 20:42:19 UTC (rev 112436)
@@ -1,3 +1,12 @@
+2012-03-26  Shawn Singh  <[email protected]>
+
+        [chromium] layer->clipRect() is not initialized for layers that create a renderSurface.
+        https://bugs.webkit.org/show_bug.cgi?id=74147
+
+        Reviewed by Adrienne Walker.
+
+        * platform/chromium/test_expectations.txt: marked test as needing rebaselining
+
 2012-03-28  John Abd-El-Malek  <[email protected]>
         [chromium] Update worker-multi-port-expected.txt.
 

Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (112435 => 112436)


--- trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-03-28 20:42:19 UTC (rev 112436)
@@ -4124,6 +4124,10 @@
 BUGWK78412 MAC WIN : fast/repaint/scroll-relative-table-inside-table-cell.html = IMAGE
 BUGWK78412 MAC WIN : fast/table/cell-pref-width-invalidation.html = TEXT
 
+// Needs rebaselining after https://bugs.webkit.org/show_bug.cgi?id=74147.
+// It is correct for the reflected text to be visible.
+BUGWK74147 : compositing/reflections/nested-reflection-on-overflow.html = IMAGE
+
 // Need rebaselining.
 BUGWK37244 : tables/mozilla/bugs/bug27038-1.html = IMAGE+TEXT
 BUGWK37244 : tables/mozilla/bugs/bug27038-2.html = IMAGE+TEXT

Modified: trunk/Source/WebCore/ChangeLog (112435 => 112436)


--- trunk/Source/WebCore/ChangeLog	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebCore/ChangeLog	2012-03-28 20:42:19 UTC (rev 112436)
@@ -1,3 +1,31 @@
+2012-03-26  Shawn Singh  <[email protected]>
+
+        [chromium] layer->clipRect() is not initialized for layers that create a renderSurface.
+        https://bugs.webkit.org/show_bug.cgi?id=74147
+
+        Reviewed by Adrienne Walker.
+
+        Added 3 additional unit tests; Modified existing unit tests and layout tests.
+
+        The layer's clipRect and usesLayerClipping information was not
+        being initialized for layers that created a renderSurface. (It
+        was, however, being initialized for the renderSurface itself.)
+        This patch adds a unit test that reproduces that this is an error,
+        other unit tests to tightly test the value of clipRect being
+        initialized, and adds the logic to properly initialize the
+        clipRect.
+
+        Before this patch, this bug was causing flashing on tab-switch on
+        the apple iphone page. Even worse, with partial swap enabled, the
+        layers would simply disappear, because the first frame the
+        clipRect is uninitialized and the layer is not drawn, and the
+        second frame onwards, the damage tracker correctly things nothing
+        is damaged, so it doesn't draw that layer again until other damage
+        causes it to be redrawn.
+
+        * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
+        (WebCore::calculateDrawTransformsAndVisibilityInternal):
+
 2012-03-28  Anders Carlsson  <[email protected]>
 
         "Sticky" or slow scrolling on some sites

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h (112435 => 112436)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2012-03-28 20:42:19 UTC (rev 112436)
@@ -158,6 +158,7 @@
     bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; }
     void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityIsAnimating = drawOpacityIsAnimating; }
 
+    // Usage: if this->usesLayerClipping() is false, then this clipRect should not be used.
     const IntRect& clipRect() const { return m_clipRect; }
     void setClipRect(const IntRect& rect) { m_clipRect = rect; }
     CCRenderSurface* targetRenderSurface() const { return m_targetRenderSurface; }

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp (112435 => 112436)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp	2012-03-28 20:42:19 UTC (rev 112436)
@@ -386,6 +386,10 @@
         // surface and is therefore expressed in the parent's coordinate system.
         renderSurface->setClipRect(layer->parent() ? layer->parent()->clipRect() : layer->clipRect());
 
+        // The layer's clipRect can be reset here. The renderSurface will correctly clip the subtree.
+        layer->setUsesLayerClipping(false);
+        layer->setClipRect(IntRect());
+
         if (layer->maskLayer()) {
             renderSurface->setMaskLayer(layer->maskLayer());
             layer->maskLayer()->setTargetRenderSurface(renderSurface);
@@ -422,13 +426,18 @@
             // Layers without their own renderSurface will render into the nearest ancestor surface.
             layer->setTargetRenderSurface(layer->parent()->targetRenderSurface());
         }
+    }
 
-        if (layer->masksToBounds()) {
-            IntRect clipRect = transformedLayerRect;
+    if (layer->masksToBounds()) {
+        IntRect clipRect = transformedLayerRect;
+
+        // If the layer already inherited a clipRect, we need to intersect with it before
+        // overriding the layer's clipRect and usesLayerClipping.
+        if (layer->usesLayerClipping())
             clipRect.intersect(layer->clipRect());
-            layer->setClipRect(clipRect);
-            layer->setUsesLayerClipping(true);
-        }
+
+        layer->setClipRect(clipRect);
+        layer->setUsesLayerClipping(true);
     }
 
     // Note that at this point, layer->drawTransform() is not necessarily the same as local variable drawTransform.

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp (112435 => 112436)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp	2012-03-28 20:42:19 UTC (rev 112436)
@@ -340,8 +340,7 @@
 {
     const RenderSurfaceType* targetSurface = m_stack.last().surface;
     FloatRect totalScissor = targetSurface->contentRect();
-    // FIXME: layer->clipRect() and layer->usesLayerClipping() is changing: https://bugs.webkit.org/show_bug.cgi?id=80622
-    if (!layer->clipRect().isEmpty())
+    if (layer->usesLayerClipping())
         totalScissor.intersect(layer->clipRect());
     return enclosingIntRect(totalScissor);
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h (112435 => 112436)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h	2012-03-28 20:42:19 UTC (rev 112436)
@@ -103,6 +103,7 @@
     bool screenSpaceTransformsAreAnimating() const { return m_screenSpaceTransformsAreAnimating; }
     void setScreenSpaceTransformsAreAnimating(bool animating) { m_screenSpaceTransformsAreAnimating = animating; }
 
+    // Usage: this clipRect should not be used if one of the two conditions is true: (a) clipRect() is empty, or (b) owningLayer->parent()->usesLayerClipping() is false.
     void setClipRect(const IntRect&);
     const IntRect& clipRect() const { return m_clipRect; }
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.h (112435 => 112436)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.h	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.h	2012-03-28 20:42:19 UTC (rev 112436)
@@ -43,6 +43,7 @@
     // The transform that layerRect() should be transformed with.
     const TransformationMatrix& layerTransform() const { return m_layerTransform; }
     const IntRect& layerRect() const { return m_layerRect; }
+    // Usage: if clipRect is empty, this clipRect should not be used.
     const IntRect& clipRect() const { return m_clipRect; }
 
     float opacity() const { return m_opacity; }

Modified: trunk/Source/WebKit/chromium/ChangeLog (112435 => 112436)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-03-28 20:42:19 UTC (rev 112436)
@@ -1,3 +1,20 @@
+2012-03-26  Shawn Singh  <[email protected]>
+
+        [chromium] layer->clipRect() is not initialized for layers that create a renderSurface.
+        https://bugs.webkit.org/show_bug.cgi?id=74147
+
+        Reviewed by Adrienne Walker.
+
+        Added 3 more unit tests. One reproduces the clipRect problem in an
+        integrated manner, the other two directly test that clipRects are
+        properly initialized.
+
+        * tests/CCLayerTreeHostCommonTest.cpp:
+        (WebCore::TEST):
+        (WebCore):
+        * tests/CCLayerTreeTestCommon.h:
+        (WebKitTests):
+
 2012-03-28  Adrienne Walker  <[email protected]>
 
         [chromium] Fix tiled layer assert for huge layers

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp (112435 => 112436)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp	2012-03-28 20:42:19 UTC (rev 112436)
@@ -625,6 +625,55 @@
     grandChild->setOpacity(0.5);
     greatGrandChild->setOpacity(0.4);
 
+    Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+    Vector<RefPtr<LayerChromium> > dummyLayerList;
+    int dummyMaxTextureSize = 512;
+
+    // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
+    parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+    renderSurfaceLayerList.append(parent.get());
+
+    CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+    ASSERT_EQ(2U, renderSurfaceLayerList.size());
+    EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
+    EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
+}
+
+TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfacesCrashRepro)
+{
+    // This is a similar situation as verifyClipRectCullsRenderSurfaces, except that
+    // it reproduces a crash bug http://code.google.com/p/chromium/issues/detail?id=106734.
+
+    const TransformationMatrix identityMatrix;
+    RefPtr<LayerChromium> parent = LayerChromium::create();
+    RefPtr<LayerChromium> child = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild = LayerChromium::create();
+    RefPtr<LayerChromium> greatGrandChild = LayerChromium::create();
+    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    parent->createRenderSurface();
+    parent->addChild(child);
+    child->addChild(grandChild);
+    grandChild->addChild(greatGrandChild);
+
+    // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
+    // even though grandChild and greatGrandChild should be clipped.
+    child->addChild(leafNode1);
+    greatGrandChild->addChild(leafNode2);
+
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
+    setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
+    setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
+    setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
+
+    child->setMasksToBounds(true);
+    child->setOpacity(0.4);
+    grandChild->setOpacity(0.5);
+    greatGrandChild->setOpacity(0.4);
+
     // Contaminate the grandChild and greatGrandChild's clipRect to reproduce the crash
     // bug found in http://code.google.com/p/chromium/issues/detail?id=106734. In this
     // bug, the clipRect was not re-computed for layers that create RenderSurfaces, and
@@ -632,9 +681,6 @@
     // renderSurface remains on the renderSurfaceLayerList, which violates the assumption
     // that an empty renderSurface will always be the last item on the list, which
     // ultimately caused the crash.
-    //
-    // FIXME: it is also useful to test with this commented out. Eventually we should
-    // create several test cases that test clipRect/drawableContentRect computation.
     child->setClipRect(IntRect(IntPoint::zero(), IntSize(20, 20)));
     greatGrandChild->setClipRect(IntRect(IntPoint::zero(), IntSize(1234, 1234)));
 
@@ -653,6 +699,148 @@
     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
 }
 
+TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToLayers)
+{
+    // Verify that layers get the appropriate clipRects when their parent masksToBounds is true.
+    //
+    //   grandChild1 - completely inside the region; clipRect should be the mask region (larger than this layer's bounds).
+    //   grandChild2 - partially clipped but NOT masksToBounds; the clipRect should be the parent's clipRect regardless of the layer's bounds.
+    //   grandChild3 - partially clipped and masksToBounds; the clipRect will be the intersection of layerBounds and the mask region.
+    //   grandChild4 - outside parent's clipRect, and masksToBounds; the clipRect should be empty.
+    //
+
+    const TransformationMatrix identityMatrix;
+    RefPtr<LayerChromium> parent = LayerChromium::create();
+    RefPtr<LayerChromium> child = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
+
+    parent->createRenderSurface();
+    parent->addChild(child);
+    child->addChild(grandChild1);
+    child->addChild(grandChild2);
+    child->addChild(grandChild3);
+    child->addChild(grandChild4);
+
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
+    setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
+    setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
+
+    child->setMasksToBounds(true);
+    grandChild3->setMasksToBounds(true);
+    grandChild4->setMasksToBounds(true);
+
+    // Force everyone to be a render surface.
+    child->setOpacity(0.4);
+    grandChild1->setOpacity(0.5);
+    grandChild2->setOpacity(0.5);
+    grandChild3->setOpacity(0.5);
+    grandChild4->setOpacity(0.5);
+
+    Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+    Vector<RefPtr<LayerChromium> > dummyLayerList;
+    int dummyMaxTextureSize = 512;
+
+    // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
+    parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+    renderSurfaceLayerList.append(parent.get());
+
+    CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+    EXPECT_INT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(20, 20)), grandChild1->clipRect());
+    EXPECT_INT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(20, 20)), grandChild2->clipRect());
+    EXPECT_INT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->clipRect());
+    EXPECT_TRUE(grandChild4->clipRect().isEmpty());
+}
+
+TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToSurfaces)
+{
+    // Verify that renderSurfaces (and their layers) get the appropriate clipRects when their parent masksToBounds is true.
+    //
+    // Layers that own renderSurfaces (at least for now) do not inherit any clipRect;
+    // instead the surface will enforce the clip for the entire subtree. They may still
+    // have a clipRect of their own layer bounds, however, if masksToBounds was true.
+    //
+
+    const TransformationMatrix identityMatrix;
+    RefPtr<LayerChromium> parent = LayerChromium::create();
+    RefPtr<LayerChromium> child = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
+    RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
+    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode3 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode4 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+
+    parent->createRenderSurface();
+    parent->addChild(child);
+    child->addChild(grandChild1);
+    child->addChild(grandChild2);
+    child->addChild(grandChild3);
+    child->addChild(grandChild4);
+
+    // the leaf nodes ensure that these grandChildren become renderSurfaces for this test.
+    grandChild1->addChild(leafNode1);
+    grandChild2->addChild(leafNode2);
+    grandChild3->addChild(leafNode3);
+    grandChild4->addChild(leafNode4);
+
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
+    setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
+    setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(leafNode3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
+    setLayerPropertiesForTesting(leafNode4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
+
+    child->setMasksToBounds(true);
+    grandChild3->setMasksToBounds(true);
+    grandChild4->setMasksToBounds(true);
+
+    // Force everyone to be a render surface.
+    child->setOpacity(0.4);
+    grandChild1->setOpacity(0.5);
+    grandChild2->setOpacity(0.5);
+    grandChild3->setOpacity(0.5);
+    grandChild4->setOpacity(0.5);
+
+    Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+    Vector<RefPtr<LayerChromium> > dummyLayerList;
+    int dummyMaxTextureSize = 512;
+
+    // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
+    parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+    renderSurfaceLayerList.append(parent.get());
+
+    CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+    ASSERT_TRUE(grandChild1->renderSurface());
+    ASSERT_TRUE(grandChild2->renderSurface());
+    ASSERT_TRUE(grandChild3->renderSurface());
+    EXPECT_FALSE(grandChild4->renderSurface()); // Because grandChild4 is entirely clipped, it is expected to not have a renderSurface.
+
+    // Surfaces are clipped by their parent, but un-affected by the owning layer's masksToBounds.
+    EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild1->renderSurface()->clipRect());
+    EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild2->renderSurface()->clipRect());
+    EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild3->renderSurface()->clipRect());
+
+    // Layers do not inherit the clipRect from their owned surfaces, but if masksToBounds is true, they do create their own clipRect.
+    EXPECT_FALSE(grandChild1->usesLayerClipping());
+    EXPECT_FALSE(grandChild2->usesLayerClipping());
+    EXPECT_TRUE(grandChild3->usesLayerClipping());
+    EXPECT_TRUE(grandChild4->usesLayerClipping());
+}
+
 TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
 {
     RefPtr<LayerChromium> parent = LayerChromium::create();

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeTestCommon.h (112435 => 112436)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeTestCommon.h	2012-03-28 20:41:15 UTC (rev 112435)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeTestCommon.h	2012-03-28 20:42:19 UTC (rev 112436)
@@ -27,13 +27,19 @@
 
 namespace WebKitTests {
 
-// This is a macro instead of function so that we get useful line numbers where a test failed.
+// These are macros instead of functions so that we get useful line numbers where a test failed.
 #define EXPECT_FLOAT_RECT_EQ(expected, actual)                          \
     EXPECT_FLOAT_EQ((expected).location().x(), (actual).location().x()); \
     EXPECT_FLOAT_EQ((expected).location().y(), (actual).location().y()); \
     EXPECT_FLOAT_EQ((expected).size().width(), (actual).size().width()); \
     EXPECT_FLOAT_EQ((expected).size().height(), (actual).size().height())
 
+#define EXPECT_INT_RECT_EQ(expected, actual)                            \
+    EXPECT_EQ((expected).location().x(), (actual).location().x());      \
+    EXPECT_EQ((expected).location().y(), (actual).location().y());      \
+    EXPECT_EQ((expected).size().width(), (actual).size().width());      \
+    EXPECT_EQ((expected).size().height(), (actual).size().height())
+
 // This is a macro instead of a function so that we get useful line numbers where a test failed.
 // Even though TransformationMatrix values are double precision, there are many other floating-point values used that affect
 // the transforms, and so we only expect them to be accurate up to floating-point precision.
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to