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

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

Issue 2539693002: Early-out from the prepaint tree walk (Closed)
Patch Set: Do not force subtree updates for all paint invalidation reasons, add todo to track paint offset cha… 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/PaintPropertyTreeBuilder.h" 5 #include "core/paint/PaintPropertyTreeBuilder.h"
6 6
7 #include "core/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "core/frame/LocalFrame.h" 8 #include "core/frame/LocalFrame.h"
9 #include "core/frame/Settings.h" 9 #include "core/frame/Settings.h"
10 #include "core/layout/LayoutInline.h" 10 #include "core/layout/LayoutInline.h"
(...skipping 16 matching lines...) Expand all
27 context.fixedPosition.clip = ClipPaintPropertyNode::root(); 27 context.fixedPosition.clip = ClipPaintPropertyNode::root();
28 context.currentEffect = EffectPaintPropertyNode::root(); 28 context.currentEffect = EffectPaintPropertyNode::root();
29 context.inputClipOfCurrentEffect = ClipPaintPropertyNode::root(); 29 context.inputClipOfCurrentEffect = ClipPaintPropertyNode::root();
30 context.current.transform = context.absolutePosition.transform = 30 context.current.transform = context.absolutePosition.transform =
31 context.fixedPosition.transform = TransformPaintPropertyNode::root(); 31 context.fixedPosition.transform = TransformPaintPropertyNode::root();
32 context.current.scroll = context.absolutePosition.scroll = 32 context.current.scroll = context.absolutePosition.scroll =
33 context.fixedPosition.scroll = ScrollPaintPropertyNode::root(); 33 context.fixedPosition.scroll = ScrollPaintPropertyNode::root();
34 return context; 34 return context;
35 } 35 }
36 36
37 void updateFrameViewPreTranslation( 37 PropertyWasCreated updatePreTranslation(
38 FrameView& frameView, 38 FrameView& frameView,
39 PassRefPtr<const TransformPaintPropertyNode> parent, 39 PassRefPtr<const TransformPaintPropertyNode> parent,
40 const TransformationMatrix& matrix, 40 const TransformationMatrix& matrix,
41 const FloatPoint3D& origin) { 41 const FloatPoint3D& origin) {
42 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 42 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
43 if (auto* existingPreTranslation = frameView.preTranslation()) { 43 if (auto* existingPreTranslation = frameView.preTranslation()) {
44 existingPreTranslation->update(std::move(parent), matrix, origin); 44 existingPreTranslation->update(std::move(parent), matrix, origin);
45 } else { 45 return DidNotCreateProperty;
46 frameView.setPreTranslation(
47 TransformPaintPropertyNode::create(std::move(parent), matrix, origin));
48 } 46 }
47 frameView.setPreTranslation(
48 TransformPaintPropertyNode::create(std::move(parent), matrix, origin));
49 return CreatedProperty;
49 } 50 }
50 51
51 void updateFrameViewContentClip( 52 PropertyWasCreated updateContentClip(
52 FrameView& frameView, 53 FrameView& frameView,
53 PassRefPtr<const ClipPaintPropertyNode> parent, 54 PassRefPtr<const ClipPaintPropertyNode> parent,
54 PassRefPtr<const TransformPaintPropertyNode> localTransformSpace, 55 PassRefPtr<const TransformPaintPropertyNode> localTransformSpace,
55 const FloatRoundedRect& clipRect) { 56 const FloatRoundedRect& clipRect) {
56 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 57 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
57 if (auto* existingContentClip = frameView.contentClip()) { 58 if (auto* existingContentClip = frameView.contentClip()) {
58 existingContentClip->update(std::move(parent), 59 existingContentClip->update(std::move(parent),
59 std::move(localTransformSpace), clipRect); 60 std::move(localTransformSpace), clipRect);
60 } else { 61 return DidNotCreateProperty;
61 frameView.setContentClip(ClipPaintPropertyNode::create(
62 std::move(parent), std::move(localTransformSpace), clipRect));
63 } 62 }
63 frameView.setContentClip(ClipPaintPropertyNode::create(
64 std::move(parent), std::move(localTransformSpace), clipRect));
65 return CreatedProperty;
64 } 66 }
65 67
66 void updateFrameViewScrollTranslation( 68 PropertyWasCreated updateScrollTranslation(
67 FrameView& frameView, 69 FrameView& frameView,
68 PassRefPtr<const TransformPaintPropertyNode> parent, 70 PassRefPtr<const TransformPaintPropertyNode> parent,
69 const TransformationMatrix& matrix, 71 const TransformationMatrix& matrix,
70 const FloatPoint3D& origin) { 72 const FloatPoint3D& origin) {
71 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 73 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
72 if (auto* existingScrollTranslation = frameView.scrollTranslation()) { 74 if (auto* existingScrollTranslation = frameView.scrollTranslation()) {
73 existingScrollTranslation->update(std::move(parent), matrix, origin); 75 existingScrollTranslation->update(std::move(parent), matrix, origin);
74 } else { 76 return DidNotCreateProperty;
75 frameView.setScrollTranslation(
76 TransformPaintPropertyNode::create(std::move(parent), matrix, origin));
77 } 77 }
78 frameView.setScrollTranslation(
79 TransformPaintPropertyNode::create(std::move(parent), matrix, origin));
80 return CreatedProperty;
78 } 81 }
79 82
80 void updateFrameViewScroll( 83 PropertyWasCreated updateScroll(
81 FrameView& frameView, 84 FrameView& frameView,
82 PassRefPtr<const ScrollPaintPropertyNode> parent, 85 PassRefPtr<const ScrollPaintPropertyNode> parent,
83 PassRefPtr<const TransformPaintPropertyNode> scrollOffset, 86 PassRefPtr<const TransformPaintPropertyNode> scrollOffset,
84 const IntSize& clip, 87 const IntSize& clip,
85 const IntSize& bounds, 88 const IntSize& bounds,
86 bool userScrollableHorizontal, 89 bool userScrollableHorizontal,
87 bool userScrollableVertical, 90 bool userScrollableVertical,
88 MainThreadScrollingReasons mainThreadScrollingReasons) { 91 MainThreadScrollingReasons mainThreadScrollingReasons) {
89 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 92 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
90 if (auto* existingScroll = frameView.scroll()) { 93 if (auto* existingScroll = frameView.scroll()) {
91 existingScroll->update(std::move(parent), std::move(scrollOffset), clip, 94 existingScroll->update(std::move(parent), std::move(scrollOffset), clip,
92 bounds, userScrollableHorizontal, 95 bounds, userScrollableHorizontal,
93 userScrollableVertical, mainThreadScrollingReasons); 96 userScrollableVertical, mainThreadScrollingReasons);
94 } else { 97 return DidNotCreateProperty;
95 frameView.setScroll(ScrollPaintPropertyNode::create(
96 std::move(parent), std::move(scrollOffset), clip, bounds,
97 userScrollableHorizontal, userScrollableVertical,
98 mainThreadScrollingReasons));
99 } 98 }
99 frameView.setScroll(ScrollPaintPropertyNode::create(
100 std::move(parent), std::move(scrollOffset), clip, bounds,
101 userScrollableHorizontal, userScrollableVertical,
102 mainThreadScrollingReasons));
103 return CreatedProperty;
100 } 104 }
101 105
102 void PaintPropertyTreeBuilder::updateProperties( 106 void PaintPropertyTreeBuilder::updateProperties(
103 FrameView& frameView, 107 FrameView& frameView,
104 PaintPropertyTreeBuilderContext& context) { 108 PaintPropertyTreeBuilderContext& context) {
105 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { 109 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
106 // With root layer scrolling, the LayoutView (a LayoutObject) properties are 110 // With root layer scrolling, the LayoutView (a LayoutObject) properties are
107 // updated like other objects (see updatePropertiesAndContextForSelf and 111 // updated like other objects (see updatePropertiesAndContextForSelf and
108 // updatePropertiesAndContextForChildren) instead of needing LayoutView- 112 // updatePropertiesAndContextForChildren) instead of needing LayoutView-
109 // specific property updates here. 113 // specific property updates here.
110 context.current.paintOffset.moveBy(frameView.location()); 114 context.current.paintOffset.moveBy(frameView.location());
111 context.current.renderingContextID = 0; 115 context.current.renderingContextID = 0;
112 context.current.shouldFlattenInheritedTransform = true; 116 context.current.shouldFlattenInheritedTransform = true;
113 context.absolutePosition = context.current; 117 context.absolutePosition = context.current;
114 context.containerForAbsolutePosition = nullptr; 118 context.containerForAbsolutePosition = nullptr;
115 context.fixedPosition = context.current; 119 context.fixedPosition = context.current;
116 return; 120 return;
117 } 121 }
118 122
123 if (context.forceSubtreeUpdate)
124 frameView.setNeedsPaintPropertyUpdateWithoutMarkingAncestors();
125
119 #if DCHECK_IS_ON() 126 #if DCHECK_IS_ON()
120 FindFrameViewPropertiesNeedingUpdateScope checkNeedsUpdateScope(&frameView); 127 FindFrameViewPropertiesNeedingUpdateScope checkScope(&frameView, context);
121 #endif 128 #endif
122 129
123 if (frameView.needsPaintPropertyUpdate()) { 130 if (frameView.needsPaintPropertyUpdate()) {
124 TransformationMatrix frameTranslate; 131 TransformationMatrix frameTranslate;
125 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), 132 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(),
126 frameView.y() + context.current.paintOffset.y()); 133 frameView.y() + context.current.paintOffset.y());
127 updateFrameViewPreTranslation(frameView, context.current.transform, 134 context.forceSubtreeUpdate |= updatePreTranslation(
chrishtr 2016/12/01 02:36:35 Did you consider passing context.forceSubtreeUpdat
128 frameTranslate, FloatPoint3D()); 135 frameView, context.current.transform, frameTranslate, FloatPoint3D());
129 136
130 FloatRoundedRect contentClip( 137 FloatRoundedRect contentClip(
131 IntRect(IntPoint(), frameView.visibleContentSize())); 138 IntRect(IntPoint(), frameView.visibleContentSize()));
132 updateFrameViewContentClip(frameView, context.current.clip, 139 context.forceSubtreeUpdate |=
133 frameView.preTranslation(), contentClip); 140 updateContentClip(frameView, context.current.clip,
141 frameView.preTranslation(), contentClip);
134 142
135 ScrollOffset scrollOffset = frameView.scrollOffset(); 143 ScrollOffset scrollOffset = frameView.scrollOffset();
136 if (frameView.isScrollable() || !scrollOffset.isZero()) { 144 if (frameView.isScrollable() || !scrollOffset.isZero()) {
137 TransformationMatrix frameScroll; 145 TransformationMatrix frameScroll;
138 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); 146 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
139 updateFrameViewScrollTranslation(frameView, frameView.preTranslation(), 147 context.forceSubtreeUpdate |= updateScrollTranslation(
140 frameScroll, FloatPoint3D()); 148 frameView, frameView.preTranslation(), frameScroll, FloatPoint3D());
141 149
142 IntSize scrollClip = frameView.visibleContentSize(); 150 IntSize scrollClip = frameView.visibleContentSize();
143 IntSize scrollBounds = frameView.contentsSize(); 151 IntSize scrollBounds = frameView.contentsSize();
144 bool userScrollableHorizontal = 152 bool userScrollableHorizontal =
145 frameView.userInputScrollable(HorizontalScrollbar); 153 frameView.userInputScrollable(HorizontalScrollbar);
146 bool userScrollableVertical = 154 bool userScrollableVertical =
147 frameView.userInputScrollable(VerticalScrollbar); 155 frameView.userInputScrollable(VerticalScrollbar);
148 156
149 MainThreadScrollingReasons reasons = 0; 157 MainThreadScrollingReasons reasons = 0;
150 if (!frameView.frame().settings()->threadedScrollingEnabled()) 158 if (!frameView.frame().settings()->threadedScrollingEnabled())
151 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; 159 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
152 if (frameView.hasBackgroundAttachmentFixedObjects()) { 160 if (frameView.hasBackgroundAttachmentFixedObjects()) {
153 reasons |= 161 reasons |=
154 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; 162 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
155 } 163 }
156 updateFrameViewScroll(frameView, context.current.scroll, 164 context.forceSubtreeUpdate |= updateScroll(
157 frameView.scrollTranslation(), scrollClip, 165 frameView, context.current.scroll, frameView.scrollTranslation(),
158 scrollBounds, userScrollableHorizontal, 166 scrollClip, scrollBounds, userScrollableHorizontal,
159 userScrollableVertical, reasons); 167 userScrollableVertical, reasons);
160 } else { 168 } else {
161 // Ensure pre-existing properties are cleared when there is no scrolling. 169 if (frameView.scrollTranslation() || frameView.scroll()) {
162 frameView.setScrollTranslation(nullptr); 170 // Ensure pre-existing properties are cleared if there is no scrolling.
163 frameView.setScroll(nullptr); 171 frameView.setScrollTranslation(nullptr);
172 frameView.setScroll(nullptr);
173
174 // Rebuild all descendant properties because a property was removed.
175 context.forceSubtreeUpdate = true;
176 }
164 } 177 }
165 } 178 }
166 179
167 // Initialize the context for current, absolute and fixed position cases. 180 // Initialize the context for current, absolute and fixed position cases.
168 // They are the same, except that scroll translation does not apply to 181 // They are the same, except that scroll translation does not apply to
169 // fixed position descendants. 182 // fixed position descendants.
170 const auto* fixedTransformNode = frameView.preTranslation() 183 const auto* fixedTransformNode = frameView.preTranslation()
171 ? frameView.preTranslation() 184 ? frameView.preTranslation()
172 : context.current.transform; 185 : context.current.transform;
173 auto* fixedScrollNode = context.current.scroll; 186 auto* fixedScrollNode = context.current.scroll;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // component for the transformed content to paint with. In spv1 this was 230 // component for the transformed content to paint with. In spv1 this was
218 // called "subpixel accumulation". For more information, see 231 // called "subpixel accumulation". For more information, see
219 // PaintLayer::subpixelAccumulation() and 232 // PaintLayer::subpixelAccumulation() and
220 // PaintLayerPainter::paintFragmentByApplyingTransform. 233 // PaintLayerPainter::paintFragmentByApplyingTransform.
221 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); 234 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
222 LayoutPoint fractionalPaintOffset = 235 LayoutPoint fractionalPaintOffset =
223 LayoutPoint(context.current.paintOffset - roundedPaintOffset); 236 LayoutPoint(context.current.paintOffset - roundedPaintOffset);
224 237
225 if (object.needsPaintPropertyUpdate()) { 238 if (object.needsPaintPropertyUpdate()) {
226 if (usesPaintOffsetTranslation) { 239 if (usesPaintOffsetTranslation) {
227 object.getMutableForPainting() 240 auto& properties = object.getMutableForPainting().ensurePaintProperties();
228 .ensurePaintProperties() 241 context.forceSubtreeUpdate |= properties.updatePaintOffsetTranslation(
229 .updatePaintOffsetTranslation( 242 context.current.transform,
230 context.current.transform, 243 TransformationMatrix().translate(roundedPaintOffset.x(),
231 TransformationMatrix().translate(roundedPaintOffset.x(), 244 roundedPaintOffset.y()),
232 roundedPaintOffset.y()), 245 FloatPoint3D(), context.current.shouldFlattenInheritedTransform,
233 FloatPoint3D(), context.current.shouldFlattenInheritedTransform, 246 context.current.renderingContextID);
234 context.current.renderingContextID);
235 } else { 247 } else {
236 if (auto* properties = object.getMutableForPainting().paintProperties()) 248 if (auto* properties = object.getMutableForPainting().paintProperties())
237 properties->clearPaintOffsetTranslation(); 249 context.forceSubtreeUpdate |= properties->clearPaintOffsetTranslation();
238 } 250 }
239 } 251 }
240 252
241 const auto* properties = object.paintProperties(); 253 const auto* properties = object.paintProperties();
242 if (properties && properties->paintOffsetTranslation()) { 254 if (properties && properties->paintOffsetTranslation()) {
243 context.current.transform = properties->paintOffsetTranslation(); 255 context.current.transform = properties->paintOffsetTranslation();
244 context.current.paintOffset = fractionalPaintOffset; 256 context.current.paintOffset = fractionalPaintOffset;
245 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && 257 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() &&
246 object.isLayoutView()) { 258 object.isLayoutView()) {
247 context.absolutePosition.transform = properties->paintOffsetTranslation(); 259 context.absolutePosition.transform = properties->paintOffsetTranslation();
(...skipping 28 matching lines...) Expand all
276 // transform function. 288 // transform function.
277 const AffineTransform& transform = object.isSVGForeignObject() 289 const AffineTransform& transform = object.isSVGForeignObject()
278 ? object.localSVGTransform() 290 ? object.localSVGTransform()
279 : object.localToSVGParentTransform(); 291 : object.localToSVGParentTransform();
280 // TODO(pdr): Check for the presence of a transform instead of the value. 292 // TODO(pdr): Check for the presence of a transform instead of the value.
281 // Checking for an identity matrix will cause the property tree structure 293 // Checking for an identity matrix will cause the property tree structure
282 // to change during animations if the animation passes through the 294 // to change during animations if the animation passes through the
283 // identity matrix. 295 // identity matrix.
284 if (!transform.isIdentity()) { 296 if (!transform.isIdentity()) {
285 // The origin is included in the local transform, so leave origin empty. 297 // The origin is included in the local transform, so leave origin empty.
286 object.getMutableForPainting().ensurePaintProperties().updateTransform( 298 auto& properties = object.getMutableForPainting().ensurePaintProperties();
299 context.forceSubtreeUpdate |= properties.updateTransform(
287 context.current.transform, TransformationMatrix(transform), 300 context.current.transform, TransformationMatrix(transform),
288 FloatPoint3D()); 301 FloatPoint3D());
289 } else { 302 } else {
290 if (auto* properties = object.getMutableForPainting().paintProperties()) 303 if (auto* properties = object.getMutableForPainting().paintProperties())
291 properties->clearTransform(); 304 context.forceSubtreeUpdate |= properties->clearTransform();
292 } 305 }
293 } 306 }
294 307
295 if (object.paintProperties() && object.paintProperties()->transform()) { 308 if (object.paintProperties() && object.paintProperties()->transform()) {
296 context.current.transform = object.paintProperties()->transform(); 309 context.current.transform = object.paintProperties()->transform();
297 context.current.shouldFlattenInheritedTransform = false; 310 context.current.shouldFlattenInheritedTransform = false;
298 context.current.renderingContextID = 0; 311 context.current.renderingContextID = 0;
299 } 312 }
300 } 313 }
301 314
(...skipping 16 matching lines...) Expand all
318 ComputedStyle::IncludeIndependentTransformProperties); 331 ComputedStyle::IncludeIndependentTransformProperties);
319 332
320 // TODO(trchen): transform-style should only be respected if a PaintLayer 333 // TODO(trchen): transform-style should only be respected if a PaintLayer
321 // is created. 334 // is created.
322 // If a node with transform-style: preserve-3d does not exist in an 335 // If a node with transform-style: preserve-3d does not exist in an
323 // existing rendering context, it establishes a new one. 336 // existing rendering context, it establishes a new one.
324 unsigned renderingContextID = context.current.renderingContextID; 337 unsigned renderingContextID = context.current.renderingContextID;
325 if (style.preserves3D() && !renderingContextID) 338 if (style.preserves3D() && !renderingContextID)
326 renderingContextID = PtrHash<const LayoutObject>::hash(&object); 339 renderingContextID = PtrHash<const LayoutObject>::hash(&object);
327 340
328 object.getMutableForPainting().ensurePaintProperties().updateTransform( 341 auto& properties = object.getMutableForPainting().ensurePaintProperties();
342 context.forceSubtreeUpdate |= properties.updateTransform(
329 context.current.transform, matrix, 343 context.current.transform, matrix,
330 transformOrigin(toLayoutBox(object)), 344 transformOrigin(toLayoutBox(object)),
331 context.current.shouldFlattenInheritedTransform, renderingContextID); 345 context.current.shouldFlattenInheritedTransform, renderingContextID);
332 } else { 346 } else {
333 if (auto* properties = object.getMutableForPainting().paintProperties()) 347 if (auto* properties = object.getMutableForPainting().paintProperties())
334 properties->clearTransform(); 348 context.forceSubtreeUpdate |= properties->clearTransform();
335 } 349 }
336 } 350 }
337 351
338 const auto* properties = object.paintProperties(); 352 const auto* properties = object.paintProperties();
339 if (properties && properties->transform()) { 353 if (properties && properties->transform()) {
340 context.current.transform = properties->transform(); 354 context.current.transform = properties->transform();
341 if (object.styleRef().preserves3D()) { 355 if (object.styleRef().preserves3D()) {
342 context.current.renderingContextID = 356 context.current.renderingContextID =
343 properties->transform()->renderingContextID(); 357 properties->transform()->renderingContextID();
344 context.current.shouldFlattenInheritedTransform = false; 358 context.current.shouldFlattenInheritedTransform = false;
345 } else { 359 } else {
346 context.current.renderingContextID = 0; 360 context.current.renderingContextID = 0;
347 context.current.shouldFlattenInheritedTransform = true; 361 context.current.shouldFlattenInheritedTransform = true;
348 } 362 }
349 } 363 }
350 } 364 }
351 365
352 void PaintPropertyTreeBuilder::updateEffect( 366 void PaintPropertyTreeBuilder::updateEffect(
353 const LayoutObject& object, 367 const LayoutObject& object,
354 PaintPropertyTreeBuilderContext& context) { 368 PaintPropertyTreeBuilderContext& context) {
355 const ComputedStyle& style = object.styleRef(); 369 const ComputedStyle& style = object.styleRef();
356 370
357 if (!style.isStackingContext()) { 371 if (!style.isStackingContext()) {
358 if (object.needsPaintPropertyUpdate()) { 372 if (object.needsPaintPropertyUpdate()) {
359 if (auto* properties = object.getMutableForPainting().paintProperties()) 373 if (auto* properties = object.getMutableForPainting().paintProperties())
360 properties->clearEffect(); 374 context.forceSubtreeUpdate |= properties->clearEffect();
361 } 375 }
362 return; 376 return;
363 } 377 }
364 378
365 // TODO(trchen): Can't omit effect node if we have 3D children. 379 // TODO(trchen): Can't omit effect node if we have 3D children.
366 // TODO(trchen): Can't omit effect node if we have blending children. 380 // TODO(trchen): Can't omit effect node if we have blending children.
367 if (object.needsPaintPropertyUpdate()) { 381 if (object.needsPaintPropertyUpdate()) {
368 bool effectNodeNeeded = false; 382 bool effectNodeNeeded = false;
369 383
370 float opacity = style.opacity(); 384 float opacity = style.opacity();
(...skipping 30 matching lines...) Expand all
401 if (!filter.isEmpty()) { 415 if (!filter.isEmpty()) {
402 effectNodeNeeded = true; 416 effectNodeNeeded = true;
403 outputClip = context.current.clip; 417 outputClip = context.current.clip;
404 418
405 // TODO(trchen): A filter may contain spatial operations such that an 419 // TODO(trchen): A filter may contain spatial operations such that an
406 // output pixel may depend on an input pixel outside of the output clip. 420 // output pixel may depend on an input pixel outside of the output clip.
407 // We should generate a special clip node to represent this expansion. 421 // We should generate a special clip node to represent this expansion.
408 } 422 }
409 423
410 if (effectNodeNeeded) { 424 if (effectNodeNeeded) {
411 object.getMutableForPainting().ensurePaintProperties().updateEffect( 425 auto& properties = object.getMutableForPainting().ensurePaintProperties();
426 context.forceSubtreeUpdate |= properties.updateEffect(
412 context.currentEffect, context.current.transform, outputClip, 427 context.currentEffect, context.current.transform, outputClip,
413 std::move(filter), opacity); 428 std::move(filter), opacity);
414 } else { 429 } else {
415 if (auto* properties = object.getMutableForPainting().paintProperties()) 430 if (auto* properties = object.getMutableForPainting().paintProperties())
416 properties->clearEffect(); 431 context.forceSubtreeUpdate |= properties->clearEffect();
417 } 432 }
418 } 433 }
419 434
420 const auto* properties = object.paintProperties(); 435 const auto* properties = object.paintProperties();
421 if (properties && properties->effect()) { 436 if (properties && properties->effect()) {
422 context.currentEffect = properties->effect(); 437 context.currentEffect = properties->effect();
423 if (!properties->effect()->filter().isEmpty()) { 438 if (!properties->effect()->filter().isEmpty()) {
424 // TODO(trchen): Change input clip to expansion hint once implemented. 439 // TODO(trchen): Change input clip to expansion hint once implemented.
425 const ClipPaintPropertyNode* inputClip = 440 const ClipPaintPropertyNode* inputClip =
426 properties->effect()->outputClip(); 441 properties->effect()->outputClip();
427 context.inputClipOfCurrentEffect = context.current.clip = 442 context.inputClipOfCurrentEffect = context.current.clip =
428 context.absolutePosition.clip = context.fixedPosition.clip = 443 context.absolutePosition.clip = context.fixedPosition.clip =
429 inputClip; 444 inputClip;
430 } 445 }
431 } 446 }
432 } 447 }
433 448
434 void PaintPropertyTreeBuilder::updateCssClip( 449 void PaintPropertyTreeBuilder::updateCssClip(
435 const LayoutObject& object, 450 const LayoutObject& object,
436 PaintPropertyTreeBuilderContext& context) { 451 PaintPropertyTreeBuilderContext& context) {
437 if (object.needsPaintPropertyUpdate()) { 452 if (object.needsPaintPropertyUpdate()) {
438 if (object.hasClip()) { 453 if (object.hasClip()) {
439 // Create clip node for descendants that are not fixed position. 454 // Create clip node for descendants that are not fixed position.
440 // We don't have to setup context.absolutePosition.clip here because this 455 // We don't have to setup context.absolutePosition.clip here because this
441 // object must be a container for absolute position descendants, and will 456 // object must be a container for absolute position descendants, and will
442 // copy from in-flow context later at updateOutOfFlowContext() step. 457 // copy from in-flow context later at updateOutOfFlowContext() step.
443 DCHECK(object.canContainAbsolutePositionObjects()); 458 DCHECK(object.canContainAbsolutePositionObjects());
444 LayoutRect clipRect = 459 LayoutRect clipRect =
445 toLayoutBox(object).clipRect(context.current.paintOffset); 460 toLayoutBox(object).clipRect(context.current.paintOffset);
446 object.getMutableForPainting().ensurePaintProperties().updateCssClip( 461 auto& properties = object.getMutableForPainting().ensurePaintProperties();
462 context.forceSubtreeUpdate |= properties.updateCssClip(
447 context.current.clip, context.current.transform, 463 context.current.clip, context.current.transform,
448 FloatRoundedRect(FloatRect(clipRect))); 464 FloatRoundedRect(FloatRect(clipRect)));
449 } else { 465 } else {
450 if (auto* properties = object.getMutableForPainting().paintProperties()) 466 if (auto* properties = object.getMutableForPainting().paintProperties())
451 properties->clearCssClip(); 467 context.forceSubtreeUpdate |= properties->clearCssClip();
452 } 468 }
453 } 469 }
454 470
455 const auto* properties = object.paintProperties(); 471 const auto* properties = object.paintProperties();
456 if (properties && properties->cssClip()) 472 if (properties && properties->cssClip())
457 context.current.clip = properties->cssClip(); 473 context.current.clip = properties->cssClip();
458 } 474 }
459 475
460 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( 476 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(
461 const LayoutObject& object, 477 const LayoutObject& object,
(...skipping 16 matching lines...) Expand all
478 context.current.scroll))); 494 context.current.scroll)));
479 object.getMutableForPainting() 495 object.getMutableForPainting()
480 .ensurePaintProperties() 496 .ensurePaintProperties()
481 .setLocalBorderBoxProperties(std::move(borderBoxContext)); 497 .setLocalBorderBoxProperties(std::move(borderBoxContext));
482 } 498 }
483 } 499 }
484 500
485 // TODO(trchen): Remove this once we bake the paint offset into frameRect. 501 // TODO(trchen): Remove this once we bake the paint offset into frameRect.
486 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( 502 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(
487 const LayoutObject& object, 503 const LayoutObject& object,
488 const PaintPropertyTreeBuilderContext& context) { 504 PaintPropertyTreeBuilderContext& context) {
489 if (!object.needsPaintPropertyUpdate()) 505 if (!object.needsPaintPropertyUpdate())
490 return; 506 return;
491 507
492 bool needsScrollbarPaintOffset = false; 508 bool needsScrollbarPaintOffset = false;
493 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); 509 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
494 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { 510 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) {
495 if (auto* area = toLayoutBoxModelObject(object).getScrollableArea()) { 511 if (auto* area = toLayoutBoxModelObject(object).getScrollableArea()) {
496 if (area->horizontalScrollbar() || area->verticalScrollbar()) { 512 if (area->horizontalScrollbar() || area->verticalScrollbar()) {
497 auto paintOffset = TransformationMatrix().translate( 513 auto paintOffset = TransformationMatrix().translate(
498 roundedPaintOffset.x(), roundedPaintOffset.y()); 514 roundedPaintOffset.x(), roundedPaintOffset.y());
499 object.getMutableForPainting() 515 auto& properties =
500 .ensurePaintProperties() 516 object.getMutableForPainting().ensurePaintProperties();
501 .updateScrollbarPaintOffset(context.current.transform, paintOffset, 517 context.forceSubtreeUpdate |= properties.updateScrollbarPaintOffset(
502 FloatPoint3D()); 518 context.current.transform, paintOffset, FloatPoint3D());
503 needsScrollbarPaintOffset = true; 519 needsScrollbarPaintOffset = true;
504 } 520 }
505 } 521 }
506 } 522 }
507 523
508 auto* properties = object.getMutableForPainting().paintProperties(); 524 auto* properties = object.getMutableForPainting().paintProperties();
509 if (!needsScrollbarPaintOffset && properties) 525 if (!needsScrollbarPaintOffset && properties)
510 properties->clearScrollbarPaintOffset(); 526 context.forceSubtreeUpdate |= properties->clearScrollbarPaintOffset();
511 } 527 }
512 528
513 void PaintPropertyTreeBuilder::updateOverflowClip( 529 void PaintPropertyTreeBuilder::updateOverflowClip(
514 const LayoutObject& object, 530 const LayoutObject& object,
515 PaintPropertyTreeBuilderContext& context) { 531 PaintPropertyTreeBuilderContext& context) {
516 if (!object.isBox()) 532 if (!object.isBox())
517 return; 533 return;
518 534
519 if (object.needsPaintPropertyUpdate()) { 535 if (object.needsPaintPropertyUpdate()) {
520 const LayoutBox& box = toLayoutBox(object); 536 const LayoutBox& box = toLayoutBox(object);
521 // The <input> elements can't have contents thus CSS overflow property 537 // The <input> elements can't have contents thus CSS overflow property
522 // doesn't apply. However for layout purposes we do generate child layout 538 // doesn't apply. However for layout purposes we do generate child layout
523 // objects for them, e.g. button label. We should clip the overflow from 539 // objects for them, e.g. button label. We should clip the overflow from
524 // those children. This is called control clip and we technically treat them 540 // those children. This is called control clip and we technically treat them
525 // like overflow clip. 541 // like overflow clip.
526 LayoutRect clipRect; 542 LayoutRect clipRect;
527 if (box.hasControlClip()) { 543 if (box.hasControlClip()) {
528 clipRect = box.controlClipRect(context.current.paintOffset); 544 clipRect = box.controlClipRect(context.current.paintOffset);
529 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() || 545 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() ||
530 (box.isSVGRoot() && 546 (box.isSVGRoot() &&
531 toLayoutSVGRoot(box).shouldApplyViewportClip())) { 547 toLayoutSVGRoot(box).shouldApplyViewportClip())) {
532 clipRect = LayoutRect(pixelSnappedIntRect( 548 clipRect = LayoutRect(pixelSnappedIntRect(
533 box.overflowClipRect(context.current.paintOffset))); 549 box.overflowClipRect(context.current.paintOffset)));
534 } else { 550 } else {
535 if (auto* properties = object.getMutableForPainting().paintProperties()) { 551 if (auto* properties = object.getMutableForPainting().paintProperties()) {
536 properties->clearInnerBorderRadiusClip(); 552 context.forceSubtreeUpdate |= properties->clearInnerBorderRadiusClip();
537 properties->clearOverflowClip(); 553 context.forceSubtreeUpdate |= properties->clearOverflowClip();
538 } 554 }
539 return; 555 return;
540 } 556 }
541 557
558 auto& properties = object.getMutableForPainting().ensurePaintProperties();
542 const auto* currentClip = context.current.clip; 559 const auto* currentClip = context.current.clip;
543 if (box.styleRef().hasBorderRadius()) { 560 if (box.styleRef().hasBorderRadius()) {
544 auto innerBorder = box.styleRef().getRoundedInnerBorderFor( 561 auto innerBorder = box.styleRef().getRoundedInnerBorderFor(
545 LayoutRect(context.current.paintOffset, box.size())); 562 LayoutRect(context.current.paintOffset, box.size()));
546 object.getMutableForPainting() 563 context.forceSubtreeUpdate |= properties.updateInnerBorderRadiusClip(
547 .ensurePaintProperties() 564 context.current.clip, context.current.transform, innerBorder);
548 .updateInnerBorderRadiusClip(context.current.clip, 565 currentClip = properties.innerBorderRadiusClip();
549 context.current.transform, innerBorder); 566 } else {
550 currentClip = object.paintProperties()->innerBorderRadiusClip(); 567 context.forceSubtreeUpdate |= properties.clearInnerBorderRadiusClip();
551 } else if (auto* properties =
552 object.getMutableForPainting().paintProperties()) {
553 properties->clearInnerBorderRadiusClip();
554 } 568 }
555 569
556 object.getMutableForPainting().ensurePaintProperties().updateOverflowClip( 570 context.forceSubtreeUpdate |=
557 currentClip, context.current.transform, 571 properties.updateOverflowClip(currentClip, context.current.transform,
558 FloatRoundedRect(FloatRect(clipRect))); 572 FloatRoundedRect(FloatRect(clipRect)));
559 } 573 }
560 574
561 const auto* properties = object.paintProperties(); 575 const auto* properties = object.paintProperties();
562 if (properties && properties->overflowClip()) 576 if (properties && properties->overflowClip())
563 context.current.clip = properties->overflowClip(); 577 context.current.clip = properties->overflowClip();
564 } 578 }
565 579
566 static FloatPoint perspectiveOrigin(const LayoutBox& box) { 580 static FloatPoint perspectiveOrigin(const LayoutBox& box) {
567 const ComputedStyle& style = box.styleRef(); 581 const ComputedStyle& style = box.styleRef();
568 FloatSize borderBoxSize(box.size()); 582 FloatSize borderBoxSize(box.size());
569 return FloatPoint( 583 return FloatPoint(
570 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), 584 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()),
571 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())); 585 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()));
572 } 586 }
573 587
574 void PaintPropertyTreeBuilder::updatePerspective( 588 void PaintPropertyTreeBuilder::updatePerspective(
575 const LayoutObject& object, 589 const LayoutObject& object,
576 PaintPropertyTreeBuilderContext& context) { 590 PaintPropertyTreeBuilderContext& context) {
577 if (object.needsPaintPropertyUpdate()) { 591 if (object.needsPaintPropertyUpdate()) {
578 const ComputedStyle& style = object.styleRef(); 592 const ComputedStyle& style = object.styleRef();
579 if (object.isBox() && style.hasPerspective()) { 593 if (object.isBox() && style.hasPerspective()) {
580 // The perspective node must not flatten (else nothing will get 594 // The perspective node must not flatten (else nothing will get
581 // perspective), but it should still extend the rendering context as 595 // perspective), but it should still extend the rendering context as
582 // most transform nodes do. 596 // most transform nodes do.
583 TransformationMatrix matrix = 597 TransformationMatrix matrix =
584 TransformationMatrix().applyPerspective(style.perspective()); 598 TransformationMatrix().applyPerspective(style.perspective());
585 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + 599 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) +
586 toLayoutSize(context.current.paintOffset); 600 toLayoutSize(context.current.paintOffset);
587 object.getMutableForPainting().ensurePaintProperties().updatePerspective( 601 auto& properties = object.getMutableForPainting().ensurePaintProperties();
602 context.forceSubtreeUpdate |= properties.updatePerspective(
588 context.current.transform, matrix, origin, 603 context.current.transform, matrix, origin,
589 context.current.shouldFlattenInheritedTransform, 604 context.current.shouldFlattenInheritedTransform,
590 context.current.renderingContextID); 605 context.current.renderingContextID);
591 } else { 606 } else {
592 if (auto* properties = object.getMutableForPainting().paintProperties()) 607 if (auto* properties = object.getMutableForPainting().paintProperties())
593 properties->clearPerspective(); 608 context.forceSubtreeUpdate |= properties->clearPerspective();
594 } 609 }
595 } 610 }
596 611
597 const auto* properties = object.paintProperties(); 612 const auto* properties = object.paintProperties();
598 if (properties && properties->perspective()) { 613 if (properties && properties->perspective()) {
599 context.current.transform = properties->perspective(); 614 context.current.transform = properties->perspective();
600 context.current.shouldFlattenInheritedTransform = false; 615 context.current.shouldFlattenInheritedTransform = false;
601 } 616 }
602 } 617 }
603 618
604 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( 619 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(
605 const LayoutObject& object, 620 const LayoutObject& object,
606 PaintPropertyTreeBuilderContext& context) { 621 PaintPropertyTreeBuilderContext& context) {
607 if (!object.isSVGRoot()) 622 if (!object.isSVGRoot())
608 return; 623 return;
609 624
610 if (object.needsPaintPropertyUpdate()) { 625 if (object.needsPaintPropertyUpdate()) {
611 AffineTransform transformToBorderBox = 626 AffineTransform transformToBorderBox =
612 SVGRootPainter(toLayoutSVGRoot(object)) 627 SVGRootPainter(toLayoutSVGRoot(object))
613 .transformToPixelSnappedBorderBox(context.current.paintOffset); 628 .transformToPixelSnappedBorderBox(context.current.paintOffset);
614 if (!transformToBorderBox.isIdentity()) { 629 if (!transformToBorderBox.isIdentity()) {
615 object.getMutableForPainting() 630 auto& properties = object.getMutableForPainting().ensurePaintProperties();
616 .ensurePaintProperties() 631 context.forceSubtreeUpdate |=
617 .updateSvgLocalToBorderBoxTransform( 632 properties.updateSvgLocalToBorderBoxTransform(
618 context.current.transform, transformToBorderBox, FloatPoint3D()); 633 context.current.transform, transformToBorderBox, FloatPoint3D());
619 } else { 634 } else {
620 if (auto* properties = object.getMutableForPainting().paintProperties()) 635 if (auto* properties = object.getMutableForPainting().paintProperties()) {
621 properties->clearSvgLocalToBorderBoxTransform(); 636 context.forceSubtreeUpdate |=
637 properties->clearSvgLocalToBorderBoxTransform();
638 }
622 } 639 }
623 } 640 }
624 641
625 const auto* properties = object.paintProperties(); 642 const auto* properties = object.paintProperties();
626 if (properties && properties->svgLocalToBorderBoxTransform()) { 643 if (properties && properties->svgLocalToBorderBoxTransform()) {
627 context.current.transform = properties->svgLocalToBorderBoxTransform(); 644 context.current.transform = properties->svgLocalToBorderBoxTransform();
628 context.current.shouldFlattenInheritedTransform = false; 645 context.current.shouldFlattenInheritedTransform = false;
629 context.current.renderingContextID = 0; 646 context.current.renderingContextID = 0;
630 } 647 }
631 // The paint offset is included in |transformToBorderBox| so SVG does not need 648 // The paint offset is included in |transformToBorderBox| so SVG does not need
632 // to handle paint offset internally. 649 // to handle paint offset internally.
633 context.current.paintOffset = LayoutPoint(); 650 context.current.paintOffset = LayoutPoint();
634 } 651 }
635 652
636 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( 653 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation(
637 const LayoutObject& object, 654 const LayoutObject& object,
638 PaintPropertyTreeBuilderContext& context) { 655 PaintPropertyTreeBuilderContext& context) {
639 if (object.needsPaintPropertyUpdate()) { 656 if (object.needsPaintPropertyUpdate()) {
640 if (object.hasOverflowClip()) { 657 if (object.hasOverflowClip()) {
641 const LayoutBox& box = toLayoutBox(object); 658 const LayoutBox& box = toLayoutBox(object);
642 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); 659 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea();
643 IntSize scrollOffset = box.scrolledContentOffset(); 660 IntSize scrollOffset = box.scrolledContentOffset();
644 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { 661 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) {
662 auto& properties =
663 object.getMutableForPainting().ensurePaintProperties();
645 TransformationMatrix matrix = TransformationMatrix().translate( 664 TransformationMatrix matrix = TransformationMatrix().translate(
646 -scrollOffset.width(), -scrollOffset.height()); 665 -scrollOffset.width(), -scrollOffset.height());
647 object.getMutableForPainting() 666 context.forceSubtreeUpdate |= properties.updateScrollTranslation(
648 .ensurePaintProperties() 667 context.current.transform, matrix, FloatPoint3D(),
649 .updateScrollTranslation( 668 context.current.shouldFlattenInheritedTransform,
650 context.current.transform, matrix, FloatPoint3D(), 669 context.current.renderingContextID);
651 context.current.shouldFlattenInheritedTransform,
652 context.current.renderingContextID);
653 670
654 IntSize scrollClip = scrollableArea->visibleContentRect().size(); 671 IntSize scrollClip = scrollableArea->visibleContentRect().size();
655 IntSize scrollBounds = scrollableArea->contentsSize(); 672 IntSize scrollBounds = scrollableArea->contentsSize();
656 bool userScrollableHorizontal = 673 bool userScrollableHorizontal =
657 scrollableArea->userInputScrollable(HorizontalScrollbar); 674 scrollableArea->userInputScrollable(HorizontalScrollbar);
658 bool userScrollableVertical = 675 bool userScrollableVertical =
659 scrollableArea->userInputScrollable(VerticalScrollbar); 676 scrollableArea->userInputScrollable(VerticalScrollbar);
660 MainThreadScrollingReasons reasons = 0; 677 MainThreadScrollingReasons reasons = 0;
661 if (!object.document().settings()->threadedScrollingEnabled()) 678 if (!object.document().settings()->threadedScrollingEnabled())
662 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; 679 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
663 // Checking for descendants in the layout tree has two downsides: 680 // Checking for descendants in the layout tree has two downsides:
664 // 1) There can be more descendants in layout order than in paint 681 // 1) There can be more descendants in layout order than in paint
665 // order (e.g., fixed position objects). 682 // order (e.g., fixed position objects).
666 // 2) Iterating overall all background attachment fixed objects for 683 // 2) Iterating overall all background attachment fixed objects for
667 // every scroll node can be slow, though there will be no objects 684 // every scroll node can be slow, though there will be no objects
668 // in the common case. 685 // in the common case.
669 const FrameView& frameView = *object.frameView(); 686 const FrameView& frameView = *object.frameView();
670 if (frameView.hasBackgroundAttachmentFixedDescendants(object)) { 687 if (frameView.hasBackgroundAttachmentFixedDescendants(object)) {
671 reasons |= 688 reasons |=
672 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; 689 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
673 } 690 }
674 object.getMutableForPainting().ensurePaintProperties().updateScroll( 691 context.forceSubtreeUpdate |= properties.updateScroll(
675 context.current.scroll, 692 context.current.scroll, properties.scrollTranslation(), scrollClip,
676 object.paintProperties()->scrollTranslation(), scrollClip,
677 scrollBounds, userScrollableHorizontal, userScrollableVertical, 693 scrollBounds, userScrollableHorizontal, userScrollableVertical,
678 reasons); 694 reasons);
679 } else { 695 } else {
680 // Ensure pre-existing properties are cleared when there is no 696 // Ensure pre-existing properties are cleared when there is no
681 // scrolling. 697 // scrolling.
682 auto* properties = object.getMutableForPainting().paintProperties(); 698 auto* properties = object.getMutableForPainting().paintProperties();
683 if (properties) { 699 if (properties) {
684 properties->clearScrollTranslation(); 700 context.forceSubtreeUpdate |= properties->clearScrollTranslation();
685 properties->clearScroll(); 701 context.forceSubtreeUpdate |= properties->clearScroll();
686 } 702 }
687 } 703 }
688 } 704 }
689 } 705 }
690 706
691 if (object.paintProperties() && object.paintProperties()->scroll()) { 707 if (object.paintProperties() && object.paintProperties()->scroll()) {
692 context.current.transform = object.paintProperties()->scrollTranslation(); 708 context.current.transform = object.paintProperties()->scrollTranslation();
693 context.current.scroll = object.paintProperties()->scroll(); 709 context.current.scroll = object.paintProperties()->scroll();
694 context.current.shouldFlattenInheritedTransform = false; 710 context.current.shouldFlattenInheritedTransform = false;
695 } 711 }
(...skipping 29 matching lines...) Expand all
725 // need to insert the clip here if we are not a containing block ancestor of 741 // need to insert the clip here if we are not a containing block ancestor of
726 // them. 742 // them.
727 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip(); 743 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip();
728 744
729 // Before we actually create anything, check whether in-flow context and 745 // Before we actually create anything, check whether in-flow context and
730 // fixed-position context has exactly the same clip. Reuse if possible. 746 // fixed-position context has exactly the same clip. Reuse if possible.
731 if (context.fixedPosition.clip == cssClip->parent()) { 747 if (context.fixedPosition.clip == cssClip->parent()) {
732 context.fixedPosition.clip = cssClip; 748 context.fixedPosition.clip = cssClip;
733 } else { 749 } else {
734 if (object.needsPaintPropertyUpdate()) { 750 if (object.needsPaintPropertyUpdate()) {
735 object.getMutableForPainting() 751 auto& properties =
736 .ensurePaintProperties() 752 object.getMutableForPainting().ensurePaintProperties();
737 .updateCssClipFixedPosition(context.fixedPosition.clip, 753 context.forceSubtreeUpdate |= properties.updateCssClipFixedPosition(
738 const_cast<TransformPaintPropertyNode*>( 754 context.fixedPosition.clip, const_cast<TransformPaintPropertyNode*>(
739 cssClip->localTransformSpace()), 755 cssClip->localTransformSpace()),
740 cssClip->clipRect()); 756 cssClip->clipRect());
741 } 757 }
742 const auto* properties = object.paintProperties(); 758 const auto* properties = object.paintProperties();
743 if (properties && properties->cssClipFixedPosition()) 759 if (properties && properties->cssClipFixedPosition())
744 context.fixedPosition.clip = properties->cssClipFixedPosition(); 760 context.fixedPosition.clip = properties->cssClipFixedPosition();
745 return; 761 return;
746 } 762 }
747 } 763 }
748 764
749 if (object.needsPaintPropertyUpdate()) { 765 if (object.needsPaintPropertyUpdate()) {
750 if (auto* properties = object.getMutableForPainting().paintProperties()) 766 if (auto* properties = object.getMutableForPainting().paintProperties())
751 properties->clearCssClipFixedPosition(); 767 context.forceSubtreeUpdate |= properties->clearCssClipFixedPosition();
752 } 768 }
753 } 769 }
754 770
755 // Override ContainingBlockContext based on the properties of a containing block 771 // Override ContainingBlockContext based on the properties of a containing block
756 // that was previously walked in a subtree other than the current subtree being 772 // that was previously walked in a subtree other than the current subtree being
757 // walked. Used for out-of-flow positioned descendants of multi-column spanner 773 // walked. Used for out-of-flow positioned descendants of multi-column spanner
758 // when the containing block is not in the normal tree walk order. 774 // when the containing block is not in the normal tree walk order.
759 // For example: 775 // For example:
760 // <div id="columns" style="columns: 2"> 776 // <div id="columns" style="columns: 2">
761 // <div id="relative" style="position: relative"> 777 // <div id="relative" style="position: relative">
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 } 888 }
873 } 889 }
874 } 890 }
875 891
876 void PaintPropertyTreeBuilder::updatePropertiesForSelf( 892 void PaintPropertyTreeBuilder::updatePropertiesForSelf(
877 const LayoutObject& object, 893 const LayoutObject& object,
878 PaintPropertyTreeBuilderContext& context) { 894 PaintPropertyTreeBuilderContext& context) {
879 if (!object.isBoxModelObject() && !object.isSVG()) 895 if (!object.isBoxModelObject() && !object.isSVG())
880 return; 896 return;
881 897
898 if (context.forceSubtreeUpdate) {
899 object.getMutableForPainting()
900 .setNeedsPaintPropertyUpdateWithoutMarkingAncestors();
901 }
902
882 #if DCHECK_IS_ON() 903 #if DCHECK_IS_ON()
883 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object); 904 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object, context);
884 #endif 905 #endif
885 906
886 deriveBorderBoxFromContainerContext(object, context); 907 deriveBorderBoxFromContainerContext(object, context);
887 908
888 updatePaintOffsetTranslation(object, context); 909 updatePaintOffsetTranslation(object, context);
889 updateTransform(object, context); 910 updateTransform(object, context);
890 updateEffect(object, context); 911 updateEffect(object, context);
891 updateCssClip(object, context); 912 updateCssClip(object, context);
892 updateLocalBorderBoxContext(object, context); 913 updateLocalBorderBoxContext(object, context);
893 updateScrollbarPaintOffset(object, context); 914 updateScrollbarPaintOffset(object, context);
894 } 915 }
895 916
896 void PaintPropertyTreeBuilder::updatePropertiesForChildren( 917 void PaintPropertyTreeBuilder::updatePropertiesForChildren(
897 const LayoutObject& object, 918 const LayoutObject& object,
898 PaintPropertyTreeBuilderContext& context) { 919 PaintPropertyTreeBuilderContext& context) {
899 if (!object.isBoxModelObject() && !object.isSVG()) 920 if (!object.isBoxModelObject() && !object.isSVG())
900 return; 921 return;
901 922
923 if (context.forceSubtreeUpdate) {
924 // This should have been set by |updatePropertiesForSelf|.
925 DCHECK(object.needsPaintPropertyUpdate());
926 }
927
902 #if DCHECK_IS_ON() 928 #if DCHECK_IS_ON()
903 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object); 929 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object, context);
904 #endif 930 #endif
905 931
906 updateOverflowClip(object, context); 932 updateOverflowClip(object, context);
907 updatePerspective(object, context); 933 updatePerspective(object, context);
908 updateSvgLocalToBorderBoxTransform(object, context); 934 updateSvgLocalToBorderBoxTransform(object, context);
909 updateScrollAndScrollTranslation(object, context); 935 updateScrollAndScrollTranslation(object, context);
910 updateOutOfFlowContext(object, context); 936 updateOutOfFlowContext(object, context);
911 } 937 }
912 938
913 } // namespace blink 939 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698