OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/trees/layer_tree_host_impl.h" | 5 #include "cc/trees/layer_tree_host_impl.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 4487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4498 const char* name; | 4498 const char* name; |
4499 const char* init_script; | 4499 const char* init_script; |
4500 const char* expected_result; | 4500 const char* expected_result; |
4501 }; | 4501 }; |
4502 | 4502 |
4503 TestCase remove_render_passes_cases[] = { | 4503 TestCase remove_render_passes_cases[] = { |
4504 { | 4504 { |
4505 "Single root pass", | 4505 "Single root pass", |
4506 "R0ssss\n", | 4506 "R0ssss\n", |
4507 "R0ssss\n" | 4507 "R0ssss\n" |
4508 }, | 4508 }, { |
4509 { | |
4510 "Single pass - no quads", | 4509 "Single pass - no quads", |
4511 "R0\n", | 4510 "R0\n", |
4512 "R0\n" | 4511 "R0\n" |
4513 }, | 4512 }, { |
4514 { | |
4515 "Two passes, no removal", | 4513 "Two passes, no removal", |
4516 "R0ssssA0sss\n" | 4514 "R0ssssA0sss\n" |
4517 "A0ssss\n", | 4515 "A0ssss\n", |
4518 "R0ssssA0sss\n" | 4516 "R0ssssA0sss\n" |
4519 "A0ssss\n" | 4517 "A0ssss\n" |
4520 }, | 4518 }, { |
4521 { | |
4522 "Two passes, remove last", | 4519 "Two passes, remove last", |
4523 "R0ssssA0[ct]sss\n" | 4520 "R0ssssA0[ct]sss\n" |
4524 "A0ssss\n", | 4521 "A0ssss\n", |
4525 "R0ssssA0sss\n" | 4522 "R0ssssA0sss\n" |
4526 }, | 4523 }, { |
4527 { | |
4528 "Have texture but contents changed - leave pass", | 4524 "Have texture but contents changed - leave pass", |
4529 "R0ssssA0[t]sss\n" | 4525 "R0ssssA0[t]sss\n" |
4530 "A0ssss\n", | 4526 "A0ssss\n", |
4531 "R0ssssA0sss\n" | 4527 "R0ssssA0sss\n" |
4532 "A0ssss\n" | 4528 "A0ssss\n" |
4533 }, | 4529 }, { |
4534 { | |
4535 "Contents didn't change but no texture - leave pass", | 4530 "Contents didn't change but no texture - leave pass", |
4536 "R0ssssA0[c]sss\n" | 4531 "R0ssssA0[c]sss\n" |
4537 "A0ssss\n", | 4532 "A0ssss\n", |
4538 "R0ssssA0sss\n" | 4533 "R0ssssA0sss\n" |
4539 "A0ssss\n" | 4534 "A0ssss\n" |
4540 }, | 4535 }, { |
4541 { | |
4542 "Replica: two quads reference the same pass; remove", | 4536 "Replica: two quads reference the same pass; remove", |
4543 "R0ssssA0[ct]A0[ct]sss\n" | 4537 "R0ssssA0[ct]A0[ct]sss\n" |
4544 "A0ssss\n", | 4538 "A0ssss\n", |
4545 "R0ssssA0A0sss\n" | 4539 "R0ssssA0A0sss\n" |
4546 }, | 4540 }, { |
4547 { | |
4548 "Replica: two quads reference the same pass; leave", | 4541 "Replica: two quads reference the same pass; leave", |
4549 "R0ssssA0[c]A0[c]sss\n" | 4542 "R0ssssA0[c]A0[c]sss\n" |
4550 "A0ssss\n", | 4543 "A0ssss\n", |
4551 "R0ssssA0A0sss\n" | 4544 "R0ssssA0A0sss\n" |
4552 "A0ssss\n", | 4545 "A0ssss\n", |
4553 }, | 4546 }, { |
4554 { | |
4555 "Many passes, remove all", | 4547 "Many passes, remove all", |
4556 "R0ssssA0[ct]sss\n" | 4548 "R0ssssA0[ct]sss\n" |
4557 "A0sssB0[ct]C0[ct]s\n" | 4549 "A0sssB0[ct]C0[ct]s\n" |
4558 "B0sssD0[ct]ssE0[ct]F0[ct]\n" | 4550 "B0sssD0[ct]ssE0[ct]F0[ct]\n" |
4559 "E0ssssss\n" | 4551 "E0ssssss\n" |
4560 "C0G0[ct]\n" | 4552 "C0G0[ct]\n" |
4561 "D0sssssss\n" | 4553 "D0sssssss\n" |
4562 "F0sssssss\n" | 4554 "F0sssssss\n" |
4563 "G0sss\n", | 4555 "G0sss\n", |
4564 | 4556 |
4565 "R0ssssA0sss\n" | 4557 "R0ssssA0sss\n" |
4566 }, | 4558 }, { |
4567 { | |
4568 "Deep recursion, remove all", | 4559 "Deep recursion, remove all", |
4569 | 4560 |
4570 "R0sssssA0[ct]ssss\n" | 4561 "R0sssssA0[ct]ssss\n" |
4571 "A0ssssB0sss\n" | 4562 "A0ssssB0sss\n" |
4572 "B0C0\n" | 4563 "B0C0\n" |
4573 "C0D0\n" | 4564 "C0D0\n" |
4574 "D0E0\n" | 4565 "D0E0\n" |
4575 "E0F0\n" | 4566 "E0F0\n" |
4576 "F0G0\n" | 4567 "F0G0\n" |
4577 "G0H0\n" | 4568 "G0H0\n" |
4578 "H0sssI0sss\n" | 4569 "H0sssI0sss\n" |
4579 "I0J0\n" | 4570 "I0J0\n" |
4580 "J0ssss\n", | 4571 "J0ssss\n", |
4581 | 4572 |
4582 "R0sssssA0ssss\n" | 4573 "R0sssssA0ssss\n" |
4583 }, | 4574 }, { |
4584 { | |
4585 "Wide recursion, remove all", | 4575 "Wide recursion, remove all", |
4586 "R0A0[ct]B0[ct]C0[ct]D0[ct]E0[ct]F0[ct]G0[ct]H0[ct]I0[ct]J0[ct]\n" | 4576 "R0A0[ct]B0[ct]C0[ct]D0[ct]E0[ct]F0[ct]G0[ct]H0[ct]I0[ct]J0[ct]\n" |
4587 "A0s\n" | 4577 "A0s\n" |
4588 "B0s\n" | 4578 "B0s\n" |
4589 "C0ssss\n" | 4579 "C0ssss\n" |
4590 "D0ssss\n" | 4580 "D0ssss\n" |
4591 "E0s\n" | 4581 "E0s\n" |
4592 "F0\n" | 4582 "F0\n" |
4593 "G0s\n" | 4583 "G0s\n" |
4594 "H0s\n" | 4584 "H0s\n" |
4595 "I0s\n" | 4585 "I0s\n" |
4596 "J0ssss\n", | 4586 "J0ssss\n", |
4597 | 4587 |
4598 "R0A0B0C0D0E0F0G0H0I0J0\n" | 4588 "R0A0B0C0D0E0F0G0H0I0J0\n" |
4599 }, | 4589 }, { |
4600 { | |
4601 "Remove passes regardless of cache state", | 4590 "Remove passes regardless of cache state", |
4602 "R0ssssA0[ct]sss\n" | 4591 "R0ssssA0[ct]sss\n" |
4603 "A0sssB0C0s\n" | 4592 "A0sssB0C0s\n" |
4604 "B0sssD0[c]ssE0[t]F0\n" | 4593 "B0sssD0[c]ssE0[t]F0\n" |
4605 "E0ssssss\n" | 4594 "E0ssssss\n" |
4606 "C0G0\n" | 4595 "C0G0\n" |
4607 "D0sssssss\n" | 4596 "D0sssssss\n" |
4608 "F0sssssss\n" | 4597 "F0sssssss\n" |
4609 "G0sss\n", | 4598 "G0sss\n", |
4610 | 4599 |
4611 "R0ssssA0sss\n" | 4600 "R0ssssA0sss\n" |
4612 }, | 4601 }, { |
4613 { | |
4614 "Leave some passes, remove others", | 4602 "Leave some passes, remove others", |
4615 | 4603 |
4616 "R0ssssA0[c]sss\n" | 4604 "R0ssssA0[c]sss\n" |
4617 "A0sssB0[t]C0[ct]s\n" | 4605 "A0sssB0[t]C0[ct]s\n" |
4618 "B0sssD0[c]ss\n" | 4606 "B0sssD0[c]ss\n" |
4619 "C0G0\n" | 4607 "C0G0\n" |
4620 "D0sssssss\n" | 4608 "D0sssssss\n" |
4621 "G0sss\n", | 4609 "G0sss\n", |
4622 | 4610 |
4623 "R0ssssA0sss\n" | 4611 "R0ssssA0sss\n" |
4624 "A0sssB0C0s\n" | 4612 "A0sssB0C0s\n" |
4625 "B0sssD0ss\n" | 4613 "B0sssD0ss\n" |
4626 "D0sssssss\n" | 4614 "D0sssssss\n" |
4627 }, | 4615 }, { |
4628 { | |
4629 0, 0, 0 | 4616 0, 0, 0 |
4630 } | 4617 } |
4631 }; | 4618 }; |
4632 | 4619 |
4633 static void VerifyRenderPassTestData( | 4620 static void VerifyRenderPassTestData( |
4634 const TestCase& test_case, | 4621 const TestCase& test_case, |
4635 const RenderPassRemovalTestData& test_data) { | 4622 const RenderPassRemovalTestData& test_data) { |
4636 char actual_result[1024]; | 4623 char actual_result[1024]; |
4637 DumpRenderPassTestData(test_data, actual_result); | 4624 DumpRenderPassTestData(test_data, actual_result); |
4638 EXPECT_STREQ(test_case.expected_result, actual_result) << "In test case: " << | 4625 EXPECT_STREQ(test_case.expected_result, actual_result) << "In test case: " << |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4932 content_layer->SetAnchorPoint(gfx::PointF()); | 4919 content_layer->SetAnchorPoint(gfx::PointF()); |
4933 content_layer->SetDrawsContent(true); | 4920 content_layer->SetDrawsContent(true); |
4934 | 4921 |
4935 gfx::Size mask_size(100, 100); | 4922 gfx::Size mask_size(100, 100); |
4936 mask_layer->SetBounds(mask_size); | 4923 mask_layer->SetBounds(mask_size); |
4937 mask_layer->SetContentBounds(mask_size); | 4924 mask_layer->SetContentBounds(mask_size); |
4938 mask_layer->SetPosition(gfx::PointF()); | 4925 mask_layer->SetPosition(gfx::PointF()); |
4939 mask_layer->SetAnchorPoint(gfx::PointF()); | 4926 mask_layer->SetAnchorPoint(gfx::PointF()); |
4940 mask_layer->SetDrawsContent(true); | 4927 mask_layer->SetDrawsContent(true); |
4941 | 4928 |
4942 | |
4943 // Check that the mask fills the surface. | 4929 // Check that the mask fills the surface. |
4944 float device_scale_factor = 1.f; | 4930 float device_scale_factor = 1.f; |
4945 host_impl_->SetViewportSize(root_size); | 4931 host_impl_->SetViewportSize(root_size); |
4946 host_impl_->SetDeviceScaleFactor(device_scale_factor); | 4932 host_impl_->SetDeviceScaleFactor(device_scale_factor); |
4947 { | 4933 { |
4948 LayerTreeHostImpl::FrameData frame; | 4934 LayerTreeHostImpl::FrameData frame; |
4949 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); | 4935 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
4950 | 4936 |
4951 ASSERT_EQ(1u, frame.render_passes.size()); | 4937 ASSERT_EQ(1u, frame.render_passes.size()); |
4952 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); | 4938 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); |
4953 ASSERT_EQ(DrawQuad::RENDER_PASS, | 4939 ASSERT_EQ(DrawQuad::RENDER_PASS, |
4954 frame.render_passes[0]->quad_list[0]->material); | 4940 frame.render_passes[0]->quad_list[0]->material); |
4955 const RenderPassDrawQuad* render_pass_quad = | 4941 const RenderPassDrawQuad* render_pass_quad = |
4956 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); | 4942 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); |
4957 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), | 4943 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), |
4958 render_pass_quad->rect.ToString()); | 4944 render_pass_quad->rect.ToString()); |
4959 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), | 4945 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
4960 render_pass_quad->mask_uv_rect.ToString()); | 4946 render_pass_quad->mask_uv_rect.ToString()); |
4961 | 4947 |
4962 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); | 4948 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
4963 host_impl_->DidDrawAllLayers(frame); | 4949 host_impl_->DidDrawAllLayers(frame); |
4964 } | 4950 } |
4965 | 4951 |
4966 | |
4967 // Applying a DSF should change the render surface size, but won't affect | 4952 // Applying a DSF should change the render surface size, but won't affect |
4968 // which part of the mask is used. | 4953 // which part of the mask is used. |
4969 device_scale_factor = 2.f; | 4954 device_scale_factor = 2.f; |
4970 gfx::Size device_viewport = | 4955 gfx::Size device_viewport = |
4971 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); | 4956 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); |
4972 host_impl_->SetViewportSize(device_viewport); | 4957 host_impl_->SetViewportSize(device_viewport); |
4973 host_impl_->SetDeviceScaleFactor(device_scale_factor); | 4958 host_impl_->SetDeviceScaleFactor(device_scale_factor); |
4974 host_impl_->active_tree()->set_needs_update_draw_properties(); | 4959 host_impl_->active_tree()->set_needs_update_draw_properties(); |
4975 { | 4960 { |
4976 LayerTreeHostImpl::FrameData frame; | 4961 LayerTreeHostImpl::FrameData frame; |
4977 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); | 4962 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
4978 | 4963 |
4979 ASSERT_EQ(1u, frame.render_passes.size()); | 4964 ASSERT_EQ(1u, frame.render_passes.size()); |
4980 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); | 4965 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); |
4981 ASSERT_EQ(DrawQuad::RENDER_PASS, | 4966 ASSERT_EQ(DrawQuad::RENDER_PASS, |
4982 frame.render_passes[0]->quad_list[0]->material); | 4967 frame.render_passes[0]->quad_list[0]->material); |
4983 const RenderPassDrawQuad* render_pass_quad = | 4968 const RenderPassDrawQuad* render_pass_quad = |
4984 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); | 4969 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); |
4985 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | 4970 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), |
4986 render_pass_quad->rect.ToString()); | 4971 render_pass_quad->rect.ToString()); |
4987 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), | 4972 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
4988 render_pass_quad->mask_uv_rect.ToString()); | 4973 render_pass_quad->mask_uv_rect.ToString()); |
4989 | 4974 |
4990 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); | 4975 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
4991 host_impl_->DidDrawAllLayers(frame); | 4976 host_impl_->DidDrawAllLayers(frame); |
4992 } | 4977 } |
4993 | 4978 |
4994 | |
4995 // Applying an equivalent content scale on the content layer and the mask | 4979 // Applying an equivalent content scale on the content layer and the mask |
4996 // should still result in the same part of the mask being used. | 4980 // should still result in the same part of the mask being used. |
4997 gfx::Size layer_size_large = | 4981 gfx::Size layer_size_large = |
4998 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor)); | 4982 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor)); |
4999 content_layer->SetContentBounds(layer_size_large); | 4983 content_layer->SetContentBounds(layer_size_large); |
5000 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); | 4984 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); |
5001 gfx::Size mask_size_large = | 4985 gfx::Size mask_size_large = |
5002 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor)); | 4986 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor)); |
5003 mask_layer->SetContentBounds(mask_size_large); | 4987 mask_layer->SetContentBounds(mask_size_large); |
5004 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); | 4988 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); |
(...skipping 10 matching lines...) Expand all Loading... |
5015 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); | 4999 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); |
5016 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | 5000 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), |
5017 render_pass_quad->rect.ToString()); | 5001 render_pass_quad->rect.ToString()); |
5018 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), | 5002 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
5019 render_pass_quad->mask_uv_rect.ToString()); | 5003 render_pass_quad->mask_uv_rect.ToString()); |
5020 | 5004 |
5021 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); | 5005 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
5022 host_impl_->DidDrawAllLayers(frame); | 5006 host_impl_->DidDrawAllLayers(frame); |
5023 } | 5007 } |
5024 | 5008 |
5025 // Applying a different contents scale to the mask layer will still result | 5009 // Applying a different contents scale to the mask layer means it will have |
5026 // in the mask covering the owning layer. | 5010 // a larger texture, but it should use the same tex coords to cover the |
| 5011 // layer it masks. |
5027 mask_layer->SetContentBounds(mask_size); | 5012 mask_layer->SetContentBounds(mask_size); |
5028 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); | 5013 mask_layer->SetContentsScale(1.f, 1.f); |
5029 host_impl_->active_tree()->set_needs_update_draw_properties(); | 5014 host_impl_->active_tree()->set_needs_update_draw_properties(); |
5030 { | 5015 { |
5031 LayerTreeHostImpl::FrameData frame; | 5016 LayerTreeHostImpl::FrameData frame; |
5032 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); | 5017 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
5033 | 5018 |
5034 ASSERT_EQ(1u, frame.render_passes.size()); | 5019 ASSERT_EQ(1u, frame.render_passes.size()); |
5035 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); | 5020 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); |
5036 ASSERT_EQ(DrawQuad::RENDER_PASS, | 5021 ASSERT_EQ(DrawQuad::RENDER_PASS, |
5037 frame.render_passes[0]->quad_list[0]->material); | 5022 frame.render_passes[0]->quad_list[0]->material); |
5038 const RenderPassDrawQuad* render_pass_quad = | 5023 const RenderPassDrawQuad* render_pass_quad = |
5039 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); | 5024 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); |
5040 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | 5025 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), |
5041 render_pass_quad->rect.ToString()); | 5026 render_pass_quad->rect.ToString()); |
5042 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), | 5027 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
5043 render_pass_quad->mask_uv_rect.ToString()); | 5028 render_pass_quad->mask_uv_rect.ToString()); |
5044 | 5029 |
5045 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); | 5030 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
5046 host_impl_->DidDrawAllLayers(frame); | 5031 host_impl_->DidDrawAllLayers(frame); |
5047 } | 5032 } |
5048 } | 5033 } |
5049 | 5034 |
| 5035 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { |
| 5036 // The replica's mask layer has bounds 100x100 but the replica is of a |
| 5037 // layer with bounds 50x50. |
| 5038 |
| 5039 scoped_ptr<LayerImpl> scoped_root = |
| 5040 LayerImpl::Create(host_impl_->active_tree(), 1); |
| 5041 LayerImpl* root = scoped_root.get(); |
| 5042 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); |
| 5043 |
| 5044 scoped_ptr<LayerImpl> scoped_content_layer = |
| 5045 LayerImpl::Create(host_impl_->active_tree(), 3); |
| 5046 LayerImpl* content_layer = scoped_content_layer.get(); |
| 5047 root->AddChild(scoped_content_layer.Pass()); |
| 5048 |
| 5049 scoped_ptr<LayerImpl> scoped_replica_layer = |
| 5050 LayerImpl::Create(host_impl_->active_tree(), 2); |
| 5051 LayerImpl* replica_layer = scoped_replica_layer.get(); |
| 5052 content_layer->SetReplicaLayer(scoped_replica_layer.Pass()); |
| 5053 |
| 5054 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = |
| 5055 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); |
| 5056 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); |
| 5057 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); |
| 5058 |
| 5059 gfx::Size root_size(100, 100); |
| 5060 root->SetBounds(root_size); |
| 5061 root->SetContentBounds(root_size); |
| 5062 root->SetPosition(gfx::PointF()); |
| 5063 root->SetAnchorPoint(gfx::PointF()); |
| 5064 |
| 5065 gfx::Size layer_size(50, 50); |
| 5066 content_layer->SetBounds(layer_size); |
| 5067 content_layer->SetContentBounds(layer_size); |
| 5068 content_layer->SetPosition(gfx::PointF()); |
| 5069 content_layer->SetAnchorPoint(gfx::PointF()); |
| 5070 content_layer->SetDrawsContent(true); |
| 5071 |
| 5072 gfx::Size mask_size(100, 100); |
| 5073 mask_layer->SetBounds(mask_size); |
| 5074 mask_layer->SetContentBounds(mask_size); |
| 5075 mask_layer->SetPosition(gfx::PointF()); |
| 5076 mask_layer->SetAnchorPoint(gfx::PointF()); |
| 5077 mask_layer->SetDrawsContent(true); |
| 5078 |
| 5079 // Check that the mask fills the surface. |
| 5080 float device_scale_factor = 1.f; |
| 5081 host_impl_->SetViewportSize(root_size); |
| 5082 host_impl_->SetDeviceScaleFactor(device_scale_factor); |
| 5083 { |
| 5084 LayerTreeHostImpl::FrameData frame; |
| 5085 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
| 5086 |
| 5087 ASSERT_EQ(1u, frame.render_passes.size()); |
| 5088 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); |
| 5089 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5090 frame.render_passes[0]->quad_list[1]->material); |
| 5091 const RenderPassDrawQuad* replica_quad = |
| 5092 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); |
| 5093 EXPECT_TRUE(replica_quad->is_replica); |
| 5094 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), |
| 5095 replica_quad->rect.ToString()); |
| 5096 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
| 5097 replica_quad->mask_uv_rect.ToString()); |
| 5098 |
| 5099 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
| 5100 host_impl_->DidDrawAllLayers(frame); |
| 5101 } |
| 5102 |
| 5103 // Applying a DSF should change the render surface size, but won't affect |
| 5104 // which part of the mask is used. |
| 5105 device_scale_factor = 2.f; |
| 5106 gfx::Size device_viewport = |
| 5107 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); |
| 5108 host_impl_->SetViewportSize(device_viewport); |
| 5109 host_impl_->SetDeviceScaleFactor(device_scale_factor); |
| 5110 host_impl_->active_tree()->set_needs_update_draw_properties(); |
| 5111 { |
| 5112 LayerTreeHostImpl::FrameData frame; |
| 5113 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
| 5114 |
| 5115 ASSERT_EQ(1u, frame.render_passes.size()); |
| 5116 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); |
| 5117 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5118 frame.render_passes[0]->quad_list[1]->material); |
| 5119 const RenderPassDrawQuad* replica_quad = |
| 5120 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); |
| 5121 EXPECT_TRUE(replica_quad->is_replica); |
| 5122 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), |
| 5123 replica_quad->rect.ToString()); |
| 5124 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
| 5125 replica_quad->mask_uv_rect.ToString()); |
| 5126 |
| 5127 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
| 5128 host_impl_->DidDrawAllLayers(frame); |
| 5129 } |
| 5130 |
| 5131 // Applying an equivalent content scale on the content layer and the mask |
| 5132 // should still result in the same part of the mask being used. |
| 5133 gfx::Size layer_size_large = |
| 5134 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor)); |
| 5135 content_layer->SetContentBounds(layer_size_large); |
| 5136 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); |
| 5137 gfx::Size mask_size_large = |
| 5138 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor)); |
| 5139 mask_layer->SetContentBounds(mask_size_large); |
| 5140 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); |
| 5141 host_impl_->active_tree()->set_needs_update_draw_properties(); |
| 5142 { |
| 5143 LayerTreeHostImpl::FrameData frame; |
| 5144 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
| 5145 |
| 5146 ASSERT_EQ(1u, frame.render_passes.size()); |
| 5147 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); |
| 5148 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5149 frame.render_passes[0]->quad_list[1]->material); |
| 5150 const RenderPassDrawQuad* replica_quad = |
| 5151 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); |
| 5152 EXPECT_TRUE(replica_quad->is_replica); |
| 5153 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), |
| 5154 replica_quad->rect.ToString()); |
| 5155 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
| 5156 replica_quad->mask_uv_rect.ToString()); |
| 5157 |
| 5158 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
| 5159 host_impl_->DidDrawAllLayers(frame); |
| 5160 } |
| 5161 |
| 5162 // Applying a different contents scale to the mask layer means it will have |
| 5163 // a larger texture, but it should use the same tex coords to cover the |
| 5164 // layer it masks. |
| 5165 mask_layer->SetContentBounds(mask_size); |
| 5166 mask_layer->SetContentsScale(1.f, 1.f); |
| 5167 host_impl_->active_tree()->set_needs_update_draw_properties(); |
| 5168 { |
| 5169 LayerTreeHostImpl::FrameData frame; |
| 5170 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
| 5171 |
| 5172 ASSERT_EQ(1u, frame.render_passes.size()); |
| 5173 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); |
| 5174 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5175 frame.render_passes[0]->quad_list[1]->material); |
| 5176 const RenderPassDrawQuad* replica_quad = |
| 5177 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); |
| 5178 EXPECT_TRUE(replica_quad->is_replica); |
| 5179 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), |
| 5180 replica_quad->rect.ToString()); |
| 5181 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), |
| 5182 replica_quad->mask_uv_rect.ToString()); |
| 5183 |
| 5184 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
| 5185 host_impl_->DidDrawAllLayers(frame); |
| 5186 } |
| 5187 } |
| 5188 |
| 5189 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) { |
| 5190 // The replica is of a layer with bounds 50x50, but it has a child that causes |
| 5191 // the surface bounds to be larger. |
| 5192 |
| 5193 scoped_ptr<LayerImpl> scoped_root = |
| 5194 LayerImpl::Create(host_impl_->active_tree(), 1); |
| 5195 LayerImpl* root = scoped_root.get(); |
| 5196 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); |
| 5197 |
| 5198 scoped_ptr<LayerImpl> scoped_content_layer = |
| 5199 LayerImpl::Create(host_impl_->active_tree(), 2); |
| 5200 LayerImpl* content_layer = scoped_content_layer.get(); |
| 5201 root->AddChild(scoped_content_layer.Pass()); |
| 5202 |
| 5203 scoped_ptr<LayerImpl> scoped_content_child_layer = |
| 5204 LayerImpl::Create(host_impl_->active_tree(), 3); |
| 5205 LayerImpl* content_child_layer = scoped_content_child_layer.get(); |
| 5206 content_layer->AddChild(scoped_content_child_layer.Pass()); |
| 5207 |
| 5208 scoped_ptr<LayerImpl> scoped_replica_layer = |
| 5209 LayerImpl::Create(host_impl_->active_tree(), 4); |
| 5210 LayerImpl* replica_layer = scoped_replica_layer.get(); |
| 5211 content_layer->SetReplicaLayer(scoped_replica_layer.Pass()); |
| 5212 |
| 5213 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = |
| 5214 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5); |
| 5215 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); |
| 5216 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); |
| 5217 |
| 5218 gfx::Size root_size(100, 100); |
| 5219 root->SetBounds(root_size); |
| 5220 root->SetContentBounds(root_size); |
| 5221 root->SetPosition(gfx::PointF()); |
| 5222 root->SetAnchorPoint(gfx::PointF()); |
| 5223 |
| 5224 gfx::Size layer_size(50, 50); |
| 5225 content_layer->SetBounds(layer_size); |
| 5226 content_layer->SetContentBounds(layer_size); |
| 5227 content_layer->SetPosition(gfx::PointF()); |
| 5228 content_layer->SetAnchorPoint(gfx::PointF()); |
| 5229 content_layer->SetDrawsContent(true); |
| 5230 |
| 5231 gfx::Size child_size(50, 50); |
| 5232 content_child_layer->SetBounds(child_size); |
| 5233 content_child_layer->SetContentBounds(child_size); |
| 5234 content_child_layer->SetPosition(gfx::Point(50, 0)); |
| 5235 content_child_layer->SetAnchorPoint(gfx::PointF()); |
| 5236 content_child_layer->SetDrawsContent(true); |
| 5237 |
| 5238 gfx::Size mask_size(50, 50); |
| 5239 mask_layer->SetBounds(mask_size); |
| 5240 mask_layer->SetContentBounds(mask_size); |
| 5241 mask_layer->SetPosition(gfx::PointF()); |
| 5242 mask_layer->SetAnchorPoint(gfx::PointF()); |
| 5243 mask_layer->SetDrawsContent(true); |
| 5244 |
| 5245 float device_scale_factor = 1.f; |
| 5246 host_impl_->SetViewportSize(root_size); |
| 5247 host_impl_->SetDeviceScaleFactor(device_scale_factor); |
| 5248 { |
| 5249 LayerTreeHostImpl::FrameData frame; |
| 5250 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
| 5251 |
| 5252 ASSERT_EQ(1u, frame.render_passes.size()); |
| 5253 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); |
| 5254 |
| 5255 // The surface is 100x50. |
| 5256 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5257 frame.render_passes[0]->quad_list[0]->material); |
| 5258 const RenderPassDrawQuad* render_pass_quad = |
| 5259 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); |
| 5260 EXPECT_FALSE(render_pass_quad->is_replica); |
| 5261 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), |
| 5262 render_pass_quad->rect.ToString()); |
| 5263 |
| 5264 // The mask covers the owning layer only. |
| 5265 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5266 frame.render_passes[0]->quad_list[1]->material); |
| 5267 const RenderPassDrawQuad* replica_quad = |
| 5268 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); |
| 5269 EXPECT_TRUE(replica_quad->is_replica); |
| 5270 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), |
| 5271 replica_quad->rect.ToString()); |
| 5272 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(), |
| 5273 replica_quad->mask_uv_rect.ToString()); |
| 5274 |
| 5275 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
| 5276 host_impl_->DidDrawAllLayers(frame); |
| 5277 } |
| 5278 |
| 5279 // Move the child to (-50, 0) instead. Now the mask should be moved to still |
| 5280 // cover the layer being replicated. |
| 5281 content_child_layer->SetPosition(gfx::Point(-50, 0)); |
| 5282 { |
| 5283 LayerTreeHostImpl::FrameData frame; |
| 5284 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
| 5285 |
| 5286 ASSERT_EQ(1u, frame.render_passes.size()); |
| 5287 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); |
| 5288 |
| 5289 // The surface is 100x50 with its origin at (-50, 0). |
| 5290 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5291 frame.render_passes[0]->quad_list[0]->material); |
| 5292 const RenderPassDrawQuad* render_pass_quad = |
| 5293 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); |
| 5294 EXPECT_FALSE(render_pass_quad->is_replica); |
| 5295 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), |
| 5296 render_pass_quad->rect.ToString()); |
| 5297 |
| 5298 // The mask covers the owning layer only. |
| 5299 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5300 frame.render_passes[0]->quad_list[1]->material); |
| 5301 const RenderPassDrawQuad* replica_quad = |
| 5302 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); |
| 5303 EXPECT_TRUE(replica_quad->is_replica); |
| 5304 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), |
| 5305 replica_quad->rect.ToString()); |
| 5306 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(), |
| 5307 replica_quad->mask_uv_rect.ToString()); |
| 5308 |
| 5309 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
| 5310 host_impl_->DidDrawAllLayers(frame); |
| 5311 } |
| 5312 } |
| 5313 |
| 5314 TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) { |
| 5315 // The masked layer has bounds 50x50, but it has a child that causes |
| 5316 // the surface bounds to be larger. It also has a parent that clips the |
| 5317 // masked layer and its surface. |
| 5318 |
| 5319 scoped_ptr<LayerImpl> scoped_root = |
| 5320 LayerImpl::Create(host_impl_->active_tree(), 1); |
| 5321 LayerImpl* root = scoped_root.get(); |
| 5322 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); |
| 5323 |
| 5324 scoped_ptr<LayerImpl> scoped_clipping_layer = |
| 5325 LayerImpl::Create(host_impl_->active_tree(), 2); |
| 5326 LayerImpl* clipping_layer = scoped_clipping_layer.get(); |
| 5327 root->AddChild(scoped_clipping_layer.Pass()); |
| 5328 |
| 5329 scoped_ptr<LayerImpl> scoped_content_layer = |
| 5330 LayerImpl::Create(host_impl_->active_tree(), 3); |
| 5331 LayerImpl* content_layer = scoped_content_layer.get(); |
| 5332 clipping_layer->AddChild(scoped_content_layer.Pass()); |
| 5333 |
| 5334 scoped_ptr<LayerImpl> scoped_content_child_layer = |
| 5335 LayerImpl::Create(host_impl_->active_tree(), 4); |
| 5336 LayerImpl* content_child_layer = scoped_content_child_layer.get(); |
| 5337 content_layer->AddChild(scoped_content_child_layer.Pass()); |
| 5338 |
| 5339 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = |
| 5340 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6); |
| 5341 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); |
| 5342 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); |
| 5343 |
| 5344 gfx::Size root_size(100, 100); |
| 5345 root->SetBounds(root_size); |
| 5346 root->SetContentBounds(root_size); |
| 5347 root->SetPosition(gfx::PointF()); |
| 5348 root->SetAnchorPoint(gfx::PointF()); |
| 5349 |
| 5350 gfx::Rect clipping_rect(20, 10, 10, 20); |
| 5351 clipping_layer->SetBounds(clipping_rect.size()); |
| 5352 clipping_layer->SetContentBounds(clipping_rect.size()); |
| 5353 clipping_layer->SetPosition(clipping_rect.origin()); |
| 5354 clipping_layer->SetAnchorPoint(gfx::PointF()); |
| 5355 clipping_layer->SetMasksToBounds(true); |
| 5356 |
| 5357 gfx::Size layer_size(50, 50); |
| 5358 content_layer->SetBounds(layer_size); |
| 5359 content_layer->SetContentBounds(layer_size); |
| 5360 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin()); |
| 5361 content_layer->SetAnchorPoint(gfx::PointF()); |
| 5362 content_layer->SetDrawsContent(true); |
| 5363 |
| 5364 gfx::Size child_size(50, 50); |
| 5365 content_child_layer->SetBounds(child_size); |
| 5366 content_child_layer->SetContentBounds(child_size); |
| 5367 content_child_layer->SetPosition(gfx::Point(50, 0)); |
| 5368 content_child_layer->SetAnchorPoint(gfx::PointF()); |
| 5369 content_child_layer->SetDrawsContent(true); |
| 5370 |
| 5371 gfx::Size mask_size(100, 100); |
| 5372 mask_layer->SetBounds(mask_size); |
| 5373 mask_layer->SetContentBounds(mask_size); |
| 5374 mask_layer->SetPosition(gfx::PointF()); |
| 5375 mask_layer->SetAnchorPoint(gfx::PointF()); |
| 5376 mask_layer->SetDrawsContent(true); |
| 5377 |
| 5378 float device_scale_factor = 1.f; |
| 5379 host_impl_->SetViewportSize(root_size); |
| 5380 host_impl_->SetDeviceScaleFactor(device_scale_factor); |
| 5381 { |
| 5382 LayerTreeHostImpl::FrameData frame; |
| 5383 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); |
| 5384 |
| 5385 ASSERT_EQ(1u, frame.render_passes.size()); |
| 5386 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); |
| 5387 |
| 5388 // The surface is clipped to 10x20. |
| 5389 ASSERT_EQ(DrawQuad::RENDER_PASS, |
| 5390 frame.render_passes[0]->quad_list[0]->material); |
| 5391 const RenderPassDrawQuad* render_pass_quad = |
| 5392 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); |
| 5393 EXPECT_FALSE(render_pass_quad->is_replica); |
| 5394 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(), |
| 5395 render_pass_quad->rect.ToString()); |
| 5396 |
| 5397 // The masked layer is 50x50, but the surface size is 10x20. So the texture |
| 5398 // coords in the mask are scaled by 10/50 and 20/50. |
| 5399 // The surface is clipped to (20,10) so the mask texture coords are offset |
| 5400 // by 20/50 and 10/50 |
| 5401 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), |
| 5402 1.f / 50.f).ToString(), |
| 5403 render_pass_quad->mask_uv_rect.ToString()); |
| 5404 |
| 5405 host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); |
| 5406 host_impl_->DidDrawAllLayers(frame); |
| 5407 } |
| 5408 } |
| 5409 |
5050 } // namespace | 5410 } // namespace |
5051 } // namespace cc | 5411 } // namespace cc |
OLD | NEW |