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