Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp (111816 => 111817)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp 2012-03-23 02:59:53 UTC (rev 111816)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp 2012-03-23 03:02:40 UTC (rev 111817)
@@ -142,9 +142,10 @@
swap(m_currentRectHistory, m_nextRectHistory);
}
-FloatRect CCDamageTracker::removeRectFromCurrentFrame(int layerID)
+FloatRect CCDamageTracker::removeRectFromCurrentFrame(int layerID, bool& layerIsNew)
{
- // This function exists mainly for readability of the code.
+ layerIsNew = !m_currentRectHistory->contains(layerID);
+
// take() will remove the entry from the map, or if not found, return a default (empty) rect.
return m_currentRectHistory->take(layerID);
}
@@ -221,13 +222,14 @@
TransformationMatrix originTransform = layer->drawTransform();
originTransform.translate(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height());
- FloatRect oldLayerRect = removeRectFromCurrentFrame(layer->id());
+ bool layerIsNew = false;
+ FloatRect oldLayerRect = removeRectFromCurrentFrame(layer->id(), layerIsNew);
FloatRect layerRectInTargetSpace = originTransform.mapRect(FloatRect(FloatPoint::zero(), layer->bounds()));
saveRectForNextFrame(layer->id(), layerRectInTargetSpace);
- if (layer->layerPropertyChanged()) {
- // If a layer has changed, then its entire layer rect affects the target surface.
+ if (layerIsNew || layer->layerPropertyChanged()) {
+ // If a layer is new or has changed, then its entire layer rect affects the target surface.
targetDamageRect.uniteIfNonZero(layerRectInTargetSpace);
// The layer's old region is now exposed on the target surface, too.
@@ -257,13 +259,14 @@
CCRenderSurface* renderSurface = layer->renderSurface();
- FloatRect oldSurfaceRect = removeRectFromCurrentFrame(layer->id());
+ bool surfaceIsNew = false;
+ FloatRect oldSurfaceRect = removeRectFromCurrentFrame(layer->id(), surfaceIsNew);
FloatRect surfaceRectInTargetSpace = renderSurface->drawableContentRect(); // already includes replica if it exists.
saveRectForNextFrame(layer->id(), surfaceRectInTargetSpace);
FloatRect damageRectInLocalSpace;
- if (renderSurface->surfacePropertyChanged()) {
+ if (surfaceIsNew || renderSurface->surfacePropertyChanged()) {
// The entire surface contributes damage.
damageRectInLocalSpace = renderSurface->contentRect();
@@ -290,7 +293,8 @@
if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) {
CCLayerImpl* replicaMaskLayer = layer->replicaLayer()->maskLayer();
- removeRectFromCurrentFrame(replicaMaskLayer->id());
+ bool replicaIsNew = false;
+ removeRectFromCurrentFrame(replicaMaskLayer->id(), replicaIsNew);
// Compute the replica's "originTransform" that maps from the replica's origin space to the target surface origin space.
TransformationMatrix replicaOriginTransform = layer->renderSurface()->originTransform();
@@ -302,7 +306,7 @@
saveRectForNextFrame(replicaMaskLayer->id(), replicaMaskLayerRect);
// In the current implementation, a change in the replica mask damages the entire replica region.
- if (replicaMaskLayer->layerPropertyChanged() || !replicaMaskLayer->updateRect().isEmpty())
+ if (replicaIsNew || replicaMaskLayer->layerPropertyChanged() || !replicaMaskLayer->updateRect().isEmpty())
targetDamageRect.uniteIfNonZero(replicaMaskLayerRect);
}
}
Modified: trunk/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp (111816 => 111817)
--- trunk/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp 2012-03-23 02:59:53 UTC (rev 111816)
+++ trunk/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp 2012-03-23 03:02:40 UTC (rev 111817)
@@ -180,7 +180,7 @@
OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
- EXPECT_EQ(static_cast<size_t>(2), root->renderSurface()->layerList().size());
+ EXPECT_EQ(2u, root->renderSurface()->layerList().size());
EXPECT_EQ(1, root->renderSurface()->layerList()[0]->id());
EXPECT_EQ(2, root->renderSurface()->layerList()[1]->id());
@@ -202,8 +202,8 @@
ASSERT_TRUE(child1->renderSurface());
EXPECT_FALSE(child2->renderSurface());
- EXPECT_EQ(static_cast<size_t>(3), root->renderSurface()->layerList().size());
- EXPECT_EQ(static_cast<size_t>(2), child1->renderSurface()->layerList().size());
+ EXPECT_EQ(3u, root->renderSurface()->layerList().size());
+ EXPECT_EQ(2u, child1->renderSurface()->layerList().size());
// The render surface for child1 only has a contentRect that encloses grandChild1 and grandChild2, because child1 does not draw content.
EXPECT_FLOAT_RECT_EQ(FloatRect(190, 190, 16, 18), childDamageRect);
@@ -254,7 +254,7 @@
// Sanity check - we should not have accidentally created a separate render surface for the translucent layer.
ASSERT_FALSE(child->renderSurface());
- ASSERT_EQ(static_cast<size_t>(2), root->renderSurface()->layerList().size());
+ ASSERT_EQ(2u, root->renderSurface()->layerList().size());
// Damage should be the entire child layer in targetSurface space.
FloatRect expectedRect = FloatRect(100, 100, 30, 30);
@@ -334,7 +334,7 @@
emulateDrawingOneFrame(root.get());
// Sanity check - all 3 layers should be on the same render surface; render surfaces are tested elsewhere.
- ASSERT_EQ(static_cast<size_t>(3), root->renderSurface()->layerList().size());
+ ASSERT_EQ(3u, root->renderSurface()->layerList().size());
FloatRect rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
EXPECT_FLOAT_RECT_EQ(FloatRect(400, 380, 6, 8), rootDamageRect);
@@ -353,6 +353,36 @@
EXPECT_FLOAT_RECT_EQ(FloatRect(100, 100, 30, 30), rootDamageRect);
}
+TEST_F(CCDamageTrackerTest, verifyDamageForNewUnchangedLayer)
+{
+ // If child2 is added to the layer tree, but it doesn't have any explicit damage of
+ // its own, it should still indeed damage the target surface.
+
+ OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
+
+ {
+ OwnPtr<CCLayerImpl> child2 = CCLayerImpl::create(3);
+ child2->setPosition(FloatPoint(400, 380));
+ child2->setAnchorPoint(FloatPoint::zero());
+ child2->setBounds(IntSize(6, 8));
+ child2->setDrawsContent(true);
+ child2->resetAllChangeTrackingForSubtree();
+ // Sanity check the initial conditions of the test, if these asserts trigger, it
+ // means the test no longer actually covers the intended scenario.
+ ASSERT_FALSE(child2->layerPropertyChanged());
+ ASSERT_TRUE(child2->updateRect().isEmpty());
+ root->addChild(child2.release());
+ }
+
+ emulateDrawingOneFrame(root.get());
+
+ // Sanity check - all 3 layers should be on the same render surface; render surfaces are tested elsewhere.
+ ASSERT_EQ(3u, root->renderSurface()->layerList().size());
+
+ FloatRect rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ EXPECT_FLOAT_RECT_EQ(FloatRect(400, 380, 6, 8), rootDamageRect);
+}
+
TEST_F(CCDamageTrackerTest, verifyDamageForMultipleLayers)
{
OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
@@ -485,7 +515,7 @@
// Sanity check that there is only one surface now.
ASSERT_FALSE(child1->renderSurface());
- ASSERT_EQ(static_cast<size_t>(4), root->renderSurface()->layerList().size());
+ ASSERT_EQ(4u, root->renderSurface()->layerList().size());
rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
EXPECT_FLOAT_RECT_EQ(FloatRect(290, 290, 16, 18), rootDamageRect);
@@ -503,8 +533,8 @@
// Sanity check that there is a new surface now.
ASSERT_TRUE(child1->renderSurface());
- EXPECT_EQ(static_cast<size_t>(3), root->renderSurface()->layerList().size());
- EXPECT_EQ(static_cast<size_t>(2), child1->renderSurface()->layerList().size());
+ EXPECT_EQ(3u, root->renderSurface()->layerList().size());
+ EXPECT_EQ(2u, child1->renderSurface()->layerList().size());
childDamageRect = child1->renderSurface()->damageTracker()->currentDamageRect();
rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();