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

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

Powered by Google App Engine
This is Rietveld 408576698