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 |