diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-12 19:40:56 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-12 19:40:56 +0000 |
commit | c79f147c0474a311a83829a44b55aaffa42c6237 (patch) | |
tree | 8bb41fcb74068042828da31c279b0d53dd0844fa /cc/layer_sorter_unittest.cc | |
parent | e62f2909e0aabf37131a65c7e50e85c1f07473f8 (diff) | |
download | chromium_src-c79f147c0474a311a83829a44b55aaffa42c6237.zip chromium_src-c79f147c0474a311a83829a44b55aaffa42c6237.tar.gz chromium_src-c79f147c0474a311a83829a44b55aaffa42c6237.tar.bz2 |
[cc] Change cc_tests.gyp filenames to Chromium style
BUG=155413
Review URL: https://codereview.chromium.org/11108020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161642 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/layer_sorter_unittest.cc')
-rw-r--r-- | cc/layer_sorter_unittest.cc | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/cc/layer_sorter_unittest.cc b/cc/layer_sorter_unittest.cc new file mode 100644 index 0000000..e2bb912 --- /dev/null +++ b/cc/layer_sorter_unittest.cc @@ -0,0 +1,267 @@ +// Copyright 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#include "CCLayerSorter.h" + +#include "CCLayerImpl.h" +#include "CCMathUtil.h" +#include "CCSingleThreadProxy.h" +#include "testing/gtest/include/gtest/gtest.h" +#include <public/WebTransformationMatrix.h> + +using namespace cc; +using WebKit::WebTransformationMatrix; + +namespace { + +// Note: In the following overlap tests, the "camera" is looking down the negative Z axis, +// meaning that layers with smaller z values (more negative) are further from the camera +// and therefore must be drawn before layers with higher z values. + +TEST(CCLayerSorterTest, BasicOverlap) +{ + CCLayerSorter::ABCompareResult overlapResult; + const float zThreshold = 0.1f; + float weight = 0; + + // Trivial test, with one layer directly obscuring the other. + WebTransformationMatrix neg4Translate; + neg4Translate.translate3d(0, 0, -4); + CCLayerSorter::LayerShape front(2, 2, neg4Translate); + + WebTransformationMatrix neg5Translate; + neg5Translate.translate3d(0, 0, -5); + CCLayerSorter::LayerShape back(2, 2, neg5Translate); + + overlapResult = CCLayerSorter::checkOverlap(&front, &back, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::BBeforeA, overlapResult); + EXPECT_EQ(1, weight); + + overlapResult = CCLayerSorter::checkOverlap(&back, &front, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::ABeforeB, overlapResult); + EXPECT_EQ(1, weight); + + // One layer translated off to the right. No overlap should be detected. + WebTransformationMatrix rightTranslate; + rightTranslate.translate3d(10, 0, -5); + CCLayerSorter::LayerShape backRight(2, 2, rightTranslate); + overlapResult = CCLayerSorter::checkOverlap(&front, &backRight, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::None, overlapResult); + + // When comparing a layer with itself, z difference is always 0. + overlapResult = CCLayerSorter::checkOverlap(&front, &front, zThreshold, weight); + EXPECT_EQ(0, weight); +} + +TEST(CCLayerSorterTest, RightAngleOverlap) +{ + CCLayerSorter::ABCompareResult overlapResult; + const float zThreshold = 0.1f; + float weight = 0; + + WebTransformationMatrix perspectiveMatrix; + perspectiveMatrix.applyPerspective(1000); + + // Two layers forming a right angle with a perspective viewing transform. + WebTransformationMatrix leftFaceMatrix; + leftFaceMatrix.rotate3d(0, 1, 0, -90); + leftFaceMatrix.translateRight3d(-1, 0, -5); + leftFaceMatrix.translate(-1, -1); + CCLayerSorter::LayerShape leftFace(2, 2, perspectiveMatrix * leftFaceMatrix); + WebTransformationMatrix frontFaceMatrix; + frontFaceMatrix.translate3d(0, 0, -4); + frontFaceMatrix.translate(-1, -1); + CCLayerSorter::LayerShape frontFace(2, 2, perspectiveMatrix * frontFaceMatrix); + + overlapResult = CCLayerSorter::checkOverlap(&frontFace, &leftFace, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::BBeforeA, overlapResult); +} + +TEST(CCLayerSorterTest, IntersectingLayerOverlap) +{ + CCLayerSorter::ABCompareResult overlapResult; + const float zThreshold = 0.1f; + float weight = 0; + + WebTransformationMatrix perspectiveMatrix; + perspectiveMatrix.applyPerspective(1000); + + // Intersecting layers. An explicit order will be returned based on relative z + // values at the overlapping features but the weight returned should be zero. + WebTransformationMatrix frontFaceMatrix; + frontFaceMatrix.translate3d(0, 0, -4); + frontFaceMatrix.translate(-1, -1); + CCLayerSorter::LayerShape frontFace(2, 2, perspectiveMatrix * frontFaceMatrix); + + WebTransformationMatrix throughMatrix; + throughMatrix.rotate3d(0, 1, 0, 45); + throughMatrix.translateRight3d(0, 0, -4); + throughMatrix.translate(-1, -1); + CCLayerSorter::LayerShape rotatedFace(2, 2, perspectiveMatrix * throughMatrix); + overlapResult = CCLayerSorter::checkOverlap(&frontFace, &rotatedFace, zThreshold, weight); + EXPECT_NE(CCLayerSorter::None, overlapResult); + EXPECT_EQ(0, weight); +} + +TEST(CCLayerSorterTest, LayersAtAngleOverlap) +{ + CCLayerSorter::ABCompareResult overlapResult; + const float zThreshold = 0.1f; + float weight = 0; + + // Trickier test with layers at an angle. + // + // -x . . . . 0 . . . . +x + // -z / + // : /----B---- + // 0 C + // : ----A----/ + // +z / + // + // C is in front of A and behind B (not what you'd expect by comparing centers). + // A and B don't overlap, so they're incomparable. + + WebTransformationMatrix transformA; + transformA.translate3d(-6, 0, 1); + transformA.translate(-4, -10); + CCLayerSorter::LayerShape layerA(8, 20, transformA); + + WebTransformationMatrix transformB; + transformB.translate3d(6, 0, -1); + transformB.translate(-4, -10); + CCLayerSorter::LayerShape layerB(8, 20, transformB); + + WebTransformationMatrix transformC; + transformC.rotate3d(0, 1, 0, 40); + transformC.translate(-4, -10); + CCLayerSorter::LayerShape layerC(8, 20, transformC); + + overlapResult = CCLayerSorter::checkOverlap(&layerA, &layerC, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::ABeforeB, overlapResult); + overlapResult = CCLayerSorter::checkOverlap(&layerC, &layerB, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::ABeforeB, overlapResult); + overlapResult = CCLayerSorter::checkOverlap(&layerA, &layerB, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::None, overlapResult); +} + +TEST(CCLayerSorterTest, LayersUnderPathologicalPerspectiveTransform) +{ + CCLayerSorter::ABCompareResult overlapResult; + const float zThreshold = 0.1f; + float weight = 0; + + // On perspective projection, if w becomes negative, the re-projected point will be + // invalid and un-usable. Correct code needs to clip away portions of the geometry + // where w < 0. If the code uses the invalid value, it will think that a layer has + // different bounds than it really does, which can cause things to sort incorrectly. + + WebTransformationMatrix perspectiveMatrix; + perspectiveMatrix.applyPerspective(1); + + WebTransformationMatrix transformA; + transformA.translate3d(-15, 0, -2); + transformA.translate(-5, -5); + CCLayerSorter::LayerShape layerA(10, 10, perspectiveMatrix * transformA); + + // With this sequence of transforms, when layer B is correctly clipped, it will be + // visible on the left half of the projection plane, in front of layerA. When it is + // not clipped, its bounds will actually incorrectly appear much smaller and the + // correct sorting dependency will not be found. + WebTransformationMatrix transformB; + transformB.translate3d(0, 0, 0.7); + transformB.rotate3d(0, 45, 0); + transformB.translate(-5, -5); + CCLayerSorter::LayerShape layerB(10, 10, perspectiveMatrix * transformB); + + // Sanity check that the test case actually covers the intended scenario, where part + // of layer B go behind the w = 0 plane. + FloatQuad testQuad = FloatQuad(FloatRect(FloatPoint(-0.5, -0.5), FloatSize(1, 1))); + bool clipped = false; + CCMathUtil::mapQuad(perspectiveMatrix * transformB, testQuad, clipped); + ASSERT_TRUE(clipped); + + overlapResult = CCLayerSorter::checkOverlap(&layerA, &layerB, zThreshold, weight); + EXPECT_EQ(CCLayerSorter::ABeforeB, overlapResult); +} + +TEST(CCLayerSorterTest, verifyExistingOrderingPreservedWhenNoZDiff) +{ + DebugScopedSetImplThread thisScopeIsOnImplThread; + + // If there is no reason to re-sort the layers (i.e. no 3d z difference), then the + // existing ordering provided on input should be retained. This test covers the fix in + // https://bugs.webkit.org/show_bug.cgi?id=75046. Before this fix, ordering was + // accidentally reversed, causing bugs in z-index ordering on websites when + // preserves3D triggered the CCLayerSorter. + + // Input list of layers: [1, 2, 3, 4, 5]. + // Expected output: [3, 4, 1, 2, 5]. + // - 1, 2, and 5 do not have a 3d z difference, and therefore their relative ordering should be retained. + // - 3 and 4 do not have a 3d z difference, and therefore their relative ordering should be retained. + // - 3 and 4 should be re-sorted so they are in front of 1, 2, and 5. + + scoped_ptr<CCLayerImpl> layer1 = CCLayerImpl::create(1); + scoped_ptr<CCLayerImpl> layer2 = CCLayerImpl::create(2); + scoped_ptr<CCLayerImpl> layer3 = CCLayerImpl::create(3); + scoped_ptr<CCLayerImpl> layer4 = CCLayerImpl::create(4); + scoped_ptr<CCLayerImpl> layer5 = CCLayerImpl::create(5); + + WebTransformationMatrix BehindMatrix; + BehindMatrix.translate3d(0, 0, 2); + WebTransformationMatrix FrontMatrix; + FrontMatrix.translate3d(0, 0, 1); + + layer1->setBounds(IntSize(10, 10)); + layer1->setContentBounds(IntSize(10, 10)); + layer1->setDrawTransform(BehindMatrix); + layer1->setDrawsContent(true); + + layer2->setBounds(IntSize(20, 20)); + layer2->setContentBounds(IntSize(20, 20)); + layer2->setDrawTransform(BehindMatrix); + layer2->setDrawsContent(true); + + layer3->setBounds(IntSize(30, 30)); + layer3->setContentBounds(IntSize(30, 30)); + layer3->setDrawTransform(FrontMatrix); + layer3->setDrawsContent(true); + + layer4->setBounds(IntSize(40, 40)); + layer4->setContentBounds(IntSize(40, 40)); + layer4->setDrawTransform(FrontMatrix); + layer4->setDrawsContent(true); + + layer5->setBounds(IntSize(50, 50)); + layer5->setContentBounds(IntSize(50, 50)); + layer5->setDrawTransform(BehindMatrix); + layer5->setDrawsContent(true); + + std::vector<CCLayerImpl*> layerList; + layerList.push_back(layer1.get()); + layerList.push_back(layer2.get()); + layerList.push_back(layer3.get()); + layerList.push_back(layer4.get()); + layerList.push_back(layer5.get()); + + ASSERT_EQ(static_cast<size_t>(5), layerList.size()); + EXPECT_EQ(1, layerList[0]->id()); + EXPECT_EQ(2, layerList[1]->id()); + EXPECT_EQ(3, layerList[2]->id()); + EXPECT_EQ(4, layerList[3]->id()); + EXPECT_EQ(5, layerList[4]->id()); + + CCLayerSorter layerSorter; + layerSorter.sort(layerList.begin(), layerList.end()); + + ASSERT_EQ(static_cast<size_t>(5), layerList.size()); + EXPECT_EQ(3, layerList[0]->id()); + EXPECT_EQ(4, layerList[1]->id()); + EXPECT_EQ(1, layerList[2]->id()); + EXPECT_EQ(2, layerList[3]->id()); + EXPECT_EQ(5, layerList[4]->id()); +} + +} // namespace |