summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp')
-rw-r--r--Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp260
1 files changed, 247 insertions, 13 deletions
diff --git a/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp b/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
index 74d635b40..11a88784b 100644
--- a/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
+++ b/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
@@ -30,6 +30,7 @@
#include "cc/CCLayerImpl.h"
#include "cc/CCLayerSorter.h"
#include "cc/CCLayerTreeHostCommon.h"
+#include "cc/CCMathUtil.h"
#include "cc/CCSingleThreadProxy.h"
#include <gtest/gtest.h>
@@ -70,7 +71,7 @@ void emulateDrawingOneFrame(CCLayerImpl* root)
// Iterate back-to-front, so that damage correctly propagates from descendant surfaces to ancestors.
for (int i = renderSurfaceLayerList.size() - 1; i >= 0; --i) {
CCRenderSurface* targetSurface = renderSurfaceLayerList[i]->renderSurface();
- targetSurface->damageTracker()->updateDamageTrackingState(targetSurface->layerList(), targetSurface->owningLayerId(), renderSurfaceLayerList[i]->maskLayer());
+ targetSurface->damageTracker()->updateDamageTrackingState(targetSurface->layerList(), targetSurface->owningLayerId(), targetSurface->surfacePropertyChangedOnlyFromDescendant(), targetSurface->contentRect(), renderSurfaceLayerList[i]->maskLayer(), renderSurfaceLayerList[i]->filters());
}
root->resetAllChangeTrackingForSubtree();
@@ -180,7 +181,7 @@ TEST_F(CCDamageTrackerTest, sanityCheckTestTreeWithOneSurface)
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 +203,8 @@ TEST_F(CCDamageTrackerTest, sanityCheckTestTreeWithTwoSurfaces)
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 +255,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForPropertyChanges)
// 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);
@@ -315,6 +316,146 @@ TEST_F(CCDamageTrackerTest, verifyDamageForTransformedLayer)
EXPECT_FLOAT_RECT_EQ(expectedRect, rootDamageRect);
}
+TEST_F(CCDamageTrackerTest, verifyDamageForPerspectiveClippedLayer)
+{
+ // If a layer has a perspective transform that causes w < 0, then not clipping the
+ // layer can cause an invalid damage rect. This test checks that the w < 0 case is
+ // tracked properly.
+ //
+ // The transform is constructed so that if w < 0 clipping is not performed, the
+ // incorrect rect will be very small, specifically: position (-3.153448, -2.750628) and size 8.548689 x 5.661383.
+ // Instead, the correctly transformed rect should actually be very huge (i.e. in theory, infinite)
+
+ OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
+ CCLayerImpl* child = root->children()[0].get();
+
+ TransformationMatrix transform;
+ transform.applyPerspective(1);
+ transform.translate3d(-150, -50, 0);
+ transform.rotate3d(0, 45, 0);
+ transform.translate3d(-50, -50, 0);
+
+ // Set up the child
+ child->setPosition(FloatPoint(0, 0));
+ child->setBounds(IntSize(100, 100));
+ child->setTransform(transform);
+ emulateDrawingOneFrame(root.get());
+
+ // Sanity check that the child layer's bounds would actually get clipped by w < 0,
+ // otherwise this test is not actually testing the intended scenario.
+ FloatQuad testQuad(FloatRect(FloatPoint::zero(), FloatSize(100, 100)));
+ bool clipped = false;
+ CCMathUtil::mapQuad(transform, testQuad, clipped);
+ EXPECT_TRUE(clipped);
+
+ // Damage the child without moving it.
+ child->setOpacity(0.5);
+ emulateDrawingOneFrame(root.get());
+
+ // The expected damage should cover the entire root surface (500x500), but we don't
+ // care whether the damage rect was clamped or is larger than the surface for this test.
+ FloatRect rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ EXPECT_GE(rootDamageRect.width(), 500);
+ EXPECT_GE(rootDamageRect.height(), 500);
+}
+
+TEST_F(CCDamageTrackerTest, verifyDamageForBlurredSurface)
+{
+ OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
+ CCLayerImpl* child = root->children()[0].get();
+
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(5, WebCore::Fixed), FilterOperation::BLUR));
+ int outsetTop, outsetRight, outsetBottom, outsetLeft;
+ filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
+ root->setFilters(filters);
+
+ // Setting the filter will damage the whole surface.
+ emulateDrawingOneFrame(root.get());
+
+ // Setting the update rect should cause the corresponding damage to the surface, blurred based on the size of the blur filter.
+ child->setUpdateRect(FloatRect(10, 11, 12, 13));
+ emulateDrawingOneFrame(root.get());
+
+ // Damage position on the surface should be: position of updateRect (10, 11) relative to the child (100, 100), but expanded by the blur outsets.
+ FloatRect rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ FloatRect expectedDamageRect = FloatRect(110, 111, 12, 13);
+ expectedDamageRect.move(-outsetLeft, -outsetTop);
+ expectedDamageRect.expand(outsetLeft + outsetRight, outsetTop + outsetBottom);
+ EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+}
+
+TEST_F(CCDamageTrackerTest, verifyDamageForBackgroundBlurredChild)
+{
+ OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithTwoSurfaces();
+ CCLayerImpl* child1 = root->children()[0].get();
+ CCLayerImpl* child2 = root->children()[1].get();
+
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(2, WebCore::Fixed), FilterOperation::BLUR));
+ int outsetTop, outsetRight, outsetBottom, outsetLeft;
+ filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
+ child1->setBackgroundFilters(filters);
+
+ // Setting the filter will damage the whole surface.
+ emulateDrawingOneFrame(root.get());
+
+ // CASE 1: Setting the update rect should cause the corresponding damage to
+ // the surface, blurred based on the size of the child's background blur
+ // filter.
+ root->setUpdateRect(FloatRect(297, 297, 2, 2));
+
+ emulateDrawingOneFrame(root.get());
+
+ FloatRect rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ // Damage position on the surface should be a composition of the damage on the root and on child2.
+ // Damage on the root should be: position of updateRect (297, 297), but expanded by the blur outsets.
+ FloatRect expectedDamageRect = FloatRect(297, 297, 2, 2);
+ expectedDamageRect.move(-outsetLeft, -outsetTop);
+ expectedDamageRect.expand(outsetLeft + outsetRight, outsetTop + outsetBottom);
+ EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+ // CASE 2: Setting the update rect should cause the corresponding damage to
+ // the surface, blurred based on the size of the child's background blur
+ // filter. Since the damage extends to the right/bottom outside of the
+ // blurred layer, only the left/top should end up expanded.
+ root->setUpdateRect(FloatRect(297, 297, 30, 30));
+
+ emulateDrawingOneFrame(root.get());
+
+ rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ // Damage position on the surface should be a composition of the damage on the root and on child2.
+ // Damage on the root should be: position of updateRect (297, 297), but expanded on the left/top
+ // by the blur outsets.
+ expectedDamageRect = FloatRect(297, 297, 30, 30);
+ expectedDamageRect.move(-outsetLeft, -outsetTop);
+ expectedDamageRect.expand(outsetLeft, outsetTop);
+ EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+ // CASE 3: Setting this update rect outside the contentBounds of the blurred
+ // child1 will not cause it to be expanded.
+ root->setUpdateRect(FloatRect(30, 30, 2, 2));
+
+ emulateDrawingOneFrame(root.get());
+
+ rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ // Damage on the root should be: position of updateRect (30, 30), not
+ // expanded.
+ expectedDamageRect = FloatRect(30, 30, 2, 2);
+ EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+ // CASE 4: Setting the update rect on child2, which is above child1, will
+ // not get blurred by child1, so it does not need to get expanded.
+ child2->setUpdateRect(FloatRect(0, 0, 1, 1));
+
+ emulateDrawingOneFrame(root.get());
+
+ rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ // Damage on child2 should be: position of updateRect offset by the child's position (11, 11), and not expanded by anything.
+ expectedDamageRect = FloatRect(11, 11, 1, 1);
+ EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+}
+
TEST_F(CCDamageTrackerTest, verifyDamageForAddingAndRemovingLayer)
{
OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
@@ -334,7 +475,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForAddingAndRemovingLayer)
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 +494,36 @@ TEST_F(CCDamageTrackerTest, verifyDamageForAddingAndRemovingLayer)
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();
@@ -402,8 +573,8 @@ TEST_F(CCDamageTrackerTest, verifyDamageForNestedSurfaces)
// CASE 2: Same as previous case, but with additional damage elsewhere that should be properly unioned.
// - child1 surface damage in root surface space: FloatRect(300, 300, 6, 8);
// - child2 damage in root surface space: FloatRect(11, 11, 18, 18);
- grandChild1->setOpacity(0.7);
- child2->setOpacity(0.7);
+ grandChild1->setOpacity(0.7f);
+ child2->setOpacity(0.7f);
emulateDrawingOneFrame(root.get());
childDamageRect = child1->renderSurface()->damageTracker()->currentDamageRect();
rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
@@ -485,7 +656,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForAddingAndRemovingRenderSurfaces)
// 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 +674,8 @@ TEST_F(CCDamageTrackerTest, verifyDamageForAddingAndRemovingRenderSurfaces)
// 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();
@@ -746,7 +917,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForReplicaMask)
ASSERT_TRUE(grandChild1->renderSurface());
// CASE 1: a property change on the mask should damage only the reflected region on the target surface.
- replicaMaskLayer->setOpacity(0.6);
+ replicaMaskLayer->setOpacity(0.6f);
emulateDrawingOneFrame(root.get());
FloatRect grandChildDamageRect = grandChild1->renderSurface()->damageTracker()->currentDamageRect();
@@ -767,7 +938,53 @@ TEST_F(CCDamageTrackerTest, verifyDamageForReplicaMask)
EXPECT_FLOAT_RECT_EQ(FloatRect(194, 200, 6, 8), childDamageRect);
}
-TEST_F(CCDamageTrackerTest, verifyDamageWhenReset)
+TEST_F(CCDamageTrackerTest, verifyDamageForReplicaMaskWithAnchor)
+{
+ OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithTwoSurfaces();
+ CCLayerImpl* child1 = root->children()[0].get();
+ CCLayerImpl* grandChild1 = child1->children()[0].get();
+
+ // Verify that the correct replicaOriginTransform is used for the replicaMask; the
+ // incorrect old code incorrectly accounted for the anchor for the replica. A
+ // non-zero anchor point should not affect the replica reflection.
+
+ grandChild1->setAnchorPoint(FloatPoint(1.0, 0.0)); // This is the anchor being tested.
+
+ {
+ OwnPtr<CCLayerImpl> grandChild1Replica = CCLayerImpl::create(6);
+ grandChild1Replica->setPosition(FloatPoint::zero());
+ grandChild1Replica->setAnchorPoint(FloatPoint::zero()); // note, this is not the anchor being tested.
+ TransformationMatrix reflection;
+ reflection.scale3d(-1.0, 1.0, 1.0);
+ grandChild1Replica->setTransform(reflection);
+ grandChild1->setReplicaLayer(grandChild1Replica.release());
+ }
+ CCLayerImpl* grandChild1Replica = grandChild1->replicaLayer();
+
+ // Set up the mask layer on the replica layer
+ {
+ OwnPtr<CCLayerImpl> replicaMaskLayer = CCLayerImpl::create(7);
+ replicaMaskLayer->setPosition(FloatPoint::zero());
+ replicaMaskLayer->setAnchorPoint(FloatPoint::zero()); // note, this is not the anchor being tested.
+ replicaMaskLayer->setBounds(grandChild1->bounds());
+ grandChild1Replica->setMaskLayer(replicaMaskLayer.release());
+ }
+ CCLayerImpl* replicaMaskLayer = grandChild1Replica->maskLayer();
+
+ emulateDrawingOneFrame(root.get());
+
+ // Sanity check that the appropriate render surfaces were created
+ ASSERT_TRUE(grandChild1->renderSurface());
+
+ // A property change on the replicaMask should damage the reflected region on the target surface.
+ replicaMaskLayer->setOpacity(0.6f);
+ emulateDrawingOneFrame(root.get());
+
+ FloatRect childDamageRect = child1->renderSurface()->damageTracker()->currentDamageRect();
+ EXPECT_FLOAT_RECT_EQ(FloatRect(194, 200, 6, 8), childDamageRect);
+}
+
+TEST_F(CCDamageTrackerTest, verifyDamageWhenForcedFullDamage)
{
OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
CCLayerImpl* child = root->children()[0].get();
@@ -790,4 +1007,21 @@ TEST_F(CCDamageTrackerTest, verifyDamageWhenReset)
EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 500, 500), rootDamageRect);
}
+TEST_F(CCDamageTrackerTest, verifyDamageForEmptyLayerList)
+{
+ // Though it should never happen, its a good idea to verify that the damage tracker
+ // does not crash when it receives an empty layerList.
+
+ OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
+ root->createRenderSurface();
+
+ ASSERT_TRUE(root->renderSurface() == root->targetRenderSurface());
+ CCRenderSurface* targetSurface = root->renderSurface();
+ targetSurface->clearLayerList();
+ targetSurface->damageTracker()->updateDamageTrackingState(targetSurface->layerList(), targetSurface->owningLayerId(), false, IntRect(), 0, FilterOperations());
+
+ FloatRect damageRect = targetSurface->damageTracker()->currentDamageRect();
+ EXPECT_TRUE(damageRect.isEmpty());
+}
+
} // namespace