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 |