Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp

Issue 2589003002: Split paint property update tests out of PaintPropertyTreeBuilderTest (Closed)
Patch Set: Rebase, minor cleanup Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "core/paint/PaintPropertyTreeBuilderTest.h"
6
5 #include "core/html/HTMLIFrameElement.h" 7 #include "core/html/HTMLIFrameElement.h"
6 #include "core/layout/LayoutTestHelper.h"
7 #include "core/layout/LayoutTreeAsText.h" 8 #include "core/layout/LayoutTreeAsText.h"
8 #include "core/layout/api/LayoutViewItem.h"
9 #include "core/paint/ObjectPaintProperties.h" 9 #include "core/paint/ObjectPaintProperties.h"
10 #include "core/paint/PaintPropertyTreePrinter.h" 10 #include "core/paint/PaintPropertyTreePrinter.h"
11 #include "platform/graphics/paint/GeometryMapper.h" 11 #include "platform/graphics/paint/GeometryMapper.h"
12 #include "platform/graphics/paint/ScrollPaintPropertyNode.h"
13 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
14 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
15 #include "platform/testing/UnitTestHelpers.h"
16 #include "platform/text/TextStream.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "wtf/HashMap.h"
19 #include "wtf/Vector.h"
20 12
21 namespace blink { 13 namespace blink {
22 14
23 typedef bool TestParamRootLayerScrolling; 15 void PaintPropertyTreeBuilderTest::loadTestData(const char* fileName) {
24 class PaintPropertyTreeBuilderTest 16 String fullPath = testing::blinkRootDir();
25 : public ::testing::WithParamInterface<TestParamRootLayerScrolling>, 17 fullPath.append("/Source/core/paint/test_data/");
26 private ScopedSlimmingPaintV2ForTest, 18 fullPath.append(fileName);
27 private ScopedRootLayerScrollingForTest, 19 RefPtr<SharedBuffer> inputBuffer = testing::readFromFile(fullPath);
28 public RenderingTest { 20 setBodyInnerHTML(String(inputBuffer->data(), inputBuffer->size()));
29 public: 21 }
30 PaintPropertyTreeBuilderTest()
31 : ScopedSlimmingPaintV2ForTest(true),
32 ScopedRootLayerScrollingForTest(GetParam()),
33 RenderingTest(SingleChildFrameLoaderClient::create()) {}
34 22
35 void loadTestData(const char* fileName) { 23 const TransformPaintPropertyNode*
36 String fullPath = testing::blinkRootDir(); 24 PaintPropertyTreeBuilderTest::framePreTranslation() {
37 fullPath.append("/Source/core/paint/test_data/"); 25 FrameView* frameView = document().view();
38 fullPath.append(fileName); 26 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
39 RefPtr<SharedBuffer> inputBuffer = testing::readFromFile(fullPath); 27 return frameView->layoutView()->paintProperties()->paintOffsetTranslation();
40 setBodyInnerHTML(String(inputBuffer->data(), inputBuffer->size())); 28 return frameView->preTranslation();
41 } 29 }
42 30
43 const TransformPaintPropertyNode* framePreTranslation() { 31 const TransformPaintPropertyNode*
44 FrameView* frameView = document().view(); 32 PaintPropertyTreeBuilderTest::frameScrollTranslation() {
45 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) 33 FrameView* frameView = document().view();
46 return frameView->layoutView() 34 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
47 ->paintProperties() 35 return frameView->layoutView()->paintProperties()->scrollTranslation();
48 ->paintOffsetTranslation(); 36 return frameView->scrollTranslation();
49 return frameView->preTranslation(); 37 }
50 }
51 38
52 const TransformPaintPropertyNode* frameScrollTranslation() { 39 const ClipPaintPropertyNode* PaintPropertyTreeBuilderTest::frameContentClip() {
53 FrameView* frameView = document().view(); 40 FrameView* frameView = document().view();
54 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) 41 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
55 return frameView->layoutView()->paintProperties()->scrollTranslation(); 42 return frameView->layoutView()->paintProperties()->overflowClip();
56 return frameView->scrollTranslation(); 43 return frameView->contentClip();
57 } 44 }
58 45
59 const ClipPaintPropertyNode* frameContentClip() { 46 const ScrollPaintPropertyNode* PaintPropertyTreeBuilderTest::frameScroll(
60 FrameView* frameView = document().view(); 47 FrameView* frameView) {
61 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) 48 if (!frameView)
62 return frameView->layoutView()->paintProperties()->overflowClip(); 49 frameView = document().view();
63 return frameView->contentClip(); 50 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
64 } 51 return frameView->layoutView()->paintProperties()->scroll();
52 return frameView->scroll();
53 }
65 54
66 const ScrollPaintPropertyNode* frameScroll(FrameView* frameView = nullptr) { 55 LayoutPoint PaintPropertyTreeBuilderTest::paintOffset(
67 if (!frameView) 56 const LayoutObject* object) {
68 frameView = document().view(); 57 return object->paintProperties()->localBorderBoxProperties()->paintOffset;
69 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) 58 }
70 return frameView->layoutView()->paintProperties()->scroll();
71 return frameView->scroll();
72 }
73 59
74 LayoutPoint paintOffset(const LayoutObject* object) { 60 void PaintPropertyTreeBuilderTest::SetUp() {
75 return object->paintProperties()->localBorderBoxProperties()->paintOffset; 61 Settings::setMockScrollbarsEnabled(true);
76 }
77 62
78 private: 63 RenderingTest::SetUp();
79 void SetUp() override { 64 enableCompositing();
80 Settings::setMockScrollbarsEnabled(true); 65 }
81 66
82 RenderingTest::SetUp(); 67 void PaintPropertyTreeBuilderTest::TearDown() {
83 enableCompositing(); 68 RenderingTest::TearDown();
84 }
85 69
86 void TearDown() override { 70 Settings::setMockScrollbarsEnabled(false);
87 RenderingTest::TearDown(); 71 }
88
89 Settings::setMockScrollbarsEnabled(false);
90 }
91 };
92 72
93 #define CHECK_VISUAL_RECT(expected, sourceLayoutObject, ancestorLayoutObject, \ 73 #define CHECK_VISUAL_RECT(expected, sourceLayoutObject, ancestorLayoutObject, \
94 slopFactor) \ 74 slopFactor) \
95 do { \ 75 do { \
96 GeometryMapper geometryMapper; \ 76 GeometryMapper geometryMapper; \
97 LayoutRect source((sourceLayoutObject)->localVisualRect()); \ 77 LayoutRect source((sourceLayoutObject)->localVisualRect()); \
98 source.moveBy((sourceLayoutObject) \ 78 source.moveBy((sourceLayoutObject) \
99 ->paintProperties() \ 79 ->paintProperties() \
100 ->localBorderBoxProperties() \ 80 ->localBorderBoxProperties() \
101 ->paintOffset); \ 81 ->paintOffset); \
(...skipping 2605 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 setBodyInnerHTML( 2687 setBodyInnerHTML(
2708 "<svg id='svg' xmlns='http://www.w3.org/2000/svg' width='100px' " 2688 "<svg id='svg' xmlns='http://www.w3.org/2000/svg' width='100px' "
2709 "height='100px' style='overflow: visible'>" 2689 "height='100px' style='overflow: visible'>"
2710 " <rect width='200' height='200' fill='red' />" 2690 " <rect width='200' height='200' fill='red' />"
2711 "</svg>"); 2691 "</svg>");
2712 2692
2713 EXPECT_FALSE( 2693 EXPECT_FALSE(
2714 getLayoutObjectByElementId("svg")->paintProperties()->overflowClip()); 2694 getLayoutObjectByElementId("svg")->paintProperties()->overflowClip());
2715 } 2695 }
2716 2696
2717 TEST_P(PaintPropertyTreeBuilderTest,
2718 ThreadedScrollingDisabledMainThreadScrollReason) {
2719 setBodyInnerHTML(
2720 "<style>"
2721 " #overflowA {"
2722 " position: absolute;"
2723 " overflow: scroll;"
2724 " width: 20px;"
2725 " height: 20px;"
2726 " }"
2727 " .forceScroll {"
2728 " height: 4000px;"
2729 " }"
2730 "</style>"
2731 "<div id='overflowA'>"
2732 " <div class='forceScroll'></div>"
2733 "</div>"
2734 "<div class='forceScroll'></div>");
2735 Element* overflowA = document().getElementById("overflowA");
2736 EXPECT_FALSE(frameScroll()->threadedScrollingDisabled());
2737 EXPECT_FALSE(overflowA->layoutObject()
2738 ->paintProperties()
2739 ->scroll()
2740 ->threadedScrollingDisabled());
2741
2742 document().settings()->setThreadedScrollingEnabled(false);
2743 // TODO(pdr): The main thread scrolling setting should invalidate properties.
2744 document().view()->setNeedsPaintPropertyUpdate();
2745 overflowA->layoutObject()->setNeedsPaintPropertyUpdate();
2746 document().view()->updateAllLifecyclePhases();
2747
2748 EXPECT_TRUE(frameScroll()->threadedScrollingDisabled());
2749 EXPECT_TRUE(overflowA->layoutObject()
2750 ->paintProperties()
2751 ->scroll()
2752 ->threadedScrollingDisabled());
2753 }
2754
2755 TEST_P(PaintPropertyTreeBuilderTest,
2756 BackgroundAttachmentFixedMainThreadScrollReasonsWithNestedScrollers) {
2757 setBodyInnerHTML(
2758 "<style>"
2759 " #overflowA {"
2760 " position: absolute;"
2761 " overflow: scroll;"
2762 " width: 20px;"
2763 " height: 20px;"
2764 " }"
2765 " #overflowB {"
2766 " position: absolute;"
2767 " overflow: scroll;"
2768 " width: 5px;"
2769 " height: 3px;"
2770 " }"
2771 " .backgroundAttachmentFixed {"
2772 " background-image: url('foo');"
2773 " background-attachment: fixed;"
2774 " }"
2775 " .forceScroll {"
2776 " height: 4000px;"
2777 " }"
2778 "</style>"
2779 "<div id='overflowA'>"
2780 " <div id='overflowB' class='backgroundAttachmentFixed'>"
2781 " <div class='forceScroll'></div>"
2782 " </div>"
2783 " <div class='forceScroll'></div>"
2784 "</div>"
2785 "<div class='forceScroll'></div>");
2786 Element* overflowA = document().getElementById("overflowA");
2787 Element* overflowB = document().getElementById("overflowB");
2788
2789 EXPECT_TRUE(frameScroll()->hasBackgroundAttachmentFixedDescendants());
2790 EXPECT_TRUE(overflowA->layoutObject()
2791 ->paintProperties()
2792 ->scroll()
2793 ->hasBackgroundAttachmentFixedDescendants());
2794 EXPECT_FALSE(overflowB->layoutObject()
2795 ->paintProperties()
2796 ->scroll()
2797 ->hasBackgroundAttachmentFixedDescendants());
2798
2799 // Removing a main thread scrolling reason should update the entire tree.
2800 overflowB->removeAttribute("class");
2801 document().view()->updateAllLifecyclePhases();
2802 EXPECT_FALSE(frameScroll()->hasBackgroundAttachmentFixedDescendants());
2803 EXPECT_FALSE(overflowA->layoutObject()
2804 ->paintProperties()
2805 ->scroll()
2806 ->hasBackgroundAttachmentFixedDescendants());
2807 EXPECT_FALSE(overflowB->layoutObject()
2808 ->paintProperties()
2809 ->scroll()
2810 ->hasBackgroundAttachmentFixedDescendants());
2811
2812 // Adding a main thread scrolling reason should update the entire tree.
2813 overflowB->setAttribute(HTMLNames::classAttr, "backgroundAttachmentFixed");
2814 document().view()->updateAllLifecyclePhases();
2815 EXPECT_TRUE(frameScroll()->hasBackgroundAttachmentFixedDescendants());
2816 EXPECT_TRUE(overflowA->layoutObject()
2817 ->paintProperties()
2818 ->scroll()
2819 ->hasBackgroundAttachmentFixedDescendants());
2820 EXPECT_FALSE(overflowB->layoutObject()
2821 ->paintProperties()
2822 ->scroll()
2823 ->hasBackgroundAttachmentFixedDescendants());
2824 }
2825
2826 TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithoutScrolling) { 2697 TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithoutScrolling) {
2827 setBodyInnerHTML( 2698 setBodyInnerHTML(
2828 "<style>" 2699 "<style>"
2829 " #overflow {" 2700 " #overflow {"
2830 " overflow: scroll;" 2701 " overflow: scroll;"
2831 " width: 100px;" 2702 " width: 100px;"
2832 " height: 100px;" 2703 " height: 100px;"
2833 " }" 2704 " }"
2834 " .backgroundAttachmentFixed {" 2705 " .backgroundAttachmentFixed {"
2835 " background-image: url('foo');" 2706 " background-image: url('foo');"
(...skipping 10 matching lines...) Expand all
2846 "</div>" 2717 "</div>"
2847 "<div class='forceScroll'></div>"); 2718 "<div class='forceScroll'></div>");
2848 Element* overflow = document().getElementById("overflow"); 2719 Element* overflow = document().getElementById("overflow");
2849 EXPECT_TRUE(frameScroll()->hasBackgroundAttachmentFixedDescendants()); 2720 EXPECT_TRUE(frameScroll()->hasBackgroundAttachmentFixedDescendants());
2850 EXPECT_TRUE(overflow->layoutObject() 2721 EXPECT_TRUE(overflow->layoutObject()
2851 ->paintProperties() 2722 ->paintProperties()
2852 ->scroll() 2723 ->scroll()
2853 ->hasBackgroundAttachmentFixedDescendants()); 2724 ->hasBackgroundAttachmentFixedDescendants());
2854 } 2725 }
2855 2726
2856 TEST_P(PaintPropertyTreeBuilderTest,
2857 BackgroundAttachmentFixedMainThreadScrollReasonsWithFixedScroller) {
2858 setBodyInnerHTML(
2859 "<style>"
2860 " #overflowA {"
2861 " position: absolute;"
2862 " overflow: scroll;"
2863 " width: 20px;"
2864 " height: 20px;"
2865 " }"
2866 " #overflowB {"
2867 " position: fixed;"
2868 " overflow: scroll;"
2869 " width: 5px;"
2870 " height: 3px;"
2871 " }"
2872 " .backgroundAttachmentFixed {"
2873 " background-image: url('foo');"
2874 " background-attachment: fixed;"
2875 " }"
2876 " .forceScroll {"
2877 " height: 4000px;"
2878 " }"
2879 "</style>"
2880 "<div id='overflowA'>"
2881 " <div id='overflowB' class='backgroundAttachmentFixed'>"
2882 " <div class='forceScroll'></div>"
2883 " </div>"
2884 " <div class='forceScroll'></div>"
2885 "</div>"
2886 "<div class='forceScroll'></div>");
2887 Element* overflowA = document().getElementById("overflowA");
2888 Element* overflowB = document().getElementById("overflowB");
2889
2890 // This should be false. We are not as strict about main thread scrolling
2891 // reasons as we could be.
2892 EXPECT_TRUE(overflowA->layoutObject()
2893 ->paintProperties()
2894 ->scroll()
2895 ->hasBackgroundAttachmentFixedDescendants());
2896 EXPECT_FALSE(overflowB->layoutObject()
2897 ->paintProperties()
2898 ->scroll()
2899 ->hasBackgroundAttachmentFixedDescendants());
2900 EXPECT_TRUE(overflowB->layoutObject()
2901 ->paintProperties()
2902 ->scroll()
2903 ->parent()
2904 ->isRoot());
2905
2906 // Removing a main thread scrolling reason should update the entire tree.
2907 overflowB->removeAttribute("class");
2908 document().view()->updateAllLifecyclePhases();
2909 EXPECT_FALSE(overflowA->layoutObject()
2910 ->paintProperties()
2911 ->scroll()
2912 ->hasBackgroundAttachmentFixedDescendants());
2913 EXPECT_FALSE(overflowB->layoutObject()
2914 ->paintProperties()
2915 ->scroll()
2916 ->hasBackgroundAttachmentFixedDescendants());
2917 EXPECT_FALSE(overflowB->layoutObject()
2918 ->paintProperties()
2919 ->scroll()
2920 ->parent()
2921 ->hasBackgroundAttachmentFixedDescendants());
2922 }
2923
2924 TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumn) { 2727 TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumn) {
2925 setBodyInnerHTML( 2728 setBodyInnerHTML(
2926 "<style>" 2729 "<style>"
2927 " body { margin: 0; }" 2730 " body { margin: 0; }"
2928 " .space { height: 30px; }" 2731 " .space { height: 30px; }"
2929 " .abs { position: absolute; width: 20px; height: 20px; }" 2732 " .abs { position: absolute; width: 20px; height: 20px; }"
2930 "</style>" 2733 "</style>"
2931 "<div style='columns:2; width: 200px; column-gap: 0'>" 2734 "<div style='columns:2; width: 200px; column-gap: 0'>"
2932 " <div style='position: relative'>" 2735 " <div style='position: relative'>"
2933 " <div id=space1 class=space></div>" 2736 " <div id=space1 class=space></div>"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3040 childProperties->localBorderBoxProperties()->propertyTreeState; 2843 childProperties->localBorderBoxProperties()->propertyTreeState;
3041 EXPECT_EQ(framePreTranslation(), 2844 EXPECT_EQ(framePreTranslation(),
3042 childProperties->paintOffsetTranslation()->parent()); 2845 childProperties->paintOffsetTranslation()->parent());
3043 EXPECT_EQ(childProperties->paintOffsetTranslation(), 2846 EXPECT_EQ(childProperties->paintOffsetTranslation(),
3044 childPaintState.transform()); 2847 childPaintState.transform());
3045 // This will change once we added clip expansion node. 2848 // This will change once we added clip expansion node.
3046 EXPECT_EQ(filterProperties->effect()->outputClip(), childPaintState.clip()); 2849 EXPECT_EQ(filterProperties->effect()->outputClip(), childPaintState.clip());
3047 EXPECT_EQ(filterProperties->effect(), childPaintState.effect()); 2850 EXPECT_EQ(filterProperties->effect(), childPaintState.effect());
3048 } 2851 }
3049 2852
3050 TEST_P(PaintPropertyTreeBuilderTest, DescendantNeedsUpdateAcrossFrames) {
3051 setBodyInnerHTML(
3052 "<style>body { margin: 0; }</style>"
3053 "<div id='divWithTransform' style='transform: translate3d(1px,2px,3px);'>"
3054 " <iframe style='border: 7px solid black'></iframe>"
3055 "</div>");
3056 setChildFrameHTML(
3057 "<style>body { margin: 0; }</style><div id='transform' style='transform: "
3058 "translate3d(4px, 5px, 6px); width: 100px; height: 200px'></div>");
3059
3060 FrameView* frameView = document().view();
3061 frameView->updateAllLifecyclePhases();
3062
3063 LayoutObject* divWithTransform =
3064 document().getElementById("divWithTransform")->layoutObject();
3065 LayoutObject* childLayoutView = childDocument().layoutView();
3066 LayoutObject* innerDivWithTransform =
3067 childDocument().getElementById("transform")->layoutObject();
3068
3069 // Initially, no objects should need a descendant update.
3070 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3071 EXPECT_FALSE(divWithTransform->descendantNeedsPaintPropertyUpdate());
3072 EXPECT_FALSE(childLayoutView->descendantNeedsPaintPropertyUpdate());
3073 EXPECT_FALSE(innerDivWithTransform->descendantNeedsPaintPropertyUpdate());
3074
3075 // Marking the child div as needing a paint property update should propagate
3076 // up the tree and across frames.
3077 innerDivWithTransform->setNeedsPaintPropertyUpdate();
3078 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3079 EXPECT_TRUE(divWithTransform->descendantNeedsPaintPropertyUpdate());
3080 EXPECT_TRUE(childLayoutView->descendantNeedsPaintPropertyUpdate());
3081 EXPECT_TRUE(innerDivWithTransform->needsPaintPropertyUpdate());
3082 EXPECT_FALSE(innerDivWithTransform->descendantNeedsPaintPropertyUpdate());
3083
3084 // After a lifecycle update, no nodes should need a descendant update.
3085 frameView->updateAllLifecyclePhases();
3086 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3087 EXPECT_FALSE(divWithTransform->descendantNeedsPaintPropertyUpdate());
3088 EXPECT_FALSE(childLayoutView->descendantNeedsPaintPropertyUpdate());
3089 EXPECT_FALSE(innerDivWithTransform->descendantNeedsPaintPropertyUpdate());
3090
3091 // A child frame marked as needing a paint property update should not be
3092 // skipped if the owning layout tree does not need an update.
3093 FrameView* childFrameView = childDocument().view();
3094 childFrameView->setNeedsPaintPropertyUpdate();
3095 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3096 frameView->updateAllLifecyclePhases();
3097 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3098 EXPECT_FALSE(frameView->needsPaintPropertyUpdate());
3099 EXPECT_FALSE(childFrameView->needsPaintPropertyUpdate());
3100 }
3101
3102 TEST_P(PaintPropertyTreeBuilderTest, UpdatingFrameViewContentClip) {
3103 setBodyInnerHTML("hello world.");
3104 EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), frameContentClip()->clipRect());
3105 document().view()->resize(800, 599);
3106 document().view()->updateAllLifecyclePhases();
3107 EXPECT_EQ(FloatRoundedRect(0, 0, 800, 599), frameContentClip()->clipRect());
3108 document().view()->resize(800, 600);
3109 document().view()->updateAllLifecyclePhases();
3110 EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), frameContentClip()->clipRect());
3111 document().view()->resize(5, 5);
3112 document().view()->updateAllLifecyclePhases();
3113 EXPECT_EQ(FloatRoundedRect(0, 0, 5, 5), frameContentClip()->clipRect());
3114 }
3115
3116 TEST_P(PaintPropertyTreeBuilderTest, BuildingStopsAtThrottledFrames) {
3117 setBodyInnerHTML(
3118 "<style>body { margin: 0; }</style>"
3119 "<div id='transform' style='transform: translate3d(4px, 5px, 6px);'>"
3120 "</div>"
3121 "<iframe id='iframe' sandbox></iframe>");
3122 setChildFrameHTML(
3123 "<style>body { margin: 0; }</style>"
3124 "<div id='iframeTransform'"
3125 " style='transform: translate3d(4px, 5px, 6px);'/>");
3126
3127 // Move the child frame offscreen so it becomes available for throttling.
3128 auto* iframe = toHTMLIFrameElement(document().getElementById("iframe"));
3129 iframe->setAttribute(HTMLNames::styleAttr, "transform: translateY(5555px)");
3130 document().view()->updateAllLifecyclePhases();
3131 // Ensure intersection observer notifications get delivered.
3132 testing::runPendingTasks();
3133 EXPECT_FALSE(document().view()->isHiddenForThrottling());
3134 EXPECT_TRUE(childDocument().view()->isHiddenForThrottling());
3135
3136 auto* transform = document().getElementById("transform")->layoutObject();
3137 auto* iframeLayoutView = childDocument().layoutView();
3138 auto* iframeTransform =
3139 childDocument().getElementById("iframeTransform")->layoutObject();
3140
3141 // Invalidate properties in the iframe and ensure ancestors are marked.
3142 iframeTransform->setNeedsPaintPropertyUpdate();
3143 EXPECT_FALSE(document().layoutView()->needsPaintPropertyUpdate());
3144 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3145 EXPECT_FALSE(transform->needsPaintPropertyUpdate());
3146 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate());
3147 EXPECT_FALSE(iframeLayoutView->needsPaintPropertyUpdate());
3148 EXPECT_TRUE(iframeLayoutView->descendantNeedsPaintPropertyUpdate());
3149 EXPECT_TRUE(iframeTransform->needsPaintPropertyUpdate());
3150 EXPECT_FALSE(iframeTransform->descendantNeedsPaintPropertyUpdate());
3151
3152 transform->setNeedsPaintPropertyUpdate();
3153 EXPECT_TRUE(transform->needsPaintPropertyUpdate());
3154 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate());
3155
3156 {
3157 DocumentLifecycle::AllowThrottlingScope throttlingScope(
3158 document().lifecycle());
3159 EXPECT_FALSE(document().view()->shouldThrottleRendering());
3160 EXPECT_TRUE(childDocument().view()->shouldThrottleRendering());
3161
3162 // A lifecycle update should update all properties except those with
3163 // actively throttled descendants.
3164 document().view()->updateAllLifecyclePhases();
3165 EXPECT_FALSE(document().layoutView()->needsPaintPropertyUpdate());
3166 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3167 EXPECT_FALSE(transform->needsPaintPropertyUpdate());
3168 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate());
3169 EXPECT_FALSE(iframeLayoutView->needsPaintPropertyUpdate());
3170 EXPECT_TRUE(iframeLayoutView->descendantNeedsPaintPropertyUpdate());
3171 EXPECT_TRUE(iframeTransform->needsPaintPropertyUpdate());
3172 EXPECT_FALSE(iframeTransform->descendantNeedsPaintPropertyUpdate());
3173 }
3174
3175 EXPECT_FALSE(document().view()->shouldThrottleRendering());
3176 EXPECT_FALSE(childDocument().view()->shouldThrottleRendering());
3177 // Once unthrottled, a lifecycel update should update all properties.
3178 document().view()->updateAllLifecyclePhases();
3179 EXPECT_FALSE(document().layoutView()->needsPaintPropertyUpdate());
3180 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate());
3181 EXPECT_FALSE(transform->needsPaintPropertyUpdate());
3182 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate());
3183 EXPECT_FALSE(iframeLayoutView->needsPaintPropertyUpdate());
3184 EXPECT_FALSE(iframeLayoutView->descendantNeedsPaintPropertyUpdate());
3185 EXPECT_FALSE(iframeTransform->needsPaintPropertyUpdate());
3186 EXPECT_FALSE(iframeTransform->descendantNeedsPaintPropertyUpdate());
3187 }
3188
3189 TEST_P(PaintPropertyTreeBuilderTest, ClipChangesUpdateOverflowClip) {
3190 setBodyInnerHTML(
3191 "<style>"
3192 " body { margin:0 }"
3193 " #div { overflow:hidden; height:0px; }"
3194 "</style>"
3195 "<div id='div'></div>");
3196 auto* div = document().getElementById("div");
3197 div->setAttribute(HTMLNames::styleAttr, "display:inline-block; width:7px;");
3198 document().view()->updateAllLifecyclePhases();
3199 auto* clipProperties = div->layoutObject()->paintProperties()->overflowClip();
3200 EXPECT_EQ(FloatRect(0, 0, 7, 0), clipProperties->clipRect().rect());
3201
3202 // Width changes should update the overflow clip.
3203 div->setAttribute(HTMLNames::styleAttr, "display:inline-block; width:7px;");
3204 document().view()->updateAllLifecyclePhases();
3205 clipProperties = div->layoutObject()->paintProperties()->overflowClip();
3206 EXPECT_EQ(FloatRect(0, 0, 7, 0), clipProperties->clipRect().rect());
3207 div->setAttribute(HTMLNames::styleAttr, "display:inline-block; width:9px;");
3208 document().view()->updateAllLifecyclePhases();
3209 EXPECT_EQ(FloatRect(0, 0, 9, 0), clipProperties->clipRect().rect());
3210
3211 // An inline block's overflow clip should be updated when padding changes,
3212 // even if the border box remains unchanged.
3213 div->setAttribute(HTMLNames::styleAttr,
3214 "display:inline-block; width:7px; padding-right:3px;");
3215 document().view()->updateAllLifecyclePhases();
3216 clipProperties = div->layoutObject()->paintProperties()->overflowClip();
3217 EXPECT_EQ(FloatRect(0, 0, 10, 0), clipProperties->clipRect().rect());
3218 div->setAttribute(HTMLNames::styleAttr,
3219 "display:inline-block; width:8px; padding-right:2px;");
3220 document().view()->updateAllLifecyclePhases();
3221 EXPECT_EQ(FloatRect(0, 0, 10, 0), clipProperties->clipRect().rect());
3222 div->setAttribute(HTMLNames::styleAttr,
3223 "display:inline-block; width:8px;"
3224 "padding-right:1px; padding-left:1px;");
3225 document().view()->updateAllLifecyclePhases();
3226 EXPECT_EQ(FloatRect(0, 0, 10, 0), clipProperties->clipRect().rect());
3227
3228 // An block's overflow clip should be updated when borders change.
3229 div->setAttribute(HTMLNames::styleAttr, "border-right:3px solid red;");
3230 document().view()->updateAllLifecyclePhases();
3231 clipProperties = div->layoutObject()->paintProperties()->overflowClip();
3232 EXPECT_EQ(FloatRect(0, 0, 797, 0), clipProperties->clipRect().rect());
3233 div->setAttribute(HTMLNames::styleAttr, "border-right:5px solid red;");
3234 document().view()->updateAllLifecyclePhases();
3235 EXPECT_EQ(FloatRect(0, 0, 795, 0), clipProperties->clipRect().rect());
3236
3237 // Removing overflow clip should remove the property.
3238 div->setAttribute(HTMLNames::styleAttr, "overflow:hidden;");
3239 document().view()->updateAllLifecyclePhases();
3240 clipProperties = div->layoutObject()->paintProperties()->overflowClip();
3241 EXPECT_EQ(FloatRect(0, 0, 800, 0), clipProperties->clipRect().rect());
3242 div->setAttribute(HTMLNames::styleAttr, "overflow:visible;");
3243 document().view()->updateAllLifecyclePhases();
3244 EXPECT_TRUE(!div->layoutObject()->paintProperties() ||
3245 !div->layoutObject()->paintProperties()->overflowClip());
3246 }
3247
3248 TEST_P(PaintPropertyTreeBuilderTest, ContainPaintChangesUpdateOverflowClip) {
3249 setBodyInnerHTML(
3250 "<style>"
3251 " body { margin:0 }"
3252 " #div { will-change:transform; width:7px; height:6px; }"
3253 "</style>"
3254 "<div id='div' style='contain:paint;'></div>");
3255 document().view()->updateAllLifecyclePhases();
3256 auto* div = document().getElementById("div");
3257 auto* properties = div->layoutObject()->paintProperties()->overflowClip();
3258 EXPECT_EQ(FloatRect(0, 0, 7, 6), properties->clipRect().rect());
3259
3260 div->setAttribute(HTMLNames::styleAttr, "");
3261 document().view()->updateAllLifecyclePhases();
3262 EXPECT_TRUE(!div->layoutObject()->paintProperties() ||
3263 !div->layoutObject()->paintProperties()->overflowClip());
3264 }
3265
3266 // A basic sanity check for over-invalidation of paint properties.
3267 TEST_P(PaintPropertyTreeBuilderTest, NoPaintPropertyUpdateOnBackgroundChange) {
3268 setBodyInnerHTML("<div id='div' style='background-color: blue'>DIV</div>");
3269 auto* div = document().getElementById("div");
3270
3271 document().view()->updateAllLifecyclePhases();
3272 div->setAttribute(HTMLNames::styleAttr, "background-color: green");
3273 document().view()->updateLifecycleToLayoutClean();
3274 EXPECT_FALSE(div->layoutObject()->needsPaintPropertyUpdate());
3275 }
3276
3277 // Disabled due to stale scrollsOverflow values, see: https://crbug.com/675296.
3278 TEST_P(PaintPropertyTreeBuilderTest,
3279 DISABLED_FrameVisibilityChangeUpdatesProperties) {
3280 setBodyInnerHTML(
3281 "<style>body { margin: 0; }</style>"
3282 "<div id='iframeContainer'>"
3283 " <iframe id='iframe' style='width: 100px; height: 100px;'></iframe>"
3284 "</div>");
3285 setChildFrameHTML(
3286 "<style>body { margin: 0; }</style>"
3287 "<div id='forceScroll' style='height: 3000px;'></div>");
3288
3289 FrameView* frameView = document().view();
3290 frameView->updateAllLifecyclePhases();
3291 EXPECT_EQ(nullptr, frameScroll(frameView));
3292 FrameView* childFrameView = childDocument().view();
3293 EXPECT_NE(nullptr, frameScroll(childFrameView));
3294
3295 auto* iframeContainer = document().getElementById("iframeContainer");
3296 iframeContainer->setAttribute(HTMLNames::styleAttr, "visibility: hidden;");
3297 frameView->updateAllLifecyclePhases();
3298
3299 EXPECT_EQ(nullptr, frameScroll(frameView));
3300 EXPECT_EQ(nullptr, frameScroll(childFrameView));
3301 }
3302
3303 } // namespace blink 2853 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698