| Index: Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp
 | 
| ===================================================================
 | 
| --- Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp	(revision 102688)
 | 
| +++ Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp	(working copy)
 | 
| @@ -509,6 +509,79 @@
 | 
|      EXPECT_EQ(parent->drawableContentRect(), IntRect());
 | 
|  }
 | 
|  
 | 
| +TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
 | 
| +{
 | 
| +    // The entire subtree of layers that are outside the clipRect should be culled away,
 | 
| +    // and should not affect the renderSurfaceLayerList.
 | 
| +    //
 | 
| +    // The test tree is set up as follows:
 | 
| +    //  - all layers except the leafNodes are forced to be a new renderSurface that have something to draw.
 | 
| +    //  - parent is a large container layer.
 | 
| +    //  - child has masksToBounds=true to cause clipping.
 | 
| +    //  - grandChild is positioned outside of the child's bounds
 | 
| +    //  - greatGrandChild is also kept outside child's bounds.
 | 
| +    //
 | 
| +    // In this configuration, grandChild and greatGrandChild are completely outside the
 | 
| +    // clipRect, and they should never get scheduled on the list of renderSurfaces.
 | 
| +    //
 | 
| +
 | 
| +    const TransformationMatrix identityMatrix;
 | 
| +    RefPtr<LayerChromium> parent = LayerChromium::create(0);
 | 
| +    RefPtr<LayerChromium> child = LayerChromium::create(0);
 | 
| +    RefPtr<LayerChromium> grandChild = LayerChromium::create(0);
 | 
| +    RefPtr<LayerChromium> greatGrandChild = LayerChromium::create(0);
 | 
| +    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent(0));
 | 
| +    RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent(0));
 | 
| +    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
 | 
| +    // therefore leafNode2 thinks it should draw itself. As a result, an extra
 | 
| +    // 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)));
 | 
| +
 | 
| +    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);
 | 
| +
 | 
| +    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());
 | 
| +}
 | 
| +
 | 
|  // FIXME:
 | 
|  // continue working on https://bugs.webkit.org/show_bug.cgi?id=68942
 | 
|  //  - add a test to verify clipping that changes the "center point"
 | 
| 
 |