| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/layer_sorter.h" | 5 #include "cc/layer_sorter.h" |
| 6 | 6 |
| 7 #include "cc/layer_impl.h" | 7 #include "cc/layer_impl.h" |
| 8 #include "cc/math_util.h" | 8 #include "cc/math_util.h" |
| 9 #include "cc/single_thread_proxy.h" | 9 #include "cc/single_thread_proxy.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 #include <public/WebTransformationMatrix.h> | 11 #include "ui/gfx/transform.h" |
| 12 | |
| 13 using WebKit::WebTransformationMatrix; | |
| 14 | 12 |
| 15 namespace cc { | 13 namespace cc { |
| 16 namespace { | 14 namespace { |
| 17 | 15 |
| 18 // Note: In the following overlap tests, the "camera" is looking down the negati
ve Z axis, | 16 // Note: In the following overlap tests, the "camera" is looking down the negati
ve Z axis, |
| 19 // meaning that layers with smaller z values (more negative) are further from th
e camera | 17 // meaning that layers with smaller z values (more negative) are further from th
e camera |
| 20 // and therefore must be drawn before layers with higher z values. | 18 // and therefore must be drawn before layers with higher z values. |
| 21 | 19 |
| 22 TEST(LayerSorterTest, BasicOverlap) | 20 TEST(LayerSorterTest, BasicOverlap) |
| 23 { | 21 { |
| 24 LayerSorter::ABCompareResult overlapResult; | 22 LayerSorter::ABCompareResult overlapResult; |
| 25 const float zThreshold = 0.1f; | 23 const float zThreshold = 0.1f; |
| 26 float weight = 0; | 24 float weight = 0; |
| 27 | 25 |
| 28 // Trivial test, with one layer directly obscuring the other. | 26 // Trivial test, with one layer directly obscuring the other. |
| 29 WebTransformationMatrix neg4Translate; | 27 gfx::Transform neg4Translate; |
| 30 neg4Translate.translate3d(0, 0, -4); | 28 neg4Translate.Translate3d(0, 0, -4); |
| 31 LayerShape front(2, 2, neg4Translate); | 29 LayerShape front(2, 2, neg4Translate); |
| 32 | 30 |
| 33 WebTransformationMatrix neg5Translate; | 31 gfx::Transform neg5Translate; |
| 34 neg5Translate.translate3d(0, 0, -5); | 32 neg5Translate.Translate3d(0, 0, -5); |
| 35 LayerShape back(2, 2, neg5Translate); | 33 LayerShape back(2, 2, neg5Translate); |
| 36 | 34 |
| 37 overlapResult = LayerSorter::checkOverlap(&front, &back, zThreshold, weight)
; | 35 overlapResult = LayerSorter::checkOverlap(&front, &back, zThreshold, weight)
; |
| 38 EXPECT_EQ(LayerSorter::BBeforeA, overlapResult); | 36 EXPECT_EQ(LayerSorter::BBeforeA, overlapResult); |
| 39 EXPECT_EQ(1, weight); | 37 EXPECT_EQ(1, weight); |
| 40 | 38 |
| 41 overlapResult = LayerSorter::checkOverlap(&back, &front, zThreshold, weight)
; | 39 overlapResult = LayerSorter::checkOverlap(&back, &front, zThreshold, weight)
; |
| 42 EXPECT_EQ(LayerSorter::ABeforeB, overlapResult); | 40 EXPECT_EQ(LayerSorter::ABeforeB, overlapResult); |
| 43 EXPECT_EQ(1, weight); | 41 EXPECT_EQ(1, weight); |
| 44 | 42 |
| 45 // One layer translated off to the right. No overlap should be detected. | 43 // One layer translated off to the right. No overlap should be detected. |
| 46 WebTransformationMatrix rightTranslate; | 44 gfx::Transform rightTranslate; |
| 47 rightTranslate.translate3d(10, 0, -5); | 45 rightTranslate.Translate3d(10, 0, -5); |
| 48 LayerShape backRight(2, 2, rightTranslate); | 46 LayerShape backRight(2, 2, rightTranslate); |
| 49 overlapResult = LayerSorter::checkOverlap(&front, &backRight, zThreshold, we
ight); | 47 overlapResult = LayerSorter::checkOverlap(&front, &backRight, zThreshold, we
ight); |
| 50 EXPECT_EQ(LayerSorter::None, overlapResult); | 48 EXPECT_EQ(LayerSorter::None, overlapResult); |
| 51 | 49 |
| 52 // When comparing a layer with itself, z difference is always 0. | 50 // When comparing a layer with itself, z difference is always 0. |
| 53 overlapResult = LayerSorter::checkOverlap(&front, &front, zThreshold, weight
); | 51 overlapResult = LayerSorter::checkOverlap(&front, &front, zThreshold, weight
); |
| 54 EXPECT_EQ(0, weight); | 52 EXPECT_EQ(0, weight); |
| 55 } | 53 } |
| 56 | 54 |
| 57 TEST(LayerSorterTest, RightAngleOverlap) | 55 TEST(LayerSorterTest, RightAngleOverlap) |
| 58 { | 56 { |
| 59 LayerSorter::ABCompareResult overlapResult; | 57 LayerSorter::ABCompareResult overlapResult; |
| 60 const float zThreshold = 0.1f; | 58 const float zThreshold = 0.1f; |
| 61 float weight = 0; | 59 float weight = 0; |
| 62 | 60 |
| 63 WebTransformationMatrix perspectiveMatrix; | 61 gfx::Transform perspectiveMatrix; |
| 64 perspectiveMatrix.applyPerspective(1000); | 62 perspectiveMatrix.ApplyPerspectiveDepth(1000); |
| 65 | 63 |
| 66 // Two layers forming a right angle with a perspective viewing transform. | 64 // Two layers forming a right angle with a perspective viewing transform. |
| 67 WebTransformationMatrix leftFaceMatrix; | 65 gfx::Transform leftFaceMatrix; |
| 68 leftFaceMatrix.translate3d(-1, 0, -5); | 66 leftFaceMatrix.Translate3d(-1, 0, -5); |
| 69 leftFaceMatrix.rotate3d(0, 1, 0, -90); | 67 MathUtil::rotateAxisAngle(&leftFaceMatrix, 0, 1, 0, -90); |
| 70 leftFaceMatrix.translate(-1, -1); | 68 leftFaceMatrix.Translate(-1, -1); |
| 71 LayerShape leftFace(2, 2, perspectiveMatrix * leftFaceMatrix); | 69 LayerShape leftFace(2, 2, perspectiveMatrix * leftFaceMatrix); |
| 72 WebTransformationMatrix frontFaceMatrix; | 70 gfx::Transform frontFaceMatrix; |
| 73 frontFaceMatrix.translate3d(0, 0, -4); | 71 frontFaceMatrix.Translate3d(0, 0, -4); |
| 74 frontFaceMatrix.translate(-1, -1); | 72 frontFaceMatrix.Translate(-1, -1); |
| 75 LayerShape frontFace(2, 2, perspectiveMatrix * frontFaceMatrix); | 73 LayerShape frontFace(2, 2, perspectiveMatrix * frontFaceMatrix); |
| 76 | 74 |
| 77 overlapResult = LayerSorter::checkOverlap(&frontFace, &leftFace, zThreshold,
weight); | 75 overlapResult = LayerSorter::checkOverlap(&frontFace, &leftFace, zThreshold,
weight); |
| 78 EXPECT_EQ(LayerSorter::BBeforeA, overlapResult); | 76 EXPECT_EQ(LayerSorter::BBeforeA, overlapResult); |
| 79 } | 77 } |
| 80 | 78 |
| 81 TEST(LayerSorterTest, IntersectingLayerOverlap) | 79 TEST(LayerSorterTest, IntersectingLayerOverlap) |
| 82 { | 80 { |
| 83 LayerSorter::ABCompareResult overlapResult; | 81 LayerSorter::ABCompareResult overlapResult; |
| 84 const float zThreshold = 0.1f; | 82 const float zThreshold = 0.1f; |
| 85 float weight = 0; | 83 float weight = 0; |
| 86 | 84 |
| 87 WebTransformationMatrix perspectiveMatrix; | 85 gfx::Transform perspectiveMatrix; |
| 88 perspectiveMatrix.applyPerspective(1000); | 86 perspectiveMatrix.ApplyPerspectiveDepth(1000); |
| 89 | 87 |
| 90 // Intersecting layers. An explicit order will be returned based on relative
z | 88 // Intersecting layers. An explicit order will be returned based on relative
z |
| 91 // values at the overlapping features but the weight returned should be zero
. | 89 // values at the overlapping features but the weight returned should be zero
. |
| 92 WebTransformationMatrix frontFaceMatrix; | 90 gfx::Transform frontFaceMatrix; |
| 93 frontFaceMatrix.translate3d(0, 0, -4); | 91 frontFaceMatrix.Translate3d(0, 0, -4); |
| 94 frontFaceMatrix.translate(-1, -1); | 92 frontFaceMatrix.Translate(-1, -1); |
| 95 LayerShape frontFace(2, 2, perspectiveMatrix * frontFaceMatrix); | 93 LayerShape frontFace(2, 2, perspectiveMatrix * frontFaceMatrix); |
| 96 | 94 |
| 97 WebTransformationMatrix throughMatrix; | 95 gfx::Transform throughMatrix; |
| 98 throughMatrix.translate3d(0, 0, -4); | 96 throughMatrix.Translate3d(0, 0, -4); |
| 99 throughMatrix.rotate3d(0, 1, 0, 45); | 97 MathUtil::rotateAxisAngle(&throughMatrix, 0, 1, 0, 45); |
| 100 throughMatrix.translate(-1, -1); | 98 throughMatrix.Translate(-1, -1); |
| 101 LayerShape rotatedFace(2, 2, perspectiveMatrix * throughMatrix); | 99 LayerShape rotatedFace(2, 2, perspectiveMatrix * throughMatrix); |
| 102 overlapResult = LayerSorter::checkOverlap(&frontFace, &rotatedFace, zThresho
ld, weight); | 100 overlapResult = LayerSorter::checkOverlap(&frontFace, &rotatedFace, zThresho
ld, weight); |
| 103 EXPECT_NE(LayerSorter::None, overlapResult); | 101 EXPECT_NE(LayerSorter::None, overlapResult); |
| 104 EXPECT_EQ(0, weight); | 102 EXPECT_EQ(0, weight); |
| 105 } | 103 } |
| 106 | 104 |
| 107 TEST(LayerSorterTest, LayersAtAngleOverlap) | 105 TEST(LayerSorterTest, LayersAtAngleOverlap) |
| 108 { | 106 { |
| 109 LayerSorter::ABCompareResult overlapResult; | 107 LayerSorter::ABCompareResult overlapResult; |
| 110 const float zThreshold = 0.1f; | 108 const float zThreshold = 0.1f; |
| 111 float weight = 0; | 109 float weight = 0; |
| 112 | 110 |
| 113 // Trickier test with layers at an angle. | 111 // Trickier test with layers at an angle. |
| 114 // | 112 // |
| 115 // -x . . . . 0 . . . . +x | 113 // -x . . . . 0 . . . . +x |
| 116 // -z / | 114 // -z / |
| 117 // : /----B---- | 115 // : /----B---- |
| 118 // 0 C | 116 // 0 C |
| 119 // : ----A----/ | 117 // : ----A----/ |
| 120 // +z / | 118 // +z / |
| 121 // | 119 // |
| 122 // C is in front of A and behind B (not what you'd expect by comparing cente
rs). | 120 // C is in front of A and behind B (not what you'd expect by comparing cente
rs). |
| 123 // A and B don't overlap, so they're incomparable. | 121 // A and B don't overlap, so they're incomparable. |
| 124 | 122 |
| 125 WebTransformationMatrix transformA; | 123 gfx::Transform transformA; |
| 126 transformA.translate3d(-6, 0, 1); | 124 transformA.Translate3d(-6, 0, 1); |
| 127 transformA.translate(-4, -10); | 125 transformA.Translate(-4, -10); |
| 128 LayerShape layerA(8, 20, transformA); | 126 LayerShape layerA(8, 20, transformA); |
| 129 | 127 |
| 130 WebTransformationMatrix transformB; | 128 gfx::Transform transformB; |
| 131 transformB.translate3d(6, 0, -1); | 129 transformB.Translate3d(6, 0, -1); |
| 132 transformB.translate(-4, -10); | 130 transformB.Translate(-4, -10); |
| 133 LayerShape layerB(8, 20, transformB); | 131 LayerShape layerB(8, 20, transformB); |
| 134 | 132 |
| 135 WebTransformationMatrix transformC; | 133 gfx::Transform transformC; |
| 136 transformC.rotate3d(0, 1, 0, 40); | 134 MathUtil::rotateAxisAngle(&transformC, 0, 1, 0, 40); |
| 137 transformC.translate(-4, -10); | 135 transformC.Translate(-4, -10); |
| 138 LayerShape layerC(8, 20, transformC); | 136 LayerShape layerC(8, 20, transformC); |
| 139 | 137 |
| 140 overlapResult = LayerSorter::checkOverlap(&layerA, &layerC, zThreshold, weig
ht); | 138 overlapResult = LayerSorter::checkOverlap(&layerA, &layerC, zThreshold, weig
ht); |
| 141 EXPECT_EQ(LayerSorter::ABeforeB, overlapResult); | 139 EXPECT_EQ(LayerSorter::ABeforeB, overlapResult); |
| 142 overlapResult = LayerSorter::checkOverlap(&layerC, &layerB, zThreshold, weig
ht); | 140 overlapResult = LayerSorter::checkOverlap(&layerC, &layerB, zThreshold, weig
ht); |
| 143 EXPECT_EQ(LayerSorter::ABeforeB, overlapResult); | 141 EXPECT_EQ(LayerSorter::ABeforeB, overlapResult); |
| 144 overlapResult = LayerSorter::checkOverlap(&layerA, &layerB, zThreshold, weig
ht); | 142 overlapResult = LayerSorter::checkOverlap(&layerA, &layerB, zThreshold, weig
ht); |
| 145 EXPECT_EQ(LayerSorter::None, overlapResult); | 143 EXPECT_EQ(LayerSorter::None, overlapResult); |
| 146 } | 144 } |
| 147 | 145 |
| 148 TEST(LayerSorterTest, LayersUnderPathologicalPerspectiveTransform) | 146 TEST(LayerSorterTest, LayersUnderPathologicalPerspectiveTransform) |
| 149 { | 147 { |
| 150 LayerSorter::ABCompareResult overlapResult; | 148 LayerSorter::ABCompareResult overlapResult; |
| 151 const float zThreshold = 0.1f; | 149 const float zThreshold = 0.1f; |
| 152 float weight = 0; | 150 float weight = 0; |
| 153 | 151 |
| 154 // On perspective projection, if w becomes negative, the re-projected point
will be | 152 // On perspective projection, if w becomes negative, the re-projected point
will be |
| 155 // invalid and un-usable. Correct code needs to clip away portions of the ge
ometry | 153 // invalid and un-usable. Correct code needs to clip away portions of the ge
ometry |
| 156 // where w < 0. If the code uses the invalid value, it will think that a lay
er has | 154 // where w < 0. If the code uses the invalid value, it will think that a lay
er has |
| 157 // different bounds than it really does, which can cause things to sort inco
rrectly. | 155 // different bounds than it really does, which can cause things to sort inco
rrectly. |
| 158 | 156 |
| 159 WebTransformationMatrix perspectiveMatrix; | 157 gfx::Transform perspectiveMatrix; |
| 160 perspectiveMatrix.applyPerspective(1); | 158 perspectiveMatrix.ApplyPerspectiveDepth(1); |
| 161 | 159 |
| 162 WebTransformationMatrix transformA; | 160 gfx::Transform transformA; |
| 163 transformA.translate3d(-15, 0, -2); | 161 transformA.Translate3d(-15, 0, -2); |
| 164 transformA.translate(-5, -5); | 162 transformA.Translate(-5, -5); |
| 165 LayerShape layerA(10, 10, perspectiveMatrix * transformA); | 163 LayerShape layerA(10, 10, perspectiveMatrix * transformA); |
| 166 | 164 |
| 167 // With this sequence of transforms, when layer B is correctly clipped, it w
ill be | 165 // With this sequence of transforms, when layer B is correctly clipped, it w
ill be |
| 168 // visible on the left half of the projection plane, in front of layerA. Whe
n it is | 166 // visible on the left half of the projection plane, in front of layerA. Whe
n it is |
| 169 // not clipped, its bounds will actually incorrectly appear much smaller and
the | 167 // not clipped, its bounds will actually incorrectly appear much smaller and
the |
| 170 // correct sorting dependency will not be found. | 168 // correct sorting dependency will not be found. |
| 171 WebTransformationMatrix transformB; | 169 gfx::Transform transformB; |
| 172 transformB.translate3d(0, 0, 0.7); | 170 transformB.Translate3d(0, 0, 0.7); |
| 173 transformB.rotate3d(0, 45, 0); | 171 MathUtil::rotateEulerAngles(&transformB, 0, 45, 0); |
| 174 transformB.translate(-5, -5); | 172 transformB.Translate(-5, -5); |
| 175 LayerShape layerB(10, 10, perspectiveMatrix * transformB); | 173 LayerShape layerB(10, 10, perspectiveMatrix * transformB); |
| 176 | 174 |
| 177 // Sanity check that the test case actually covers the intended scenario, wh
ere part | 175 // Sanity check that the test case actually covers the intended scenario, wh
ere part |
| 178 // of layer B go behind the w = 0 plane. | 176 // of layer B go behind the w = 0 plane. |
| 179 gfx::QuadF testQuad = gfx::QuadF(gfx::RectF(-0.5, -0.5, 1, 1)); | 177 gfx::QuadF testQuad = gfx::QuadF(gfx::RectF(-0.5, -0.5, 1, 1)); |
| 180 bool clipped = false; | 178 bool clipped = false; |
| 181 MathUtil::mapQuad(perspectiveMatrix * transformB, testQuad, clipped); | 179 MathUtil::mapQuad(perspectiveMatrix * transformB, testQuad, clipped); |
| 182 ASSERT_TRUE(clipped); | 180 ASSERT_TRUE(clipped); |
| 183 | 181 |
| 184 overlapResult = LayerSorter::checkOverlap(&layerA, &layerB, zThreshold, weig
ht); | 182 overlapResult = LayerSorter::checkOverlap(&layerA, &layerB, zThreshold, weig
ht); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 198 // - 1, 2, and 5 do not have a 3d z difference, and therefore their relat
ive ordering should be retained. | 196 // - 1, 2, and 5 do not have a 3d z difference, and therefore their relat
ive ordering should be retained. |
| 199 // - 3 and 4 do not have a 3d z difference, and therefore their relative
ordering should be retained. | 197 // - 3 and 4 do not have a 3d z difference, and therefore their relative
ordering should be retained. |
| 200 // - 3 and 4 should be re-sorted so they are in front of 1, 2, and 5. | 198 // - 3 and 4 should be re-sorted so they are in front of 1, 2, and 5. |
| 201 | 199 |
| 202 scoped_ptr<LayerImpl> layer1 = LayerImpl::create(1); | 200 scoped_ptr<LayerImpl> layer1 = LayerImpl::create(1); |
| 203 scoped_ptr<LayerImpl> layer2 = LayerImpl::create(2); | 201 scoped_ptr<LayerImpl> layer2 = LayerImpl::create(2); |
| 204 scoped_ptr<LayerImpl> layer3 = LayerImpl::create(3); | 202 scoped_ptr<LayerImpl> layer3 = LayerImpl::create(3); |
| 205 scoped_ptr<LayerImpl> layer4 = LayerImpl::create(4); | 203 scoped_ptr<LayerImpl> layer4 = LayerImpl::create(4); |
| 206 scoped_ptr<LayerImpl> layer5 = LayerImpl::create(5); | 204 scoped_ptr<LayerImpl> layer5 = LayerImpl::create(5); |
| 207 | 205 |
| 208 WebTransformationMatrix BehindMatrix; | 206 gfx::Transform BehindMatrix; |
| 209 BehindMatrix.translate3d(0, 0, 2); | 207 BehindMatrix.Translate3d(0, 0, 2); |
| 210 WebTransformationMatrix FrontMatrix; | 208 gfx::Transform FrontMatrix; |
| 211 FrontMatrix.translate3d(0, 0, 1); | 209 FrontMatrix.Translate3d(0, 0, 1); |
| 212 | 210 |
| 213 layer1->setBounds(gfx::Size(10, 10)); | 211 layer1->setBounds(gfx::Size(10, 10)); |
| 214 layer1->setContentBounds(gfx::Size(10, 10)); | 212 layer1->setContentBounds(gfx::Size(10, 10)); |
| 215 layer1->setDrawTransform(BehindMatrix); | 213 layer1->setDrawTransform(BehindMatrix); |
| 216 layer1->setDrawsContent(true); | 214 layer1->setDrawsContent(true); |
| 217 | 215 |
| 218 layer2->setBounds(gfx::Size(20, 20)); | 216 layer2->setBounds(gfx::Size(20, 20)); |
| 219 layer2->setContentBounds(gfx::Size(20, 20)); | 217 layer2->setContentBounds(gfx::Size(20, 20)); |
| 220 layer2->setDrawTransform(BehindMatrix); | 218 layer2->setDrawTransform(BehindMatrix); |
| 221 layer2->setDrawsContent(true); | 219 layer2->setDrawsContent(true); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 ASSERT_EQ(static_cast<size_t>(5), layerList.size()); | 253 ASSERT_EQ(static_cast<size_t>(5), layerList.size()); |
| 256 EXPECT_EQ(3, layerList[0]->id()); | 254 EXPECT_EQ(3, layerList[0]->id()); |
| 257 EXPECT_EQ(4, layerList[1]->id()); | 255 EXPECT_EQ(4, layerList[1]->id()); |
| 258 EXPECT_EQ(1, layerList[2]->id()); | 256 EXPECT_EQ(1, layerList[2]->id()); |
| 259 EXPECT_EQ(2, layerList[3]->id()); | 257 EXPECT_EQ(2, layerList[3]->id()); |
| 260 EXPECT_EQ(5, layerList[4]->id()); | 258 EXPECT_EQ(5, layerList[4]->id()); |
| 261 } | 259 } |
| 262 | 260 |
| 263 } // namespace | 261 } // namespace |
| 264 } // namespace cc | 262 } // namespace cc |
| OLD | NEW |