| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/compiler_specific.h" | 6 #include "base/compiler_specific.h" |
| 7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "ui/gfx/canvas_skia.h" | 13 #include "ui/gfx/canvas_skia.h" |
| 14 #include "ui/gfx/codec/png_codec.h" | 14 #include "ui/gfx/codec/png_codec.h" |
| 15 #include "ui/gfx/compositor/compositor_observer.h" | 15 #include "ui/gfx/compositor/compositor_observer.h" |
| 16 #include "ui/gfx/compositor/layer.h" | 16 #include "ui/gfx/compositor/layer.h" |
| 17 #include "ui/gfx/compositor/layer_animation_sequence.h" | 17 #include "ui/gfx/compositor/layer_animation_sequence.h" |
| 18 #include "ui/gfx/compositor/test/test_compositor_host.h" | 18 #include "ui/gfx/compositor/test/test_compositor_host.h" |
| 19 #include "ui/gfx/gfx_paths.h" | 19 #include "ui/gfx/gfx_paths.h" |
| 20 #include "ui/gfx/skia_util.h" | 20 #include "ui/gfx/skia_util.h" |
| 21 | 21 |
| 22 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 23 #include "ui/gfx/compositor/compositor_setup.h" | 22 #include "ui/gfx/compositor/compositor_setup.h" |
| 24 #else | |
| 25 #include "ui/gfx/compositor/test/test_compositor.h" | |
| 26 #endif | |
| 27 | 23 |
| 28 namespace ui { | 24 namespace ui { |
| 29 | 25 |
| 30 namespace { | 26 namespace { |
| 31 | 27 |
| 32 // Encodes a bitmap into a PNG and write to disk. Returns true on success. The | 28 // Encodes a bitmap into a PNG and write to disk. Returns true on success. The |
| 33 // parent directory does not have to exist. | 29 // parent directory does not have to exist. |
| 34 bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) { | 30 bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) { |
| 35 std::vector<unsigned char> png_data; | 31 std::vector<unsigned char> png_data; |
| 36 if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) && | 32 if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) && |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) { | 140 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) { |
| 145 test_data_directory_ = test_data_directory_.AppendASCII("compositor"); | 141 test_data_directory_ = test_data_directory_.AppendASCII("compositor"); |
| 146 } else { | 142 } else { |
| 147 LOG(ERROR) << "Could not open test data directory."; | 143 LOG(ERROR) << "Could not open test data directory."; |
| 148 } | 144 } |
| 149 } | 145 } |
| 150 virtual ~LayerWithRealCompositorTest() {} | 146 virtual ~LayerWithRealCompositorTest() {} |
| 151 | 147 |
| 152 // Overridden from testing::Test: | 148 // Overridden from testing::Test: |
| 153 virtual void SetUp() OVERRIDE { | 149 virtual void SetUp() OVERRIDE { |
| 154 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 155 ui::DisableTestCompositor(); | 150 ui::DisableTestCompositor(); |
| 156 #endif | |
| 157 const gfx::Rect host_bounds(10, 10, 500, 500); | 151 const gfx::Rect host_bounds(10, 10, 500, 500); |
| 158 window_.reset(TestCompositorHost::Create(host_bounds)); | 152 window_.reset(TestCompositorHost::Create(host_bounds)); |
| 159 window_->Show(); | 153 window_->Show(); |
| 160 } | 154 } |
| 161 | 155 |
| 162 virtual void TearDown() OVERRIDE { | 156 virtual void TearDown() OVERRIDE { |
| 163 } | 157 } |
| 164 | 158 |
| 165 Compositor* GetCompositor() { | 159 Compositor* GetCompositor() { |
| 166 return window_->GetCompositor(); | 160 return window_->GetCompositor(); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 DrawTree(l1.get()); | 354 DrawTree(l1.get()); |
| 361 } | 355 } |
| 362 | 356 |
| 363 class LayerWithDelegateTest : public testing::Test, public CompositorDelegate { | 357 class LayerWithDelegateTest : public testing::Test, public CompositorDelegate { |
| 364 public: | 358 public: |
| 365 LayerWithDelegateTest() : schedule_draw_invoked_(false) {} | 359 LayerWithDelegateTest() : schedule_draw_invoked_(false) {} |
| 366 virtual ~LayerWithDelegateTest() {} | 360 virtual ~LayerWithDelegateTest() {} |
| 367 | 361 |
| 368 // Overridden from testing::Test: | 362 // Overridden from testing::Test: |
| 369 virtual void SetUp() OVERRIDE { | 363 virtual void SetUp() OVERRIDE { |
| 370 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 371 ui::SetupTestCompositor(); | 364 ui::SetupTestCompositor(); |
| 372 compositor_ = ui::Compositor::Create(this, NULL, gfx::Size(1000, 1000)); | 365 compositor_ = ui::Compositor::Create(this, NULL, gfx::Size(1000, 1000)); |
| 373 #else | |
| 374 compositor_ = new TestCompositor(this); | |
| 375 #endif | |
| 376 } | 366 } |
| 377 | 367 |
| 378 virtual void TearDown() OVERRIDE { | 368 virtual void TearDown() OVERRIDE { |
| 379 } | 369 } |
| 380 | 370 |
| 381 Compositor* compositor() { return compositor_.get(); } | 371 Compositor* compositor() { return compositor_.get(); } |
| 382 | 372 |
| 383 virtual Layer* CreateLayer(Layer::LayerType type) { | 373 virtual Layer* CreateLayer(Layer::LayerType type) { |
| 384 return new Layer(type); | 374 return new Layer(type); |
| 385 } | 375 } |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 void RunPendingMessages() { | 601 void RunPendingMessages() { |
| 612 MessageLoopForUI::current()->RunAllPending(); | 602 MessageLoopForUI::current()->RunAllPending(); |
| 613 } | 603 } |
| 614 | 604 |
| 615 private: | 605 private: |
| 616 scoped_ptr<NullLayerDelegate> default_layer_delegate_; | 606 scoped_ptr<NullLayerDelegate> default_layer_delegate_; |
| 617 | 607 |
| 618 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest); | 608 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest); |
| 619 }; | 609 }; |
| 620 | 610 |
| 621 // With the webkit compositor, we don't explicitly textures for layers, making | |
| 622 // tests that check that we do fail. | |
| 623 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 624 #define NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(X) DISABLED_ ## X | |
| 625 #else | |
| 626 #define NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(X) X | |
| 627 #endif | |
| 628 | |
| 629 // Verifies that a layer which is set never to have a texture does not | |
| 630 // get a texture when SetFillsBoundsOpaquely is called. | |
| 631 TEST_F(LayerWithNullDelegateTest, | |
| 632 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR( | |
| 633 LayerNoTextureSetFillsBoundsOpaquely)) { | |
| 634 scoped_ptr<Layer> parent(CreateNoTextureLayer(gfx::Rect(0, 0, 400, 400))); | |
| 635 scoped_ptr<Layer> child(CreateNoTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 636 parent->Add(child.get()); | |
| 637 | |
| 638 compositor()->SetRootLayer(parent.get()); | |
| 639 parent->SetFillsBoundsOpaquely(true); | |
| 640 child->SetFillsBoundsOpaquely(true); | |
| 641 Draw(); | |
| 642 RunPendingMessages(); | |
| 643 EXPECT_TRUE(child->texture() == NULL); | |
| 644 EXPECT_TRUE(parent->texture() == NULL); | |
| 645 | |
| 646 parent->SetFillsBoundsOpaquely(false); | |
| 647 child->SetFillsBoundsOpaquely(false); | |
| 648 Draw(); | |
| 649 RunPendingMessages(); | |
| 650 EXPECT_TRUE(child->texture() == NULL); | |
| 651 EXPECT_TRUE(parent->texture() == NULL); | |
| 652 } | |
| 653 | |
| 654 // Verifies that a layer does not have a texture when the hole is the size | |
| 655 // of the parent layer. | |
| 656 TEST_F(LayerWithNullDelegateTest, | |
| 657 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(LayerNoTextureHoleSizeOfLayer)) { | |
| 658 scoped_ptr<Layer> parent(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 659 scoped_ptr<Layer> child(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 660 parent->Add(child.get()); | |
| 661 | |
| 662 Draw(); | |
| 663 EXPECT_EQ(gfx::Rect(50, 50, 100, 100), parent->hole_rect()); | |
| 664 EXPECT_TRUE(parent->texture() != NULL); | |
| 665 | |
| 666 child->SetBounds(gfx::Rect(0, 0, 400, 400)); | |
| 667 Draw(); | |
| 668 EXPECT_TRUE(parent->texture() == NULL); | |
| 669 } | |
| 670 | |
| 671 // Verifies that a layer which has opacity == 0 does not have a texture. | |
| 672 TEST_F(LayerWithNullDelegateTest, | |
| 673 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(LayerNoTextureTransparent)) { | |
| 674 scoped_ptr<Layer> parent(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 675 scoped_ptr<Layer> child(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 676 parent->Add(child.get()); | |
| 677 | |
| 678 parent->SetOpacity(0.0f); | |
| 679 child->SetOpacity(0.0f); | |
| 680 Draw(); | |
| 681 EXPECT_TRUE(parent->texture() == NULL); | |
| 682 EXPECT_TRUE(child->texture() == NULL); | |
| 683 | |
| 684 parent->SetOpacity(1.0f); | |
| 685 Draw(); | |
| 686 EXPECT_TRUE(parent->texture() != NULL); | |
| 687 EXPECT_TRUE(child->texture() == NULL); | |
| 688 | |
| 689 child->SetOpacity(1.0f); | |
| 690 Draw(); | |
| 691 EXPECT_TRUE(parent->texture() != NULL); | |
| 692 EXPECT_TRUE(child->texture() != NULL); | |
| 693 } | |
| 694 | |
| 695 // Verifies that no texture is created for a layer with empty bounds. | |
| 696 TEST_F(LayerWithNullDelegateTest, | |
| 697 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(LayerTextureNonEmptySchedulePaint)) { | |
| 698 scoped_ptr<Layer> layer(CreateTextureRootLayer(gfx::Rect(0, 0, 0, 0))); | |
| 699 Draw(); | |
| 700 EXPECT_TRUE(layer->texture() == NULL); | |
| 701 | |
| 702 layer->SetBounds(gfx::Rect(0, 0, 400, 400)); | |
| 703 Draw(); | |
| 704 EXPECT_TRUE(layer->texture() != NULL); | |
| 705 } | |
| 706 | |
| 707 // Verifies that when there are many potential holes, the largest one is picked. | |
| 708 TEST_F(LayerWithNullDelegateTest, | |
| 709 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(LargestHole)) { | |
| 710 scoped_ptr<Layer> parent(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 711 | |
| 712 scoped_ptr<Layer> child1(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 713 parent->Add(child1.get()); | |
| 714 | |
| 715 scoped_ptr<Layer> child2(CreateTextureLayer(gfx::Rect(75, 75, 200, 200))); | |
| 716 parent->Add(child2.get()); | |
| 717 | |
| 718 Draw(); | |
| 719 | |
| 720 EXPECT_EQ(gfx::Rect(75, 75, 200, 200), parent->hole_rect()); | |
| 721 } | |
| 722 | |
| 723 // Verifies that the largest hole in the draw order is picked | |
| 724 TEST_F(LayerWithNullDelegateTest, | |
| 725 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(HoleGeneratedFromLeaf)) { | |
| 726 // Layer tree looks like: | |
| 727 // node 1 | |
| 728 // |_ node 11 | |
| 729 // |_ node 111 | |
| 730 // |_ node 12 | |
| 731 // |_ node 121 | |
| 732 | |
| 733 scoped_ptr<Layer> node1(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 734 | |
| 735 scoped_ptr<Layer> node11(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 736 node1->Add(node11.get()); | |
| 737 | |
| 738 scoped_ptr<Layer> node12(CreateTextureLayer(gfx::Rect(75, 75, 200, 200))); | |
| 739 node1->Add(node12.get()); | |
| 740 | |
| 741 scoped_ptr<Layer> node111(CreateTextureLayer(gfx::Rect(10, 10, 20, 20))); | |
| 742 node11->Add(node111.get()); | |
| 743 | |
| 744 scoped_ptr<Layer> node121(CreateTextureLayer(gfx::Rect(10, 10, 190, 190))); | |
| 745 node12->Add(node121.get()); | |
| 746 | |
| 747 Draw(); | |
| 748 | |
| 749 EXPECT_EQ(gfx::Rect(75, 75, 200, 200), node1->hole_rect()); | |
| 750 EXPECT_EQ(gfx::Rect(25, 25, 75, 75), node11->hole_rect()); | |
| 751 EXPECT_EQ(gfx::Rect(10, 10, 190, 190), node12->hole_rect()); | |
| 752 } | |
| 753 | |
| 754 // Verifies that a hole can only punched into a layer with opacity = 1.0f. | |
| 755 TEST_F(LayerWithNullDelegateTest, | |
| 756 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(NoHoleWhenPartialOpacity)) { | |
| 757 // Layer tree looks like: | |
| 758 // node 1 | |
| 759 // |_ node 11 | |
| 760 // |_ node 111 | |
| 761 | |
| 762 scoped_ptr<Layer> node1(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 763 | |
| 764 scoped_ptr<Layer> node11(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 765 node1->Add(node11.get()); | |
| 766 | |
| 767 scoped_ptr<Layer> node111(CreateTextureLayer(gfx::Rect(10, 10, 20, 20))); | |
| 768 node11->Add(node111.get()); | |
| 769 | |
| 770 Draw(); | |
| 771 EXPECT_EQ(gfx::Rect(50, 50, 100, 100), node1->hole_rect()); | |
| 772 EXPECT_EQ(gfx::Rect(10, 10, 20, 20), node11->hole_rect()); | |
| 773 | |
| 774 | |
| 775 node11->SetOpacity(0.5f); | |
| 776 Draw(); | |
| 777 EXPECT_TRUE(node1->hole_rect().IsEmpty()); | |
| 778 EXPECT_TRUE(node11->hole_rect().IsEmpty()); | |
| 779 } | |
| 780 | |
| 781 // Verifies that a non visible layer or any of its children is not a hole. | |
| 782 TEST_F(LayerWithNullDelegateTest, | |
| 783 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(NonVisibleLayerCannotBeHole)) { | |
| 784 // Layer tree looks like: | |
| 785 // node 1 | |
| 786 // |_ node 11 | |
| 787 // |_ node 111 | |
| 788 | |
| 789 scoped_ptr<Layer> node1(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 790 | |
| 791 scoped_ptr<Layer> node11(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 792 node1->Add(node11.get()); | |
| 793 | |
| 794 scoped_ptr<Layer> node111(CreateTextureLayer(gfx::Rect(10, 10, 20, 20))); | |
| 795 node11->Add(node111.get()); | |
| 796 | |
| 797 Draw(); | |
| 798 EXPECT_EQ(gfx::Rect(50, 50, 100, 100), node1->hole_rect()); | |
| 799 EXPECT_EQ(gfx::Rect(10, 10, 20, 20), node11->hole_rect()); | |
| 800 | |
| 801 | |
| 802 node11->SetVisible(false); | |
| 803 Draw(); | |
| 804 EXPECT_TRUE(node1->hole_rect().IsEmpty()); | |
| 805 EXPECT_TRUE(node11->hole_rect().IsEmpty()); | |
| 806 } | |
| 807 | |
| 808 // Verifies that a layer which doesn't fill its bounds opaquely cannot punch a | |
| 809 // hole. However its children should still be able to punch a hole. | |
| 810 TEST_F(LayerWithNullDelegateTest, | |
| 811 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR( | |
| 812 LayerNotFillingBoundsOpaquelyCannotBeHole)) { | |
| 813 // Layer tree looks like: | |
| 814 // node 1 | |
| 815 // |_ node 11 | |
| 816 // |_ node 111 | |
| 817 | |
| 818 scoped_ptr<Layer> node1(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 819 | |
| 820 scoped_ptr<Layer> node11(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 821 node1->Add(node11.get()); | |
| 822 | |
| 823 scoped_ptr<Layer> node111(CreateTextureLayer(gfx::Rect(10, 10, 20, 20))); | |
| 824 node11->Add(node111.get()); | |
| 825 | |
| 826 Draw(); | |
| 827 EXPECT_EQ(gfx::Rect(50, 50, 100, 100), node1->hole_rect()); | |
| 828 EXPECT_EQ(gfx::Rect(10, 10, 20, 20), node11->hole_rect()); | |
| 829 | |
| 830 | |
| 831 node11->SetFillsBoundsOpaquely(false); | |
| 832 Draw(); | |
| 833 EXPECT_EQ(gfx::Rect(60, 60, 20, 20), node1->hole_rect()); | |
| 834 EXPECT_TRUE(node11->hole_rect().IsEmpty()); | |
| 835 } | |
| 836 | |
| 837 // Verifies that the hole is with respect to the local bounds of its parent. | |
| 838 TEST_F(LayerWithNullDelegateTest, | |
| 839 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(HoleLocalBounds)) { | |
| 840 scoped_ptr<Layer> parent(CreateTextureRootLayer( | |
| 841 gfx::Rect(100, 100, 150, 150))); | |
| 842 | |
| 843 scoped_ptr<Layer> child(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 844 parent->Add(child.get()); | |
| 845 | |
| 846 Draw(); | |
| 847 | |
| 848 EXPECT_EQ(gfx::Rect(50, 50, 100, 100), parent->hole_rect()); | |
| 849 } | |
| 850 | |
| 851 // Verifies that there is no hole present when one of the child layers has a | |
| 852 // transform. | |
| 853 TEST_F(LayerWithNullDelegateTest, | |
| 854 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(NoHoleWithTransform)) { | |
| 855 scoped_ptr<Layer> parent(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 856 scoped_ptr<Layer> child(CreateTextureLayer(gfx::Rect(50, 50, 100, 100))); | |
| 857 parent->Add(child.get()); | |
| 858 | |
| 859 Draw(); | |
| 860 | |
| 861 EXPECT_TRUE(!parent->hole_rect().IsEmpty()); | |
| 862 | |
| 863 ui::Transform t; | |
| 864 t.SetTranslate(-50, -50); | |
| 865 t.ConcatRotate(45.0f); | |
| 866 t.ConcatTranslate(50, 50); | |
| 867 child->SetTransform(t); | |
| 868 | |
| 869 Draw(); | |
| 870 | |
| 871 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), parent->hole_rect()); | |
| 872 } | |
| 873 | |
| 874 // Verifies that if the child layer is rotated by a multiple of ninety degrees | |
| 875 // we punch a hole | |
| 876 TEST_F(LayerWithNullDelegateTest, | |
| 877 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(HoleWithNinetyDegreeTransforms)) { | |
| 878 scoped_ptr<Layer> parent(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 879 scoped_ptr<Layer> child(CreateTextureLayer(gfx::Rect(50, 50, 50, 50))); | |
| 880 parent->Add(child.get()); | |
| 881 | |
| 882 Draw(); | |
| 883 | |
| 884 EXPECT_TRUE(!parent->hole_rect().IsEmpty()); | |
| 885 | |
| 886 for (int i = -4; i <= 4; ++i) { | |
| 887 SCOPED_TRACE(::testing::Message() << "Iteration " << i); | |
| 888 | |
| 889 ui::Transform t; | |
| 890 // Need to rotate in local coordinates. | |
| 891 t.SetTranslate(-25, -25); | |
| 892 t.ConcatRotate(90.0f * i); | |
| 893 t.ConcatTranslate(25, 25); | |
| 894 child->SetTransform(t); | |
| 895 | |
| 896 gfx::Rect target_rect(child->bounds().size()); | |
| 897 t.ConcatTranslate(child->bounds().x(), child->bounds().y()); | |
| 898 t.TransformRect(&target_rect); | |
| 899 | |
| 900 Draw(); | |
| 901 | |
| 902 EXPECT_EQ(target_rect, parent->hole_rect()); | |
| 903 } | |
| 904 } | |
| 905 | |
| 906 // Verifies that a layer which doesn't have a texture cannot punch a | |
| 907 // hole. However its children should still be able to punch a hole. | |
| 908 TEST_F(LayerWithNullDelegateTest, | |
| 909 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR( | |
| 910 HoleWithRelativeNinetyDegreeTransforms)) { | |
| 911 // Layer tree looks like: | |
| 912 // node 1 | |
| 913 // |_ node 11 | |
| 914 // |_ node 12 | |
| 915 | |
| 916 scoped_ptr<Layer> node1(CreateTextureRootLayer(gfx::Rect(0, 0, 400, 400))); | |
| 917 | |
| 918 scoped_ptr<Layer> node11(CreateTextureLayer(gfx::Rect(50, 50, 50, 50))); | |
| 919 node1->Add(node11.get()); | |
| 920 | |
| 921 scoped_ptr<Layer> node12(CreateTextureLayer(gfx::Rect(50, 50, 50, 50))); | |
| 922 node1->Add(node12.get()); | |
| 923 | |
| 924 Draw(); | |
| 925 | |
| 926 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), node11->hole_rect()); | |
| 927 EXPECT_TRUE(node12->hole_rect().IsEmpty()); | |
| 928 | |
| 929 ui::Transform t1; | |
| 930 // Need to rotate in local coordinates. | |
| 931 t1.SetTranslate(-25, -25); | |
| 932 t1.ConcatRotate(45.0f); | |
| 933 t1.ConcatTranslate(25, 25); | |
| 934 node11->SetTransform(t1); | |
| 935 | |
| 936 Draw(); | |
| 937 | |
| 938 EXPECT_TRUE(node12->hole_rect().IsEmpty()); | |
| 939 EXPECT_TRUE(node11->hole_rect().IsEmpty()); | |
| 940 | |
| 941 ui::Transform t2; | |
| 942 // Need to rotate in local coordinates. | |
| 943 t2.SetTranslate(-25, -25); | |
| 944 t2.ConcatRotate(-135.0f); | |
| 945 t2.ConcatTranslate(25, 25); | |
| 946 node12->SetTransform(t2); | |
| 947 | |
| 948 // Do translation of target rect in order to account for inprecision of | |
| 949 // using floating point matrices vs integer rects. | |
| 950 ui::Transform t3; | |
| 951 gfx::Rect target_rect = gfx::Rect(node11->bounds().size()); | |
| 952 t3.ConcatTransform(t2); | |
| 953 t1.GetInverse(&t1); | |
| 954 t3.ConcatTransform(t1); | |
| 955 t3.TransformRect(&target_rect); | |
| 956 | |
| 957 Draw(); | |
| 958 | |
| 959 EXPECT_TRUE(node12->hole_rect().IsEmpty()); | |
| 960 EXPECT_EQ(target_rect, node11->hole_rect()); | |
| 961 } | |
| 962 | |
| 963 // Create this hierarchy: | |
| 964 // L1 (no texture) | |
| 965 // +- L11 (texture) | |
| 966 // +- L12 (no texture) (added after L1 is already set as root-layer) | |
| 967 // +- L121 (texture) | |
| 968 // +- L122 (texture) | |
| 969 TEST_F(LayerWithNullDelegateTest, | |
| 970 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(NoCompositor)) { | |
| 971 scoped_ptr<Layer> l1(CreateLayer(Layer::LAYER_HAS_NO_TEXTURE)); | |
| 972 scoped_ptr<Layer> l11(CreateLayer(Layer::LAYER_HAS_TEXTURE)); | |
| 973 scoped_ptr<Layer> l12(CreateLayer(Layer::LAYER_HAS_NO_TEXTURE)); | |
| 974 scoped_ptr<Layer> l121(CreateLayer(Layer::LAYER_HAS_TEXTURE)); | |
| 975 scoped_ptr<Layer> l122(CreateLayer(Layer::LAYER_HAS_TEXTURE)); | |
| 976 | |
| 977 EXPECT_EQ(NULL, l1->texture()); | |
| 978 EXPECT_EQ(NULL, l11->texture()); | |
| 979 EXPECT_EQ(NULL, l12->texture()); | |
| 980 EXPECT_EQ(NULL, l121->texture()); | |
| 981 EXPECT_EQ(NULL, l122->texture()); | |
| 982 | |
| 983 l1->Add(l11.get()); | |
| 984 l1->SetBounds(gfx::Rect(0, 0, 500, 500)); | |
| 985 l11->SetBounds(gfx::Rect(5, 5, 490, 490)); | |
| 986 | |
| 987 EXPECT_EQ(NULL, l11->texture()); | |
| 988 | |
| 989 compositor()->SetRootLayer(l1.get()); | |
| 990 | |
| 991 EXPECT_EQ(NULL, l1->texture()); | |
| 992 | |
| 993 // Despite having type LAYER_HAS_TEXTURE, l11 will not have one set yet | |
| 994 // because it has never been asked to draw. | |
| 995 EXPECT_EQ(NULL, l11->texture()); | |
| 996 | |
| 997 l12->Add(l121.get()); | |
| 998 l12->Add(l122.get()); | |
| 999 l12->SetBounds(gfx::Rect(5, 5, 480, 480)); | |
| 1000 l121->SetBounds(gfx::Rect(5, 5, 100, 100)); | |
| 1001 l122->SetBounds(gfx::Rect(110, 110, 100, 100)); | |
| 1002 | |
| 1003 EXPECT_EQ(NULL, l121->texture()); | |
| 1004 EXPECT_EQ(NULL, l122->texture()); | |
| 1005 | |
| 1006 l1->Add(l12.get()); | |
| 1007 | |
| 1008 // By asking l121 and l122 to paint, we cause them to generate a texture. | |
| 1009 SchedulePaintForLayer(l121.get()); | |
| 1010 SchedulePaintForLayer(l122.get()); | |
| 1011 Draw(); | |
| 1012 | |
| 1013 EXPECT_EQ(NULL, l12->texture()); | |
| 1014 EXPECT_TRUE(NULL != l121->texture()); | |
| 1015 EXPECT_TRUE(NULL != l122->texture()); | |
| 1016 | |
| 1017 // Toggling l2's visibility should drop all sub-layer textures. | |
| 1018 l12->SetVisible(false); | |
| 1019 EXPECT_EQ(NULL, l12->texture()); | |
| 1020 EXPECT_EQ(NULL, l121->texture()); | |
| 1021 EXPECT_EQ(NULL, l122->texture()); | |
| 1022 } | |
| 1023 | |
| 1024 // Various visibile/drawn assertions. | 611 // Various visibile/drawn assertions. |
| 1025 TEST_F(LayerWithNullDelegateTest, Visibility) { | 612 TEST_F(LayerWithNullDelegateTest, Visibility) { |
| 1026 scoped_ptr<Layer> l1(new Layer(Layer::LAYER_HAS_TEXTURE)); | 613 scoped_ptr<Layer> l1(new Layer(Layer::LAYER_HAS_TEXTURE)); |
| 1027 scoped_ptr<Layer> l2(new Layer(Layer::LAYER_HAS_TEXTURE)); | 614 scoped_ptr<Layer> l2(new Layer(Layer::LAYER_HAS_TEXTURE)); |
| 1028 scoped_ptr<Layer> l3(new Layer(Layer::LAYER_HAS_TEXTURE)); | 615 scoped_ptr<Layer> l3(new Layer(Layer::LAYER_HAS_TEXTURE)); |
| 1029 l1->Add(l2.get()); | 616 l1->Add(l2.get()); |
| 1030 l2->Add(l3.get()); | 617 l2->Add(l3.get()); |
| 1031 | 618 |
| 1032 NullLayerDelegate delegate; | 619 NullLayerDelegate delegate; |
| 1033 l1->set_delegate(&delegate); | 620 l1->set_delegate(&delegate); |
| 1034 l2->set_delegate(&delegate); | 621 l2->set_delegate(&delegate); |
| 1035 l3->set_delegate(&delegate); | 622 l3->set_delegate(&delegate); |
| 1036 | 623 |
| 1037 // Layers should initially be drawn. | 624 // Layers should initially be drawn. |
| 1038 EXPECT_TRUE(l1->IsDrawn()); | 625 EXPECT_TRUE(l1->IsDrawn()); |
| 1039 EXPECT_TRUE(l2->IsDrawn()); | 626 EXPECT_TRUE(l2->IsDrawn()); |
| 1040 EXPECT_TRUE(l3->IsDrawn()); | 627 EXPECT_TRUE(l3->IsDrawn()); |
| 1041 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 1042 EXPECT_EQ(1.f, l1->web_layer().opacity()); | 628 EXPECT_EQ(1.f, l1->web_layer().opacity()); |
| 1043 EXPECT_EQ(1.f, l2->web_layer().opacity()); | 629 EXPECT_EQ(1.f, l2->web_layer().opacity()); |
| 1044 EXPECT_EQ(1.f, l3->web_layer().opacity()); | 630 EXPECT_EQ(1.f, l3->web_layer().opacity()); |
| 1045 #endif | |
| 1046 | 631 |
| 1047 compositor()->SetRootLayer(l1.get()); | 632 compositor()->SetRootLayer(l1.get()); |
| 1048 | 633 |
| 1049 Draw(); | 634 Draw(); |
| 1050 | 635 |
| 1051 l1->SetVisible(false); | 636 l1->SetVisible(false); |
| 1052 EXPECT_FALSE(l1->IsDrawn()); | 637 EXPECT_FALSE(l1->IsDrawn()); |
| 1053 EXPECT_FALSE(l2->IsDrawn()); | 638 EXPECT_FALSE(l2->IsDrawn()); |
| 1054 EXPECT_FALSE(l3->IsDrawn()); | 639 EXPECT_FALSE(l3->IsDrawn()); |
| 1055 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 1056 EXPECT_EQ(0.f, l1->web_layer().opacity()); | 640 EXPECT_EQ(0.f, l1->web_layer().opacity()); |
| 1057 #endif | |
| 1058 | 641 |
| 1059 l3->SetVisible(false); | 642 l3->SetVisible(false); |
| 1060 EXPECT_FALSE(l1->IsDrawn()); | 643 EXPECT_FALSE(l1->IsDrawn()); |
| 1061 EXPECT_FALSE(l2->IsDrawn()); | 644 EXPECT_FALSE(l2->IsDrawn()); |
| 1062 EXPECT_FALSE(l3->IsDrawn()); | 645 EXPECT_FALSE(l3->IsDrawn()); |
| 1063 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 1064 EXPECT_EQ(0.f, l3->web_layer().opacity()); | 646 EXPECT_EQ(0.f, l3->web_layer().opacity()); |
| 1065 #endif | |
| 1066 | 647 |
| 1067 l1->SetVisible(true); | 648 l1->SetVisible(true); |
| 1068 EXPECT_TRUE(l1->IsDrawn()); | 649 EXPECT_TRUE(l1->IsDrawn()); |
| 1069 EXPECT_TRUE(l2->IsDrawn()); | 650 EXPECT_TRUE(l2->IsDrawn()); |
| 1070 EXPECT_FALSE(l3->IsDrawn()); | 651 EXPECT_FALSE(l3->IsDrawn()); |
| 1071 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 1072 EXPECT_EQ(1.f, l1->web_layer().opacity()); | 652 EXPECT_EQ(1.f, l1->web_layer().opacity()); |
| 1073 #endif | |
| 1074 } | 653 } |
| 1075 | 654 |
| 1076 // Checks that stacking-related methods behave as advertised. | 655 // Checks that stacking-related methods behave as advertised. |
| 1077 TEST_F(LayerWithNullDelegateTest, Stacking) { | 656 TEST_F(LayerWithNullDelegateTest, Stacking) { |
| 1078 scoped_ptr<Layer> root(new Layer(Layer::LAYER_HAS_NO_TEXTURE)); | 657 scoped_ptr<Layer> root(new Layer(Layer::LAYER_HAS_NO_TEXTURE)); |
| 1079 scoped_ptr<Layer> l1(new Layer(Layer::LAYER_HAS_TEXTURE)); | 658 scoped_ptr<Layer> l1(new Layer(Layer::LAYER_HAS_TEXTURE)); |
| 1080 scoped_ptr<Layer> l2(new Layer(Layer::LAYER_HAS_TEXTURE)); | 659 scoped_ptr<Layer> l2(new Layer(Layer::LAYER_HAS_TEXTURE)); |
| 1081 scoped_ptr<Layer> l3(new Layer(Layer::LAYER_HAS_TEXTURE)); | 660 scoped_ptr<Layer> l3(new Layer(Layer::LAYER_HAS_TEXTURE)); |
| 1082 l1->set_name("1"); | 661 l1->set_name("1"); |
| 1083 l2->set_name("2"); | 662 l2->set_name("2"); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 root->StackBelow(l3.get(), l2.get()); | 704 root->StackBelow(l3.get(), l2.get()); |
| 1126 EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get())); | 705 EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get())); |
| 1127 | 706 |
| 1128 root->StackBelow(l3.get(), l2.get()); | 707 root->StackBelow(l3.get(), l2.get()); |
| 1129 EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get())); | 708 EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get())); |
| 1130 | 709 |
| 1131 root->StackBelow(l3.get(), l1.get()); | 710 root->StackBelow(l3.get(), l1.get()); |
| 1132 EXPECT_EQ("2,3,1", GetLayerChildrenNames(*root.get())); | 711 EXPECT_EQ("2,3,1", GetLayerChildrenNames(*root.get())); |
| 1133 } | 712 } |
| 1134 | 713 |
| 1135 // Checks that the invalid rect assumes correct values when setting bounds. | |
| 1136 // TODO(vollick): for USE_WEBKIT_COMPOSITOR, use WebKit's dirty rect. | |
| 1137 TEST_F(LayerWithNullDelegateTest, | |
| 1138 NOT_APPLICABLE_TO_WEBKIT_COMPOSITOR(SetBoundsInvalidRect)) { | |
| 1139 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200))); | |
| 1140 compositor()->SetRootLayer(l1.get()); | |
| 1141 | |
| 1142 // After a draw the invalid rect should be empty. | |
| 1143 Draw(); | |
| 1144 EXPECT_TRUE(l1->invalid_rect().IsEmpty()); | |
| 1145 | |
| 1146 // After a move the invalid rect should be empty. | |
| 1147 l1->SetBounds(gfx::Rect(5, 5, 200, 200)); | |
| 1148 EXPECT_TRUE(l1->invalid_rect().IsEmpty()); | |
| 1149 | |
| 1150 // Bounds change should trigger both the invalid rect to update as well as | |
| 1151 // CompositorDelegate being told to draw. | |
| 1152 l1->SetBounds(gfx::Rect(5, 5, 100, 100)); | |
| 1153 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | |
| 1154 l1->invalid_rect().ToString()); | |
| 1155 } | |
| 1156 | |
| 1157 // Verifies SetBounds triggers the appropriate painting/drawing. | 714 // Verifies SetBounds triggers the appropriate painting/drawing. |
| 1158 TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) { | 715 TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) { |
| 1159 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200))); | 716 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200))); |
| 1160 compositor()->SetRootLayer(l1.get()); | 717 compositor()->SetRootLayer(l1.get()); |
| 1161 | 718 |
| 1162 Draw(); | 719 Draw(); |
| 1163 | 720 |
| 1164 schedule_draw_invoked_ = false; | 721 schedule_draw_invoked_ = false; |
| 1165 l1->SetBounds(gfx::Rect(5, 5, 200, 200)); | 722 l1->SetBounds(gfx::Rect(5, 5, 200, 200)); |
| 1166 | 723 |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1458 EXPECT_TRUE(schedule_draw_invoked_); | 1015 EXPECT_TRUE(schedule_draw_invoked_); |
| 1459 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should | 1016 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should |
| 1460 // still need to be painted. | 1017 // still need to be painted. |
| 1461 DrawTree(root.get()); | 1018 DrawTree(root.get()); |
| 1462 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear()); | 1019 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear()); |
| 1463 EXPECT_TRUE(child_delegate.last_clip_rect().Contains( | 1020 EXPECT_TRUE(child_delegate.last_clip_rect().Contains( |
| 1464 gfx::Rect(10, 10, 30, 30))); | 1021 gfx::Rect(10, 10, 30, 30))); |
| 1465 } | 1022 } |
| 1466 | 1023 |
| 1467 } // namespace ui | 1024 } // namespace ui |
| OLD | NEW |