OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 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.h" | 5 #include "cc/trees/layer_tree_host.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "cc/layers/content_layer.h" | 8 #include "cc/layers/content_layer.h" |
9 #include "cc/layers/heads_up_display_layer.h" | 9 #include "cc/layers/heads_up_display_layer.h" |
10 #include "cc/layers/io_surface_layer.h" | 10 #include "cc/layers/io_surface_layer.h" |
11 #include "cc/layers/layer_impl.h" | 11 #include "cc/layers/layer_impl.h" |
12 #include "cc/layers/picture_layer.h" | 12 #include "cc/layers/picture_layer.h" |
13 #include "cc/layers/scrollbar_layer.h" | 13 #include "cc/layers/scrollbar_layer.h" |
14 #include "cc/layers/texture_layer.h" | 14 #include "cc/layers/texture_layer.h" |
15 #include "cc/layers/texture_layer_impl.h" | 15 #include "cc/layers/texture_layer_impl.h" |
16 #include "cc/layers/video_layer.h" | 16 #include "cc/layers/video_layer.h" |
17 #include "cc/layers/video_layer_impl.h" | 17 #include "cc/layers/video_layer_impl.h" |
18 #include "cc/output/filter_operations.h" | 18 #include "cc/output/filter_operations.h" |
19 #include "cc/test/fake_content_layer.h" | 19 #include "cc/test/fake_content_layer.h" |
20 #include "cc/test/fake_content_layer_client.h" | 20 #include "cc/test/fake_content_layer_client.h" |
21 #include "cc/test/fake_content_layer_impl.h" | 21 #include "cc/test/fake_content_layer_impl.h" |
22 #include "cc/test/fake_context_provider.h" | 22 #include "cc/test/fake_context_provider.h" |
23 #include "cc/test/fake_delegated_renderer_layer.h" | 23 #include "cc/test/fake_delegated_renderer_layer.h" |
24 #include "cc/test/fake_delegated_renderer_layer_impl.h" | 24 #include "cc/test/fake_delegated_renderer_layer_impl.h" |
25 #include "cc/test/fake_layer_tree_host_client.h" | 25 #include "cc/test/fake_layer_tree_host_client.h" |
26 #include "cc/test/fake_output_surface.h" | 26 #include "cc/test/fake_output_surface.h" |
| 27 #include "cc/test/fake_scoped_ui_resource.h" |
27 #include "cc/test/fake_scrollbar.h" | 28 #include "cc/test/fake_scrollbar.h" |
28 #include "cc/test/fake_scrollbar_layer.h" | 29 #include "cc/test/fake_scrollbar_layer.h" |
29 #include "cc/test/fake_video_frame_provider.h" | 30 #include "cc/test/fake_video_frame_provider.h" |
30 #include "cc/test/layer_tree_test.h" | 31 #include "cc/test/layer_tree_test.h" |
31 #include "cc/test/render_pass_test_common.h" | 32 #include "cc/test/render_pass_test_common.h" |
32 #include "cc/test/test_web_graphics_context_3d.h" | 33 #include "cc/test/test_web_graphics_context_3d.h" |
33 #include "cc/trees/layer_tree_host_impl.h" | 34 #include "cc/trees/layer_tree_host_impl.h" |
34 #include "cc/trees/layer_tree_impl.h" | 35 #include "cc/trees/layer_tree_impl.h" |
35 #include "cc/trees/single_thread_proxy.h" | 36 #include "cc/trees/single_thread_proxy.h" |
36 #include "gpu/GLES2/gl2extchromium.h" | 37 #include "gpu/GLES2/gl2extchromium.h" |
(...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 layer_tree_host()->root_layer()->AddChild(scroll_layer); | 1496 layer_tree_host()->root_layer()->AddChild(scroll_layer); |
1496 PostSetNeedsCommitToMainThread(); | 1497 PostSetNeedsCommitToMainThread(); |
1497 } | 1498 } |
1498 | 1499 |
1499 virtual void AfterTest() OVERRIDE {} | 1500 virtual void AfterTest() OVERRIDE {} |
1500 | 1501 |
1501 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { | 1502 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
1502 LayerTreeHostContextTest::CommitCompleteOnThread(impl); | 1503 LayerTreeHostContextTest::CommitCompleteOnThread(impl); |
1503 | 1504 |
1504 ++commits_; | 1505 ++commits_; |
1505 size_t upload_count = scrollbar_layer_->last_update_full_upload_size() + | |
1506 scrollbar_layer_->last_update_partial_upload_size(); | |
1507 switch (commits_) { | 1506 switch (commits_) { |
1508 case 1: | 1507 case 1: |
1509 // First (regular) update, we should upload 2 resources (thumb, and | 1508 // First (regular) update, we should upload 2 resources (thumb, and |
1510 // backtrack). | 1509 // backtrack). |
1511 EXPECT_EQ(1, scrollbar_layer_->update_count()); | 1510 EXPECT_EQ(1, scrollbar_layer_->update_count()); |
1512 EXPECT_EQ(2u, upload_count); | |
1513 LoseContext(); | 1511 LoseContext(); |
1514 break; | 1512 break; |
1515 case 2: | 1513 case 2: |
1516 // Second update, after the lost context, we should still upload 2 | 1514 // Second update, after the lost context, we should still upload 2 |
1517 // resources even if the contents haven't changed. | 1515 // resources even if the contents haven't changed. |
1518 EXPECT_EQ(2, scrollbar_layer_->update_count()); | 1516 EXPECT_EQ(2, scrollbar_layer_->update_count()); |
1519 EXPECT_EQ(2u, upload_count); | |
1520 EndTest(); | 1517 EndTest(); |
1521 break; | 1518 break; |
1522 default: | 1519 default: |
1523 NOTREACHED(); | 1520 NOTREACHED(); |
1524 } | 1521 } |
1525 } | 1522 } |
1526 | 1523 |
1527 private: | 1524 private: |
1528 int commits_; | 1525 int commits_; |
1529 scoped_refptr<FakeScrollbarLayer> scrollbar_layer_; | 1526 scoped_refptr<FakeScrollbarLayer> scrollbar_layer_; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 this, | 1593 this, |
1597 settings, | 1594 settings, |
1598 impl_thread ? impl_thread->message_loop_proxy() : NULL); | 1595 impl_thread ? impl_thread->message_loop_proxy() : NULL); |
1599 EXPECT_FALSE(layer_tree_host); | 1596 EXPECT_FALSE(layer_tree_host); |
1600 } | 1597 } |
1601 }; | 1598 }; |
1602 | 1599 |
1603 SINGLE_AND_MULTI_THREAD_TEST_F( | 1600 SINGLE_AND_MULTI_THREAD_TEST_F( |
1604 LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface); | 1601 LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface); |
1605 | 1602 |
| 1603 class UIResourceLostTest : public LayerTreeHostContextTest { |
| 1604 public: |
| 1605 UIResourceLostTest() : time_step_(0) {} |
| 1606 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } |
| 1607 virtual void AfterTest() OVERRIDE {} |
| 1608 |
| 1609 protected: |
| 1610 int time_step_; |
| 1611 scoped_ptr<FakeScopedUIResource> ui_resource_; |
| 1612 }; |
| 1613 |
| 1614 // Losing context after an UI resource has been created. |
| 1615 class UIResourceLostAfterCommit : public UIResourceLostTest { |
| 1616 public: |
| 1617 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1618 LayerTreeHostContextTest::CommitCompleteOnThread(impl); |
| 1619 switch (time_step_) { |
| 1620 case 0: |
| 1621 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); |
| 1622 // Expects a valid UIResourceId. |
| 1623 EXPECT_NE(0, ui_resource_->id()); |
| 1624 PostSetNeedsCommitToMainThread(); |
| 1625 break; |
| 1626 case 1: |
| 1627 // The resource should have been created on LTHI after the commit. |
| 1628 if (!layer_tree_host()->settings().impl_side_painting) |
| 1629 EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1630 PostSetNeedsCommitToMainThread(); |
| 1631 break; |
| 1632 case 2: |
| 1633 LoseContext(); |
| 1634 break; |
| 1635 case 3: |
| 1636 // The resources should have been recreated. The bitmap callback should |
| 1637 // have been called once with the resource_lost flag set to true. |
| 1638 EXPECT_EQ(1, ui_resource_->lost_resource_count); |
| 1639 // Resource Id on the impl-side have been recreated as well. Note |
| 1640 // that the same UIResourceId persists after the context lost. |
| 1641 if (!layer_tree_host()->settings().impl_side_painting) |
| 1642 EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1643 PostSetNeedsCommitToMainThread(); |
| 1644 break; |
| 1645 case 4: |
| 1646 // Release resource before ending test. |
| 1647 ui_resource_.reset(); |
| 1648 EndTest(); |
| 1649 break; |
| 1650 } |
| 1651 } |
| 1652 |
| 1653 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1654 LayerTreeHostContextTest::DidActivateTreeOnThread(impl); |
| 1655 switch (time_step_) { |
| 1656 case 1: |
| 1657 if (layer_tree_host()->settings().impl_side_painting) |
| 1658 EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1659 break; |
| 1660 case 3: |
| 1661 if (layer_tree_host()->settings().impl_side_painting) |
| 1662 EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1663 break; |
| 1664 } |
| 1665 ++time_step_; |
| 1666 } |
| 1667 }; |
| 1668 |
| 1669 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostAfterCommit); |
| 1670 |
| 1671 // Losing context before UI resource requests can be commited. Three sequences |
| 1672 // of creation/deletion are considered: |
| 1673 // 1. Create one resource -> Context Lost => Expect the resource to have been |
| 1674 // created. |
| 1675 // 2. Delete an exisiting resource (test_id0_) -> create a second resource |
| 1676 // (test_id1_) -> Context Lost => Expect the test_id0_ to be removed and |
| 1677 // test_id1_ to have been created. |
| 1678 // 3. Create one resource -> Delete that same resource -> Context Lost => Expect |
| 1679 // the resource to not exist in the manager. |
| 1680 class UIResourceLostBeforeCommit : public UIResourceLostTest { |
| 1681 public: |
| 1682 UIResourceLostBeforeCommit() |
| 1683 : test_id0_(0), |
| 1684 test_id1_(0) {} |
| 1685 |
| 1686 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1687 LayerTreeHostContextTest::CommitCompleteOnThread(impl); |
| 1688 switch (time_step_) { |
| 1689 case 0: |
| 1690 // Sequence 1: |
| 1691 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); |
| 1692 LoseContext(); |
| 1693 // Resource Id on the impl-side should no longer be valid after |
| 1694 // context is lost. |
| 1695 EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1696 break; |
| 1697 case 1: |
| 1698 // The resources should have been recreated. |
| 1699 EXPECT_EQ(2, ui_resource_->resource_create_count); |
| 1700 // "resource lost" callback was called once for the resource in the |
| 1701 // resource map. |
| 1702 EXPECT_EQ(1, ui_resource_->lost_resource_count); |
| 1703 // Resource Id on the impl-side have been recreated as well. Note |
| 1704 // that the same UIResourceId persists after the context lost. |
| 1705 if (!layer_tree_host()->settings().impl_side_painting) |
| 1706 EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1707 PostSetNeedsCommitToMainThread(); |
| 1708 break; |
| 1709 case 2: |
| 1710 // Sequence 2: |
| 1711 // Currently one resource has been created. |
| 1712 test_id0_ = ui_resource_->id(); |
| 1713 // Delete this resource. |
| 1714 ui_resource_.reset(); |
| 1715 // Create another resource. |
| 1716 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); |
| 1717 test_id1_ = ui_resource_->id(); |
| 1718 // Sanity check that two resource creations return different ids. |
| 1719 EXPECT_NE(test_id0_, test_id1_); |
| 1720 // Lose the context before commit. |
| 1721 LoseContext(); |
| 1722 break; |
| 1723 case 3: |
| 1724 if (!layer_tree_host()->settings().impl_side_painting) { |
| 1725 // The previous resource should have been deleted. |
| 1726 EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_)); |
| 1727 // The second resource should have been created. |
| 1728 EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_)); |
| 1729 } |
| 1730 |
| 1731 // The second resource called the resource callback once and since the |
| 1732 // context is lost, a "resource lost" callback was also issued. |
| 1733 EXPECT_EQ(2, ui_resource_->resource_create_count); |
| 1734 EXPECT_EQ(1, ui_resource_->lost_resource_count); |
| 1735 // Clear the manager of resources. |
| 1736 ui_resource_.reset(); |
| 1737 PostSetNeedsCommitToMainThread(); |
| 1738 break; |
| 1739 case 4: |
| 1740 // Sequence 3: |
| 1741 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); |
| 1742 test_id0_ = ui_resource_->id(); |
| 1743 // Sanity check the UIResourceId should not be 0. |
| 1744 EXPECT_NE(0, test_id0_); |
| 1745 // Usually ScopedUIResource are deleted from the manager in their |
| 1746 // destructor (so usually ui_resource_.reset()). But here we need |
| 1747 // ui_resource_ for the next step, so call DeleteUIResource directly. |
| 1748 layer_tree_host()->DeleteUIResource(test_id0_); |
| 1749 LoseContext(); |
| 1750 break; |
| 1751 case 5: |
| 1752 // Expect the resource callback to have been called once. |
| 1753 EXPECT_EQ(1, ui_resource_->resource_create_count); |
| 1754 // No "resource lost" callbacks. |
| 1755 EXPECT_EQ(0, ui_resource_->lost_resource_count); |
| 1756 if (!layer_tree_host()->settings().impl_side_painting) { |
| 1757 // The UI resource id should not be valid |
| 1758 EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_)); |
| 1759 } |
| 1760 PostSetNeedsCommitToMainThread(); |
| 1761 break; |
| 1762 case 6: |
| 1763 ui_resource_.reset(); |
| 1764 EndTest(); |
| 1765 break; |
| 1766 } |
| 1767 } |
| 1768 |
| 1769 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1770 LayerTreeHostContextTest::DidActivateTreeOnThread(impl); |
| 1771 switch (time_step_) { |
| 1772 case 1: |
| 1773 if (layer_tree_host()->settings().impl_side_painting) |
| 1774 EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1775 break; |
| 1776 case 3: |
| 1777 if (layer_tree_host()->settings().impl_side_painting) { |
| 1778 EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_)); |
| 1779 EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_)); |
| 1780 } |
| 1781 break; |
| 1782 case 5: |
| 1783 if (layer_tree_host()->settings().impl_side_painting) |
| 1784 EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_)); |
| 1785 break; |
| 1786 } |
| 1787 ++time_step_; |
| 1788 } |
| 1789 |
| 1790 private: |
| 1791 UIResourceId test_id0_; |
| 1792 UIResourceId test_id1_; |
| 1793 }; |
| 1794 |
| 1795 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit); |
| 1796 |
| 1797 // Losing UI resource before the pending trees is activated but after the |
| 1798 // commit. Impl-side-painting only. |
| 1799 class UIResourceLostBeforeActivateTree : public UIResourceLostTest { |
| 1800 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1801 LayerTreeHostContextTest::CommitCompleteOnThread(impl); |
| 1802 switch (time_step_) { |
| 1803 case 0: |
| 1804 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); |
| 1805 PostSetNeedsCommitToMainThread(); |
| 1806 break; |
| 1807 case 2: |
| 1808 PostSetNeedsCommitToMainThread(); |
| 1809 break; |
| 1810 case 3: |
| 1811 test_id_ = ui_resource_->id(); |
| 1812 ui_resource_.reset(); |
| 1813 PostSetNeedsCommitToMainThread(); |
| 1814 break; |
| 1815 case 4: |
| 1816 PostSetNeedsCommitToMainThread(); |
| 1817 break; |
| 1818 case 5: |
| 1819 EndTest(); |
| 1820 break; |
| 1821 } |
| 1822 } |
| 1823 |
| 1824 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1825 switch (time_step_) { |
| 1826 case 0: |
| 1827 break; |
| 1828 case 1: |
| 1829 // The resource creation callback has been called. |
| 1830 EXPECT_EQ(1, ui_resource_->resource_create_count); |
| 1831 // The resource is not yet lost (sanity check). |
| 1832 EXPECT_EQ(0, ui_resource_->lost_resource_count); |
| 1833 // The resource should not have been created yet on the impl-side. |
| 1834 EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1835 LoseContext(); |
| 1836 break; |
| 1837 case 3: |
| 1838 LoseContext(); |
| 1839 break; |
| 1840 } |
| 1841 } |
| 1842 |
| 1843 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1844 LayerTreeHostContextTest::DidActivateTreeOnThread(impl); |
| 1845 switch (time_step_) { |
| 1846 case 1: |
| 1847 // The pending requests on the impl-side should have been processed. |
| 1848 EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id())); |
| 1849 break; |
| 1850 case 2: |
| 1851 // The "lost resource" callback should have been called once. |
| 1852 EXPECT_EQ(1, ui_resource_->lost_resource_count); |
| 1853 break; |
| 1854 case 4: |
| 1855 // The resource is deleted and should not be in the manager. Use |
| 1856 // test_id_ since ui_resource_ has been deleted. |
| 1857 EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id_)); |
| 1858 break; |
| 1859 } |
| 1860 ++time_step_; |
| 1861 } |
| 1862 |
| 1863 private: |
| 1864 UIResourceId test_id_; |
| 1865 }; |
| 1866 |
| 1867 TEST_F(UIResourceLostBeforeActivateTree, |
| 1868 RunMultiThread_DirectRenderer_ImplSidePaint) { |
| 1869 RunTest(true, false, true); |
| 1870 } |
| 1871 |
| 1872 TEST_F(UIResourceLostBeforeActivateTree, |
| 1873 RunMultiThread_DelegatingRenderer_ImplSidePaint) { |
| 1874 RunTest(true, true, true); |
| 1875 } |
| 1876 |
1606 } // namespace | 1877 } // namespace |
1607 } // namespace cc | 1878 } // namespace cc |
OLD | NEW |