Diff
Modified: trunk/LayoutTests/ChangeLog (103010 => 103011)
--- trunk/LayoutTests/ChangeLog 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/LayoutTests/ChangeLog 2011-12-16 02:32:29 UTC (rev 103011)
@@ -1,3 +1,12 @@
+2011-12-15 James Robinson <[email protected]>
+
+ [chromium] Set the CCLayerTreeHost pointer on LayerChromium instances eagerly
+ https://bugs.webkit.org/show_bug.cgi?id=74477
+
+ Reviewed by Kenneth Russell.
+
+ * platform/chromium/test_expectations.txt:
+
2011-12-15 Adam Barth <[email protected]>
<ruby><div><p><rp> parses incorrectly
Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (103010 => 103011)
--- trunk/LayoutTests/platform/chromium/test_expectations.txt 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt 2011-12-16 02:32:29 UTC (rev 103011)
@@ -2804,6 +2804,10 @@
BUGWK49629 SKIP : platform/chromium/compositing/lots-of-img-layers-with-opacity.html = PASS
BUGWK49629 SKIP : compositing/iframes/page-cache-layer-tree.html = PASS
+// Needs an image-only rebaseline since we no longer invalidate when setting the replica layer
+// to NULL when it already was NULL so we have no damage at the end of the test.
+BUGJAMESR : compositing/iframes/iframe-content-flipping.html = IMAGE
+
BUGNONE SLOW WIN DEBUG GPU : fast/canvas/canvas-getImageData.html = PASS
// Accelerated 2d for mac isn't supported yet, so SKIP this test for now.
Modified: trunk/Source/WebCore/ChangeLog (103010 => 103011)
--- trunk/Source/WebCore/ChangeLog 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/ChangeLog 2011-12-16 02:32:29 UTC (rev 103011)
@@ -1,3 +1,34 @@
+2011-12-15 James Robinson <[email protected]>
+
+ [chromium] Set the CCLayerTreeHost pointer on LayerChromium instances eagerly
+ https://bugs.webkit.org/show_bug.cgi?id=74477
+
+ Reviewed by Kenneth Russell.
+
+ This enforces that the m_layerTreeHost pointer on LayerChromium instances is always up to date, instead of
+ lazily setting it in the paintContents loop. There are two invariants:
+ 1.) If a LayerChromium is the root layer of a CCLayerTreeHost, or is reachable via the children, mask, or
+ replica pointers from the root layer of a CCLayerTreeHost, then that LayerChromium's m_layerTreeHost pointer
+ refers to that CCLayerTreeHost
+ 2.) If a LayerChromium is not a root layer or reachable from a root layer of any CCLayerTreeHost, its
+ CCLayerTreeHost pointer is nil.
+
+ Covered by several new layout tests in LayerChromiumTest
+
+ * platform/graphics/chromium/LayerChromium.cpp:
+ (WebCore::LayerChromium::setLayerTreeHost):
+ (WebCore::LayerChromium::setParent):
+ (WebCore::LayerChromium::setMaskLayer):
+ (WebCore::LayerChromium::setReplicaLayer):
+ * platform/graphics/chromium/LayerChromium.h:
+ * platform/graphics/chromium/TiledLayerChromium.cpp:
+ (WebCore::TiledLayerChromium::createTile):
+ * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+ (WebCore::CCLayerTreeHost::setRootLayer):
+ (WebCore::CCLayerTreeHost::paintMaskAndReplicaForRenderSurface):
+ (WebCore::CCLayerTreeHost::paintLayerContents):
+ * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+
2011-12-15 Sheriff Bot <[email protected]>
Unreviewed, rolling out r102652 and r102717.
Modified: trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp (103010 => 103011)
--- trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp 2011-12-16 02:32:29 UTC (rev 103011)
@@ -85,7 +85,6 @@
ContentLayerChromium::~ContentLayerChromium()
{
- cleanupResources();
}
void ContentLayerChromium::cleanupResources()
Modified: trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp (103010 => 103011)
--- trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp 2011-12-16 02:32:29 UTC (rev 103011)
@@ -169,11 +169,8 @@
if (m_needsDisplay) {
m_textureUpdater->updateFromImage(m_contents->nativeImageForCurrentFrame());
updateTileSizeAndTilingOption();
- IntRect paintRect(IntPoint(), contentBounds());
- if (m_needsDisplay) {
- invalidateRect(paintRect);
- m_needsDisplay = false;
- }
+ invalidateRect(IntRect(IntPoint(), contentBounds()));
+ m_needsDisplay = false;
}
prepareToUpdate(visibleLayerRect());
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp (103010 => 103011)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp 2011-12-16 02:32:29 UTC (rev 103011)
@@ -108,14 +108,25 @@
void LayerChromium::setLayerTreeHost(CCLayerTreeHost* host)
{
- // If we're changing layer renderers then we need to free up any resources
- // allocated by the old renderer.
- if (layerTreeHost() && layerTreeHost() != host) {
+ if (m_layerTreeHost == host)
+ return;
+
+ // If we're changing hosts then we need to free up any resources
+ // allocated by the old host.
+ if (m_layerTreeHost) {
cleanupResources();
setNeedsDisplay();
}
m_layerTreeHost = host;
+
+ for (size_t i = 0; i < m_children.size(); ++i)
+ m_children[i]->setLayerTreeHost(host);
+
+ if (m_maskLayer)
+ m_maskLayer->setLayerTreeHost(host);
+ if (m_replicaLayer)
+ m_replicaLayer->setLayerTreeHost(host);
}
void LayerChromium::setNeedsCommit()
@@ -128,6 +139,7 @@
{
ASSERT(!layer || !layer->hasAncestor(this));
m_parent = layer;
+ setLayerTreeHost(m_parent ? m_parent->layerTreeHost() : 0);
}
bool LayerChromium::hasAncestor(LayerChromium* ancestor) const
@@ -281,10 +293,26 @@
{
if (m_maskLayer == maskLayer)
return;
+ if (m_maskLayer)
+ m_maskLayer->setLayerTreeHost(0);
m_maskLayer = maskLayer;
+ if (m_maskLayer)
+ m_maskLayer->setLayerTreeHost(m_layerTreeHost.get());
setNeedsCommit();
}
+void LayerChromium::setReplicaLayer(LayerChromium* layer)
+{
+ if (m_replicaLayer == layer)
+ return;
+ if (m_replicaLayer)
+ m_replicaLayer->setLayerTreeHost(0);
+ m_replicaLayer = layer;
+ if (m_replicaLayer)
+ m_replicaLayer->setLayerTreeHost(m_layerTreeHost.get());
+ setNeedsCommit();
+}
+
void LayerChromium::setOpacity(float opacity)
{
if (m_opacity == opacity)
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h (103010 => 103011)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2011-12-16 02:32:29 UTC (rev 103011)
@@ -155,7 +155,7 @@
void setDelegate(CCLayerDelegate* delegate) { m_delegate = delegate; }
- void setReplicaLayer(LayerChromium* layer) { m_replicaLayer = layer; setNeedsCommit(); }
+ void setReplicaLayer(LayerChromium*);
LayerChromium* replicaLayer() const { return m_replicaLayer.get(); }
// These methods typically need to be overwritten by derived classes.
Modified: trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp (103010 => 103011)
--- trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp 2011-12-16 02:32:29 UTC (rev 103011)
@@ -154,13 +154,18 @@
void TiledLayerChromium::setLayerTreeHost(CCLayerTreeHost* host)
{
+ if (host == layerTreeHost())
+ return;
+
+ if (layerTreeHost())
+ cleanupResources();
+
LayerChromium::setLayerTreeHost(host);
- if (m_tiler || !host)
+ if (!host)
return;
createTextureUpdater(host);
-
setTextureFormat(host->layerRendererCapabilities().bestTextureFormat);
m_sampledTexelFormat = textureUpdater()->sampledTexelFormat(m_textureFormat);
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (103010 => 103011)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-12-16 02:32:29 UTC (rev 103011)
@@ -174,8 +174,10 @@
void CCLayerTreeHost::didRecreateGraphicsContext(bool success)
{
- if (rootLayer())
- rootLayer()->cleanupResourcesRecursive();
+ if (m_rootLayer) {
+ m_rootLayer->setLayerTreeHost(0);
+ m_rootLayer->setLayerTreeHost(this);
+ }
m_client->didRecreateGraphicsContext(success);
}
@@ -233,6 +235,18 @@
m_client->scheduleComposite();
}
+void CCLayerTreeHost::setRootLayer(PassRefPtr<LayerChromium> rootLayer)
+{
+ if (m_rootLayer == rootLayer)
+ return;
+
+ if (m_rootLayer)
+ m_rootLayer->setLayerTreeHost(0);
+ m_rootLayer = rootLayer;
+ if (m_rootLayer)
+ m_rootLayer->setLayerTreeHost(this);
+}
+
void CCLayerTreeHost::setViewport(const IntSize& viewportSize)
{
contentsTextureManager()->setMaxMemoryLimitBytes(TextureManager::highLimitBytes(viewportSize));
@@ -371,7 +385,6 @@
// mask and replica should be painted.
if (renderSurfaceLayer->maskLayer()) {
- renderSurfaceLayer->maskLayer()->setLayerTreeHost(this);
renderSurfaceLayer->maskLayer()->setVisibleLayerRect(IntRect(IntPoint(), renderSurfaceLayer->contentBounds()));
renderSurfaceLayer->maskLayer()->paintContentsIfDirty();
}
@@ -379,11 +392,9 @@
LayerChromium* replicaLayer = renderSurfaceLayer->replicaLayer();
if (replicaLayer) {
- replicaLayer->setLayerTreeHost(this);
replicaLayer->paintContentsIfDirty();
if (replicaLayer->maskLayer()) {
- replicaLayer->maskLayer()->setLayerTreeHost(this);
replicaLayer->maskLayer()->setVisibleLayerRect(IntRect(IntPoint(), replicaLayer->maskLayer()->contentBounds()));
replicaLayer->maskLayer()->paintContentsIfDirty();
}
@@ -398,7 +409,6 @@
ASSERT(renderSurface);
ASSERT(renderSurface->drawOpacity());
- renderSurfaceLayer->setLayerTreeHost(this);
paintMaskAndReplicaForRenderSurface(renderSurfaceLayer);
const LayerList& layerList = renderSurface->layerList();
@@ -410,8 +420,6 @@
if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<LayerChromium>(layer, renderSurfaceLayer->id()))
continue;
- layer->setLayerTreeHost(this);
-
ASSERT(layer->opacity());
ASSERT(!layer->bounds().isEmpty());
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (103010 => 103011)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-12-16 02:32:29 UTC (rev 103011)
@@ -168,7 +168,7 @@
LayerChromium* rootLayer() { return m_rootLayer.get(); }
const LayerChromium* rootLayer() const { return m_rootLayer.get(); }
- void setRootLayer(PassRefPtr<LayerChromium> rootLayer) { m_rootLayer = rootLayer; }
+ void setRootLayer(PassRefPtr<LayerChromium>);
const CCSettings& settings() const { return m_settings; }
Modified: trunk/Source/WebKit/chromium/ChangeLog (103010 => 103011)
--- trunk/Source/WebKit/chromium/ChangeLog 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebKit/chromium/ChangeLog 2011-12-16 02:32:29 UTC (rev 103011)
@@ -1,3 +1,20 @@
+2011-12-15 James Robinson <[email protected]>
+
+ [chromium] Set the CCLayerTreeHost pointer on LayerChromium instances eagerly
+ https://bugs.webkit.org/show_bug.cgi?id=74477
+
+ Reviewed by Kenneth Russell.
+
+ Add some new tests for LayerChromium::m_layerTreeHost behavior.
+
+ * tests/CCLayerTreeHostTest.cpp:
+ (::MockLayerTreeHost::create):
+ (::MockLayerTreeHost::MockLayerTreeHost):
+ (::CCLayerTreeHostTestShortlived1::beginTest):
+ (::CCLayerTreeHostTestShortlived2::beginTest):
+ (::CCLayerTreeHostTestShortlived3::beginTest):
+ * tests/LayerChromiumTest.cpp:
+
2011-12-15 Nat Duca <[email protected]>
[chromium] Add forUseOnAnotherThread to WebGraphicsContext3D::Attributes
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (103010 => 103011)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2011-12-16 02:32:29 UTC (rev 103011)
@@ -103,12 +103,15 @@
public:
static PassRefPtr<MockLayerTreeHost> create(TestHooks* testHooks, CCLayerTreeHostClient* client, PassRefPtr<LayerChromium> rootLayer, const CCSettings& settings)
{
- RefPtr<MockLayerTreeHost> layerTreeHost = adoptRef(new MockLayerTreeHost(testHooks, client, rootLayer, settings));
+ RefPtr<MockLayerTreeHost> mock = adoptRef(new MockLayerTreeHost(testHooks, client, settings));
+ mock->setRootLayer(rootLayer);
+ bool success = mock->initialize();
+ EXPECT_TRUE(success);
// LayerTreeHostImpl won't draw if it has 1x1 viewport.
- layerTreeHost->setViewport(IntSize(1, 1));
+ mock->setViewport(IntSize(1, 1));
- return layerTreeHost;
+ return mock.release();
}
virtual PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl(CCLayerTreeHostImplClient* client)
@@ -117,13 +120,10 @@
}
private:
- MockLayerTreeHost(TestHooks* testHooks, CCLayerTreeHostClient* client, PassRefPtr<LayerChromium> rootLayer, const CCSettings& settings)
+ MockLayerTreeHost(TestHooks* testHooks, CCLayerTreeHostClient* client, const CCSettings& settings)
: CCLayerTreeHost(client, settings)
, m_testHooks(testHooks)
{
- setRootLayer(rootLayer);
- bool success = initialize();
- EXPECT_TRUE(success);
}
TestHooks* m_testHooks;
@@ -453,7 +453,7 @@
virtual void beginTest()
{
// Kill the layerTreeHost immediately.
- m_layerTreeHost->rootLayer()->setLayerTreeHost(0);
+ m_layerTreeHost->setRootLayer(0);
m_layerTreeHost.clear();
endTest();
@@ -486,7 +486,7 @@
postSetNeedsCommitToMainThread();
// Kill the layerTreeHost immediately.
- m_layerTreeHost->rootLayer()->setLayerTreeHost(0);
+ m_layerTreeHost->setRootLayer(0);
m_layerTreeHost.clear();
endTest();
@@ -509,7 +509,7 @@
postSetNeedsRedrawToMainThread();
// Kill the layerTreeHost immediately.
- m_layerTreeHost->rootLayer()->setLayerTreeHost(0);
+ m_layerTreeHost->setRootLayer(0);
m_layerTreeHost.clear();
endTest();
Modified: trunk/Source/WebKit/chromium/tests/LayerChromiumTest.cpp (103010 => 103011)
--- trunk/Source/WebKit/chromium/tests/LayerChromiumTest.cpp 2011-12-16 02:32:08 UTC (rev 103010)
+++ trunk/Source/WebKit/chromium/tests/LayerChromiumTest.cpp 2011-12-16 02:32:29 UTC (rev 103011)
@@ -29,6 +29,8 @@
#include "CCLayerTreeTestCommon.h"
#include "LayerPainterChromium.h"
#include "NonCompositedContentHost.h"
+#include "WebCompositor.h"
+#include "cc/CCLayerTreeHost.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -734,4 +736,219 @@
EXPECT_TRUE(testLayer->needsDisplay());
}
+class FakeCCLayerTreeHostClient : public CCLayerTreeHostClient {
+public:
+ virtual void animateAndLayout(double frameBeginTime) { }
+ virtual void applyScrollAndScale(const IntSize& scrollDelta, float pageScale) { }
+ virtual PassRefPtr<GraphicsContext3D> createLayerTreeHostContext3D() { return 0; }
+ virtual void didRecreateGraphicsContext(bool success) { }
+ virtual void didCommitAndDrawFrame() { }
+ virtual void didCompleteSwapBuffers() { }
+ virtual void scheduleComposite() { }
+};
+
+class FakeCCLayerTreeHost : public CCLayerTreeHost {
+public:
+ static PassRefPtr<FakeCCLayerTreeHost> create()
+ {
+ RefPtr<FakeCCLayerTreeHost> host = adoptRef(new FakeCCLayerTreeHost);
+ // The initialize call will fail, since our client doesn't provide a valid GraphicsContext3D, but it doesn't matter in the tests that use this fake so ignore the return value.
+ host->initialize();
+ return host.release();
+ }
+
+private:
+ FakeCCLayerTreeHost()
+ : CCLayerTreeHost(&m_client, CCSettings())
+ {
+ }
+
+ FakeCCLayerTreeHostClient m_client;
+};
+
+void assertLayerTreeHostMatchesForSubtree(LayerChromium* layer, CCLayerTreeHost* host)
+{
+ EXPECT_EQ(host, layer->layerTreeHost());
+
+ for (size_t i = 0; i < layer->children().size(); ++i)
+ assertLayerTreeHostMatchesForSubtree(layer->children()[i].get(), host);
+
+ if (layer->maskLayer())
+ assertLayerTreeHostMatchesForSubtree(layer->maskLayer(), host);
+
+ if (layer->replicaLayer())
+ assertLayerTreeHostMatchesForSubtree(layer->replicaLayer(), host);
+}
+
+
+TEST(LayerChromiumLayerTreeHostTest, enteringTree)
+{
+ WebCompositor::initialize(0);
+ RefPtr<LayerChromium> parent = LayerChromium::create(0);
+ RefPtr<LayerChromium> child = LayerChromium::create(0);
+ RefPtr<LayerChromium> mask = LayerChromium::create(0);
+ RefPtr<LayerChromium> replica = LayerChromium::create(0);
+ RefPtr<LayerChromium> replicaMask = LayerChromium::create(0);
+
+ // Set up a detached tree of layers. The host pointer should be nil for these layers.
+ parent->addChild(child);
+ child->setMaskLayer(mask.get());
+ child->setReplicaLayer(replica.get());
+ replica->setMaskLayer(mask.get());
+
+ assertLayerTreeHostMatchesForSubtree(parent.get(), 0);
+
+ RefPtr<FakeCCLayerTreeHost> layerTreeHost = FakeCCLayerTreeHost::create();
+ // Setting the root layer should set the host pointer for all layers in the tree.
+ layerTreeHost->setRootLayer(parent.get());
+
+ assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get());
+
+ // Clearing the root layer should also clear out the host pointers for all layers in the tree.
+ layerTreeHost->setRootLayer(0);
+
+ assertLayerTreeHostMatchesForSubtree(parent.get(), 0);
+
+ layerTreeHost.clear();
+ WebCompositor::shutdown();
+}
+
+TEST(LayerChromiumLayerTreeHostTest, addingLayerSubtree)
+{
+ WebCompositor::initialize(0);
+ RefPtr<LayerChromium> parent = LayerChromium::create(0);
+ RefPtr<FakeCCLayerTreeHost> layerTreeHost = FakeCCLayerTreeHost::create();
+
+ layerTreeHost->setRootLayer(parent.get());
+
+ EXPECT_EQ(parent->layerTreeHost(), layerTreeHost.get());
+
+ // Adding a subtree to a layer already associated with a host should set the host pointer on all layers in that subtree.
+ RefPtr<LayerChromium> child = LayerChromium::create(0);
+ RefPtr<LayerChromium> grandChild = LayerChromium::create(0);
+ child->addChild(grandChild);
+
+ // Masks, replicas, and replica masks should pick up the new host too.
+ RefPtr<LayerChromium> childMask = LayerChromium::create(0);
+ child->setMaskLayer(childMask.get());
+ RefPtr<LayerChromium> childReplica = LayerChromium::create(0);
+ child->setReplicaLayer(childReplica.get());
+ RefPtr<LayerChromium> childReplicaMask = LayerChromium::create(0);
+ childReplica->setMaskLayer(childReplicaMask.get());
+
+ parent->addChild(child);
+ assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get());
+
+ layerTreeHost->setRootLayer(0);
+ layerTreeHost.clear();
+ WebCompositor::shutdown();
+}
+
+TEST(LayerChromiumLayerTreeHostTest, changeHost)
+{
+ WebCompositor::initialize(0);
+ RefPtr<LayerChromium> parent = LayerChromium::create(0);
+ RefPtr<LayerChromium> child = LayerChromium::create(0);
+ RefPtr<LayerChromium> mask = LayerChromium::create(0);
+ RefPtr<LayerChromium> replica = LayerChromium::create(0);
+ RefPtr<LayerChromium> replicaMask = LayerChromium::create(0);
+
+ // Same setup as the previous test.
+ parent->addChild(child);
+ child->setMaskLayer(mask.get());
+ child->setReplicaLayer(replica.get());
+ replica->setMaskLayer(mask.get());
+
+ RefPtr<FakeCCLayerTreeHost> firstLayerTreeHost = FakeCCLayerTreeHost::create();
+ firstLayerTreeHost->setRootLayer(parent.get());
+
+ assertLayerTreeHostMatchesForSubtree(parent.get(), firstLayerTreeHost.get());
+
+ // Now re-root the tree to a new host (simulating what we do on a context lost event).
+ // This should update the host pointers for all layers in the tree.
+ RefPtr<FakeCCLayerTreeHost> secondLayerTreeHost = FakeCCLayerTreeHost::create();
+ secondLayerTreeHost->setRootLayer(parent.get());
+
+ assertLayerTreeHostMatchesForSubtree(parent.get(), secondLayerTreeHost.get());
+
+ secondLayerTreeHost->setRootLayer(0);
+ firstLayerTreeHost.clear();
+ secondLayerTreeHost.clear();
+ WebCompositor::shutdown();
+}
+
+TEST(LayerChromiumLayerTreeHostTest, changeHostInSubtree)
+{
+ WebCompositor::initialize(0);
+ RefPtr<LayerChromium> firstParent = LayerChromium::create(0);
+ RefPtr<LayerChromium> firstChild = LayerChromium::create(0);
+ RefPtr<LayerChromium> secondParent = LayerChromium::create(0);
+ RefPtr<LayerChromium> secondChild = LayerChromium::create(0);
+ RefPtr<LayerChromium> secondGrandChild = LayerChromium::create(0);
+
+ // First put all children under the first parent and set the first host.
+ firstParent->addChild(firstChild);
+ secondChild->addChild(secondGrandChild);
+ firstParent->addChild(secondChild);
+
+ RefPtr<FakeCCLayerTreeHost> firstLayerTreeHost = FakeCCLayerTreeHost::create();
+ firstLayerTreeHost->setRootLayer(firstParent.get());
+
+ assertLayerTreeHostMatchesForSubtree(firstParent.get(), firstLayerTreeHost.get());
+
+ // Now reparent the subtree starting at secondChild to a layer in a different tree.
+ RefPtr<FakeCCLayerTreeHost> secondLayerTreeHost = FakeCCLayerTreeHost::create();
+ secondLayerTreeHost->setRootLayer(secondParent.get());
+
+ secondParent->addChild(secondChild);
+
+ // The moved layer and its children should point to the new host.
+ EXPECT_EQ(secondLayerTreeHost.get(), secondChild->layerTreeHost());
+ EXPECT_EQ(secondLayerTreeHost.get(), secondGrandChild->layerTreeHost());
+
+ // Test over, cleanup time.
+ firstLayerTreeHost->setRootLayer(0);
+ secondLayerTreeHost->setRootLayer(0);
+ firstLayerTreeHost.clear();
+ secondLayerTreeHost.clear();
+ WebCompositor::shutdown();
+}
+
+TEST(LayerChromiumLayerTreeHostTest, replaceMaskAndReplicaLayer)
+{
+ WebCompositor::initialize(0);
+ RefPtr<LayerChromium> parent = LayerChromium::create(0);
+ RefPtr<LayerChromium> mask = LayerChromium::create(0);
+ RefPtr<LayerChromium> replica = LayerChromium::create(0);
+ RefPtr<LayerChromium> maskChild = LayerChromium::create(0);
+ RefPtr<LayerChromium> replicaChild = LayerChromium::create(0);
+ RefPtr<LayerChromium> maskReplacement = LayerChromium::create(0);
+ RefPtr<LayerChromium> replicaReplacement = LayerChromium::create(0);
+
+ parent->setMaskLayer(mask.get());
+ parent->setReplicaLayer(replica.get());
+ mask->addChild(maskChild);
+ replica->addChild(replicaChild);
+
+ RefPtr<FakeCCLayerTreeHost> layerTreeHost = FakeCCLayerTreeHost::create();
+ layerTreeHost->setRootLayer(parent.get());
+
+ assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get());
+
+ // Replacing the mask should clear out the old mask's subtree's host pointers.
+ parent->setMaskLayer(maskReplacement.get());
+ EXPECT_EQ(0, mask->layerTreeHost());
+ EXPECT_EQ(0, maskChild->layerTreeHost());
+
+ // Same for replacing a replica layer.
+ parent->setReplicaLayer(replicaReplacement.get());
+ EXPECT_EQ(0, replica->layerTreeHost());
+ EXPECT_EQ(0, replicaChild->layerTreeHost());
+
+ // Test over, cleanup time.
+ layerTreeHost->setRootLayer(0);
+ layerTreeHost.clear();
+ WebCompositor::shutdown();
+}
+
} // namespace