diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-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.cpp | 260 |
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 |