| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "bindings/core/v8/ScriptController.h" | 5 #include "bindings/core/v8/ScriptController.h" |
| 6 #include "bindings/core/v8/ScriptSourceCode.h" | 6 #include "bindings/core/v8/ScriptSourceCode.h" |
| 7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/dom/Element.h" | 8 #include "core/dom/Element.h" |
| 9 #include "core/frame/FrameView.h" | 9 #include "core/frame/FrameView.h" |
| 10 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 using namespace HTMLNames; | 38 using namespace HTMLNames; |
| 39 | 39 |
| 40 // NOTE: This test uses <iframe sandbox> to create cross origin iframes. | 40 // NOTE: This test uses <iframe sandbox> to create cross origin iframes. |
| 41 | 41 |
| 42 namespace { | 42 namespace { |
| 43 | 43 |
| 44 class MockWebDisplayItemList : public WebDisplayItemList { | 44 class MockWebDisplayItemList : public WebDisplayItemList { |
| 45 public: | 45 public: |
| 46 ~MockWebDisplayItemList() override {} | 46 ~MockWebDisplayItemList() override {} |
| 47 | 47 |
| 48 MOCK_METHOD3(AppendDrawingItem, | 48 MOCK_METHOD2(AppendDrawingItem, |
| 49 void(const WebRect& visual_rect, | 49 void(const WebRect&, sk_sp<const PaintRecord>)); |
| 50 sk_sp<const cc::PaintRecord>, | |
| 51 const WebRect& record_bounds)); | |
| 52 }; | 50 }; |
| 53 | 51 |
| 54 void PaintRecursively(GraphicsLayer* layer, WebDisplayItemList* display_items) { | 52 void PaintRecursively(GraphicsLayer* layer, WebDisplayItemList* display_items) { |
| 55 if (layer->DrawsContent()) { | 53 if (layer->DrawsContent()) { |
| 56 layer->SetNeedsDisplay(); | 54 layer->SetNeedsDisplay(); |
| 57 layer->ContentLayerDelegateForTesting()->PaintContents( | 55 layer->ContentLayerDelegateForTesting()->PaintContents( |
| 58 display_items, ContentLayerDelegate::kPaintDefaultBehaviorForTest); | 56 display_items, ContentLayerDelegate::kPaintDefaultBehaviorForTest); |
| 59 } | 57 } |
| 60 for (const auto& child : layer->Children()) | 58 for (const auto& child : layer->Children()) |
| 61 PaintRecursively(child, display_items); | 59 PaintRecursively(child, display_items); |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 SimRequest main_resource("https://example.com/", "text/html"); | 826 SimRequest main_resource("https://example.com/", "text/html"); |
| 829 SimRequest frame_resource("https://example.com/iframe.html", "text/html"); | 827 SimRequest frame_resource("https://example.com/iframe.html", "text/html"); |
| 830 | 828 |
| 831 LoadURL("https://example.com/"); | 829 LoadURL("https://example.com/"); |
| 832 main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>"); | 830 main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>"); |
| 833 frame_resource.Complete("throttled"); | 831 frame_resource.Complete("throttled"); |
| 834 CompositeFrame(); | 832 CompositeFrame(); |
| 835 | 833 |
| 836 // Before the iframe is throttled, we should create all drawing items. | 834 // Before the iframe is throttled, we should create all drawing items. |
| 837 MockWebDisplayItemList display_items_not_throttled; | 835 MockWebDisplayItemList display_items_not_throttled; |
| 838 EXPECT_CALL(display_items_not_throttled, AppendDrawingItem(_, _, _)).Times(3); | 836 EXPECT_CALL(display_items_not_throttled, AppendDrawingItem(_, _)).Times(3); |
| 839 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_not_throttled); | 837 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_not_throttled); |
| 840 | 838 |
| 841 // Move the frame offscreen to throttle it and make sure it is backed by a | 839 // Move the frame offscreen to throttle it and make sure it is backed by a |
| 842 // graphics layer. | 840 // graphics layer. |
| 843 auto* frame_element = | 841 auto* frame_element = |
| 844 toHTMLIFrameElement(GetDocument().getElementById("frame")); | 842 toHTMLIFrameElement(GetDocument().getElementById("frame")); |
| 845 frame_element->setAttribute(styleAttr, | 843 frame_element->setAttribute(styleAttr, |
| 846 "transform: translateY(480px) translateZ(0px)"); | 844 "transform: translateY(480px) translateZ(0px)"); |
| 847 EXPECT_FALSE( | 845 EXPECT_FALSE( |
| 848 frame_element->contentDocument()->View()->CanThrottleRendering()); | 846 frame_element->contentDocument()->View()->CanThrottleRendering()); |
| 849 CompositeFrame(); | 847 CompositeFrame(); |
| 850 EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering()); | 848 EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering()); |
| 851 | 849 |
| 852 // If painting of the iframe is throttled, we should only receive two | 850 // If painting of the iframe is throttled, we should only receive two |
| 853 // drawing items. | 851 // drawing items. |
| 854 MockWebDisplayItemList display_items_throttled; | 852 MockWebDisplayItemList display_items_throttled; |
| 855 EXPECT_CALL(display_items_throttled, AppendDrawingItem(_, _, _)).Times(2); | 853 EXPECT_CALL(display_items_throttled, AppendDrawingItem(_, _)).Times(2); |
| 856 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_throttled); | 854 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_throttled); |
| 857 } | 855 } |
| 858 | 856 |
| 859 TEST_P(FrameThrottlingTest, ThrottleInnerCompositedLayer) { | 857 TEST_P(FrameThrottlingTest, ThrottleInnerCompositedLayer) { |
| 860 WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); | 858 WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); |
| 861 WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true); | 859 WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true); |
| 862 | 860 |
| 863 // Create a hidden frame which is throttled. | 861 // Create a hidden frame which is throttled. |
| 864 SimRequest main_resource("https://example.com/", "text/html"); | 862 SimRequest main_resource("https://example.com/", "text/html"); |
| 865 SimRequest frame_resource("https://example.com/iframe.html", "text/html"); | 863 SimRequest frame_resource("https://example.com/iframe.html", "text/html"); |
| 866 | 864 |
| 867 LoadURL("https://example.com/"); | 865 LoadURL("https://example.com/"); |
| 868 main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>"); | 866 main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>"); |
| 869 frame_resource.Complete( | 867 frame_resource.Complete( |
| 870 "<div id=div style='will-change: transform; background: blue'>DIV</div>"); | 868 "<div id=div style='will-change: transform; background: blue'>DIV</div>"); |
| 871 CompositeFrame(); | 869 CompositeFrame(); |
| 872 | 870 |
| 873 auto* frame_element = | 871 auto* frame_element = |
| 874 toHTMLIFrameElement(GetDocument().getElementById("frame")); | 872 toHTMLIFrameElement(GetDocument().getElementById("frame")); |
| 875 // The inner div is composited. | 873 // The inner div is composited. |
| 876 auto* inner_div = frame_element->contentDocument()->getElementById("div"); | 874 auto* inner_div = frame_element->contentDocument()->getElementById("div"); |
| 877 EXPECT_NE(nullptr, | 875 EXPECT_NE(nullptr, |
| 878 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); | 876 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); |
| 879 | 877 |
| 880 // Before the iframe is throttled, we should create all drawing items. | 878 // Before the iframe is throttled, we should create all drawing items. |
| 881 MockWebDisplayItemList display_items_not_throttled; | 879 MockWebDisplayItemList display_items_not_throttled; |
| 882 EXPECT_CALL(display_items_not_throttled, AppendDrawingItem(_, _, _)).Times(4); | 880 EXPECT_CALL(display_items_not_throttled, AppendDrawingItem(_, _)).Times(4); |
| 883 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_not_throttled); | 881 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_not_throttled); |
| 884 | 882 |
| 885 // Move the frame offscreen to throttle it. | 883 // Move the frame offscreen to throttle it. |
| 886 frame_element->setAttribute(styleAttr, "transform: translateY(480px)"); | 884 frame_element->setAttribute(styleAttr, "transform: translateY(480px)"); |
| 887 EXPECT_FALSE( | 885 EXPECT_FALSE( |
| 888 frame_element->contentDocument()->View()->CanThrottleRendering()); | 886 frame_element->contentDocument()->View()->CanThrottleRendering()); |
| 889 CompositeFrame(); | 887 CompositeFrame(); |
| 890 EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering()); | 888 EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering()); |
| 891 // The inner div should still be composited. | 889 // The inner div should still be composited. |
| 892 EXPECT_NE(nullptr, | 890 EXPECT_NE(nullptr, |
| 893 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); | 891 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); |
| 894 | 892 |
| 895 // If painting of the iframe is throttled, we should only receive two | 893 // If painting of the iframe is throttled, we should only receive two |
| 896 // drawing items. | 894 // drawing items. |
| 897 MockWebDisplayItemList display_items_throttled; | 895 MockWebDisplayItemList display_items_throttled; |
| 898 EXPECT_CALL(display_items_throttled, AppendDrawingItem(_, _, _)).Times(2); | 896 EXPECT_CALL(display_items_throttled, AppendDrawingItem(_, _)).Times(2); |
| 899 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_throttled); | 897 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_throttled); |
| 900 | 898 |
| 901 // Remove compositing trigger of inner_div. | 899 // Remove compositing trigger of inner_div. |
| 902 inner_div->setAttribute(styleAttr, "background: yellow; overflow: hidden"); | 900 inner_div->setAttribute(styleAttr, "background: yellow; overflow: hidden"); |
| 903 // Do an unthrottled style and layout update, simulating the situation | 901 // Do an unthrottled style and layout update, simulating the situation |
| 904 // triggered by script style/layout access. | 902 // triggered by script style/layout access. |
| 905 GetDocument().View()->UpdateLifecycleToLayoutClean(); | 903 GetDocument().View()->UpdateLifecycleToLayoutClean(); |
| 906 { | 904 { |
| 907 // And a throttled full lifecycle update. | 905 // And a throttled full lifecycle update. |
| 908 DocumentLifecycle::AllowThrottlingScope throttling_scope( | 906 DocumentLifecycle::AllowThrottlingScope throttling_scope( |
| 909 GetDocument().Lifecycle()); | 907 GetDocument().Lifecycle()); |
| 910 GetDocument().View()->UpdateAllLifecyclePhases(); | 908 GetDocument().View()->UpdateAllLifecyclePhases(); |
| 911 } | 909 } |
| 912 // The inner div should still be composited because compositing update is | 910 // The inner div should still be composited because compositing update is |
| 913 // throttled, though the inner_div's self-painting status has been updated. | 911 // throttled, though the inner_div's self-painting status has been updated. |
| 914 EXPECT_FALSE(inner_div->GetLayoutBox()->Layer()->IsSelfPaintingLayer()); | 912 EXPECT_FALSE(inner_div->GetLayoutBox()->Layer()->IsSelfPaintingLayer()); |
| 915 { | 913 { |
| 916 DisableCompositingQueryAsserts disabler; | 914 DisableCompositingQueryAsserts disabler; |
| 917 EXPECT_NE(nullptr, | 915 EXPECT_NE(nullptr, |
| 918 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); | 916 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); |
| 919 } | 917 } |
| 920 | 918 |
| 921 MockWebDisplayItemList display_items_throttled1; | 919 MockWebDisplayItemList display_items_throttled1; |
| 922 EXPECT_CALL(display_items_throttled1, AppendDrawingItem(_, _, _)).Times(2); | 920 EXPECT_CALL(display_items_throttled1, AppendDrawingItem(_, _)).Times(2); |
| 923 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_throttled1); | 921 PaintRecursively(WebView().RootGraphicsLayer(), &display_items_throttled1); |
| 924 | 922 |
| 925 // Move the frame back on screen. | 923 // Move the frame back on screen. |
| 926 frame_element->setAttribute(styleAttr, ""); | 924 frame_element->setAttribute(styleAttr, ""); |
| 927 CompositeFrame(); | 925 CompositeFrame(); |
| 928 EXPECT_FALSE( | 926 EXPECT_FALSE( |
| 929 frame_element->contentDocument()->View()->CanThrottleRendering()); | 927 frame_element->contentDocument()->View()->CanThrottleRendering()); |
| 930 CompositeFrame(); | 928 CompositeFrame(); |
| 931 // The inner div is no longer composited. | 929 // The inner div is no longer composited. |
| 932 EXPECT_EQ(nullptr, | 930 EXPECT_EQ(nullptr, |
| 933 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); | 931 inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking()); |
| 934 | 932 |
| 935 // After the iframe is unthrottled, we should create all drawing items. | 933 // After the iframe is unthrottled, we should create all drawing items. |
| 936 MockWebDisplayItemList display_items_not_throttled1; | 934 MockWebDisplayItemList display_items_not_throttled1; |
| 937 EXPECT_CALL(display_items_not_throttled1, AppendDrawingItem(_, _, _)) | 935 EXPECT_CALL(display_items_not_throttled1, AppendDrawingItem(_, _)) |
| 938 .Times(4); | 936 .Times(4); |
| 939 PaintRecursively(WebView().RootGraphicsLayer(), | 937 PaintRecursively(WebView().RootGraphicsLayer(), |
| 940 &display_items_not_throttled1); | 938 &display_items_not_throttled1); |
| 941 } | 939 } |
| 942 | 940 |
| 943 TEST_P(FrameThrottlingTest, ThrottleSubtreeAtomically) { | 941 TEST_P(FrameThrottlingTest, ThrottleSubtreeAtomically) { |
| 944 // Create two nested frames which are throttled. | 942 // Create two nested frames which are throttled. |
| 945 SimRequest main_resource("https://example.com/", "text/html"); | 943 SimRequest main_resource("https://example.com/", "text/html"); |
| 946 SimRequest frame_resource("https://example.com/iframe.html", "text/html"); | 944 SimRequest frame_resource("https://example.com/iframe.html", "text/html"); |
| 947 SimRequest child_frame_resource("https://example.com/child-iframe.html", | 945 SimRequest child_frame_resource("https://example.com/child-iframe.html", |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 // the child. This behavior matches Safari. | 1220 // the child. This behavior matches Safari. |
| 1223 frame_element->setAttribute(styleAttr, "display: none"); | 1221 frame_element->setAttribute(styleAttr, "display: none"); |
| 1224 CompositeFrame(); | 1222 CompositeFrame(); |
| 1225 EXPECT_FALSE( | 1223 EXPECT_FALSE( |
| 1226 frame_element->contentDocument()->View()->CanThrottleRendering()); | 1224 frame_element->contentDocument()->View()->CanThrottleRendering()); |
| 1227 EXPECT_TRUE( | 1225 EXPECT_TRUE( |
| 1228 child_frame_element->contentDocument()->View()->CanThrottleRendering()); | 1226 child_frame_element->contentDocument()->View()->CanThrottleRendering()); |
| 1229 } | 1227 } |
| 1230 | 1228 |
| 1231 } // namespace blink | 1229 } // namespace blink |
| OLD | NEW |