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