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

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

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

Powered by Google App Engine
This is Rietveld 408576698