OLD | NEW |
| (Empty) |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/trees/occlusion_tracker.h" | |
6 | |
7 #include "cc/animation/layer_animation_controller.h" | |
8 #include "cc/base/math_util.h" | |
9 #include "cc/layers/layer.h" | |
10 #include "cc/layers/layer_impl.h" | |
11 #include "cc/output/copy_output_request.h" | |
12 #include "cc/output/copy_output_result.h" | |
13 #include "cc/output/filter_operation.h" | |
14 #include "cc/output/filter_operations.h" | |
15 #include "cc/test/animation_test_common.h" | |
16 #include "cc/test/fake_impl_proxy.h" | |
17 #include "cc/test/fake_layer_tree_host.h" | |
18 #include "cc/test/fake_layer_tree_host_impl.h" | |
19 #include "cc/test/geometry_test_utils.h" | |
20 #include "cc/test/test_occlusion_tracker.h" | |
21 #include "cc/trees/layer_tree_host_common.h" | |
22 #include "cc/trees/single_thread_proxy.h" | |
23 #include "testing/gmock/include/gmock/gmock.h" | |
24 #include "testing/gtest/include/gtest/gtest.h" | |
25 #include "ui/gfx/transform.h" | |
26 | |
27 namespace cc { | |
28 namespace { | |
29 | |
30 class TestContentLayer : public Layer { | |
31 public: | |
32 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) { | |
33 SetIsDrawable(true); | |
34 } | |
35 | |
36 SimpleEnclosedRegion VisibleContentOpaqueRegion() const override { | |
37 if (override_opaque_contents_rect_) { | |
38 return SimpleEnclosedRegion( | |
39 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect())); | |
40 } | |
41 return Layer::VisibleContentOpaqueRegion(); | |
42 } | |
43 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { | |
44 override_opaque_contents_rect_ = true; | |
45 opaque_contents_rect_ = opaque_contents_rect; | |
46 } | |
47 | |
48 private: | |
49 ~TestContentLayer() override {} | |
50 | |
51 bool override_opaque_contents_rect_; | |
52 gfx::Rect opaque_contents_rect_; | |
53 }; | |
54 | |
55 class TestContentLayerImpl : public LayerImpl { | |
56 public: | |
57 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id) | |
58 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) { | |
59 SetDrawsContent(true); | |
60 } | |
61 | |
62 SimpleEnclosedRegion VisibleContentOpaqueRegion() const override { | |
63 if (override_opaque_contents_rect_) { | |
64 return SimpleEnclosedRegion( | |
65 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect())); | |
66 } | |
67 return LayerImpl::VisibleContentOpaqueRegion(); | |
68 } | |
69 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { | |
70 override_opaque_contents_rect_ = true; | |
71 opaque_contents_rect_ = opaque_contents_rect; | |
72 } | |
73 | |
74 private: | |
75 bool override_opaque_contents_rect_; | |
76 gfx::Rect opaque_contents_rect_; | |
77 }; | |
78 | |
79 template <typename LayerType> | |
80 class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> { | |
81 public: | |
82 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect) | |
83 : TestOcclusionTracker<LayerType>(viewport_rect) {} | |
84 | |
85 bool OccludedLayer(const LayerType* layer, | |
86 const gfx::Rect& content_rect) const { | |
87 DCHECK(layer->visible_content_rect().Contains(content_rect)); | |
88 return this->GetCurrentOcclusionForLayer(layer->draw_transform()) | |
89 .IsOccluded(content_rect); | |
90 } | |
91 | |
92 // Gives an unoccluded sub-rect of |content_rect| in the content space of the | |
93 // layer. Simple wrapper around GetUnoccludedContentRect. | |
94 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer, | |
95 const gfx::Rect& content_rect) const { | |
96 DCHECK(layer->visible_content_rect().Contains(content_rect)); | |
97 return this->GetCurrentOcclusionForLayer(layer->draw_transform()) | |
98 .GetUnoccludedContentRect(content_rect); | |
99 } | |
100 | |
101 gfx::Rect UnoccludedSurfaceContentRect(const LayerType* layer, | |
102 const gfx::Rect& content_rect) const { | |
103 typename LayerType::RenderSurfaceType* surface = layer->render_surface(); | |
104 return this->GetCurrentOcclusionForContributingSurface( | |
105 surface->draw_transform()) | |
106 .GetUnoccludedContentRect(content_rect); | |
107 } | |
108 }; | |
109 | |
110 struct OcclusionTrackerTestMainThreadTypes { | |
111 typedef Layer LayerType; | |
112 typedef FakeLayerTreeHost HostType; | |
113 typedef RenderSurface RenderSurfaceType; | |
114 typedef TestContentLayer ContentLayerType; | |
115 typedef scoped_refptr<Layer> LayerPtrType; | |
116 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType; | |
117 typedef LayerIterator<Layer> TestLayerIterator; | |
118 typedef OcclusionTracker<Layer> OcclusionTrackerType; | |
119 | |
120 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); } | |
121 static ContentLayerPtrType CreateContentLayer(HostType* host) { | |
122 return make_scoped_refptr(new ContentLayerType()); | |
123 } | |
124 | |
125 template <typename T> | |
126 static LayerPtrType PassLayerPtr(T* layer) { | |
127 LayerPtrType ref(*layer); | |
128 *layer = NULL; | |
129 return ref; | |
130 } | |
131 static void SetForceRenderSurface(LayerType* layer, bool force) { | |
132 layer->SetForceRenderSurface(force); | |
133 } | |
134 | |
135 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; } | |
136 | |
137 static void RecursiveUpdateNumChildren(LayerType* layerType) {} | |
138 }; | |
139 | |
140 struct OcclusionTrackerTestImplThreadTypes { | |
141 typedef LayerImpl LayerType; | |
142 typedef LayerTreeImpl HostType; | |
143 typedef RenderSurfaceImpl RenderSurfaceType; | |
144 typedef TestContentLayerImpl ContentLayerType; | |
145 typedef scoped_ptr<LayerImpl> LayerPtrType; | |
146 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType; | |
147 typedef LayerIterator<LayerImpl> TestLayerIterator; | |
148 typedef OcclusionTracker<LayerImpl> OcclusionTrackerType; | |
149 | |
150 static LayerPtrType CreateLayer(HostType* host) { | |
151 return LayerImpl::Create(host, next_layer_impl_id++); | |
152 } | |
153 static ContentLayerPtrType CreateContentLayer(HostType* host) { | |
154 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++)); | |
155 } | |
156 static int next_layer_impl_id; | |
157 | |
158 template <typename T> | |
159 static LayerPtrType PassLayerPtr(T* layer) { | |
160 return layer->Pass(); | |
161 } | |
162 | |
163 static void SetForceRenderSurface(LayerType* layer, bool force) { | |
164 layer->SetHasRenderSurface(force); | |
165 } | |
166 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); } | |
167 | |
168 static void RecursiveUpdateNumChildren(LayerType* layer) { | |
169 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer); | |
170 } | |
171 }; | |
172 | |
173 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1; | |
174 | |
175 template <typename Types> class OcclusionTrackerTest : public testing::Test { | |
176 protected: | |
177 explicit OcclusionTrackerTest(bool opaque_layers) | |
178 : opaque_layers_(opaque_layers), | |
179 client_(FakeLayerTreeHostClient::DIRECT_3D), | |
180 host_(FakeLayerTreeHost::Create(&client_)) {} | |
181 | |
182 virtual void RunMyTest() = 0; | |
183 | |
184 void TearDown() override { DestroyLayers(); } | |
185 | |
186 typename Types::HostType* GetHost(); | |
187 | |
188 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform, | |
189 const gfx::PointF& position, | |
190 const gfx::Size& bounds) { | |
191 typename Types::ContentLayerPtrType layer( | |
192 Types::CreateContentLayer(GetHost())); | |
193 typename Types::ContentLayerType* layer_ptr = layer.get(); | |
194 SetProperties(layer_ptr, transform, position, bounds); | |
195 | |
196 DCHECK(!root_.get()); | |
197 root_ = Types::PassLayerPtr(&layer); | |
198 | |
199 Types::SetForceRenderSurface(layer_ptr, true); | |
200 SetRootLayerOnMainThread(layer_ptr); | |
201 | |
202 return layer_ptr; | |
203 } | |
204 | |
205 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent, | |
206 const gfx::Transform& transform, | |
207 const gfx::PointF& position, | |
208 const gfx::Size& bounds) { | |
209 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost())); | |
210 typename Types::LayerType* layer_ptr = layer.get(); | |
211 SetProperties(layer_ptr, transform, position, bounds); | |
212 parent->AddChild(Types::PassLayerPtr(&layer)); | |
213 return layer_ptr; | |
214 } | |
215 | |
216 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent, | |
217 const gfx::Transform& transform, | |
218 const gfx::PointF& position, | |
219 const gfx::Size& bounds) { | |
220 typename Types::LayerType* layer = | |
221 CreateLayer(parent, transform, position, bounds); | |
222 Types::SetForceRenderSurface(layer, true); | |
223 return layer; | |
224 } | |
225 | |
226 typename Types::ContentLayerType* CreateDrawingLayer( | |
227 typename Types::LayerType* parent, | |
228 const gfx::Transform& transform, | |
229 const gfx::PointF& position, | |
230 const gfx::Size& bounds, | |
231 bool opaque) { | |
232 typename Types::ContentLayerPtrType layer( | |
233 Types::CreateContentLayer(GetHost())); | |
234 typename Types::ContentLayerType* layer_ptr = layer.get(); | |
235 SetProperties(layer_ptr, transform, position, bounds); | |
236 | |
237 if (opaque_layers_) { | |
238 layer_ptr->SetContentsOpaque(opaque); | |
239 } else { | |
240 layer_ptr->SetContentsOpaque(false); | |
241 if (opaque) | |
242 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds)); | |
243 else | |
244 layer_ptr->SetOpaqueContentsRect(gfx::Rect()); | |
245 } | |
246 | |
247 parent->AddChild(Types::PassLayerPtr(&layer)); | |
248 return layer_ptr; | |
249 } | |
250 | |
251 typename Types::LayerType* CreateReplicaLayer( | |
252 typename Types::LayerType* owning_layer, | |
253 const gfx::Transform& transform, | |
254 const gfx::PointF& position, | |
255 const gfx::Size& bounds) { | |
256 typename Types::ContentLayerPtrType layer( | |
257 Types::CreateContentLayer(GetHost())); | |
258 typename Types::ContentLayerType* layer_ptr = layer.get(); | |
259 SetProperties(layer_ptr, transform, position, bounds); | |
260 SetReplica(owning_layer, Types::PassLayerPtr(&layer)); | |
261 return layer_ptr; | |
262 } | |
263 | |
264 typename Types::LayerType* CreateMaskLayer( | |
265 typename Types::LayerType* owning_layer, | |
266 const gfx::Size& bounds) { | |
267 typename Types::ContentLayerPtrType layer( | |
268 Types::CreateContentLayer(GetHost())); | |
269 typename Types::ContentLayerType* layer_ptr = layer.get(); | |
270 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds); | |
271 SetMask(owning_layer, Types::PassLayerPtr(&layer)); | |
272 return layer_ptr; | |
273 } | |
274 | |
275 typename Types::ContentLayerType* CreateDrawingSurface( | |
276 typename Types::LayerType* parent, | |
277 const gfx::Transform& transform, | |
278 const gfx::PointF& position, | |
279 const gfx::Size& bounds, | |
280 bool opaque) { | |
281 typename Types::ContentLayerType* layer = | |
282 CreateDrawingLayer(parent, transform, position, bounds, opaque); | |
283 Types::SetForceRenderSurface(layer, true); | |
284 return layer; | |
285 } | |
286 | |
287 void DestroyLayers() { | |
288 Types::DestroyLayer(&root_); | |
289 render_surface_layer_list_ = nullptr; | |
290 render_surface_layer_list_impl_.clear(); | |
291 replica_layers_.clear(); | |
292 mask_layers_.clear(); | |
293 ResetLayerIterator(); | |
294 } | |
295 | |
296 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} | |
297 | |
298 void AddCopyRequest(Layer* layer) { | |
299 layer->RequestCopyOfOutput( | |
300 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
301 &OcclusionTrackerTest<Types>::CopyOutputCallback, | |
302 base::Unretained(this)))); | |
303 } | |
304 | |
305 void AddCopyRequest(LayerImpl* layer) { | |
306 ScopedPtrVector<CopyOutputRequest> requests; | |
307 requests.push_back( | |
308 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
309 &OcclusionTrackerTest<Types>::CopyOutputCallback, | |
310 base::Unretained(this)))); | |
311 layer->SetHasRenderSurface(true); | |
312 layer->PassCopyRequests(&requests); | |
313 } | |
314 | |
315 void CalcDrawEtc(TestContentLayerImpl* root) { | |
316 DCHECK(root == root_.get()); | |
317 | |
318 Types::RecursiveUpdateNumChildren(root); | |
319 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( | |
320 root, root->bounds(), &render_surface_layer_list_impl_); | |
321 inputs.can_adjust_raster_scales = true; | |
322 LayerTreeHostCommon::CalculateDrawProperties(&inputs); | |
323 | |
324 layer_iterator_ = layer_iterator_begin_ = | |
325 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_); | |
326 } | |
327 | |
328 void CalcDrawEtc(TestContentLayer* root) { | |
329 DCHECK(root == root_.get()); | |
330 DCHECK(!root->render_surface()); | |
331 | |
332 render_surface_layer_list_.reset(new RenderSurfaceLayerList); | |
333 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( | |
334 root, root->bounds(), render_surface_layer_list_.get()); | |
335 inputs.can_adjust_raster_scales = true; | |
336 LayerTreeHostCommon::CalculateDrawProperties(&inputs); | |
337 | |
338 layer_iterator_ = layer_iterator_begin_ = | |
339 Types::TestLayerIterator::Begin(render_surface_layer_list_.get()); | |
340 } | |
341 | |
342 void EnterLayer(typename Types::LayerType* layer, | |
343 typename Types::OcclusionTrackerType* occlusion) { | |
344 ASSERT_EQ(*layer_iterator_, layer); | |
345 ASSERT_TRUE(layer_iterator_.represents_itself()); | |
346 occlusion->EnterLayer(layer_iterator_); | |
347 } | |
348 | |
349 void LeaveLayer(typename Types::LayerType* layer, | |
350 typename Types::OcclusionTrackerType* occlusion) { | |
351 ASSERT_EQ(*layer_iterator_, layer); | |
352 ASSERT_TRUE(layer_iterator_.represents_itself()); | |
353 occlusion->LeaveLayer(layer_iterator_); | |
354 ++layer_iterator_; | |
355 } | |
356 | |
357 void VisitLayer(typename Types::LayerType* layer, | |
358 typename Types::OcclusionTrackerType* occlusion) { | |
359 EnterLayer(layer, occlusion); | |
360 LeaveLayer(layer, occlusion); | |
361 } | |
362 | |
363 void EnterContributingSurface( | |
364 typename Types::LayerType* layer, | |
365 typename Types::OcclusionTrackerType* occlusion) { | |
366 ASSERT_EQ(*layer_iterator_, layer); | |
367 ASSERT_TRUE(layer_iterator_.represents_target_render_surface()); | |
368 occlusion->EnterLayer(layer_iterator_); | |
369 occlusion->LeaveLayer(layer_iterator_); | |
370 ++layer_iterator_; | |
371 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface()); | |
372 occlusion->EnterLayer(layer_iterator_); | |
373 } | |
374 | |
375 void LeaveContributingSurface( | |
376 typename Types::LayerType* layer, | |
377 typename Types::OcclusionTrackerType* occlusion) { | |
378 ASSERT_EQ(*layer_iterator_, layer); | |
379 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface()); | |
380 occlusion->LeaveLayer(layer_iterator_); | |
381 ++layer_iterator_; | |
382 } | |
383 | |
384 void VisitContributingSurface( | |
385 typename Types::LayerType* layer, | |
386 typename Types::OcclusionTrackerType* occlusion) { | |
387 EnterContributingSurface(layer, occlusion); | |
388 LeaveContributingSurface(layer, occlusion); | |
389 } | |
390 | |
391 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; } | |
392 | |
393 const gfx::Transform identity_matrix; | |
394 | |
395 private: | |
396 void SetRootLayerOnMainThread(Layer* root) { | |
397 host_->SetRootLayer(scoped_refptr<Layer>(root)); | |
398 } | |
399 | |
400 void SetRootLayerOnMainThread(LayerImpl* root) {} | |
401 | |
402 void SetBaseProperties(typename Types::LayerType* layer, | |
403 const gfx::Transform& transform, | |
404 const gfx::PointF& position, | |
405 const gfx::Size& bounds) { | |
406 layer->SetTransform(transform); | |
407 layer->SetPosition(position); | |
408 layer->SetBounds(bounds); | |
409 } | |
410 | |
411 void SetProperties(Layer* layer, | |
412 const gfx::Transform& transform, | |
413 const gfx::PointF& position, | |
414 const gfx::Size& bounds) { | |
415 SetBaseProperties(layer, transform, position, bounds); | |
416 } | |
417 | |
418 void SetProperties(LayerImpl* layer, | |
419 const gfx::Transform& transform, | |
420 const gfx::PointF& position, | |
421 const gfx::Size& bounds) { | |
422 SetBaseProperties(layer, transform, position, bounds); | |
423 | |
424 layer->SetContentBounds(layer->bounds()); | |
425 } | |
426 | |
427 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) { | |
428 owning_layer->SetReplicaLayer(layer.get()); | |
429 replica_layers_.push_back(layer); | |
430 } | |
431 | |
432 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { | |
433 owning_layer->SetReplicaLayer(layer.Pass()); | |
434 } | |
435 | |
436 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) { | |
437 owning_layer->SetMaskLayer(layer.get()); | |
438 mask_layers_.push_back(layer); | |
439 } | |
440 | |
441 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { | |
442 owning_layer->SetMaskLayer(layer.Pass()); | |
443 } | |
444 | |
445 bool opaque_layers_; | |
446 FakeLayerTreeHostClient client_; | |
447 scoped_ptr<FakeLayerTreeHost> host_; | |
448 // These hold ownership of the layers for the duration of the test. | |
449 typename Types::LayerPtrType root_; | |
450 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_; | |
451 LayerImplList render_surface_layer_list_impl_; | |
452 typename Types::TestLayerIterator layer_iterator_begin_; | |
453 typename Types::TestLayerIterator layer_iterator_; | |
454 typename Types::LayerType* last_layer_visited_; | |
455 LayerList replica_layers_; | |
456 LayerList mask_layers_; | |
457 }; | |
458 | |
459 template <> | |
460 FakeLayerTreeHost* | |
461 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() { | |
462 return host_.get(); | |
463 } | |
464 | |
465 template <> | |
466 LayerTreeImpl* | |
467 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() { | |
468 return host_->host_impl()->active_tree(); | |
469 } | |
470 | |
471 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ | |
472 class ClassName##MainThreadOpaqueLayers \ | |
473 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \ | |
474 public: /* NOLINT(whitespace/indent) */ \ | |
475 ClassName##MainThreadOpaqueLayers() \ | |
476 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \ | |
477 }; \ | |
478 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); } | |
479 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \ | |
480 class ClassName##MainThreadOpaquePaints \ | |
481 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \ | |
482 public: /* NOLINT(whitespace/indent) */ \ | |
483 ClassName##MainThreadOpaquePaints() \ | |
484 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \ | |
485 }; \ | |
486 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); } | |
487 | |
488 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \ | |
489 class ClassName##ImplThreadOpaqueLayers \ | |
490 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \ | |
491 public: /* NOLINT(whitespace/indent) */ \ | |
492 ClassName##ImplThreadOpaqueLayers() \ | |
493 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \ | |
494 }; \ | |
495 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); } | |
496 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \ | |
497 class ClassName##ImplThreadOpaquePaints \ | |
498 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \ | |
499 public: /* NOLINT(whitespace/indent) */ \ | |
500 ClassName##ImplThreadOpaquePaints() \ | |
501 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \ | |
502 }; \ | |
503 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); } | |
504 | |
505 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \ | |
506 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ | |
507 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \ | |
508 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \ | |
509 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) | |
510 | |
511 #define MAIN_THREAD_TEST(ClassName) \ | |
512 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) | |
513 | |
514 #define IMPL_THREAD_TEST(ClassName) \ | |
515 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) | |
516 | |
517 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \ | |
518 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ | |
519 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) | |
520 | |
521 template <class Types> | |
522 class OcclusionTrackerTestIdentityTransforms | |
523 : public OcclusionTrackerTest<Types> { | |
524 protected: | |
525 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers) | |
526 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
527 | |
528 void RunMyTest() override { | |
529 typename Types::ContentLayerType* root = this->CreateRoot( | |
530 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); | |
531 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( | |
532 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); | |
533 typename Types::ContentLayerType* layer = | |
534 this->CreateDrawingLayer(parent, | |
535 this->identity_matrix, | |
536 gfx::PointF(30.f, 30.f), | |
537 gfx::Size(500, 500), | |
538 true); | |
539 parent->SetMasksToBounds(true); | |
540 this->CalcDrawEtc(root); | |
541 | |
542 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
543 gfx::Rect(0, 0, 1000, 1000)); | |
544 | |
545 this->VisitLayer(layer, &occlusion); | |
546 this->EnterLayer(parent, &occlusion); | |
547 | |
548 EXPECT_EQ(gfx::Rect().ToString(), | |
549 occlusion.occlusion_from_outside_target().ToString()); | |
550 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), | |
551 occlusion.occlusion_from_inside_target().ToString()); | |
552 } | |
553 }; | |
554 | |
555 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms); | |
556 | |
557 template <class Types> | |
558 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> { | |
559 protected: | |
560 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers) | |
561 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
562 void RunMyTest() override { | |
563 gfx::Transform layer_transform; | |
564 layer_transform.Translate(250.0, 250.0); | |
565 layer_transform.Rotate(90.0); | |
566 layer_transform.Translate(-250.0, -250.0); | |
567 | |
568 typename Types::ContentLayerType* root = this->CreateRoot( | |
569 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200)); | |
570 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( | |
571 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); | |
572 typename Types::ContentLayerType* layer = | |
573 this->CreateDrawingLayer(parent, | |
574 layer_transform, | |
575 gfx::PointF(30.f, 30.f), | |
576 gfx::Size(500, 500), | |
577 true); | |
578 parent->SetMasksToBounds(true); | |
579 this->CalcDrawEtc(root); | |
580 | |
581 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
582 gfx::Rect(0, 0, 1000, 1000)); | |
583 | |
584 this->VisitLayer(layer, &occlusion); | |
585 this->EnterLayer(parent, &occlusion); | |
586 | |
587 EXPECT_EQ(gfx::Rect().ToString(), | |
588 occlusion.occlusion_from_outside_target().ToString()); | |
589 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), | |
590 occlusion.occlusion_from_inside_target().ToString()); | |
591 } | |
592 }; | |
593 | |
594 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild); | |
595 | |
596 template <class Types> | |
597 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> { | |
598 protected: | |
599 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers) | |
600 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
601 void RunMyTest() override { | |
602 gfx::Transform layer_transform; | |
603 layer_transform.Translate(20.0, 20.0); | |
604 | |
605 typename Types::ContentLayerType* root = this->CreateRoot( | |
606 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); | |
607 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( | |
608 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); | |
609 typename Types::ContentLayerType* layer = | |
610 this->CreateDrawingLayer(parent, | |
611 layer_transform, | |
612 gfx::PointF(30.f, 30.f), | |
613 gfx::Size(500, 500), | |
614 true); | |
615 parent->SetMasksToBounds(true); | |
616 this->CalcDrawEtc(root); | |
617 | |
618 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
619 gfx::Rect(0, 0, 1000, 1000)); | |
620 | |
621 this->VisitLayer(layer, &occlusion); | |
622 this->EnterLayer(parent, &occlusion); | |
623 | |
624 EXPECT_EQ(gfx::Rect().ToString(), | |
625 occlusion.occlusion_from_outside_target().ToString()); | |
626 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), | |
627 occlusion.occlusion_from_inside_target().ToString()); | |
628 } | |
629 }; | |
630 | |
631 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild); | |
632 | |
633 template <class Types> | |
634 class OcclusionTrackerTestChildInRotatedChild | |
635 : public OcclusionTrackerTest<Types> { | |
636 protected: | |
637 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers) | |
638 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
639 void RunMyTest() override { | |
640 gfx::Transform child_transform; | |
641 child_transform.Translate(250.0, 250.0); | |
642 child_transform.Rotate(90.0); | |
643 child_transform.Translate(-250.0, -250.0); | |
644 | |
645 typename Types::ContentLayerType* parent = this->CreateRoot( | |
646 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); | |
647 parent->SetMasksToBounds(true); | |
648 typename Types::LayerType* child = this->CreateSurface( | |
649 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); | |
650 child->SetMasksToBounds(true); | |
651 typename Types::ContentLayerType* layer = | |
652 this->CreateDrawingLayer(child, | |
653 this->identity_matrix, | |
654 gfx::PointF(10.f, 10.f), | |
655 gfx::Size(500, 500), | |
656 true); | |
657 this->CalcDrawEtc(parent); | |
658 | |
659 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
660 gfx::Rect(0, 0, 1000, 1000)); | |
661 | |
662 this->VisitLayer(layer, &occlusion); | |
663 this->EnterContributingSurface(child, &occlusion); | |
664 | |
665 EXPECT_EQ(gfx::Rect().ToString(), | |
666 occlusion.occlusion_from_outside_target().ToString()); | |
667 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), | |
668 occlusion.occlusion_from_inside_target().ToString()); | |
669 | |
670 this->LeaveContributingSurface(child, &occlusion); | |
671 this->EnterLayer(parent, &occlusion); | |
672 | |
673 EXPECT_EQ(gfx::Rect().ToString(), | |
674 occlusion.occlusion_from_outside_target().ToString()); | |
675 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), | |
676 occlusion.occlusion_from_inside_target().ToString()); | |
677 | |
678 /* Justification for the above occlusion from |layer|: | |
679 100 | |
680 +---------------------+ | |
681 | | | |
682 | 30 | rotate(90) | |
683 | 30 + ---------------------------------+ | |
684 100 | | 10 | | ==> | |
685 | |10+---------------------------------+ | |
686 | | | | | | | |
687 | | | | | | | |
688 | | | | | | | |
689 +----|--|-------------+ | | | |
690 | | | | | |
691 | | | | | |
692 | | | |500 | |
693 | | | | | |
694 | | | | | |
695 | | | | | |
696 | | | | | |
697 +--|-------------------------------+ | | |
698 | | | |
699 +---------------------------------+ | |
700 500 | |
701 | |
702 +---------------------+ | |
703 | |30 Visible region of |layer|: ///// | |
704 | | | |
705 | +---------------------------------+ | |
706 100| | |10 | | |
707 | +---------------------------------+ | | |
708 | | |///////////////| 420 | | | |
709 | | |///////////////|60 | | | |
710 | | |///////////////| | | | |
711 +--|--|---------------+ | | | |
712 20|10| 70 | | | |
713 | | | | | |
714 | | | | | |
715 | | | | | |
716 | | | | | |
717 | | | | | |
718 | | |10| | |
719 | +------------------------------|--+ | |
720 | 490 | | |
721 +---------------------------------+ | |
722 500 | |
723 | |
724 */ | |
725 } | |
726 }; | |
727 | |
728 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild); | |
729 | |
730 template <class Types> | |
731 class OcclusionTrackerTestScaledRenderSurface | |
732 : public OcclusionTrackerTest<Types> { | |
733 protected: | |
734 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers) | |
735 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
736 | |
737 void RunMyTest() override { | |
738 typename Types::ContentLayerType* parent = this->CreateRoot( | |
739 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); | |
740 | |
741 gfx::Transform layer1_matrix; | |
742 layer1_matrix.Scale(2.0, 2.0); | |
743 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( | |
744 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true); | |
745 Types::SetForceRenderSurface(layer1, true); | |
746 | |
747 gfx::Transform layer2_matrix; | |
748 layer2_matrix.Translate(25.0, 25.0); | |
749 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer( | |
750 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true); | |
751 typename Types::ContentLayerType* occluder = | |
752 this->CreateDrawingLayer(parent, | |
753 this->identity_matrix, | |
754 gfx::PointF(100.f, 100.f), | |
755 gfx::Size(500, 500), | |
756 true); | |
757 this->CalcDrawEtc(parent); | |
758 | |
759 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
760 gfx::Rect(0, 0, 1000, 1000)); | |
761 | |
762 this->VisitLayer(occluder, &occlusion); | |
763 this->EnterLayer(layer2, &occlusion); | |
764 | |
765 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), | |
766 occlusion.occlusion_from_outside_target().ToString()); | |
767 EXPECT_EQ(gfx::Rect().ToString(), | |
768 occlusion.occlusion_from_inside_target().ToString()); | |
769 } | |
770 }; | |
771 | |
772 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface); | |
773 | |
774 template <class Types> | |
775 class OcclusionTrackerTestVisitTargetTwoTimes | |
776 : public OcclusionTrackerTest<Types> { | |
777 protected: | |
778 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers) | |
779 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
780 void RunMyTest() override { | |
781 typename Types::ContentLayerType* root = this->CreateRoot( | |
782 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); | |
783 typename Types::LayerType* surface = this->CreateSurface( | |
784 root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size()); | |
785 typename Types::ContentLayerType* surface_child = | |
786 this->CreateDrawingLayer(surface, | |
787 this->identity_matrix, | |
788 gfx::PointF(10.f, 10.f), | |
789 gfx::Size(50, 50), | |
790 true); | |
791 // |top_layer| makes |root|'s surface get considered by OcclusionTracker | |
792 // first, instead of |surface|'s. This exercises different code in | |
793 // LeaveToRenderTarget, as the target surface has already been seen when | |
794 // leaving |surface| later. | |
795 typename Types::ContentLayerType* top_layer = | |
796 this->CreateDrawingLayer(root, | |
797 this->identity_matrix, | |
798 gfx::PointF(40.f, 90.f), | |
799 gfx::Size(50, 20), | |
800 true); | |
801 this->CalcDrawEtc(root); | |
802 | |
803 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
804 gfx::Rect(0, 0, 1000, 1000)); | |
805 | |
806 this->VisitLayer(top_layer, &occlusion); | |
807 | |
808 EXPECT_EQ(gfx::Rect().ToString(), | |
809 occlusion.occlusion_from_outside_target().ToString()); | |
810 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(), | |
811 occlusion.occlusion_from_inside_target().ToString()); | |
812 | |
813 this->VisitLayer(surface_child, &occlusion); | |
814 | |
815 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), | |
816 occlusion.occlusion_from_outside_target().ToString()); | |
817 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), | |
818 occlusion.occlusion_from_inside_target().ToString()); | |
819 | |
820 this->EnterContributingSurface(surface, &occlusion); | |
821 | |
822 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), | |
823 occlusion.occlusion_from_outside_target().ToString()); | |
824 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), | |
825 occlusion.occlusion_from_inside_target().ToString()); | |
826 | |
827 // Occlusion from |top_layer| already in the root target should get merged | |
828 // with the occlusion from the |surface| we are leaving now. | |
829 this->LeaveContributingSurface(surface, &occlusion); | |
830 this->EnterLayer(root, &occlusion); | |
831 | |
832 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
833 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(), | |
834 occlusion.occlusion_from_inside_target().ToString()); | |
835 } | |
836 }; | |
837 | |
838 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes); | |
839 | |
840 template <class Types> | |
841 class OcclusionTrackerTestSurfaceRotatedOffAxis | |
842 : public OcclusionTrackerTest<Types> { | |
843 protected: | |
844 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers) | |
845 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
846 void RunMyTest() override { | |
847 gfx::Transform child_transform; | |
848 child_transform.Translate(250.0, 250.0); | |
849 child_transform.Rotate(95.0); | |
850 child_transform.Translate(-250.0, -250.0); | |
851 | |
852 gfx::Transform layer_transform; | |
853 layer_transform.Translate(10.0, 10.0); | |
854 | |
855 typename Types::ContentLayerType* root = this->CreateRoot( | |
856 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); | |
857 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( | |
858 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); | |
859 typename Types::LayerType* child = this->CreateSurface( | |
860 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); | |
861 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( | |
862 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true); | |
863 this->CalcDrawEtc(root); | |
864 | |
865 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
866 gfx::Rect(0, 0, 1000, 1000)); | |
867 | |
868 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect( | |
869 layer_transform, layer->visible_content_rect()); | |
870 | |
871 this->VisitLayer(layer, &occlusion); | |
872 this->EnterContributingSurface(child, &occlusion); | |
873 | |
874 EXPECT_EQ(gfx::Rect().ToString(), | |
875 occlusion.occlusion_from_outside_target().ToString()); | |
876 EXPECT_EQ(clipped_layer_in_child.ToString(), | |
877 occlusion.occlusion_from_inside_target().ToString()); | |
878 | |
879 this->LeaveContributingSurface(child, &occlusion); | |
880 this->EnterLayer(parent, &occlusion); | |
881 | |
882 EXPECT_EQ(gfx::Rect().ToString(), | |
883 occlusion.occlusion_from_outside_target().ToString()); | |
884 EXPECT_EQ(gfx::Rect().ToString(), | |
885 occlusion.occlusion_from_inside_target().ToString()); | |
886 } | |
887 }; | |
888 | |
889 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis); | |
890 | |
891 template <class Types> | |
892 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren | |
893 : public OcclusionTrackerTest<Types> { | |
894 protected: | |
895 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers) | |
896 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
897 void RunMyTest() override { | |
898 gfx::Transform child_transform; | |
899 child_transform.Translate(250.0, 250.0); | |
900 child_transform.Rotate(90.0); | |
901 child_transform.Translate(-250.0, -250.0); | |
902 | |
903 typename Types::ContentLayerType* root = this->CreateRoot( | |
904 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); | |
905 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( | |
906 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); | |
907 parent->SetMasksToBounds(true); | |
908 typename Types::ContentLayerType* child = | |
909 this->CreateDrawingSurface(parent, | |
910 child_transform, | |
911 gfx::PointF(30.f, 30.f), | |
912 gfx::Size(500, 500), | |
913 false); | |
914 child->SetMasksToBounds(true); | |
915 typename Types::ContentLayerType* layer1 = | |
916 this->CreateDrawingLayer(child, | |
917 this->identity_matrix, | |
918 gfx::PointF(10.f, 10.f), | |
919 gfx::Size(500, 500), | |
920 true); | |
921 typename Types::ContentLayerType* layer2 = | |
922 this->CreateDrawingLayer(child, | |
923 this->identity_matrix, | |
924 gfx::PointF(10.f, 450.f), | |
925 gfx::Size(500, 60), | |
926 true); | |
927 this->CalcDrawEtc(root); | |
928 | |
929 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
930 gfx::Rect(0, 0, 1000, 1000)); | |
931 | |
932 this->VisitLayer(layer2, &occlusion); | |
933 this->VisitLayer(layer1, &occlusion); | |
934 this->VisitLayer(child, &occlusion); | |
935 this->EnterContributingSurface(child, &occlusion); | |
936 | |
937 EXPECT_EQ(gfx::Rect().ToString(), | |
938 occlusion.occlusion_from_outside_target().ToString()); | |
939 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), | |
940 occlusion.occlusion_from_inside_target().ToString()); | |
941 | |
942 this->LeaveContributingSurface(child, &occlusion); | |
943 this->EnterLayer(parent, &occlusion); | |
944 | |
945 EXPECT_EQ(gfx::Rect().ToString(), | |
946 occlusion.occlusion_from_outside_target().ToString()); | |
947 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), | |
948 occlusion.occlusion_from_inside_target().ToString()); | |
949 | |
950 /* Justification for the above occlusion from |layer1| and |layer2|: | |
951 | |
952 +---------------------+ | |
953 | |30 Visible region of |layer1|: ///// | |
954 | | Visible region of |layer2|: \\\\\ | |
955 | +---------------------------------+ | |
956 | | |10 | | |
957 | +---------------+-----------------+ | | |
958 | | |\\\\\\\\\\\\|//| 420 | | | |
959 | | |\\\\\\\\\\\\|//|60 | | | |
960 | | |\\\\\\\\\\\\|//| | | | |
961 +--|--|------------|--+ | | | |
962 20|10| 70 | | | | |
963 | | | | | | |
964 | | | | | | |
965 | | | | | | |
966 | | | | | | |
967 | | | | | | |
968 | | | |10| | |
969 | +------------|-----------------|--+ | |
970 | | 490 | | |
971 +---------------+-----------------+ | |
972 60 440 | |
973 */ | |
974 } | |
975 }; | |
976 | |
977 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren); | |
978 | |
979 template <class Types> | |
980 class OcclusionTrackerTestOverlappingSurfaceSiblings | |
981 : public OcclusionTrackerTest<Types> { | |
982 protected: | |
983 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers) | |
984 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
985 void RunMyTest() override { | |
986 typename Types::ContentLayerType* parent = this->CreateRoot( | |
987 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); | |
988 parent->SetMasksToBounds(true); | |
989 typename Types::LayerType* child1 = this->CreateSurface( | |
990 parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size()); | |
991 typename Types::LayerType* child2 = this->CreateSurface( | |
992 parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size()); | |
993 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( | |
994 child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true); | |
995 typename Types::ContentLayerType* layer2 = | |
996 this->CreateDrawingLayer(child2, | |
997 this->identity_matrix, | |
998 gfx::PointF(10.f, 0.f), | |
999 gfx::Size(40, 50), | |
1000 true); | |
1001 this->CalcDrawEtc(parent); | |
1002 | |
1003 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1004 gfx::Rect(0, 0, 1000, 1000)); | |
1005 | |
1006 this->VisitLayer(layer2, &occlusion); | |
1007 this->EnterContributingSurface(child2, &occlusion); | |
1008 | |
1009 // layer2's occlusion. | |
1010 EXPECT_EQ(gfx::Rect().ToString(), | |
1011 occlusion.occlusion_from_outside_target().ToString()); | |
1012 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(), | |
1013 occlusion.occlusion_from_inside_target().ToString()); | |
1014 | |
1015 this->LeaveContributingSurface(child2, &occlusion); | |
1016 this->VisitLayer(layer1, &occlusion); | |
1017 this->EnterContributingSurface(child1, &occlusion); | |
1018 | |
1019 // layer2's occlusion in the target space of layer1. | |
1020 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(), | |
1021 occlusion.occlusion_from_outside_target().ToString()); | |
1022 // layer1's occlusion. | |
1023 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(), | |
1024 occlusion.occlusion_from_inside_target().ToString()); | |
1025 | |
1026 this->LeaveContributingSurface(child1, &occlusion); | |
1027 this->EnterLayer(parent, &occlusion); | |
1028 | |
1029 // The occlusion from from layer1 and layer2 is merged. | |
1030 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1031 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(), | |
1032 occlusion.occlusion_from_inside_target().ToString()); | |
1033 } | |
1034 }; | |
1035 | |
1036 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings); | |
1037 | |
1038 template <class Types> | |
1039 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms | |
1040 : public OcclusionTrackerTest<Types> { | |
1041 protected: | |
1042 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms( | |
1043 bool opaque_layers) | |
1044 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1045 void RunMyTest() override { | |
1046 gfx::Transform child1_transform; | |
1047 child1_transform.Translate(250.0, 250.0); | |
1048 child1_transform.Rotate(-90.0); | |
1049 child1_transform.Translate(-250.0, -250.0); | |
1050 | |
1051 gfx::Transform child2_transform; | |
1052 child2_transform.Translate(250.0, 250.0); | |
1053 child2_transform.Rotate(90.0); | |
1054 child2_transform.Translate(-250.0, -250.0); | |
1055 | |
1056 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1057 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); | |
1058 parent->SetMasksToBounds(true); | |
1059 typename Types::LayerType* child1 = this->CreateSurface( | |
1060 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10)); | |
1061 typename Types::LayerType* child2 = | |
1062 this->CreateDrawingSurface(parent, | |
1063 child2_transform, | |
1064 gfx::PointF(20.f, 40.f), | |
1065 gfx::Size(10, 10), | |
1066 false); | |
1067 typename Types::ContentLayerType* layer1 = | |
1068 this->CreateDrawingLayer(child1, | |
1069 this->identity_matrix, | |
1070 gfx::PointF(-10.f, -20.f), | |
1071 gfx::Size(510, 510), | |
1072 true); | |
1073 typename Types::ContentLayerType* layer2 = | |
1074 this->CreateDrawingLayer(child2, | |
1075 this->identity_matrix, | |
1076 gfx::PointF(-10.f, -10.f), | |
1077 gfx::Size(510, 510), | |
1078 true); | |
1079 this->CalcDrawEtc(parent); | |
1080 | |
1081 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1082 gfx::Rect(0, 0, 1000, 1000)); | |
1083 | |
1084 this->VisitLayer(layer2, &occlusion); | |
1085 this->EnterLayer(child2, &occlusion); | |
1086 | |
1087 EXPECT_EQ(gfx::Rect().ToString(), | |
1088 occlusion.occlusion_from_outside_target().ToString()); | |
1089 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), | |
1090 occlusion.occlusion_from_inside_target().ToString()); | |
1091 | |
1092 this->LeaveLayer(child2, &occlusion); | |
1093 this->EnterContributingSurface(child2, &occlusion); | |
1094 | |
1095 EXPECT_EQ(gfx::Rect().ToString(), | |
1096 occlusion.occlusion_from_outside_target().ToString()); | |
1097 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), | |
1098 occlusion.occlusion_from_inside_target().ToString()); | |
1099 | |
1100 this->LeaveContributingSurface(child2, &occlusion); | |
1101 this->VisitLayer(layer1, &occlusion); | |
1102 this->EnterContributingSurface(child1, &occlusion); | |
1103 | |
1104 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), | |
1105 occlusion.occlusion_from_outside_target().ToString()); | |
1106 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), | |
1107 occlusion.occlusion_from_inside_target().ToString()); | |
1108 | |
1109 this->LeaveContributingSurface(child1, &occlusion); | |
1110 this->EnterLayer(parent, &occlusion); | |
1111 | |
1112 EXPECT_EQ(gfx::Rect().ToString(), | |
1113 occlusion.occlusion_from_outside_target().ToString()); | |
1114 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), | |
1115 occlusion.occlusion_from_inside_target().ToString()); | |
1116 | |
1117 /* Justification for the above occlusion: | |
1118 100 | |
1119 +---------------------+ | |
1120 |20 | layer1 | |
1121 10+----------------------------------+ | |
1122 100 || 30 | layer2 | | |
1123 |20+----------------------------------+ | |
1124 || | | | | | |
1125 || | | | | | |
1126 || | | | | | |
1127 +|-|------------------+ | | | |
1128 | | | | 510 | |
1129 | | 510 | | | |
1130 | | | | | |
1131 | | | | | |
1132 | | | | | |
1133 | | | | | |
1134 | | 520 | | | |
1135 +----------------------------------+ | | |
1136 | | | |
1137 +----------------------------------+ | |
1138 510 | |
1139 */ | |
1140 } | |
1141 }; | |
1142 | |
1143 ALL_OCCLUSIONTRACKER_TEST( | |
1144 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms); | |
1145 | |
1146 template <class Types> | |
1147 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> { | |
1148 protected: | |
1149 explicit OcclusionTrackerTestFilters(bool opaque_layers) | |
1150 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1151 void RunMyTest() override { | |
1152 gfx::Transform layer_transform; | |
1153 layer_transform.Translate(250.0, 250.0); | |
1154 layer_transform.Rotate(90.0); | |
1155 layer_transform.Translate(-250.0, -250.0); | |
1156 | |
1157 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1158 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); | |
1159 parent->SetMasksToBounds(true); | |
1160 typename Types::ContentLayerType* blur_layer = | |
1161 this->CreateDrawingLayer(parent, | |
1162 layer_transform, | |
1163 gfx::PointF(30.f, 30.f), | |
1164 gfx::Size(500, 500), | |
1165 true); | |
1166 typename Types::ContentLayerType* opaque_layer = | |
1167 this->CreateDrawingLayer(parent, | |
1168 layer_transform, | |
1169 gfx::PointF(30.f, 30.f), | |
1170 gfx::Size(500, 500), | |
1171 true); | |
1172 typename Types::ContentLayerType* opacity_layer = | |
1173 this->CreateDrawingLayer(parent, | |
1174 layer_transform, | |
1175 gfx::PointF(30.f, 30.f), | |
1176 gfx::Size(500, 500), | |
1177 true); | |
1178 | |
1179 Types::SetForceRenderSurface(blur_layer, true); | |
1180 FilterOperations filters; | |
1181 filters.Append(FilterOperation::CreateBlurFilter(10.f)); | |
1182 blur_layer->SetFilters(filters); | |
1183 | |
1184 Types::SetForceRenderSurface(opaque_layer, true); | |
1185 filters.Clear(); | |
1186 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); | |
1187 opaque_layer->SetFilters(filters); | |
1188 | |
1189 Types::SetForceRenderSurface(opacity_layer, true); | |
1190 filters.Clear(); | |
1191 filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); | |
1192 opacity_layer->SetFilters(filters); | |
1193 | |
1194 this->CalcDrawEtc(parent); | |
1195 | |
1196 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1197 gfx::Rect(0, 0, 1000, 1000)); | |
1198 | |
1199 // Opacity layer won't contribute to occlusion. | |
1200 this->VisitLayer(opacity_layer, &occlusion); | |
1201 this->EnterContributingSurface(opacity_layer, &occlusion); | |
1202 | |
1203 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1204 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1205 | |
1206 // And has nothing to contribute to its parent surface. | |
1207 this->LeaveContributingSurface(opacity_layer, &occlusion); | |
1208 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1209 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1210 | |
1211 // Opaque layer will contribute to occlusion. | |
1212 this->VisitLayer(opaque_layer, &occlusion); | |
1213 this->EnterContributingSurface(opaque_layer, &occlusion); | |
1214 | |
1215 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1216 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), | |
1217 occlusion.occlusion_from_inside_target().ToString()); | |
1218 | |
1219 // And it gets translated to the parent surface. | |
1220 this->LeaveContributingSurface(opaque_layer, &occlusion); | |
1221 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1222 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), | |
1223 occlusion.occlusion_from_inside_target().ToString()); | |
1224 | |
1225 // The blur layer needs to throw away any occlusion from outside its | |
1226 // subtree. | |
1227 this->EnterLayer(blur_layer, &occlusion); | |
1228 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1229 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1230 | |
1231 // And it won't contribute to occlusion. | |
1232 this->LeaveLayer(blur_layer, &occlusion); | |
1233 this->EnterContributingSurface(blur_layer, &occlusion); | |
1234 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1235 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1236 | |
1237 // But the opaque layer's occlusion is preserved on the parent. | |
1238 this->LeaveContributingSurface(blur_layer, &occlusion); | |
1239 this->EnterLayer(parent, &occlusion); | |
1240 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1241 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), | |
1242 occlusion.occlusion_from_inside_target().ToString()); | |
1243 } | |
1244 }; | |
1245 | |
1246 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters); | |
1247 | |
1248 template <class Types> | |
1249 class OcclusionTrackerTestReplicaDoesOcclude | |
1250 : public OcclusionTrackerTest<Types> { | |
1251 protected: | |
1252 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers) | |
1253 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1254 void RunMyTest() override { | |
1255 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1256 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); | |
1257 typename Types::LayerType* surface = this->CreateDrawingSurface( | |
1258 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true); | |
1259 this->CreateReplicaLayer( | |
1260 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size()); | |
1261 this->CalcDrawEtc(parent); | |
1262 | |
1263 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1264 gfx::Rect(0, 0, 1000, 1000)); | |
1265 | |
1266 this->VisitLayer(surface, &occlusion); | |
1267 | |
1268 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), | |
1269 occlusion.occlusion_from_inside_target().ToString()); | |
1270 | |
1271 this->VisitContributingSurface(surface, &occlusion); | |
1272 this->EnterLayer(parent, &occlusion); | |
1273 | |
1274 // The surface and replica should both be occluding the parent. | |
1275 EXPECT_EQ(gfx::Rect(50, 100).ToString(), | |
1276 occlusion.occlusion_from_inside_target().ToString()); | |
1277 } | |
1278 }; | |
1279 | |
1280 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude); | |
1281 | |
1282 template <class Types> | |
1283 class OcclusionTrackerTestReplicaWithClipping | |
1284 : public OcclusionTrackerTest<Types> { | |
1285 protected: | |
1286 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers) | |
1287 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1288 void RunMyTest() override { | |
1289 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1290 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170)); | |
1291 parent->SetMasksToBounds(true); | |
1292 typename Types::LayerType* surface = | |
1293 this->CreateDrawingSurface(parent, | |
1294 this->identity_matrix, | |
1295 gfx::PointF(0.f, 100.f), | |
1296 gfx::Size(50, 50), | |
1297 true); | |
1298 this->CreateReplicaLayer( | |
1299 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size()); | |
1300 this->CalcDrawEtc(parent); | |
1301 | |
1302 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1303 gfx::Rect(0, 0, 1000, 1000)); | |
1304 | |
1305 this->VisitLayer(surface, &occlusion); | |
1306 | |
1307 // The surface layer's occlusion in its own space. | |
1308 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), | |
1309 occlusion.occlusion_from_inside_target().ToString()); | |
1310 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1311 | |
1312 this->VisitContributingSurface(surface, &occlusion); | |
1313 this->EnterLayer(parent, &occlusion); | |
1314 | |
1315 // The surface and replica should both be occluding the parent, the | |
1316 // replica's occlusion is clipped by the parent. | |
1317 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(), | |
1318 occlusion.occlusion_from_inside_target().ToString()); | |
1319 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1320 } | |
1321 }; | |
1322 | |
1323 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping); | |
1324 | |
1325 template <class Types> | |
1326 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> { | |
1327 protected: | |
1328 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers) | |
1329 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1330 void RunMyTest() override { | |
1331 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1332 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); | |
1333 typename Types::LayerType* surface = | |
1334 this->CreateDrawingSurface(parent, | |
1335 this->identity_matrix, | |
1336 gfx::PointF(0.f, 100.f), | |
1337 gfx::Size(50, 50), | |
1338 true); | |
1339 typename Types::LayerType* replica = this->CreateReplicaLayer( | |
1340 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size()); | |
1341 this->CreateMaskLayer(replica, gfx::Size(10, 10)); | |
1342 this->CalcDrawEtc(parent); | |
1343 | |
1344 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1345 gfx::Rect(0, 0, 1000, 1000)); | |
1346 | |
1347 this->VisitLayer(surface, &occlusion); | |
1348 | |
1349 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), | |
1350 occlusion.occlusion_from_inside_target().ToString()); | |
1351 | |
1352 this->VisitContributingSurface(surface, &occlusion); | |
1353 this->EnterLayer(parent, &occlusion); | |
1354 | |
1355 // The replica should not be occluding the parent, since it has a mask | |
1356 // applied to it. | |
1357 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), | |
1358 occlusion.occlusion_from_inside_target().ToString()); | |
1359 } | |
1360 }; | |
1361 | |
1362 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask); | |
1363 | |
1364 template <class Types> | |
1365 class OcclusionTrackerTestOpaqueContentsRegionEmpty | |
1366 : public OcclusionTrackerTest<Types> { | |
1367 protected: | |
1368 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers) | |
1369 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1370 void RunMyTest() override { | |
1371 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1372 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); | |
1373 typename Types::ContentLayerType* layer = | |
1374 this->CreateDrawingSurface(parent, | |
1375 this->identity_matrix, | |
1376 gfx::PointF(), | |
1377 gfx::Size(200, 200), | |
1378 false); | |
1379 this->CalcDrawEtc(parent); | |
1380 | |
1381 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1382 gfx::Rect(0, 0, 1000, 1000)); | |
1383 this->EnterLayer(layer, &occlusion); | |
1384 | |
1385 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1386 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1387 | |
1388 this->LeaveLayer(layer, &occlusion); | |
1389 this->VisitContributingSurface(layer, &occlusion); | |
1390 this->EnterLayer(parent, &occlusion); | |
1391 | |
1392 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1393 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1394 } | |
1395 }; | |
1396 | |
1397 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty); | |
1398 | |
1399 template <class Types> | |
1400 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty | |
1401 : public OcclusionTrackerTest<Types> { | |
1402 protected: | |
1403 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers) | |
1404 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1405 void RunMyTest() override { | |
1406 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1407 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); | |
1408 typename Types::ContentLayerType* layer = | |
1409 this->CreateDrawingLayer(parent, | |
1410 this->identity_matrix, | |
1411 gfx::PointF(100.f, 100.f), | |
1412 gfx::Size(200, 200), | |
1413 false); | |
1414 this->CalcDrawEtc(parent); | |
1415 { | |
1416 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1417 gfx::Rect(0, 0, 1000, 1000)); | |
1418 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100)); | |
1419 | |
1420 this->ResetLayerIterator(); | |
1421 this->VisitLayer(layer, &occlusion); | |
1422 this->EnterLayer(parent, &occlusion); | |
1423 | |
1424 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), | |
1425 occlusion.occlusion_from_inside_target().ToString()); | |
1426 } | |
1427 { | |
1428 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1429 gfx::Rect(0, 0, 1000, 1000)); | |
1430 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180)); | |
1431 | |
1432 this->ResetLayerIterator(); | |
1433 this->VisitLayer(layer, &occlusion); | |
1434 this->EnterLayer(parent, &occlusion); | |
1435 | |
1436 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), | |
1437 occlusion.occlusion_from_inside_target().ToString()); | |
1438 } | |
1439 { | |
1440 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1441 gfx::Rect(0, 0, 1000, 1000)); | |
1442 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100)); | |
1443 | |
1444 this->ResetLayerIterator(); | |
1445 this->VisitLayer(layer, &occlusion); | |
1446 this->EnterLayer(parent, &occlusion); | |
1447 | |
1448 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), | |
1449 occlusion.occlusion_from_inside_target().ToString()); | |
1450 } | |
1451 } | |
1452 }; | |
1453 | |
1454 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty); | |
1455 | |
1456 template <class Types> | |
1457 class OcclusionTrackerTestUnsorted3dLayers | |
1458 : public OcclusionTrackerTest<Types> { | |
1459 protected: | |
1460 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers) | |
1461 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1462 void RunMyTest() override { | |
1463 // Currently, The main thread layer iterator does not iterate over 3d items | |
1464 // in sorted order, because layer sorting is not performed on the main | |
1465 // thread. Because of this, the occlusion tracker cannot assume that a 3d | |
1466 // layer occludes other layers that have not yet been iterated over. For | |
1467 // now, the expected behavior is that a 3d layer simply does not add any | |
1468 // occlusion to the occlusion tracker. | |
1469 | |
1470 gfx::Transform translation_to_front; | |
1471 translation_to_front.Translate3d(0.0, 0.0, -10.0); | |
1472 gfx::Transform translation_to_back; | |
1473 translation_to_front.Translate3d(0.0, 0.0, -100.0); | |
1474 | |
1475 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1476 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); | |
1477 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer( | |
1478 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true); | |
1479 typename Types::ContentLayerType* child2 = | |
1480 this->CreateDrawingLayer(parent, | |
1481 translation_to_front, | |
1482 gfx::PointF(50.f, 50.f), | |
1483 gfx::Size(100, 100), | |
1484 true); | |
1485 parent->SetShouldFlattenTransform(false); | |
1486 parent->Set3dSortingContextId(1); | |
1487 child1->Set3dSortingContextId(1); | |
1488 child2->Set3dSortingContextId(1); | |
1489 | |
1490 this->CalcDrawEtc(parent); | |
1491 | |
1492 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1493 gfx::Rect(0, 0, 1000, 1000)); | |
1494 this->VisitLayer(child2, &occlusion); | |
1495 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1496 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1497 | |
1498 this->VisitLayer(child1, &occlusion); | |
1499 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1500 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1501 } | |
1502 }; | |
1503 | |
1504 // This test will have different layer ordering on the impl thread; the test | |
1505 // will only work on the main thread. | |
1506 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers); | |
1507 | |
1508 template <class Types> | |
1509 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude | |
1510 : public OcclusionTrackerTest<Types> { | |
1511 protected: | |
1512 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude( | |
1513 bool opaque_layers) | |
1514 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1515 void RunMyTest() override { | |
1516 gfx::Transform transform; | |
1517 transform.Translate(50.0, 50.0); | |
1518 transform.ApplyPerspectiveDepth(100.0); | |
1519 transform.Translate3d(0.0, 0.0, 110.0); | |
1520 transform.Translate(-50.0, -50.0); | |
1521 | |
1522 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1523 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); | |
1524 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( | |
1525 parent, transform, gfx::PointF(), gfx::Size(100, 100), true); | |
1526 parent->SetShouldFlattenTransform(false); | |
1527 parent->Set3dSortingContextId(1); | |
1528 layer->SetShouldFlattenTransform(false); | |
1529 layer->Set3dSortingContextId(1); | |
1530 this->CalcDrawEtc(parent); | |
1531 | |
1532 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1533 gfx::Rect(0, 0, 1000, 1000)); | |
1534 | |
1535 // The |layer| is entirely behind the camera and should not occlude. | |
1536 this->VisitLayer(layer, &occlusion); | |
1537 this->EnterLayer(parent, &occlusion); | |
1538 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
1539 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
1540 } | |
1541 }; | |
1542 | |
1543 template <class Types> | |
1544 class OcclusionTrackerTestAnimationOpacity1OnMainThread | |
1545 : public OcclusionTrackerTest<Types> { | |
1546 protected: | |
1547 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers) | |
1548 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1549 void RunMyTest() override { | |
1550 // parent | |
1551 // +--layer | |
1552 // +--surface | |
1553 // | +--surface_child | |
1554 // | +--surface_child2 | |
1555 // +--parent2 | |
1556 // +--topmost | |
1557 | |
1558 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1559 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); | |
1560 typename Types::ContentLayerType* layer = | |
1561 this->CreateDrawingLayer(parent, | |
1562 this->identity_matrix, | |
1563 gfx::PointF(), | |
1564 gfx::Size(300, 300), | |
1565 true); | |
1566 typename Types::ContentLayerType* surface = | |
1567 this->CreateDrawingSurface(parent, | |
1568 this->identity_matrix, | |
1569 gfx::PointF(), | |
1570 gfx::Size(300, 300), | |
1571 true); | |
1572 typename Types::ContentLayerType* surface_child = | |
1573 this->CreateDrawingLayer(surface, | |
1574 this->identity_matrix, | |
1575 gfx::PointF(), | |
1576 gfx::Size(200, 300), | |
1577 true); | |
1578 typename Types::ContentLayerType* surface_child2 = | |
1579 this->CreateDrawingLayer(surface, | |
1580 this->identity_matrix, | |
1581 gfx::PointF(), | |
1582 gfx::Size(100, 300), | |
1583 true); | |
1584 typename Types::ContentLayerType* parent2 = | |
1585 this->CreateDrawingLayer(parent, | |
1586 this->identity_matrix, | |
1587 gfx::PointF(), | |
1588 gfx::Size(300, 300), | |
1589 false); | |
1590 typename Types::ContentLayerType* topmost = | |
1591 this->CreateDrawingLayer(parent, | |
1592 this->identity_matrix, | |
1593 gfx::PointF(250.f, 0.f), | |
1594 gfx::Size(50, 300), | |
1595 true); | |
1596 | |
1597 AddOpacityTransitionToController( | |
1598 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false); | |
1599 AddOpacityTransitionToController( | |
1600 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false); | |
1601 this->CalcDrawEtc(parent); | |
1602 | |
1603 EXPECT_TRUE(layer->draw_opacity_is_animating()); | |
1604 EXPECT_FALSE(surface->draw_opacity_is_animating()); | |
1605 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating()); | |
1606 | |
1607 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1608 gfx::Rect(0, 0, 1000, 1000)); | |
1609 | |
1610 this->VisitLayer(topmost, &occlusion); | |
1611 this->EnterLayer(parent2, &occlusion); | |
1612 | |
1613 // This occlusion will affect all surfaces. | |
1614 EXPECT_EQ(gfx::Rect().ToString(), | |
1615 occlusion.occlusion_from_outside_target().ToString()); | |
1616 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1617 occlusion.occlusion_from_inside_target().ToString()); | |
1618 | |
1619 this->LeaveLayer(parent2, &occlusion); | |
1620 this->VisitLayer(surface_child2, &occlusion); | |
1621 this->EnterLayer(surface_child, &occlusion); | |
1622 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1623 occlusion.occlusion_from_outside_target().ToString()); | |
1624 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), | |
1625 occlusion.occlusion_from_inside_target().ToString()); | |
1626 | |
1627 this->LeaveLayer(surface_child, &occlusion); | |
1628 this->EnterLayer(surface, &occlusion); | |
1629 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1630 occlusion.occlusion_from_outside_target().ToString()); | |
1631 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), | |
1632 occlusion.occlusion_from_inside_target().ToString()); | |
1633 | |
1634 this->LeaveLayer(surface, &occlusion); | |
1635 this->EnterContributingSurface(surface, &occlusion); | |
1636 // Occlusion within the surface is lost when leaving the animating surface. | |
1637 EXPECT_EQ(gfx::Rect().ToString(), | |
1638 occlusion.occlusion_from_outside_target().ToString()); | |
1639 EXPECT_EQ(gfx::Rect().ToString(), | |
1640 occlusion.occlusion_from_inside_target().ToString()); | |
1641 | |
1642 this->LeaveContributingSurface(surface, &occlusion); | |
1643 // Occlusion from outside the animating surface still exists. | |
1644 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1645 occlusion.occlusion_from_inside_target().ToString()); | |
1646 EXPECT_EQ(gfx::Rect().ToString(), | |
1647 occlusion.occlusion_from_outside_target().ToString()); | |
1648 | |
1649 this->VisitLayer(layer, &occlusion); | |
1650 this->EnterLayer(parent, &occlusion); | |
1651 | |
1652 // Occlusion is not added for the animating |layer|. | |
1653 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1654 occlusion.occlusion_from_inside_target().ToString()); | |
1655 EXPECT_EQ(gfx::Rect().ToString(), | |
1656 occlusion.occlusion_from_outside_target().ToString()); | |
1657 } | |
1658 }; | |
1659 | |
1660 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread); | |
1661 | |
1662 template <class Types> | |
1663 class OcclusionTrackerTestAnimationOpacity0OnMainThread | |
1664 : public OcclusionTrackerTest<Types> { | |
1665 protected: | |
1666 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers) | |
1667 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1668 void RunMyTest() override { | |
1669 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1670 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); | |
1671 typename Types::ContentLayerType* layer = | |
1672 this->CreateDrawingLayer(parent, | |
1673 this->identity_matrix, | |
1674 gfx::PointF(), | |
1675 gfx::Size(300, 300), | |
1676 true); | |
1677 typename Types::ContentLayerType* surface = | |
1678 this->CreateDrawingSurface(parent, | |
1679 this->identity_matrix, | |
1680 gfx::PointF(), | |
1681 gfx::Size(300, 300), | |
1682 true); | |
1683 typename Types::ContentLayerType* surface_child = | |
1684 this->CreateDrawingLayer(surface, | |
1685 this->identity_matrix, | |
1686 gfx::PointF(), | |
1687 gfx::Size(200, 300), | |
1688 true); | |
1689 typename Types::ContentLayerType* surface_child2 = | |
1690 this->CreateDrawingLayer(surface, | |
1691 this->identity_matrix, | |
1692 gfx::PointF(), | |
1693 gfx::Size(100, 300), | |
1694 true); | |
1695 typename Types::ContentLayerType* parent2 = | |
1696 this->CreateDrawingLayer(parent, | |
1697 this->identity_matrix, | |
1698 gfx::PointF(), | |
1699 gfx::Size(300, 300), | |
1700 false); | |
1701 typename Types::ContentLayerType* topmost = | |
1702 this->CreateDrawingLayer(parent, | |
1703 this->identity_matrix, | |
1704 gfx::PointF(250.f, 0.f), | |
1705 gfx::Size(50, 300), | |
1706 true); | |
1707 | |
1708 AddOpacityTransitionToController( | |
1709 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false); | |
1710 AddOpacityTransitionToController( | |
1711 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false); | |
1712 this->CalcDrawEtc(parent); | |
1713 | |
1714 EXPECT_TRUE(layer->draw_opacity_is_animating()); | |
1715 EXPECT_FALSE(surface->draw_opacity_is_animating()); | |
1716 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating()); | |
1717 | |
1718 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1719 gfx::Rect(0, 0, 1000, 1000)); | |
1720 | |
1721 this->VisitLayer(topmost, &occlusion); | |
1722 this->EnterLayer(parent2, &occlusion); | |
1723 // This occlusion will affect all surfaces. | |
1724 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1725 occlusion.occlusion_from_inside_target().ToString()); | |
1726 EXPECT_EQ(gfx::Rect().ToString(), | |
1727 occlusion.occlusion_from_outside_target().ToString()); | |
1728 | |
1729 this->LeaveLayer(parent2, &occlusion); | |
1730 this->VisitLayer(surface_child2, &occlusion); | |
1731 this->EnterLayer(surface_child, &occlusion); | |
1732 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), | |
1733 occlusion.occlusion_from_inside_target().ToString()); | |
1734 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1735 occlusion.occlusion_from_outside_target().ToString()); | |
1736 | |
1737 this->LeaveLayer(surface_child, &occlusion); | |
1738 this->EnterLayer(surface, &occlusion); | |
1739 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), | |
1740 occlusion.occlusion_from_inside_target().ToString()); | |
1741 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1742 occlusion.occlusion_from_outside_target().ToString()); | |
1743 | |
1744 this->LeaveLayer(surface, &occlusion); | |
1745 this->EnterContributingSurface(surface, &occlusion); | |
1746 // Occlusion within the surface is lost when leaving the animating surface. | |
1747 EXPECT_EQ(gfx::Rect().ToString(), | |
1748 occlusion.occlusion_from_inside_target().ToString()); | |
1749 EXPECT_EQ(gfx::Rect().ToString(), | |
1750 occlusion.occlusion_from_outside_target().ToString()); | |
1751 | |
1752 this->LeaveContributingSurface(surface, &occlusion); | |
1753 // Occlusion from outside the animating surface still exists. | |
1754 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1755 occlusion.occlusion_from_inside_target().ToString()); | |
1756 EXPECT_EQ(gfx::Rect().ToString(), | |
1757 occlusion.occlusion_from_outside_target().ToString()); | |
1758 | |
1759 this->VisitLayer(layer, &occlusion); | |
1760 this->EnterLayer(parent, &occlusion); | |
1761 | |
1762 // Occlusion is not added for the animating |layer|. | |
1763 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), | |
1764 occlusion.occlusion_from_inside_target().ToString()); | |
1765 EXPECT_EQ(gfx::Rect().ToString(), | |
1766 occlusion.occlusion_from_outside_target().ToString()); | |
1767 } | |
1768 }; | |
1769 | |
1770 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread); | |
1771 | |
1772 template <class Types> | |
1773 class OcclusionTrackerTestAnimationTranslateOnMainThread | |
1774 : public OcclusionTrackerTest<Types> { | |
1775 protected: | |
1776 explicit OcclusionTrackerTestAnimationTranslateOnMainThread( | |
1777 bool opaque_layers) | |
1778 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1779 void RunMyTest() override { | |
1780 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1781 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); | |
1782 typename Types::ContentLayerType* layer = | |
1783 this->CreateDrawingLayer(parent, | |
1784 this->identity_matrix, | |
1785 gfx::PointF(), | |
1786 gfx::Size(300, 300), | |
1787 true); | |
1788 typename Types::ContentLayerType* surface = | |
1789 this->CreateDrawingSurface(parent, | |
1790 this->identity_matrix, | |
1791 gfx::PointF(), | |
1792 gfx::Size(300, 300), | |
1793 true); | |
1794 typename Types::ContentLayerType* surface_child = | |
1795 this->CreateDrawingLayer(surface, | |
1796 this->identity_matrix, | |
1797 gfx::PointF(), | |
1798 gfx::Size(200, 300), | |
1799 true); | |
1800 typename Types::ContentLayerType* surface_child2 = | |
1801 this->CreateDrawingLayer(surface, | |
1802 this->identity_matrix, | |
1803 gfx::PointF(), | |
1804 gfx::Size(100, 300), | |
1805 true); | |
1806 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface( | |
1807 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true); | |
1808 | |
1809 AddAnimatedTransformToController( | |
1810 layer->layer_animation_controller(), 10.0, 30, 0); | |
1811 AddAnimatedTransformToController( | |
1812 surface->layer_animation_controller(), 10.0, 30, 0); | |
1813 AddAnimatedTransformToController( | |
1814 surface_child->layer_animation_controller(), 10.0, 30, 0); | |
1815 this->CalcDrawEtc(parent); | |
1816 | |
1817 EXPECT_TRUE(layer->draw_transform_is_animating()); | |
1818 EXPECT_TRUE(layer->screen_space_transform_is_animating()); | |
1819 EXPECT_TRUE( | |
1820 surface->render_surface()->target_surface_transforms_are_animating()); | |
1821 EXPECT_TRUE( | |
1822 surface->render_surface()->screen_space_transforms_are_animating()); | |
1823 // The surface owning layer doesn't animate against its own surface. | |
1824 EXPECT_FALSE(surface->draw_transform_is_animating()); | |
1825 EXPECT_TRUE(surface->screen_space_transform_is_animating()); | |
1826 EXPECT_TRUE(surface_child->draw_transform_is_animating()); | |
1827 EXPECT_TRUE(surface_child->screen_space_transform_is_animating()); | |
1828 | |
1829 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1830 gfx::Rect(0, 0, 1000, 1000)); | |
1831 | |
1832 this->VisitLayer(surface2, &occlusion); | |
1833 this->EnterContributingSurface(surface2, &occlusion); | |
1834 | |
1835 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), | |
1836 occlusion.occlusion_from_inside_target().ToString()); | |
1837 | |
1838 this->LeaveContributingSurface(surface2, &occlusion); | |
1839 this->EnterLayer(surface_child2, &occlusion); | |
1840 // surface_child2 is moving in screen space but not relative to its target, | |
1841 // so occlusion should happen in its target space only. It also means that | |
1842 // things occluding from outside the target (e.g. surface2) cannot occlude | |
1843 // this layer. | |
1844 EXPECT_EQ(gfx::Rect().ToString(), | |
1845 occlusion.occlusion_from_outside_target().ToString()); | |
1846 EXPECT_EQ(gfx::Rect().ToString(), | |
1847 occlusion.occlusion_from_inside_target().ToString()); | |
1848 | |
1849 this->LeaveLayer(surface_child2, &occlusion); | |
1850 this->EnterLayer(surface_child, &occlusion); | |
1851 // surface_child2 added to the occlusion since it is not moving relative | |
1852 // to its target. | |
1853 EXPECT_EQ(gfx::Rect().ToString(), | |
1854 occlusion.occlusion_from_outside_target().ToString()); | |
1855 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), | |
1856 occlusion.occlusion_from_inside_target().ToString()); | |
1857 | |
1858 this->LeaveLayer(surface_child, &occlusion); | |
1859 // surface_child is moving relative to its target, so it does not add | |
1860 // occlusion. | |
1861 EXPECT_EQ(gfx::Rect().ToString(), | |
1862 occlusion.occlusion_from_outside_target().ToString()); | |
1863 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), | |
1864 occlusion.occlusion_from_inside_target().ToString()); | |
1865 | |
1866 this->EnterLayer(surface, &occlusion); | |
1867 EXPECT_EQ(gfx::Rect().ToString(), | |
1868 occlusion.occlusion_from_outside_target().ToString()); | |
1869 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), | |
1870 occlusion.occlusion_from_inside_target().ToString()); | |
1871 | |
1872 this->LeaveLayer(surface, &occlusion); | |
1873 // The surface's owning layer is moving in screen space but not relative to | |
1874 // its target, so it adds to the occlusion. | |
1875 EXPECT_EQ(gfx::Rect().ToString(), | |
1876 occlusion.occlusion_from_outside_target().ToString()); | |
1877 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), | |
1878 occlusion.occlusion_from_inside_target().ToString()); | |
1879 | |
1880 this->EnterContributingSurface(surface, &occlusion); | |
1881 this->LeaveContributingSurface(surface, &occlusion); | |
1882 // The |surface| is moving in the screen and in its target, so all occlusion | |
1883 // within the surface is lost when leaving it. Only the |surface2| occlusion | |
1884 // is left. | |
1885 EXPECT_EQ(gfx::Rect().ToString(), | |
1886 occlusion.occlusion_from_outside_target().ToString()); | |
1887 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), | |
1888 occlusion.occlusion_from_inside_target().ToString()); | |
1889 | |
1890 this->VisitLayer(layer, &occlusion); | |
1891 // The |layer| is animating in the screen and in its target, so no occlusion | |
1892 // is added. | |
1893 EXPECT_EQ(gfx::Rect().ToString(), | |
1894 occlusion.occlusion_from_outside_target().ToString()); | |
1895 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), | |
1896 occlusion.occlusion_from_inside_target().ToString()); | |
1897 } | |
1898 }; | |
1899 | |
1900 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread); | |
1901 | |
1902 template <class Types> | |
1903 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent | |
1904 : public OcclusionTrackerTest<Types> { | |
1905 protected: | |
1906 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent( | |
1907 bool opaque_layers) | |
1908 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1909 void RunMyTest() override { | |
1910 gfx::Transform surface_transform; | |
1911 surface_transform.Translate(300.0, 300.0); | |
1912 surface_transform.Scale(2.0, 2.0); | |
1913 surface_transform.Translate(-150.0, -150.0); | |
1914 | |
1915 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1916 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500)); | |
1917 typename Types::ContentLayerType* surface = this->CreateDrawingSurface( | |
1918 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false); | |
1919 typename Types::ContentLayerType* surface2 = | |
1920 this->CreateDrawingSurface(parent, | |
1921 this->identity_matrix, | |
1922 gfx::PointF(50.f, 50.f), | |
1923 gfx::Size(300, 300), | |
1924 false); | |
1925 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); | |
1926 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); | |
1927 this->CalcDrawEtc(parent); | |
1928 | |
1929 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1930 gfx::Rect(0, 0, 1000, 1000)); | |
1931 | |
1932 this->VisitLayer(surface2, &occlusion); | |
1933 this->VisitContributingSurface(surface2, &occlusion); | |
1934 | |
1935 EXPECT_EQ(gfx::Rect().ToString(), | |
1936 occlusion.occlusion_from_outside_target().ToString()); | |
1937 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), | |
1938 occlusion.occlusion_from_inside_target().ToString()); | |
1939 | |
1940 // Clear any stored occlusion. | |
1941 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); | |
1942 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); | |
1943 | |
1944 this->VisitLayer(surface, &occlusion); | |
1945 this->VisitContributingSurface(surface, &occlusion); | |
1946 | |
1947 EXPECT_EQ(gfx::Rect().ToString(), | |
1948 occlusion.occlusion_from_outside_target().ToString()); | |
1949 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), | |
1950 occlusion.occlusion_from_inside_target().ToString()); | |
1951 } | |
1952 }; | |
1953 | |
1954 MAIN_AND_IMPL_THREAD_TEST( | |
1955 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent); | |
1956 | |
1957 template <class Types> | |
1958 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping | |
1959 : public OcclusionTrackerTest<Types> { | |
1960 protected: | |
1961 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping( | |
1962 bool opaque_layers) | |
1963 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1964 void RunMyTest() override { | |
1965 typename Types::ContentLayerType* parent = this->CreateRoot( | |
1966 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); | |
1967 parent->SetMasksToBounds(true); | |
1968 typename Types::ContentLayerType* surface = | |
1969 this->CreateDrawingSurface(parent, | |
1970 this->identity_matrix, | |
1971 gfx::PointF(), | |
1972 gfx::Size(500, 300), | |
1973 false); | |
1974 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200)); | |
1975 this->CalcDrawEtc(parent); | |
1976 | |
1977 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
1978 gfx::Rect(0, 0, 1000, 1000)); | |
1979 | |
1980 this->VisitLayer(surface, &occlusion); | |
1981 this->VisitContributingSurface(surface, &occlusion); | |
1982 | |
1983 EXPECT_EQ(gfx::Rect().ToString(), | |
1984 occlusion.occlusion_from_outside_target().ToString()); | |
1985 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), | |
1986 occlusion.occlusion_from_inside_target().ToString()); | |
1987 } | |
1988 }; | |
1989 | |
1990 MAIN_AND_IMPL_THREAD_TEST( | |
1991 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping); | |
1992 | |
1993 template <class Types> | |
1994 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded | |
1995 : public OcclusionTrackerTest<Types> { | |
1996 protected: | |
1997 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers) | |
1998 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
1999 void RunMyTest() override { | |
2000 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2001 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); | |
2002 typename Types::LayerType* surface = | |
2003 this->CreateDrawingSurface(parent, | |
2004 this->identity_matrix, | |
2005 gfx::PointF(), | |
2006 gfx::Size(100, 100), | |
2007 true); | |
2008 this->CreateReplicaLayer(surface, | |
2009 this->identity_matrix, | |
2010 gfx::PointF(0.f, 100.f), | |
2011 gfx::Size(100, 100)); | |
2012 typename Types::LayerType* topmost = | |
2013 this->CreateDrawingLayer(parent, | |
2014 this->identity_matrix, | |
2015 gfx::PointF(), | |
2016 gfx::Size(100, 110), | |
2017 true); | |
2018 this->CalcDrawEtc(parent); | |
2019 | |
2020 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2021 gfx::Rect(0, 0, 1000, 1000)); | |
2022 | |
2023 // |topmost| occludes the surface, but not the entire surface's replica. | |
2024 this->VisitLayer(topmost, &occlusion); | |
2025 | |
2026 EXPECT_EQ(gfx::Rect().ToString(), | |
2027 occlusion.occlusion_from_outside_target().ToString()); | |
2028 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), | |
2029 occlusion.occlusion_from_inside_target().ToString()); | |
2030 | |
2031 this->VisitLayer(surface, &occlusion); | |
2032 | |
2033 // Render target with replica ignores occlusion from outside. | |
2034 EXPECT_EQ(gfx::Rect().ToString(), | |
2035 occlusion.occlusion_from_outside_target().ToString()); | |
2036 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | |
2037 occlusion.occlusion_from_inside_target().ToString()); | |
2038 | |
2039 this->EnterContributingSurface(surface, &occlusion); | |
2040 | |
2041 // Only occlusion from outside the surface occludes the surface/replica. | |
2042 EXPECT_EQ(gfx::Rect().ToString(), | |
2043 occlusion.occlusion_on_contributing_surface_from_outside_target() | |
2044 .ToString()); | |
2045 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), | |
2046 occlusion.occlusion_on_contributing_surface_from_inside_target() | |
2047 .ToString()); | |
2048 } | |
2049 }; | |
2050 | |
2051 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded); | |
2052 | |
2053 template <class Types> | |
2054 class OcclusionTrackerTestSurfaceChildOfSurface | |
2055 : public OcclusionTrackerTest<Types> { | |
2056 protected: | |
2057 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers) | |
2058 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2059 void RunMyTest() override { | |
2060 // This test verifies that the surface cliprect does not end up empty and | |
2061 // clip away the entire unoccluded rect. | |
2062 | |
2063 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2064 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); | |
2065 typename Types::LayerType* surface = | |
2066 this->CreateDrawingSurface(parent, | |
2067 this->identity_matrix, | |
2068 gfx::PointF(), | |
2069 gfx::Size(100, 100), | |
2070 false); | |
2071 typename Types::LayerType* surface_child = | |
2072 this->CreateDrawingSurface(surface, | |
2073 this->identity_matrix, | |
2074 gfx::PointF(0.f, 10.f), | |
2075 gfx::Size(100, 50), | |
2076 true); | |
2077 typename Types::LayerType* topmost = this->CreateDrawingLayer( | |
2078 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true); | |
2079 this->CalcDrawEtc(parent); | |
2080 | |
2081 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2082 gfx::Rect(-100, -100, 1000, 1000)); | |
2083 | |
2084 // |topmost| occludes everything partially so we know occlusion is happening | |
2085 // at all. | |
2086 this->VisitLayer(topmost, &occlusion); | |
2087 | |
2088 EXPECT_EQ(gfx::Rect().ToString(), | |
2089 occlusion.occlusion_from_outside_target().ToString()); | |
2090 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), | |
2091 occlusion.occlusion_from_inside_target().ToString()); | |
2092 | |
2093 this->VisitLayer(surface_child, &occlusion); | |
2094 | |
2095 // surface_child increases the occlusion in the screen by a narrow sliver. | |
2096 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), | |
2097 occlusion.occlusion_from_outside_target().ToString()); | |
2098 // In its own surface, surface_child is at 0,0 as is its occlusion. | |
2099 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), | |
2100 occlusion.occlusion_from_inside_target().ToString()); | |
2101 | |
2102 // The root layer always has a clip rect. So the parent of |surface| has a | |
2103 // clip rect. However, the owning layer for |surface| does not mask to | |
2104 // bounds, so it doesn't have a clip rect of its own. Thus the parent of | |
2105 // |surface_child| exercises different code paths as its parent does not | |
2106 // have a clip rect. | |
2107 | |
2108 this->EnterContributingSurface(surface_child, &occlusion); | |
2109 // The |surface_child| can't occlude its own surface, but occlusion from | |
2110 // |topmost| can. | |
2111 EXPECT_EQ(gfx::Rect().ToString(), | |
2112 occlusion.occlusion_on_contributing_surface_from_outside_target() | |
2113 .ToString()); | |
2114 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), | |
2115 occlusion.occlusion_on_contributing_surface_from_inside_target() | |
2116 .ToString()); | |
2117 this->LeaveContributingSurface(surface_child, &occlusion); | |
2118 | |
2119 // When the surface_child's occlusion is transformed up to its parent, make | |
2120 // sure it is not clipped away inappropriately. | |
2121 this->EnterLayer(surface, &occlusion); | |
2122 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), | |
2123 occlusion.occlusion_from_outside_target().ToString()); | |
2124 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), | |
2125 occlusion.occlusion_from_inside_target().ToString()); | |
2126 this->LeaveLayer(surface, &occlusion); | |
2127 | |
2128 this->EnterContributingSurface(surface, &occlusion); | |
2129 // The occlusion from inside |surface| can't affect the surface, but | |
2130 // |topmost| can. | |
2131 EXPECT_EQ(gfx::Rect().ToString(), | |
2132 occlusion.occlusion_on_contributing_surface_from_outside_target() | |
2133 .ToString()); | |
2134 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), | |
2135 occlusion.occlusion_on_contributing_surface_from_inside_target() | |
2136 .ToString()); | |
2137 | |
2138 this->LeaveContributingSurface(surface, &occlusion); | |
2139 this->EnterLayer(parent, &occlusion); | |
2140 // The occlusion in |surface| and without are merged into the parent. | |
2141 EXPECT_EQ(gfx::Rect().ToString(), | |
2142 occlusion.occlusion_from_outside_target().ToString()); | |
2143 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), | |
2144 occlusion.occlusion_from_inside_target().ToString()); | |
2145 } | |
2146 }; | |
2147 | |
2148 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface); | |
2149 | |
2150 template <class Types> | |
2151 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter | |
2152 : public OcclusionTrackerTest<Types> { | |
2153 protected: | |
2154 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter( | |
2155 bool opaque_layers) | |
2156 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2157 void RunMyTest() override { | |
2158 gfx::Transform scale_by_half; | |
2159 scale_by_half.Scale(0.5, 0.5); | |
2160 | |
2161 FilterOperations filters; | |
2162 filters.Append(FilterOperation::CreateBlurFilter(10.f)); | |
2163 | |
2164 // Save the distance of influence for the blur effect. | |
2165 int outset_top, outset_right, outset_bottom, outset_left; | |
2166 filters.GetOutsets( | |
2167 &outset_top, &outset_right, &outset_bottom, &outset_left); | |
2168 | |
2169 enum Direction { | |
2170 LEFT, | |
2171 RIGHT, | |
2172 TOP, | |
2173 BOTTOM, | |
2174 LAST_DIRECTION = BOTTOM, | |
2175 }; | |
2176 | |
2177 for (int i = 0; i <= LAST_DIRECTION; ++i) { | |
2178 SCOPED_TRACE(i); | |
2179 | |
2180 // Make a 50x50 filtered surface that is adjacent to occluding layers | |
2181 // which are above it in the z-order in various configurations. The | |
2182 // surface is scaled to test that the pixel moving is done in the target | |
2183 // space, where the background filter is applied. | |
2184 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2185 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); | |
2186 typename Types::LayerType* filtered_surface = | |
2187 this->CreateDrawingLayer(parent, | |
2188 scale_by_half, | |
2189 gfx::PointF(50.f, 50.f), | |
2190 gfx::Size(100, 100), | |
2191 false); | |
2192 Types::SetForceRenderSurface(filtered_surface, true); | |
2193 filtered_surface->SetBackgroundFilters(filters); | |
2194 gfx::Rect occlusion_rect; | |
2195 switch (i) { | |
2196 case LEFT: | |
2197 occlusion_rect = gfx::Rect(0, 0, 50, 200); | |
2198 break; | |
2199 case RIGHT: | |
2200 occlusion_rect = gfx::Rect(100, 0, 50, 200); | |
2201 break; | |
2202 case TOP: | |
2203 occlusion_rect = gfx::Rect(0, 0, 200, 50); | |
2204 break; | |
2205 case BOTTOM: | |
2206 occlusion_rect = gfx::Rect(0, 100, 200, 50); | |
2207 break; | |
2208 } | |
2209 | |
2210 typename Types::LayerType* occluding_layer = | |
2211 this->CreateDrawingLayer(parent, | |
2212 this->identity_matrix, | |
2213 occlusion_rect.origin(), | |
2214 occlusion_rect.size(), | |
2215 true); | |
2216 this->CalcDrawEtc(parent); | |
2217 | |
2218 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2219 gfx::Rect(0, 0, 200, 200)); | |
2220 | |
2221 // This layer occludes pixels directly beside the filtered_surface. | |
2222 // Because filtered surface blends pixels in a radius, it will need to see | |
2223 // some of the pixels (up to radius far) underneath the occluding layers. | |
2224 this->VisitLayer(occluding_layer, &occlusion); | |
2225 | |
2226 EXPECT_EQ(occlusion_rect.ToString(), | |
2227 occlusion.occlusion_from_inside_target().ToString()); | |
2228 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
2229 | |
2230 this->VisitLayer(filtered_surface, &occlusion); | |
2231 | |
2232 // The occlusion is used fully inside the surface. | |
2233 gfx::Rect occlusion_inside_surface = | |
2234 occlusion_rect - gfx::Vector2d(50, 50); | |
2235 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
2236 EXPECT_EQ(occlusion_inside_surface.ToString(), | |
2237 occlusion.occlusion_from_outside_target().ToString()); | |
2238 | |
2239 // The surface has a background blur, so it needs pixels that are | |
2240 // currently considered occluded in order to be drawn. So the pixels it | |
2241 // needs should be removed some the occluded area so that when we get to | |
2242 // the parent they are drawn. | |
2243 this->VisitContributingSurface(filtered_surface, &occlusion); | |
2244 this->EnterLayer(parent, &occlusion); | |
2245 | |
2246 gfx::Rect expected_occlusion = occlusion_rect; | |
2247 switch (i) { | |
2248 case LEFT: | |
2249 expected_occlusion.Inset(0, 0, outset_right, 0); | |
2250 break; | |
2251 case RIGHT: | |
2252 expected_occlusion.Inset(outset_right, 0, 0, 0); | |
2253 break; | |
2254 case TOP: | |
2255 expected_occlusion.Inset(0, 0, 0, outset_right); | |
2256 break; | |
2257 case BOTTOM: | |
2258 expected_occlusion.Inset(0, outset_right, 0, 0); | |
2259 break; | |
2260 } | |
2261 | |
2262 EXPECT_EQ(expected_occlusion.ToString(), | |
2263 occlusion.occlusion_from_inside_target().ToString()); | |
2264 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
2265 | |
2266 this->DestroyLayers(); | |
2267 } | |
2268 } | |
2269 }; | |
2270 | |
2271 ALL_OCCLUSIONTRACKER_TEST( | |
2272 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter); | |
2273 | |
2274 template <class Types> | |
2275 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice | |
2276 : public OcclusionTrackerTest<Types> { | |
2277 protected: | |
2278 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice( | |
2279 bool opaque_layers) | |
2280 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2281 void RunMyTest() override { | |
2282 gfx::Transform scale_by_half; | |
2283 scale_by_half.Scale(0.5, 0.5); | |
2284 | |
2285 // Makes two surfaces that completely cover |parent|. The occlusion both | |
2286 // above and below the filters will be reduced by each of them. | |
2287 typename Types::ContentLayerType* root = this->CreateRoot( | |
2288 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75)); | |
2289 typename Types::LayerType* parent = this->CreateSurface( | |
2290 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150)); | |
2291 parent->SetMasksToBounds(true); | |
2292 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer( | |
2293 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); | |
2294 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer( | |
2295 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); | |
2296 typename Types::LayerType* occluding_layer_above = | |
2297 this->CreateDrawingLayer(parent, | |
2298 this->identity_matrix, | |
2299 gfx::PointF(100.f, 100.f), | |
2300 gfx::Size(50, 50), | |
2301 true); | |
2302 | |
2303 // Filters make the layers own surfaces. | |
2304 Types::SetForceRenderSurface(filtered_surface1, true); | |
2305 Types::SetForceRenderSurface(filtered_surface2, true); | |
2306 FilterOperations filters; | |
2307 filters.Append(FilterOperation::CreateBlurFilter(1.f)); | |
2308 filtered_surface1->SetBackgroundFilters(filters); | |
2309 filtered_surface2->SetBackgroundFilters(filters); | |
2310 | |
2311 // Save the distance of influence for the blur effect. | |
2312 int outset_top, outset_right, outset_bottom, outset_left; | |
2313 filters.GetOutsets( | |
2314 &outset_top, &outset_right, &outset_bottom, &outset_left); | |
2315 | |
2316 this->CalcDrawEtc(root); | |
2317 | |
2318 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2319 gfx::Rect(0, 0, 1000, 1000)); | |
2320 | |
2321 this->VisitLayer(occluding_layer_above, &occlusion); | |
2322 EXPECT_EQ(gfx::Rect().ToString(), | |
2323 occlusion.occlusion_from_outside_target().ToString()); | |
2324 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), | |
2325 occlusion.occlusion_from_inside_target().ToString()); | |
2326 | |
2327 this->VisitLayer(filtered_surface2, &occlusion); | |
2328 this->VisitContributingSurface(filtered_surface2, &occlusion); | |
2329 this->VisitLayer(filtered_surface1, &occlusion); | |
2330 this->VisitContributingSurface(filtered_surface1, &occlusion); | |
2331 | |
2332 // Test expectations in the target. | |
2333 gfx::Rect expected_occlusion = | |
2334 gfx::Rect(100 / 2 + outset_right * 2, | |
2335 100 / 2 + outset_bottom * 2, | |
2336 50 / 2 - (outset_left + outset_right) * 2, | |
2337 50 / 2 - (outset_top + outset_bottom) * 2); | |
2338 EXPECT_EQ(expected_occlusion.ToString(), | |
2339 occlusion.occlusion_from_inside_target().ToString()); | |
2340 | |
2341 // Test expectations in the screen are the same as in the target, as the | |
2342 // render surface is 1:1 with the screen. | |
2343 EXPECT_EQ(expected_occlusion.ToString(), | |
2344 occlusion.occlusion_from_outside_target().ToString()); | |
2345 } | |
2346 }; | |
2347 | |
2348 ALL_OCCLUSIONTRACKER_TEST( | |
2349 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice); | |
2350 | |
2351 template <class Types> | |
2352 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter | |
2353 : public OcclusionTrackerTest<Types> { | |
2354 protected: | |
2355 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter( | |
2356 bool opaque_layers) | |
2357 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2358 void RunMyTest() override { | |
2359 gfx::Transform scale_by_half; | |
2360 scale_by_half.Scale(0.5, 0.5); | |
2361 | |
2362 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer | |
2363 // centered below each. The surface is scaled to test that the pixel moving | |
2364 // is done in the target space, where the background filter is applied, but | |
2365 // the surface appears at 50, 50 and the replica at 200, 50. | |
2366 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2367 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); | |
2368 typename Types::LayerType* behind_surface_layer = | |
2369 this->CreateDrawingLayer(parent, | |
2370 this->identity_matrix, | |
2371 gfx::PointF(60.f, 60.f), | |
2372 gfx::Size(30, 30), | |
2373 true); | |
2374 typename Types::LayerType* behind_replica_layer = | |
2375 this->CreateDrawingLayer(parent, | |
2376 this->identity_matrix, | |
2377 gfx::PointF(210.f, 60.f), | |
2378 gfx::Size(30, 30), | |
2379 true); | |
2380 typename Types::LayerType* filtered_surface = | |
2381 this->CreateDrawingLayer(parent, | |
2382 scale_by_half, | |
2383 gfx::PointF(50.f, 50.f), | |
2384 gfx::Size(100, 100), | |
2385 false); | |
2386 this->CreateReplicaLayer(filtered_surface, | |
2387 this->identity_matrix, | |
2388 gfx::PointF(300.f, 0.f), | |
2389 gfx::Size()); | |
2390 | |
2391 // Filters make the layer own a surface. | |
2392 Types::SetForceRenderSurface(filtered_surface, true); | |
2393 FilterOperations filters; | |
2394 filters.Append(FilterOperation::CreateBlurFilter(3.f)); | |
2395 filtered_surface->SetBackgroundFilters(filters); | |
2396 | |
2397 this->CalcDrawEtc(parent); | |
2398 | |
2399 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2400 gfx::Rect(0, 0, 1000, 1000)); | |
2401 | |
2402 // The surface has a background blur, so it blurs non-opaque pixels below | |
2403 // it. | |
2404 this->VisitLayer(filtered_surface, &occlusion); | |
2405 this->VisitContributingSurface(filtered_surface, &occlusion); | |
2406 | |
2407 this->VisitLayer(behind_replica_layer, &occlusion); | |
2408 | |
2409 // The layers behind the surface are not blurred, and their occlusion does | |
2410 // not change, until we leave the surface. So it should not be modified by | |
2411 // the filter here. | |
2412 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30); | |
2413 EXPECT_EQ(occlusion_behind_replica.ToString(), | |
2414 occlusion.occlusion_from_inside_target().ToString()); | |
2415 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
2416 | |
2417 // Clear the occlusion so the |behind_surface_layer| can add its occlusion | |
2418 // without existing occlusion interfering. | |
2419 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); | |
2420 | |
2421 this->VisitLayer(behind_surface_layer, &occlusion); | |
2422 | |
2423 // The layers behind the surface are not blurred, and their occlusion does | |
2424 // not change, until we leave the surface. So it should not be modified by | |
2425 // the filter here. | |
2426 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30); | |
2427 EXPECT_EQ(occlusion_behind_surface.ToString(), | |
2428 occlusion.occlusion_from_inside_target().ToString()); | |
2429 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
2430 } | |
2431 }; | |
2432 | |
2433 ALL_OCCLUSIONTRACKER_TEST( | |
2434 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter); | |
2435 | |
2436 template <class Types> | |
2437 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded | |
2438 : public OcclusionTrackerTest<Types> { | |
2439 protected: | |
2440 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded( | |
2441 bool opaque_layers) | |
2442 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2443 void RunMyTest() override { | |
2444 gfx::Transform scale_by_half; | |
2445 scale_by_half.Scale(0.5, 0.5); | |
2446 | |
2447 // Make a 50x50 filtered surface that is completely occluded by an opaque | |
2448 // layer which is above it in the z-order. The surface is | |
2449 // scaled to test that the pixel moving is done in the target space, where | |
2450 // the background filter is applied, but the surface appears at 50, 50. | |
2451 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2452 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150)); | |
2453 typename Types::LayerType* filtered_surface = | |
2454 this->CreateDrawingLayer(parent, | |
2455 scale_by_half, | |
2456 gfx::PointF(50.f, 50.f), | |
2457 gfx::Size(100, 100), | |
2458 false); | |
2459 typename Types::LayerType* occluding_layer = | |
2460 this->CreateDrawingLayer(parent, | |
2461 this->identity_matrix, | |
2462 gfx::PointF(50.f, 50.f), | |
2463 gfx::Size(50, 50), | |
2464 true); | |
2465 | |
2466 // Filters make the layer own a surface. | |
2467 Types::SetForceRenderSurface(filtered_surface, true); | |
2468 FilterOperations filters; | |
2469 filters.Append(FilterOperation::CreateBlurFilter(3.f)); | |
2470 filtered_surface->SetBackgroundFilters(filters); | |
2471 | |
2472 this->CalcDrawEtc(parent); | |
2473 | |
2474 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2475 gfx::Rect(0, 0, 1000, 1000)); | |
2476 | |
2477 this->VisitLayer(occluding_layer, &occlusion); | |
2478 | |
2479 this->VisitLayer(filtered_surface, &occlusion); | |
2480 { | |
2481 // The layers above the filtered surface occlude from outside. | |
2482 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50); | |
2483 | |
2484 EXPECT_EQ(gfx::Rect().ToString(), | |
2485 occlusion.occlusion_from_inside_target().ToString()); | |
2486 EXPECT_EQ(occlusion_above_surface.ToString(), | |
2487 occlusion.occlusion_from_outside_target().ToString()); | |
2488 } | |
2489 | |
2490 // The surface has a background blur, so it blurs non-opaque pixels below | |
2491 // it. | |
2492 this->VisitContributingSurface(filtered_surface, &occlusion); | |
2493 { | |
2494 // The filter is completely occluded, so it should not blur anything and | |
2495 // reduce any occlusion. | |
2496 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50); | |
2497 | |
2498 EXPECT_EQ(occlusion_above_surface.ToString(), | |
2499 occlusion.occlusion_from_inside_target().ToString()); | |
2500 EXPECT_EQ(gfx::Rect().ToString(), | |
2501 occlusion.occlusion_from_outside_target().ToString()); | |
2502 } | |
2503 } | |
2504 }; | |
2505 | |
2506 ALL_OCCLUSIONTRACKER_TEST( | |
2507 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded); | |
2508 | |
2509 template <class Types> | |
2510 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded | |
2511 : public OcclusionTrackerTest<Types> { | |
2512 protected: | |
2513 explicit | |
2514 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded( | |
2515 bool opaque_layers) | |
2516 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2517 void RunMyTest() override { | |
2518 gfx::Transform scale_by_half; | |
2519 scale_by_half.Scale(0.5, 0.5); | |
2520 | |
2521 // Make a surface and its replica, each 50x50, that are partially occluded | |
2522 // by opaque layers which are above them in the z-order. The surface is | |
2523 // scaled to test that the pixel moving is done in the target space, where | |
2524 // the background filter is applied, but the surface appears at 50, 50 and | |
2525 // the replica at 200, 50. | |
2526 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2527 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); | |
2528 typename Types::LayerType* filtered_surface = | |
2529 this->CreateDrawingLayer(parent, | |
2530 scale_by_half, | |
2531 gfx::PointF(50.f, 50.f), | |
2532 gfx::Size(100, 100), | |
2533 false); | |
2534 this->CreateReplicaLayer(filtered_surface, | |
2535 this->identity_matrix, | |
2536 gfx::PointF(300.f, 0.f), | |
2537 gfx::Size()); | |
2538 typename Types::LayerType* above_surface_layer = | |
2539 this->CreateDrawingLayer(parent, | |
2540 this->identity_matrix, | |
2541 gfx::PointF(70.f, 50.f), | |
2542 gfx::Size(30, 50), | |
2543 true); | |
2544 typename Types::LayerType* above_replica_layer = | |
2545 this->CreateDrawingLayer(parent, | |
2546 this->identity_matrix, | |
2547 gfx::PointF(200.f, 50.f), | |
2548 gfx::Size(30, 50), | |
2549 true); | |
2550 typename Types::LayerType* beside_surface_layer = | |
2551 this->CreateDrawingLayer(parent, | |
2552 this->identity_matrix, | |
2553 gfx::PointF(90.f, 40.f), | |
2554 gfx::Size(10, 10), | |
2555 true); | |
2556 typename Types::LayerType* beside_replica_layer = | |
2557 this->CreateDrawingLayer(parent, | |
2558 this->identity_matrix, | |
2559 gfx::PointF(200.f, 40.f), | |
2560 gfx::Size(10, 10), | |
2561 true); | |
2562 | |
2563 // Filters make the layer own a surface. | |
2564 Types::SetForceRenderSurface(filtered_surface, true); | |
2565 FilterOperations filters; | |
2566 filters.Append(FilterOperation::CreateBlurFilter(3.f)); | |
2567 filtered_surface->SetBackgroundFilters(filters); | |
2568 | |
2569 // Save the distance of influence for the blur effect. | |
2570 int outset_top, outset_right, outset_bottom, outset_left; | |
2571 filters.GetOutsets( | |
2572 &outset_top, &outset_right, &outset_bottom, &outset_left); | |
2573 | |
2574 this->CalcDrawEtc(parent); | |
2575 | |
2576 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2577 gfx::Rect(0, 0, 1000, 1000)); | |
2578 | |
2579 this->VisitLayer(beside_replica_layer, &occlusion); | |
2580 this->VisitLayer(beside_surface_layer, &occlusion); | |
2581 this->VisitLayer(above_replica_layer, &occlusion); | |
2582 this->VisitLayer(above_surface_layer, &occlusion); | |
2583 | |
2584 // The surface has a background blur, so it blurs non-opaque pixels below | |
2585 // it. | |
2586 this->VisitLayer(filtered_surface, &occlusion); | |
2587 this->VisitContributingSurface(filtered_surface, &occlusion); | |
2588 | |
2589 // The filter in the surface and replica are partially unoccluded. Only the | |
2590 // unoccluded parts should reduce occlusion. This means it will push back | |
2591 // the occlusion that touches the unoccluded part (occlusion_above___), but | |
2592 // it will not touch occlusion_beside____ since that is not beside the | |
2593 // unoccluded part of the surface, even though it is beside the occluded | |
2594 // part of the surface. | |
2595 gfx::Rect occlusion_above_surface = | |
2596 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50); | |
2597 gfx::Rect occlusion_above_replica = | |
2598 gfx::Rect(200, 50, 30 - outset_left, 50); | |
2599 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10); | |
2600 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10); | |
2601 | |
2602 SimpleEnclosedRegion expected_occlusion; | |
2603 expected_occlusion.Union(occlusion_beside_replica); | |
2604 expected_occlusion.Union(occlusion_beside_surface); | |
2605 expected_occlusion.Union(occlusion_above_replica); | |
2606 expected_occlusion.Union(occlusion_above_surface); | |
2607 | |
2608 EXPECT_EQ(expected_occlusion.ToString(), | |
2609 occlusion.occlusion_from_inside_target().ToString()); | |
2610 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
2611 | |
2612 const SimpleEnclosedRegion& actual_occlusion = | |
2613 occlusion.occlusion_from_inside_target(); | |
2614 for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) { | |
2615 ASSERT_LT(i, actual_occlusion.GetRegionComplexity()); | |
2616 EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i)); | |
2617 } | |
2618 } | |
2619 }; | |
2620 | |
2621 ALL_OCCLUSIONTRACKER_TEST( | |
2622 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded); | |
2623 | |
2624 template <class Types> | |
2625 class OcclusionTrackerTestBlendModeDoesNotOcclude | |
2626 : public OcclusionTrackerTest<Types> { | |
2627 protected: | |
2628 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers) | |
2629 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2630 void RunMyTest() override { | |
2631 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2632 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); | |
2633 typename Types::LayerType* blend_mode_layer = this->CreateDrawingLayer( | |
2634 parent, this->identity_matrix, gfx::PointF(0.f, 0.f), | |
2635 gfx::Size(100, 100), true); | |
2636 typename Types::LayerType* top_layer = this->CreateDrawingLayer( | |
2637 parent, this->identity_matrix, gfx::PointF(10.f, 12.f), | |
2638 gfx::Size(20, 22), true); | |
2639 | |
2640 // Blend mode makes the layer own a surface. | |
2641 Types::SetForceRenderSurface(blend_mode_layer, true); | |
2642 blend_mode_layer->SetBlendMode(SkXfermode::kMultiply_Mode); | |
2643 | |
2644 this->CalcDrawEtc(parent); | |
2645 | |
2646 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2647 gfx::Rect(0, 0, 1000, 1000)); | |
2648 | |
2649 this->VisitLayer(top_layer, &occlusion); | |
2650 // |top_layer| occludes. | |
2651 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), | |
2652 occlusion.occlusion_from_inside_target().ToString()); | |
2653 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
2654 | |
2655 this->VisitLayer(blend_mode_layer, &occlusion); | |
2656 // |top_layer| occludes but not |blend_mode_layer|. | |
2657 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), | |
2658 occlusion.occlusion_from_outside_target().ToString()); | |
2659 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | |
2660 | |
2661 this->VisitContributingSurface(blend_mode_layer, &occlusion); | |
2662 // |top_layer| occludes but not |blend_mode_layer|. | |
2663 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), | |
2664 occlusion.occlusion_from_inside_target().ToString()); | |
2665 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | |
2666 } | |
2667 }; | |
2668 | |
2669 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude); | |
2670 | |
2671 template <class Types> | |
2672 class OcclusionTrackerTestMinimumTrackingSize | |
2673 : public OcclusionTrackerTest<Types> { | |
2674 protected: | |
2675 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers) | |
2676 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2677 void RunMyTest() override { | |
2678 gfx::Size tracking_size(100, 100); | |
2679 gfx::Size below_tracking_size(99, 99); | |
2680 | |
2681 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2682 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); | |
2683 typename Types::LayerType* large = this->CreateDrawingLayer( | |
2684 parent, this->identity_matrix, gfx::PointF(), tracking_size, true); | |
2685 typename Types::LayerType* small = | |
2686 this->CreateDrawingLayer(parent, | |
2687 this->identity_matrix, | |
2688 gfx::PointF(), | |
2689 below_tracking_size, | |
2690 true); | |
2691 this->CalcDrawEtc(parent); | |
2692 | |
2693 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2694 gfx::Rect(0, 0, 1000, 1000)); | |
2695 occlusion.set_minimum_tracking_size(tracking_size); | |
2696 | |
2697 // The small layer is not tracked because it is too small. | |
2698 this->VisitLayer(small, &occlusion); | |
2699 | |
2700 EXPECT_EQ(gfx::Rect().ToString(), | |
2701 occlusion.occlusion_from_outside_target().ToString()); | |
2702 EXPECT_EQ(gfx::Rect().ToString(), | |
2703 occlusion.occlusion_from_inside_target().ToString()); | |
2704 | |
2705 // The large layer is tracked as it is large enough. | |
2706 this->VisitLayer(large, &occlusion); | |
2707 | |
2708 EXPECT_EQ(gfx::Rect().ToString(), | |
2709 occlusion.occlusion_from_outside_target().ToString()); | |
2710 EXPECT_EQ(gfx::Rect(tracking_size).ToString(), | |
2711 occlusion.occlusion_from_inside_target().ToString()); | |
2712 } | |
2713 }; | |
2714 | |
2715 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize); | |
2716 | |
2717 template <class Types> | |
2718 class OcclusionTrackerTestScaledLayerIsClipped | |
2719 : public OcclusionTrackerTest<Types> { | |
2720 protected: | |
2721 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers) | |
2722 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2723 void RunMyTest() override { | |
2724 gfx::Transform scale_transform; | |
2725 scale_transform.Scale(512.0, 512.0); | |
2726 | |
2727 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2728 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); | |
2729 typename Types::LayerType* clip = this->CreateLayer(parent, | |
2730 this->identity_matrix, | |
2731 gfx::PointF(10.f, 10.f), | |
2732 gfx::Size(50, 50)); | |
2733 clip->SetMasksToBounds(true); | |
2734 typename Types::LayerType* scale = this->CreateLayer( | |
2735 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1)); | |
2736 typename Types::LayerType* scaled = this->CreateDrawingLayer( | |
2737 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); | |
2738 this->CalcDrawEtc(parent); | |
2739 | |
2740 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2741 gfx::Rect(0, 0, 1000, 1000)); | |
2742 | |
2743 this->VisitLayer(scaled, &occlusion); | |
2744 | |
2745 EXPECT_EQ(gfx::Rect().ToString(), | |
2746 occlusion.occlusion_from_outside_target().ToString()); | |
2747 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), | |
2748 occlusion.occlusion_from_inside_target().ToString()); | |
2749 } | |
2750 }; | |
2751 | |
2752 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped) | |
2753 | |
2754 template <class Types> | |
2755 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped | |
2756 : public OcclusionTrackerTest<Types> { | |
2757 protected: | |
2758 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers) | |
2759 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2760 void RunMyTest() override { | |
2761 gfx::Transform scale_transform; | |
2762 scale_transform.Scale(512.0, 512.0); | |
2763 | |
2764 typename Types::ContentLayerType* parent = this->CreateRoot( | |
2765 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); | |
2766 typename Types::LayerType* clip = this->CreateLayer(parent, | |
2767 this->identity_matrix, | |
2768 gfx::PointF(10.f, 10.f), | |
2769 gfx::Size(50, 50)); | |
2770 clip->SetMasksToBounds(true); | |
2771 typename Types::LayerType* surface = this->CreateDrawingSurface( | |
2772 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false); | |
2773 typename Types::LayerType* scale = this->CreateLayer( | |
2774 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1)); | |
2775 typename Types::LayerType* scaled = this->CreateDrawingLayer( | |
2776 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); | |
2777 this->CalcDrawEtc(parent); | |
2778 | |
2779 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2780 gfx::Rect(0, 0, 1000, 1000)); | |
2781 | |
2782 this->VisitLayer(scaled, &occlusion); | |
2783 this->VisitLayer(surface, &occlusion); | |
2784 this->VisitContributingSurface(surface, &occlusion); | |
2785 | |
2786 EXPECT_EQ(gfx::Rect().ToString(), | |
2787 occlusion.occlusion_from_outside_target().ToString()); | |
2788 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), | |
2789 occlusion.occlusion_from_inside_target().ToString()); | |
2790 } | |
2791 }; | |
2792 | |
2793 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped) | |
2794 | |
2795 template <class Types> | |
2796 class OcclusionTrackerTestCopyRequestDoesOcclude | |
2797 : public OcclusionTrackerTest<Types> { | |
2798 protected: | |
2799 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers) | |
2800 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2801 void RunMyTest() override { | |
2802 typename Types::ContentLayerType* root = this->CreateRoot( | |
2803 this->identity_matrix, gfx::Point(), gfx::Size(400, 400)); | |
2804 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( | |
2805 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true); | |
2806 typename Types::LayerType* copy = this->CreateLayer(parent, | |
2807 this->identity_matrix, | |
2808 gfx::Point(100, 0), | |
2809 gfx::Size(200, 400)); | |
2810 this->AddCopyRequest(copy); | |
2811 typename Types::LayerType* copy_child = this->CreateDrawingLayer( | |
2812 copy, | |
2813 this->identity_matrix, | |
2814 gfx::PointF(), | |
2815 gfx::Size(200, 400), | |
2816 true); | |
2817 typename Types::LayerType* top_layer = | |
2818 this->CreateDrawingLayer(root, this->identity_matrix, | |
2819 gfx::PointF(50, 0), gfx::Size(50, 400), true); | |
2820 this->CalcDrawEtc(root); | |
2821 | |
2822 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2823 gfx::Rect(0, 0, 1000, 1000)); | |
2824 | |
2825 this->VisitLayer(top_layer, &occlusion); | |
2826 EXPECT_EQ(gfx::Rect().ToString(), | |
2827 occlusion.occlusion_from_outside_target().ToString()); | |
2828 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(), | |
2829 occlusion.occlusion_from_inside_target().ToString()); | |
2830 | |
2831 this->VisitLayer(copy_child, &occlusion); | |
2832 // Layers outside the copy request do not occlude. | |
2833 EXPECT_EQ(gfx::Rect().ToString(), | |
2834 occlusion.occlusion_from_outside_target().ToString()); | |
2835 EXPECT_EQ(gfx::Rect(200, 400).ToString(), | |
2836 occlusion.occlusion_from_inside_target().ToString()); | |
2837 | |
2838 // CopyRequests cause the layer to own a surface. | |
2839 this->VisitContributingSurface(copy, &occlusion); | |
2840 | |
2841 // The occlusion from the copy should be kept. | |
2842 EXPECT_EQ(gfx::Rect().ToString(), | |
2843 occlusion.occlusion_from_outside_target().ToString()); | |
2844 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(), | |
2845 occlusion.occlusion_from_inside_target().ToString()); | |
2846 } | |
2847 }; | |
2848 | |
2849 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude) | |
2850 | |
2851 template <class Types> | |
2852 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude | |
2853 : public OcclusionTrackerTest<Types> { | |
2854 protected: | |
2855 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude( | |
2856 bool opaque_layers) | |
2857 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2858 void RunMyTest() override { | |
2859 typename Types::ContentLayerType* root = this->CreateRoot( | |
2860 this->identity_matrix, gfx::Point(), gfx::Size(400, 400)); | |
2861 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( | |
2862 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true); | |
2863 typename Types::LayerType* hide = this->CreateLayer( | |
2864 parent, this->identity_matrix, gfx::Point(), gfx::Size()); | |
2865 typename Types::LayerType* copy = this->CreateLayer( | |
2866 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400)); | |
2867 this->AddCopyRequest(copy); | |
2868 typename Types::LayerType* copy_child = this->CreateDrawingLayer( | |
2869 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true); | |
2870 | |
2871 // The |copy| layer is hidden but since it is being copied, it will be | |
2872 // drawn. | |
2873 hide->SetHideLayerAndSubtree(true); | |
2874 | |
2875 this->CalcDrawEtc(root); | |
2876 | |
2877 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2878 gfx::Rect(0, 0, 1000, 1000)); | |
2879 | |
2880 this->VisitLayer(copy_child, &occlusion); | |
2881 EXPECT_EQ(gfx::Rect().ToString(), | |
2882 occlusion.occlusion_from_outside_target().ToString()); | |
2883 EXPECT_EQ(gfx::Rect(200, 400).ToString(), | |
2884 occlusion.occlusion_from_inside_target().ToString()); | |
2885 | |
2886 // CopyRequests cause the layer to own a surface. | |
2887 this->VisitContributingSurface(copy, &occlusion); | |
2888 | |
2889 // The occlusion from the copy should be dropped since it is hidden. | |
2890 EXPECT_EQ(gfx::Rect().ToString(), | |
2891 occlusion.occlusion_from_outside_target().ToString()); | |
2892 EXPECT_EQ(gfx::Rect().ToString(), | |
2893 occlusion.occlusion_from_inside_target().ToString()); | |
2894 } | |
2895 }; | |
2896 | |
2897 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude) | |
2898 | |
2899 template <class Types> | |
2900 class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> { | |
2901 protected: | |
2902 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers) | |
2903 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2904 void RunMyTest() override { | |
2905 gfx::Transform translate; | |
2906 translate.Translate(10.0, 20.0); | |
2907 typename Types::ContentLayerType* root = this->CreateRoot( | |
2908 this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); | |
2909 typename Types::LayerType* surface = this->CreateSurface( | |
2910 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); | |
2911 typename Types::LayerType* layer = this->CreateDrawingLayer( | |
2912 surface, translate, gfx::Point(), gfx::Size(200, 200), false); | |
2913 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( | |
2914 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); | |
2915 this->CalcDrawEtc(root); | |
2916 | |
2917 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
2918 gfx::Rect(0, 0, 200, 200)); | |
2919 this->VisitLayer(outside_layer, &occlusion); | |
2920 this->EnterLayer(layer, &occlusion); | |
2921 | |
2922 // No occlusion, is not occluded. | |
2923 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); | |
2924 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); | |
2925 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100))); | |
2926 | |
2927 // Partial occlusion from outside, is not occluded. | |
2928 occlusion.set_occlusion_from_outside_target( | |
2929 SimpleEnclosedRegion(50, 50, 100, 100)); | |
2930 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); | |
2931 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); | |
2932 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); | |
2933 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); | |
2934 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); | |
2935 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); | |
2936 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); | |
2937 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); | |
2938 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); | |
2939 | |
2940 // Full occlusion from outside, is occluded. | |
2941 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); | |
2942 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); | |
2943 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); | |
2944 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); | |
2945 | |
2946 // Partial occlusion from inside, is not occluded. | |
2947 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); | |
2948 occlusion.set_occlusion_from_inside_target( | |
2949 SimpleEnclosedRegion(50, 50, 100, 100)); | |
2950 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); | |
2951 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); | |
2952 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); | |
2953 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); | |
2954 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); | |
2955 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); | |
2956 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); | |
2957 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); | |
2958 | |
2959 // Full occlusion from inside, is occluded. | |
2960 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); | |
2961 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); | |
2962 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); | |
2963 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); | |
2964 | |
2965 // Partial occlusion from both, is not occluded. | |
2966 occlusion.set_occlusion_from_outside_target( | |
2967 SimpleEnclosedRegion(50, 50, 100, 50)); | |
2968 occlusion.set_occlusion_from_inside_target( | |
2969 SimpleEnclosedRegion(50, 100, 100, 50)); | |
2970 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); | |
2971 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); | |
2972 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); | |
2973 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); | |
2974 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); | |
2975 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); | |
2976 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); | |
2977 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); | |
2978 | |
2979 // Full occlusion from both, is occluded. | |
2980 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); | |
2981 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); | |
2982 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); | |
2983 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); | |
2984 } | |
2985 }; | |
2986 | |
2987 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer) | |
2988 | |
2989 template <class Types> | |
2990 class OcclusionTrackerTestUnoccludedLayerQuery | |
2991 : public OcclusionTrackerTest<Types> { | |
2992 protected: | |
2993 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers) | |
2994 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
2995 void RunMyTest() override { | |
2996 gfx::Transform translate; | |
2997 translate.Translate(10.0, 20.0); | |
2998 typename Types::ContentLayerType* root = this->CreateRoot( | |
2999 this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); | |
3000 typename Types::LayerType* surface = this->CreateSurface( | |
3001 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); | |
3002 typename Types::LayerType* layer = this->CreateDrawingLayer( | |
3003 surface, translate, gfx::Point(), gfx::Size(200, 200), false); | |
3004 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( | |
3005 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); | |
3006 this->CalcDrawEtc(root); | |
3007 | |
3008 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
3009 gfx::Rect(0, 0, 200, 200)); | |
3010 this->VisitLayer(outside_layer, &occlusion); | |
3011 this->EnterLayer(layer, &occlusion); | |
3012 | |
3013 // No occlusion, is not occluded. | |
3014 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); | |
3015 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); | |
3016 EXPECT_EQ(gfx::Rect(100, 100), | |
3017 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100))); | |
3018 | |
3019 // Partial occlusion from outside. | |
3020 occlusion.set_occlusion_from_outside_target( | |
3021 SimpleEnclosedRegion(50, 50, 100, 100)); | |
3022 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); | |
3023 EXPECT_EQ( | |
3024 gfx::Rect(0, 0, 100, 100), | |
3025 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); | |
3026 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), | |
3027 occlusion.UnoccludedLayerContentRect( | |
3028 layer, gfx::Rect(90, 30, 100, 100))); | |
3029 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), | |
3030 occlusion.UnoccludedLayerContentRect(layer, | |
3031 gfx::Rect(40, 0, 100, 100))); | |
3032 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), | |
3033 occlusion.UnoccludedLayerContentRect( | |
3034 layer, gfx::Rect(40, 80, 100, 100))); | |
3035 EXPECT_EQ( | |
3036 gfx::Rect(0, 0, 80, 100), | |
3037 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); | |
3038 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), | |
3039 occlusion.UnoccludedLayerContentRect( | |
3040 layer, gfx::Rect(90, 80, 100, 100))); | |
3041 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), | |
3042 occlusion.UnoccludedLayerContentRect(layer, | |
3043 gfx::Rect(0, 80, 100, 100))); | |
3044 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), | |
3045 occlusion.UnoccludedLayerContentRect(layer, | |
3046 gfx::Rect(90, 0, 100, 100))); | |
3047 | |
3048 // Full occlusion from outside, is occluded. | |
3049 EXPECT_EQ(gfx::Rect(), | |
3050 occlusion.UnoccludedLayerContentRect( | |
3051 layer, gfx::Rect(40, 30, 100, 100))); | |
3052 EXPECT_EQ( | |
3053 gfx::Rect(), | |
3054 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); | |
3055 EXPECT_EQ(gfx::Rect(), | |
3056 occlusion.UnoccludedLayerContentRect( | |
3057 layer, gfx::Rect(130, 120, 10, 10))); | |
3058 EXPECT_EQ( | |
3059 gfx::Rect(), | |
3060 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); | |
3061 | |
3062 // Partial occlusion from inside, is not occluded. | |
3063 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); | |
3064 occlusion.set_occlusion_from_inside_target( | |
3065 SimpleEnclosedRegion(50, 50, 100, 100)); | |
3066 EXPECT_EQ( | |
3067 gfx::Rect(0, 0, 100, 100), | |
3068 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); | |
3069 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), | |
3070 occlusion.UnoccludedLayerContentRect( | |
3071 layer, gfx::Rect(90, 30, 100, 100))); | |
3072 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), | |
3073 occlusion.UnoccludedLayerContentRect(layer, | |
3074 gfx::Rect(40, 0, 100, 100))); | |
3075 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), | |
3076 occlusion.UnoccludedLayerContentRect( | |
3077 layer, gfx::Rect(40, 80, 100, 100))); | |
3078 EXPECT_EQ( | |
3079 gfx::Rect(0, 0, 80, 100), | |
3080 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); | |
3081 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), | |
3082 occlusion.UnoccludedLayerContentRect( | |
3083 layer, gfx::Rect(90, 80, 100, 100))); | |
3084 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), | |
3085 occlusion.UnoccludedLayerContentRect(layer, | |
3086 gfx::Rect(0, 80, 100, 100))); | |
3087 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), | |
3088 occlusion.UnoccludedLayerContentRect(layer, | |
3089 gfx::Rect(90, 0, 100, 100))); | |
3090 | |
3091 // Full occlusion from inside, is occluded. | |
3092 EXPECT_EQ(gfx::Rect(), | |
3093 occlusion.UnoccludedLayerContentRect( | |
3094 layer, gfx::Rect(40, 30, 100, 100))); | |
3095 EXPECT_EQ( | |
3096 gfx::Rect(), | |
3097 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); | |
3098 EXPECT_EQ(gfx::Rect(), | |
3099 occlusion.UnoccludedLayerContentRect( | |
3100 layer, gfx::Rect(130, 120, 10, 10))); | |
3101 EXPECT_EQ( | |
3102 gfx::Rect(), | |
3103 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); | |
3104 | |
3105 // Partial occlusion from both, is not occluded. | |
3106 occlusion.set_occlusion_from_outside_target( | |
3107 SimpleEnclosedRegion(50, 50, 100, 50)); | |
3108 occlusion.set_occlusion_from_inside_target( | |
3109 SimpleEnclosedRegion(50, 100, 100, 50)); | |
3110 EXPECT_EQ( | |
3111 gfx::Rect(0, 0, 100, 100), | |
3112 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); | |
3113 // This could be (140, 30, 50, 100). But because we do a lossy subtract, | |
3114 // it's larger. | |
3115 EXPECT_EQ(gfx::Rect(90, 30, 100, 100), | |
3116 occlusion.UnoccludedLayerContentRect( | |
3117 layer, gfx::Rect(90, 30, 100, 100))); | |
3118 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), | |
3119 occlusion.UnoccludedLayerContentRect(layer, | |
3120 gfx::Rect(40, 0, 100, 100))); | |
3121 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), | |
3122 occlusion.UnoccludedLayerContentRect( | |
3123 layer, gfx::Rect(40, 80, 100, 100))); | |
3124 EXPECT_EQ( | |
3125 gfx::Rect(0, 0, 80, 100), | |
3126 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); | |
3127 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), | |
3128 occlusion.UnoccludedLayerContentRect( | |
3129 layer, gfx::Rect(90, 80, 100, 100))); | |
3130 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), | |
3131 occlusion.UnoccludedLayerContentRect(layer, | |
3132 gfx::Rect(0, 80, 100, 100))); | |
3133 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), | |
3134 occlusion.UnoccludedLayerContentRect(layer, | |
3135 gfx::Rect(90, 0, 100, 100))); | |
3136 | |
3137 // Full occlusion from both, is occluded. | |
3138 EXPECT_EQ(gfx::Rect(), | |
3139 occlusion.UnoccludedLayerContentRect( | |
3140 layer, gfx::Rect(40, 30, 100, 100))); | |
3141 EXPECT_EQ( | |
3142 gfx::Rect(), | |
3143 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); | |
3144 EXPECT_EQ(gfx::Rect(), | |
3145 occlusion.UnoccludedLayerContentRect( | |
3146 layer, gfx::Rect(130, 120, 10, 10))); | |
3147 EXPECT_EQ( | |
3148 gfx::Rect(), | |
3149 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); | |
3150 } | |
3151 }; | |
3152 | |
3153 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery) | |
3154 | |
3155 template <class Types> | |
3156 class OcclusionTrackerTestUnoccludedSurfaceQuery | |
3157 : public OcclusionTrackerTest<Types> { | |
3158 protected: | |
3159 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers) | |
3160 : OcclusionTrackerTest<Types>(opaque_layers) {} | |
3161 void RunMyTest() override { | |
3162 gfx::Transform translate; | |
3163 translate.Translate(10.0, 20.0); | |
3164 typename Types::ContentLayerType* root = this->CreateRoot( | |
3165 this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); | |
3166 typename Types::LayerType* surface = | |
3167 this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200)); | |
3168 typename Types::LayerType* layer = | |
3169 this->CreateDrawingLayer(surface, | |
3170 this->identity_matrix, | |
3171 gfx::Point(), | |
3172 gfx::Size(200, 200), | |
3173 false); | |
3174 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( | |
3175 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); | |
3176 this->CalcDrawEtc(root); | |
3177 | |
3178 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( | |
3179 gfx::Rect(0, 0, 200, 200)); | |
3180 this->VisitLayer(outside_layer, &occlusion); | |
3181 this->VisitLayer(layer, &occlusion); | |
3182 this->EnterContributingSurface(surface, &occlusion); | |
3183 | |
3184 // No occlusion, is not occluded. | |
3185 occlusion.set_occlusion_on_contributing_surface_from_outside_target( | |
3186 SimpleEnclosedRegion()); | |
3187 occlusion.set_occlusion_on_contributing_surface_from_inside_target( | |
3188 SimpleEnclosedRegion()); | |
3189 EXPECT_EQ( | |
3190 gfx::Rect(100, 100), | |
3191 occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100))); | |
3192 | |
3193 // Partial occlusion from outside. | |
3194 occlusion.set_occlusion_on_contributing_surface_from_outside_target( | |
3195 SimpleEnclosedRegion(50, 50, 100, 100)); | |
3196 occlusion.set_occlusion_on_contributing_surface_from_inside_target( | |
3197 SimpleEnclosedRegion()); | |
3198 EXPECT_EQ(gfx::Rect(0, 0, 100, 100), | |
3199 occlusion.UnoccludedSurfaceContentRect( | |
3200 surface, gfx::Rect(0, 0, 100, 100))); | |
3201 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), | |
3202 occlusion.UnoccludedSurfaceContentRect( | |
3203 surface, gfx::Rect(90, 30, 100, 100))); | |
3204 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), | |
3205 occlusion.UnoccludedSurfaceContentRect( | |
3206 surface, gfx::Rect(40, 0, 100, 100))); | |
3207 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), | |
3208 occlusion.UnoccludedSurfaceContentRect( | |
3209 surface, gfx::Rect(40, 80, 100, 100))); | |
3210 EXPECT_EQ(gfx::Rect(0, 0, 80, 100), | |
3211 occlusion.UnoccludedSurfaceContentRect(surface, | |
3212 gfx::Rect(0, 0, 80, 100))); | |
3213 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), | |
3214 occlusion.UnoccludedSurfaceContentRect( | |
3215 surface, gfx::Rect(90, 80, 100, 100))); | |
3216 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), | |
3217 occlusion.UnoccludedSurfaceContentRect( | |
3218 surface, gfx::Rect(0, 80, 100, 100))); | |
3219 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), | |
3220 occlusion.UnoccludedSurfaceContentRect( | |
3221 surface, gfx::Rect(90, 0, 100, 100))); | |
3222 | |
3223 // Full occlusion from outside, is occluded. | |
3224 EXPECT_EQ(gfx::Rect(), | |
3225 occlusion.UnoccludedSurfaceContentRect( | |
3226 surface, gfx::Rect(40, 30, 100, 100))); | |
3227 EXPECT_EQ(gfx::Rect(), | |
3228 occlusion.UnoccludedSurfaceContentRect( | |
3229 surface, gfx::Rect(40, 30, 10, 10))); | |
3230 EXPECT_EQ(gfx::Rect(), | |
3231 occlusion.UnoccludedSurfaceContentRect( | |
3232 surface, gfx::Rect(130, 120, 10, 10))); | |
3233 EXPECT_EQ(gfx::Rect(), | |
3234 occlusion.UnoccludedSurfaceContentRect( | |
3235 surface, gfx::Rect(80, 70, 50, 50))); | |
3236 | |
3237 // Partial occlusion from inside, is not occluded. | |
3238 occlusion.set_occlusion_on_contributing_surface_from_outside_target( | |
3239 SimpleEnclosedRegion()); | |
3240 occlusion.set_occlusion_on_contributing_surface_from_inside_target( | |
3241 SimpleEnclosedRegion(50, 50, 100, 100)); | |
3242 EXPECT_EQ(gfx::Rect(0, 0, 100, 100), | |
3243 occlusion.UnoccludedSurfaceContentRect( | |
3244 surface, gfx::Rect(0, 0, 100, 100))); | |
3245 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), | |
3246 occlusion.UnoccludedSurfaceContentRect( | |
3247 surface, gfx::Rect(90, 30, 100, 100))); | |
3248 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), | |
3249 occlusion.UnoccludedSurfaceContentRect( | |
3250 surface, gfx::Rect(40, 0, 100, 100))); | |
3251 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), | |
3252 occlusion.UnoccludedSurfaceContentRect( | |
3253 surface, gfx::Rect(40, 80, 100, 100))); | |
3254 EXPECT_EQ(gfx::Rect(0, 0, 80, 100), | |
3255 occlusion.UnoccludedSurfaceContentRect(surface, | |
3256 gfx::Rect(0, 0, 80, 100))); | |
3257 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), | |
3258 occlusion.UnoccludedSurfaceContentRect( | |
3259 surface, gfx::Rect(90, 80, 100, 100))); | |
3260 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), | |
3261 occlusion.UnoccludedSurfaceContentRect( | |
3262 surface, gfx::Rect(0, 80, 100, 100))); | |
3263 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), | |
3264 occlusion.UnoccludedSurfaceContentRect( | |
3265 surface, gfx::Rect(90, 0, 100, 100))); | |
3266 | |
3267 // Full occlusion from inside, is occluded. | |
3268 EXPECT_EQ(gfx::Rect(), | |
3269 occlusion.UnoccludedSurfaceContentRect( | |
3270 surface, gfx::Rect(40, 30, 100, 100))); | |
3271 EXPECT_EQ(gfx::Rect(), | |
3272 occlusion.UnoccludedSurfaceContentRect( | |
3273 surface, gfx::Rect(40, 30, 10, 10))); | |
3274 EXPECT_EQ(gfx::Rect(), | |
3275 occlusion.UnoccludedSurfaceContentRect( | |
3276 surface, gfx::Rect(130, 120, 10, 10))); | |
3277 EXPECT_EQ(gfx::Rect(), | |
3278 occlusion.UnoccludedSurfaceContentRect( | |
3279 surface, gfx::Rect(80, 70, 50, 50))); | |
3280 | |
3281 // Partial occlusion from both, is not occluded. | |
3282 occlusion.set_occlusion_on_contributing_surface_from_outside_target( | |
3283 SimpleEnclosedRegion(50, 50, 100, 50)); | |
3284 occlusion.set_occlusion_on_contributing_surface_from_inside_target( | |
3285 SimpleEnclosedRegion(50, 100, 100, 50)); | |
3286 EXPECT_EQ(gfx::Rect(0, 0, 100, 100), | |
3287 occlusion.UnoccludedSurfaceContentRect( | |
3288 surface, gfx::Rect(0, 0, 100, 100))); | |
3289 // This could be (140, 30, 50, 100). But because we do a lossy subtract, | |
3290 // it's larger. | |
3291 EXPECT_EQ(gfx::Rect(90, 30, 100, 100), | |
3292 occlusion.UnoccludedSurfaceContentRect( | |
3293 surface, gfx::Rect(90, 30, 100, 100))); | |
3294 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), | |
3295 occlusion.UnoccludedSurfaceContentRect( | |
3296 surface, gfx::Rect(40, 0, 100, 100))); | |
3297 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), | |
3298 occlusion.UnoccludedSurfaceContentRect( | |
3299 surface, gfx::Rect(40, 80, 100, 100))); | |
3300 EXPECT_EQ(gfx::Rect(0, 0, 80, 100), | |
3301 occlusion.UnoccludedSurfaceContentRect(surface, | |
3302 gfx::Rect(0, 0, 80, 100))); | |
3303 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), | |
3304 occlusion.UnoccludedSurfaceContentRect( | |
3305 surface, gfx::Rect(90, 80, 100, 100))); | |
3306 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), | |
3307 occlusion.UnoccludedSurfaceContentRect( | |
3308 surface, gfx::Rect(0, 80, 100, 100))); | |
3309 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), | |
3310 occlusion.UnoccludedSurfaceContentRect( | |
3311 surface, gfx::Rect(90, 0, 100, 100))); | |
3312 | |
3313 // Full occlusion from both, is occluded. | |
3314 EXPECT_EQ(gfx::Rect(), | |
3315 occlusion.UnoccludedSurfaceContentRect( | |
3316 surface, gfx::Rect(40, 30, 100, 100))); | |
3317 EXPECT_EQ(gfx::Rect(), | |
3318 occlusion.UnoccludedSurfaceContentRect( | |
3319 surface, gfx::Rect(40, 30, 10, 10))); | |
3320 EXPECT_EQ(gfx::Rect(), | |
3321 occlusion.UnoccludedSurfaceContentRect( | |
3322 surface, gfx::Rect(130, 120, 10, 10))); | |
3323 EXPECT_EQ(gfx::Rect(), | |
3324 occlusion.UnoccludedSurfaceContentRect( | |
3325 surface, gfx::Rect(80, 70, 50, 50))); | |
3326 } | |
3327 }; | |
3328 | |
3329 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery) | |
3330 | |
3331 } // namespace | |
3332 } // namespace cc | |
OLD | NEW |