add a use_alsa gyp setting
[chromium-blink-merge.git] / cc / layer_tree_host_unittest_occlusion.cc
blob20434f68d04e0b4c5475ed4d5fa19016a7e936ce
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.
5 #include "cc/layer_tree_host.h"
7 #include "cc/layer.h"
8 #include "cc/test/layer_tree_test_common.h"
9 #include "cc/test/occlusion_tracker_test_common.h"
11 namespace cc {
12 namespace {
14 class TestLayer : public Layer {
15 public:
16 static scoped_refptr<TestLayer> Create() {
17 return make_scoped_refptr(new TestLayer());
20 virtual void update(
21 ResourceUpdateQueue& update_queue,
22 const OcclusionTracker* occlusion,
23 RenderingStats* stats) OVERRIDE {
24 if (!occlusion)
25 return;
27 // Gain access to internals of the OcclusionTracker.
28 const TestOcclusionTracker* test_occlusion =
29 static_cast<const TestOcclusionTracker*>(occlusion);
30 occlusion_ = UnionRegions(
31 test_occlusion->occlusionFromInsideTarget(),
32 test_occlusion->occlusionFromOutsideTarget());
35 const Region& occlusion() const { return occlusion_; }
36 const Region& expected_occlusion() const { return expected_occlusion_; }
37 void set_expected_occlusion(const Region& occlusion) {
38 expected_occlusion_ = occlusion;
41 private:
42 TestLayer() : Layer() {
43 setIsDrawable(true);
45 virtual ~TestLayer() { }
47 Region occlusion_;
48 Region expected_occlusion_;
51 class LayerTreeHostOcclusionTest : public ThreadedTest {
52 public:
54 LayerTreeHostOcclusionTest()
55 : root_(TestLayer::Create()),
56 child_(TestLayer::Create()),
57 child2_(TestLayer::Create()),
58 grand_child_(TestLayer::Create()),
59 mask_(TestLayer::Create()) {
62 virtual void beginTest() OVERRIDE {
63 postSetNeedsCommitToMainThread();
66 virtual void didCommit() OVERRIDE {
67 TestLayer* root = static_cast<TestLayer*>(m_layerTreeHost->rootLayer());
68 VerifyOcclusion(root);
70 endTest();
73 virtual void afterTest() OVERRIDE {}
75 void VerifyOcclusion(TestLayer* layer) const {
76 EXPECT_EQ(layer->expected_occlusion().ToString(),
77 layer->occlusion().ToString());
79 for (size_t i = 0; i < layer->children().size(); ++i) {
80 TestLayer* child = static_cast<TestLayer*>(layer->children()[i].get());
81 VerifyOcclusion(child);
85 void SetLayerPropertiesForTesting(
86 TestLayer* layer, TestLayer* parent, const gfx::Transform& transform,
87 const gfx::PointF& position, const gfx::Size& bounds, bool opaque) const {
88 layer->removeAllChildren();
89 if (parent)
90 parent->addChild(layer);
91 layer->setTransform(transform);
92 layer->setPosition(position);
93 layer->setBounds(bounds);
94 layer->setContentsOpaque(opaque);
96 layer->setAnchorPoint(gfx::PointF());
99 protected:
100 scoped_refptr<TestLayer> root_;
101 scoped_refptr<TestLayer> child_;
102 scoped_refptr<TestLayer> child2_;
103 scoped_refptr<TestLayer> grand_child_;
104 scoped_refptr<TestLayer> mask_;
106 gfx::Transform identity_matrix_;
110 class LayerTreeHostOcclusionTestOcclusionSurfaceClipping :
111 public LayerTreeHostOcclusionTest {
112 public:
113 virtual void setupTree() OVERRIDE {
114 // The child layer is a surface and the grandChild is opaque, but clipped to
115 // the child and root
116 SetLayerPropertiesForTesting(
117 root_.get(), NULL, identity_matrix_,
118 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
119 SetLayerPropertiesForTesting(
120 child_.get(), root_.get(), identity_matrix_,
121 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
122 SetLayerPropertiesForTesting(
123 grand_child_.get(), child_.get(), identity_matrix_,
124 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
126 child_->setMasksToBounds(true);
127 child_->setForceRenderSurface(true);
129 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
130 root_->set_expected_occlusion(gfx::Rect(10, 10, 10, 190));
132 m_layerTreeHost->setRootLayer(root_);
133 ThreadedTest::setupTree();
137 SINGLE_AND_MULTI_THREAD_TEST_F(
138 LayerTreeHostOcclusionTestOcclusionSurfaceClipping)
140 class LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque :
141 public LayerTreeHostOcclusionTest {
142 public:
143 virtual void setupTree() OVERRIDE {
144 // If the child layer is opaque, then it adds to the occlusion seen by the
145 // root_.
146 SetLayerPropertiesForTesting(
147 root_.get(), NULL, identity_matrix_,
148 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
149 SetLayerPropertiesForTesting(
150 child_.get(), root_.get(), identity_matrix_,
151 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
152 SetLayerPropertiesForTesting(
153 grand_child_.get(), child_.get(), identity_matrix_,
154 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
156 child_->setMasksToBounds(true);
157 child_->setForceRenderSurface(true);
159 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
160 root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));
162 m_layerTreeHost->setRootLayer(root_);
163 ThreadedTest::setupTree();
167 SINGLE_AND_MULTI_THREAD_TEST_F(
168 LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque);
170 class LayerTreeHostOcclusionTestOcclusionTwoChildren :
171 public LayerTreeHostOcclusionTest {
172 public:
173 virtual void setupTree() OVERRIDE {
174 // Add a second child to the root layer and the regions should merge
175 SetLayerPropertiesForTesting(
176 root_.get(), NULL, identity_matrix_,
177 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
178 SetLayerPropertiesForTesting(
179 child_.get(), root_.get(), identity_matrix_,
180 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
181 SetLayerPropertiesForTesting(
182 grand_child_.get(), child_.get(), identity_matrix_,
183 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
184 SetLayerPropertiesForTesting(
185 child2_.get(), root_.get(), identity_matrix_,
186 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
188 child_->setMasksToBounds(true);
189 child_->setForceRenderSurface(true);
191 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
192 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
193 root_->set_expected_occlusion(gfx::Rect(10, 10, 20, 190));
195 m_layerTreeHost->setRootLayer(root_);
196 ThreadedTest::setupTree();
200 SINGLE_AND_MULTI_THREAD_TEST_F(
201 LayerTreeHostOcclusionTestOcclusionTwoChildren)
203 class LayerTreeHostOcclusionTestOcclusionMask :
204 public LayerTreeHostOcclusionTest {
205 public:
206 virtual void setupTree() OVERRIDE {
207 // If the child layer has a mask on it, then it shouldn't contribute to
208 // occlusion on stuff below it.
209 SetLayerPropertiesForTesting(
210 root_.get(), NULL, identity_matrix_,
211 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
212 SetLayerPropertiesForTesting(
213 child2_.get(), root_.get(), identity_matrix_,
214 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
215 SetLayerPropertiesForTesting(
216 child_.get(), root_.get(), identity_matrix_,
217 gfx::PointF(20.f, 20.f), gfx::Size(500, 500), true);
218 SetLayerPropertiesForTesting(
219 grand_child_.get(), child_.get(), identity_matrix_,
220 gfx::PointF(-10.f, -10.f), gfx::Size(500, 500), true);
222 child_->setMasksToBounds(true);
223 child_->setForceRenderSurface(true);
224 child_->setMaskLayer(mask_.get());
226 child_->set_expected_occlusion(gfx::Rect(0, 0, 180, 180));
227 root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));
229 m_layerTreeHost->setRootLayer(root_);
230 ThreadedTest::setupTree();
234 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionMask)
236 class LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion :
237 public LayerTreeHostOcclusionTest {
238 public:
239 virtual void setupTree() OVERRIDE {
240 // If the child layer with a mask is below child2, then child2 should
241 // contribute to occlusion on everything, and child shouldn't contribute
242 // to the root_.
243 SetLayerPropertiesForTesting(
244 root_.get(), NULL, identity_matrix_,
245 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
246 SetLayerPropertiesForTesting(
247 child_.get(), root_.get(), identity_matrix_,
248 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
249 SetLayerPropertiesForTesting(
250 grand_child_.get(), child_.get(), identity_matrix_,
251 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
252 SetLayerPropertiesForTesting(
253 child2_.get(), root_.get(), identity_matrix_,
254 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
256 child_->setMasksToBounds(true);
257 child_->setForceRenderSurface(true);
258 child_->setMaskLayer(mask_.get());
260 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
261 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
262 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
264 m_layerTreeHost->setRootLayer(root_);
265 ThreadedTest::setupTree();
269 SINGLE_AND_MULTI_THREAD_TEST_F(
270 LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion)
272 class LayerTreeHostOcclusionTestOcclusionOpacity :
273 public LayerTreeHostOcclusionTest {
274 public:
275 virtual void setupTree() OVERRIDE {
276 // If the child layer has a non-opaque opacity, then it shouldn't
277 // contribute to occlusion on stuff below it
278 SetLayerPropertiesForTesting(
279 root_.get(), NULL, identity_matrix_,
280 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
281 SetLayerPropertiesForTesting(
282 child2_.get(), root_.get(), identity_matrix_,
283 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
284 SetLayerPropertiesForTesting(
285 child_.get(), root_.get(), identity_matrix_,
286 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
287 SetLayerPropertiesForTesting(
288 grand_child_.get(), child_.get(), identity_matrix_,
289 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
291 child_->setMasksToBounds(true);
292 child_->setForceRenderSurface(true);
293 child_->setOpacity(0.5f);
295 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
296 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
298 m_layerTreeHost->setRootLayer(root_);
299 ThreadedTest::setupTree();
303 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionOpacity)
305 class LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion :
306 public LayerTreeHostOcclusionTest {
307 public:
308 virtual void setupTree() OVERRIDE {
309 // If the child layer with non-opaque opacity is below child2, then
310 // child2 should contribute to occlusion on everything, and child shouldn't
311 // contribute to the root_.
312 SetLayerPropertiesForTesting(
313 root_.get(), NULL, identity_matrix_,
314 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
315 SetLayerPropertiesForTesting(
316 child_.get(), root_.get(), identity_matrix_,
317 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
318 SetLayerPropertiesForTesting(
319 grand_child_.get(), child_.get(), identity_matrix_,
320 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
321 SetLayerPropertiesForTesting(
322 child2_.get(), root_.get(), identity_matrix_,
323 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
325 child_->setMasksToBounds(true);
326 child_->setForceRenderSurface(true);
327 child_->setOpacity(0.5f);
329 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
330 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
331 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
333 m_layerTreeHost->setRootLayer(root_);
334 ThreadedTest::setupTree();
338 SINGLE_AND_MULTI_THREAD_TEST_F(
339 LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion)
341 class LayerTreeHostOcclusionTestOcclusionOpacityFilter :
342 public LayerTreeHostOcclusionTest {
343 public:
344 virtual void setupTree() OVERRIDE {
345 gfx::Transform childTransform;
346 childTransform.Translate(250.0, 250.0);
347 childTransform.Rotate(90.0);
348 childTransform.Translate(-250.0, -250.0);
350 WebKit::WebFilterOperations filters;
351 filters.append(WebKit::WebFilterOperation::createOpacityFilter(0.5));
353 // If the child layer has a filter that changes alpha values, and is below
354 // child2, then child2 should contribute to occlusion on everything,
355 // and child shouldn't contribute to the root
356 SetLayerPropertiesForTesting(
357 root_.get(), NULL, identity_matrix_,
358 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
359 SetLayerPropertiesForTesting(
360 child_.get(), root_.get(), childTransform,
361 gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true);
362 SetLayerPropertiesForTesting(
363 grand_child_.get(), child_.get(), identity_matrix_,
364 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
365 SetLayerPropertiesForTesting(
366 child2_.get(), root_.get(), identity_matrix_,
367 gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true);
369 child_->setMasksToBounds(true);
370 child_->setFilters(filters);
372 grand_child_->set_expected_occlusion(gfx::Rect(40, 330, 130, 190));
373 child_->set_expected_occlusion(UnionRegions(
374 gfx::Rect(10, 330, 160, 170), gfx::Rect(40, 500, 130, 20)));
375 root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130));
377 m_layerTreeHost->setRootLayer(root_);
378 ThreadedTest::setupTree();
382 SINGLE_AND_MULTI_THREAD_TEST_F(
383 LayerTreeHostOcclusionTestOcclusionOpacityFilter)
385 class LayerTreeHostOcclusionTestOcclusionBlurFilter :
386 public LayerTreeHostOcclusionTest {
387 public:
388 virtual void setupTree() OVERRIDE {
389 gfx::Transform childTransform;
390 childTransform.Translate(250.0, 250.0);
391 childTransform.Rotate(90.0);
392 childTransform.Translate(-250.0, -250.0);
394 WebKit::WebFilterOperations filters;
395 filters.append(WebKit::WebFilterOperation::createBlurFilter(10));
397 // If the child layer has a filter that moves pixels/changes alpha, and is
398 // below child2, then child should not inherit occlusion from outside its
399 // subtree, and should not contribute to the root
400 SetLayerPropertiesForTesting(
401 root_.get(), NULL, identity_matrix_,
402 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
403 SetLayerPropertiesForTesting(
404 child_.get(), root_.get(), childTransform,
405 gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true);
406 SetLayerPropertiesForTesting(
407 grand_child_.get(), child_.get(), identity_matrix_,
408 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
409 SetLayerPropertiesForTesting(
410 child2_.get(), root_.get(), identity_matrix_,
411 gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true);
413 child_->setMasksToBounds(true);
414 child_->setFilters(filters);
416 child_->set_expected_occlusion(gfx::Rect(10, 330, 160, 170));
417 root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130));
419 m_layerTreeHost->setRootLayer(root_);
420 ThreadedTest::setupTree();
424 SINGLE_AND_MULTI_THREAD_TEST_F(
425 LayerTreeHostOcclusionTestOcclusionBlurFilter)
427 class LayerTreeHostOcclusionTestManySurfaces :
428 public LayerTreeHostOcclusionTest {
429 public:
430 virtual void setupTree() OVERRIDE {
431 // We create enough RenderSurfaces that it will trigger Vector reallocation
432 // while computing occlusion.
433 std::vector<scoped_refptr<TestLayer> > layers;
434 int num_surfaces = 200;
435 int root_width = 400;
436 int root_height = 400;
438 for (int i = 0; i < num_surfaces; ++i) {
439 layers.push_back(TestLayer::Create());
440 if (!i) {
441 SetLayerPropertiesForTesting(
442 layers.back().get(), NULL, identity_matrix_,
443 gfx::PointF(0.f, 0.f),
444 gfx::Size(root_width, root_height), true);
445 layers.back()->createRenderSurface();
446 } else {
447 SetLayerPropertiesForTesting(
448 layers.back().get(), layers[layers.size() - 2].get(),
449 identity_matrix_,
450 gfx::PointF(1.f, 1.f),
451 gfx::Size(root_width-i, root_height-i), true);
452 layers.back()->setForceRenderSurface(true);
456 for (int i = 1; i < num_surfaces; ++i) {
457 scoped_refptr<TestLayer> child = TestLayer::Create();
458 SetLayerPropertiesForTesting(
459 child.get(), layers[i].get(), identity_matrix_,
460 gfx::PointF(0.f, 0.f), gfx::Size(root_width, root_height), false);
463 for (int i = 0; i < num_surfaces-1; ++i) {
464 gfx::Rect expected_occlusion(1, 1, root_width-i-1, root_height-i-1);
465 layers[i]->set_expected_occlusion(expected_occlusion);
468 m_layerTreeHost->setRootLayer(layers[0].get());
469 ThreadedTest::setupTree();
473 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestManySurfaces)
475 } // namespace
476 } // namespace cc