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

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

Issue 2495893002: Implement incremental paint property tree rebuilding (Closed)
Patch Set: Suppress main thread scrolling invalidation failures Created 4 years, 1 month 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"
11 #include "core/layout/LayoutView.h" 11 #include "core/layout/LayoutView.h"
12 #include "core/layout/svg/LayoutSVGRoot.h" 12 #include "core/layout/svg/LayoutSVGRoot.h"
13 #include "core/paint/FindPropertiesNeedingUpdate.h"
13 #include "core/paint/ObjectPaintProperties.h" 14 #include "core/paint/ObjectPaintProperties.h"
14 #include "core/paint/PaintLayer.h" 15 #include "core/paint/PaintLayer.h"
15 #include "core/paint/SVGRootPainter.h" 16 #include "core/paint/SVGRootPainter.h"
16 #include "platform/transforms/TransformationMatrix.h" 17 #include "platform/transforms/TransformationMatrix.h"
17 #include "wtf/PtrUtil.h" 18 #include "wtf/PtrUtil.h"
18 #include <memory> 19 #include <memory>
19 20
20 namespace blink { 21 namespace blink {
21 22
22 PaintPropertyTreeBuilderContext 23 PaintPropertyTreeBuilderContext
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 existingScroll->update(std::move(parent), std::move(scrollOffset), clip, 95 existingScroll->update(std::move(parent), std::move(scrollOffset), clip,
95 bounds, userScrollableHorizontal, 96 bounds, userScrollableHorizontal,
96 userScrollableVertical); 97 userScrollableVertical);
97 } else { 98 } else {
98 frameView.setScroll(ScrollPaintPropertyNode::create( 99 frameView.setScroll(ScrollPaintPropertyNode::create(
99 std::move(parent), std::move(scrollOffset), clip, bounds, 100 std::move(parent), std::move(scrollOffset), clip, bounds,
100 userScrollableHorizontal, userScrollableVertical)); 101 userScrollableHorizontal, userScrollableVertical));
101 } 102 }
102 } 103 }
103 104
104 void PaintPropertyTreeBuilder::updateFramePropertiesAndContext( 105 void PaintPropertyTreeBuilder::updateProperties(
105 FrameView& frameView, 106 FrameView& frameView,
106 PaintPropertyTreeBuilderContext& context) { 107 PaintPropertyTreeBuilderContext& context) {
107 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { 108 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
108 // With root layer scrolling, the LayoutView (a LayoutObject) properties are 109 // With root layer scrolling, the LayoutView (a LayoutObject) properties are
109 // updated like other objects (see updatePropertiesAndContextForSelf and 110 // updated like other objects (see updatePropertiesAndContextForSelf and
110 // updatePropertiesAndContextForChildren) instead of needing LayoutView- 111 // updatePropertiesAndContextForChildren) instead of needing LayoutView-
111 // specific property updates here. 112 // specific property updates here.
112 context.current.paintOffset.moveBy(frameView.location()); 113 context.current.paintOffset.moveBy(frameView.location());
113 context.current.renderingContextID = 0; 114 context.current.renderingContextID = 0;
114 context.current.shouldFlattenInheritedTransform = true; 115 context.current.shouldFlattenInheritedTransform = true;
115 context.absolutePosition = context.current; 116 context.absolutePosition = context.current;
116 context.containerForAbsolutePosition = nullptr; 117 context.containerForAbsolutePosition = nullptr;
117 context.fixedPosition = context.current; 118 context.fixedPosition = context.current;
118 return; 119 return;
119 } 120 }
120 121
121 TransformationMatrix frameTranslate; 122 #if DCHECK_IS_ON()
122 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), 123 FindFrameViewPropertiesNeedingUpdateScope checkNeedsUpdateScope(&frameView);
123 frameView.y() + context.current.paintOffset.y()); 124 #endif
124 updateFrameViewPreTranslation(frameView, context.current.transform,
125 frameTranslate, FloatPoint3D());
126 125
127 FloatRoundedRect contentClip( 126 if (frameView.needsPaintPropertyUpdate()) {
128 IntRect(IntPoint(), frameView.visibleContentSize())); 127 TransformationMatrix frameTranslate;
129 updateFrameViewContentClip(frameView, context.current.clip, 128 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(),
130 frameView.preTranslation(), contentClip); 129 frameView.y() + context.current.paintOffset.y());
130 updateFrameViewPreTranslation(frameView, context.current.transform,
131 frameTranslate, FloatPoint3D());
131 132
132 ScrollOffset scrollOffset = frameView.scrollOffset(); 133 FloatRoundedRect contentClip(
133 if (frameView.isScrollable() || !scrollOffset.isZero()) { 134 IntRect(IntPoint(), frameView.visibleContentSize()));
134 TransformationMatrix frameScroll; 135 updateFrameViewContentClip(frameView, context.current.clip,
135 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); 136 frameView.preTranslation(), contentClip);
136 updateFrameViewScrollTranslation(frameView, frameView.preTranslation(),
137 frameScroll, FloatPoint3D());
138 137
139 IntSize scrollClip = frameView.visibleContentSize(); 138 ScrollOffset scrollOffset = frameView.scrollOffset();
140 IntSize scrollBounds = frameView.contentsSize(); 139 if (frameView.isScrollable() || !scrollOffset.isZero()) {
141 bool userScrollableHorizontal = 140 TransformationMatrix frameScroll;
142 frameView.userInputScrollable(HorizontalScrollbar); 141 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
143 bool userScrollableVertical = 142 updateFrameViewScrollTranslation(frameView, frameView.preTranslation(),
144 frameView.userInputScrollable(VerticalScrollbar); 143 frameScroll, FloatPoint3D());
145 updateFrameViewScroll(frameView, context.current.scroll, 144
146 frameView.scrollTranslation(), scrollClip, 145 IntSize scrollClip = frameView.visibleContentSize();
147 scrollBounds, userScrollableHorizontal, 146 IntSize scrollBounds = frameView.contentsSize();
148 userScrollableVertical); 147 bool userScrollableHorizontal =
149 } else { 148 frameView.userInputScrollable(HorizontalScrollbar);
150 // Ensure pre-existing properties are cleared when there is no scrolling. 149 bool userScrollableVertical =
151 frameView.setScrollTranslation(nullptr); 150 frameView.userInputScrollable(VerticalScrollbar);
152 frameView.setScroll(nullptr); 151 updateFrameViewScroll(frameView, context.current.scroll,
152 frameView.scrollTranslation(), scrollClip,
153 scrollBounds, userScrollableHorizontal,
154 userScrollableVertical);
155 } else {
156 // Ensure pre-existing properties are cleared when there is no scrolling.
157 frameView.setScrollTranslation(nullptr);
158 frameView.setScroll(nullptr);
159 }
153 } 160 }
154 161
155 // Initialize the context for current, absolute and fixed position cases. 162 // Initialize the context for current, absolute and fixed position cases.
156 // They are the same, except that scroll translation does not apply to 163 // They are the same, except that scroll translation does not apply to
157 // fixed position descendants. 164 // fixed position descendants.
158 const auto* fixedTransformNode = frameView.preTranslation() 165 const auto* fixedTransformNode = frameView.preTranslation()
159 ? frameView.preTranslation() 166 ? frameView.preTranslation()
160 : context.current.transform; 167 : context.current.transform;
161 auto* fixedScrollNode = context.current.scroll; 168 auto* fixedScrollNode = context.current.scroll;
162 DCHECK(frameView.preTranslation()); 169 DCHECK(frameView.preTranslation());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 // regardless of whether a transform is present. If there is a transform 210 // regardless of whether a transform is present. If there is a transform
204 // we round the paint offset but keep around the residual fractional 211 // we round the paint offset but keep around the residual fractional
205 // component for the transformed content to paint with. In spv1 this was 212 // component for the transformed content to paint with. In spv1 this was
206 // called "subpixel accumulation". For more information, see 213 // called "subpixel accumulation". For more information, see
207 // PaintLayer::subpixelAccumulation() and 214 // PaintLayer::subpixelAccumulation() and
208 // PaintLayerPainter::paintFragmentByApplyingTransform. 215 // PaintLayerPainter::paintFragmentByApplyingTransform.
209 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); 216 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
210 LayoutPoint fractionalPaintOffset = 217 LayoutPoint fractionalPaintOffset =
211 LayoutPoint(context.current.paintOffset - roundedPaintOffset); 218 LayoutPoint(context.current.paintOffset - roundedPaintOffset);
212 219
213 if (usesPaintOffsetTranslation) { 220 if (object.needsPaintPropertyUpdate()) {
214 object.getMutableForPainting() 221 if (usesPaintOffsetTranslation) {
215 .ensurePaintProperties() 222 object.getMutableForPainting()
216 .updatePaintOffsetTranslation( 223 .ensurePaintProperties()
217 context.current.transform, 224 .updatePaintOffsetTranslation(
218 TransformationMatrix().translate(roundedPaintOffset.x(), 225 context.current.transform,
219 roundedPaintOffset.y()), 226 TransformationMatrix().translate(roundedPaintOffset.x(),
220 FloatPoint3D(), context.current.shouldFlattenInheritedTransform, 227 roundedPaintOffset.y()),
221 context.current.renderingContextID); 228 FloatPoint3D(), context.current.shouldFlattenInheritedTransform,
222 } else { 229 context.current.renderingContextID);
223 if (auto* properties = object.getMutableForPainting().paintProperties()) 230 } else {
224 properties->clearPaintOffsetTranslation(); 231 if (auto* properties = object.getMutableForPainting().paintProperties())
232 properties->clearPaintOffsetTranslation();
233 }
225 } 234 }
226 235
227 const auto* properties = object.paintProperties(); 236 const auto* properties = object.paintProperties();
228 if (properties && properties->paintOffsetTranslation()) { 237 if (properties && properties->paintOffsetTranslation()) {
229 context.current.transform = properties->paintOffsetTranslation(); 238 context.current.transform = properties->paintOffsetTranslation();
230 context.current.paintOffset = fractionalPaintOffset; 239 context.current.paintOffset = fractionalPaintOffset;
231 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && 240 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() &&
232 object.isLayoutView()) { 241 object.isLayoutView()) {
233 context.absolutePosition.transform = properties->paintOffsetTranslation(); 242 context.absolutePosition.transform = properties->paintOffsetTranslation();
234 context.fixedPosition.transform = properties->paintOffsetTranslation(); 243 context.fixedPosition.transform = properties->paintOffsetTranslation();
(...skipping 15 matching lines...) Expand all
250 // SVG does not use the general transform update of |updateTransform|, instead 259 // SVG does not use the general transform update of |updateTransform|, instead
251 // creating a transform node for SVG-specific transforms without 3D. 260 // creating a transform node for SVG-specific transforms without 3D.
252 void PaintPropertyTreeBuilder::updateTransformForNonRootSVG( 261 void PaintPropertyTreeBuilder::updateTransformForNonRootSVG(
253 const LayoutObject& object, 262 const LayoutObject& object,
254 PaintPropertyTreeBuilderContext& context) { 263 PaintPropertyTreeBuilderContext& context) {
255 DCHECK(object.isSVG() && !object.isSVGRoot()); 264 DCHECK(object.isSVG() && !object.isSVGRoot());
256 // SVG (other than SVGForeignObject) does not use paint offset internally. 265 // SVG (other than SVGForeignObject) does not use paint offset internally.
257 DCHECK(object.isSVGForeignObject() || 266 DCHECK(object.isSVGForeignObject() ||
258 context.current.paintOffset == LayoutPoint()); 267 context.current.paintOffset == LayoutPoint());
259 268
260 // TODO(pdr): Refactor this so all non-root SVG objects use the same 269 if (object.needsPaintPropertyUpdate()) {
261 // transform function. 270 // TODO(pdr): Refactor this so all non-root SVG objects use the same
262 const AffineTransform& transform = object.isSVGForeignObject() 271 // transform function.
263 ? object.localSVGTransform() 272 const AffineTransform& transform = object.isSVGForeignObject()
264 : object.localToSVGParentTransform(); 273 ? object.localSVGTransform()
265 // TODO(pdr): Check for the presence of a transform instead of the value. 274 : object.localToSVGParentTransform();
266 // Checking for an identity matrix will cause the property tree structure 275 // TODO(pdr): Check for the presence of a transform instead of the value.
267 // to change during animations if the animation passes through the 276 // Checking for an identity matrix will cause the property tree structure
268 // identity matrix. 277 // to change during animations if the animation passes through the
269 if (!transform.isIdentity()) { 278 // identity matrix.
270 // The origin is included in the local transform, so leave origin empty. 279 if (!transform.isIdentity()) {
271 object.getMutableForPainting().ensurePaintProperties().updateTransform( 280 // The origin is included in the local transform, so leave origin empty.
272 context.current.transform, TransformationMatrix(transform), 281 object.getMutableForPainting().ensurePaintProperties().updateTransform(
273 FloatPoint3D()); 282 context.current.transform, TransformationMatrix(transform),
274 } else { 283 FloatPoint3D());
275 if (auto* properties = object.getMutableForPainting().paintProperties()) 284 } else {
276 properties->clearTransform(); 285 if (auto* properties = object.getMutableForPainting().paintProperties())
286 properties->clearTransform();
287 }
277 } 288 }
278 289
279 if (object.paintProperties() && object.paintProperties()->transform()) { 290 if (object.paintProperties() && object.paintProperties()->transform()) {
280 context.current.transform = object.paintProperties()->transform(); 291 context.current.transform = object.paintProperties()->transform();
281 context.current.shouldFlattenInheritedTransform = false; 292 context.current.shouldFlattenInheritedTransform = false;
282 context.current.renderingContextID = 0; 293 context.current.renderingContextID = 0;
283 } 294 }
284 } 295 }
285 296
286 void PaintPropertyTreeBuilder::updateTransform( 297 void PaintPropertyTreeBuilder::updateTransform(
287 const LayoutObject& object, 298 const LayoutObject& object,
288 PaintPropertyTreeBuilderContext& context) { 299 PaintPropertyTreeBuilderContext& context) {
289 if (object.isSVG() && !object.isSVGRoot()) { 300 if (object.isSVG() && !object.isSVGRoot()) {
290 updateTransformForNonRootSVG(object, context); 301 updateTransformForNonRootSVG(object, context);
291 return; 302 return;
292 } 303 }
293 304
294 const ComputedStyle& style = object.styleRef(); 305 if (object.needsPaintPropertyUpdate()) {
295 if (object.isBox() && (style.hasTransform() || style.preserves3D())) { 306 const ComputedStyle& style = object.styleRef();
296 TransformationMatrix matrix; 307 if (object.isBox() && (style.hasTransform() || style.preserves3D())) {
297 style.applyTransform(matrix, toLayoutBox(object).size(), 308 TransformationMatrix matrix;
298 ComputedStyle::ExcludeTransformOrigin, 309 style.applyTransform(
299 ComputedStyle::IncludeMotionPath, 310 matrix, toLayoutBox(object).size(),
300 ComputedStyle::IncludeIndependentTransformProperties); 311 ComputedStyle::ExcludeTransformOrigin,
312 ComputedStyle::IncludeMotionPath,
313 ComputedStyle::IncludeIndependentTransformProperties);
301 314
302 // TODO(trchen): transform-style should only be respected if a PaintLayer 315 // TODO(trchen): transform-style should only be respected if a PaintLayer
303 // is created. 316 // is created.
304 // If a node with transform-style: preserve-3d does not exist in an 317 // If a node with transform-style: preserve-3d does not exist in an
305 // existing rendering context, it establishes a new one. 318 // existing rendering context, it establishes a new one.
306 unsigned renderingContextID = context.current.renderingContextID; 319 unsigned renderingContextID = context.current.renderingContextID;
307 if (style.preserves3D() && !renderingContextID) 320 if (style.preserves3D() && !renderingContextID)
308 renderingContextID = PtrHash<const LayoutObject>::hash(&object); 321 renderingContextID = PtrHash<const LayoutObject>::hash(&object);
309 322
310 object.getMutableForPainting().ensurePaintProperties().updateTransform( 323 object.getMutableForPainting().ensurePaintProperties().updateTransform(
311 context.current.transform, matrix, transformOrigin(toLayoutBox(object)), 324 context.current.transform, matrix,
312 context.current.shouldFlattenInheritedTransform, renderingContextID); 325 transformOrigin(toLayoutBox(object)),
313 } else { 326 context.current.shouldFlattenInheritedTransform, renderingContextID);
314 if (auto* properties = object.getMutableForPainting().paintProperties()) 327 } else {
315 properties->clearTransform(); 328 if (auto* properties = object.getMutableForPainting().paintProperties())
329 properties->clearTransform();
330 }
316 } 331 }
317 332
318 const auto* properties = object.paintProperties(); 333 const auto* properties = object.paintProperties();
319 if (properties && properties->transform()) { 334 if (properties && properties->transform()) {
320 context.current.transform = properties->transform(); 335 context.current.transform = properties->transform();
321 if (object.styleRef().preserves3D()) { 336 if (object.styleRef().preserves3D()) {
322 context.current.renderingContextID = 337 context.current.renderingContextID =
323 properties->transform()->renderingContextID(); 338 properties->transform()->renderingContextID();
324 context.current.shouldFlattenInheritedTransform = false; 339 context.current.shouldFlattenInheritedTransform = false;
325 } else { 340 } else {
326 context.current.renderingContextID = 0; 341 context.current.renderingContextID = 0;
327 context.current.shouldFlattenInheritedTransform = true; 342 context.current.shouldFlattenInheritedTransform = true;
328 } 343 }
329 } 344 }
330 } 345 }
331 346
332 void PaintPropertyTreeBuilder::updateEffect( 347 void PaintPropertyTreeBuilder::updateEffect(
333 const LayoutObject& object, 348 const LayoutObject& object,
334 PaintPropertyTreeBuilderContext& context) { 349 PaintPropertyTreeBuilderContext& context) {
335 const ComputedStyle& style = object.styleRef(); 350 const ComputedStyle& style = object.styleRef();
336 351
337 if (!style.isStackingContext()) { 352 if (!style.isStackingContext()) {
338 if (auto* properties = object.getMutableForPainting().paintProperties()) 353 if (object.needsPaintPropertyUpdate()) {
339 properties->clearEffect(); 354 if (auto* properties = object.getMutableForPainting().paintProperties())
355 properties->clearEffect();
356 }
340 return; 357 return;
341 } 358 }
342 359
343 // TODO(trchen): Can't omit effect node if we have 3D children. 360 // TODO(trchen): Can't omit effect node if we have 3D children.
344 // TODO(trchen): Can't omit effect node if we have blending children. 361 // TODO(trchen): Can't omit effect node if we have blending children.
345 bool effectNodeNeeded = false; 362 if (object.needsPaintPropertyUpdate()) {
363 bool effectNodeNeeded = false;
346 364
347 float opacity = style.opacity(); 365 float opacity = style.opacity();
348 if (opacity != 1.0f) 366 if (opacity != 1.0f)
349 effectNodeNeeded = true; 367 effectNodeNeeded = true;
350 368
351 CompositorFilterOperations filter; 369 CompositorFilterOperations filter;
352 if (object.isSVG() && !object.isSVGRoot()) { 370 if (object.isSVG() && !object.isSVGRoot()) {
353 // TODO(trchen): SVG caches filters in SVGResources. Implement it. 371 // TODO(trchen): SVG caches filters in SVGResources. Implement it.
354 } else if (PaintLayer* layer = toLayoutBoxModelObject(object).layer()) { 372 } else if (PaintLayer* layer = toLayoutBoxModelObject(object).layer()) {
355 // TODO(trchen): Eliminate PaintLayer dependency. 373 // TODO(trchen): Eliminate PaintLayer dependency.
356 filter = layer->createCompositorFilterOperationsForFilter(style); 374 filter = layer->createCompositorFilterOperationsForFilter(style);
357 } 375 }
358 376
359 const ClipPaintPropertyNode* outputClip = ClipPaintPropertyNode::root(); 377 const ClipPaintPropertyNode* outputClip = ClipPaintPropertyNode::root();
360 // The CSS filter spec didn't specify how filters interact with overflow 378 // The CSS filter spec didn't specify how filters interact with overflow
361 // clips. The implementation here mimics the old Blink/WebKit behavior for 379 // clips. The implementation here mimics the old Blink/WebKit behavior for
362 // backward compatibility. 380 // backward compatibility.
363 // Basically the output of the filter will be affected by clips that applies 381 // Basically the output of the filter will be affected by clips that applies
364 // to the current element. The descendants that paints into the input of the 382 // to the current element. The descendants that paints into the input of the
365 // filter ignores any clips collected so far. For example: 383 // filter ignores any clips collected so far. For example:
366 // <div style="overflow:scroll"> 384 // <div style="overflow:scroll">
367 // <div style="filter:blur(1px);"> 385 // <div style="filter:blur(1px);">
368 // <div>A</div> 386 // <div>A</div>
369 // <div style="position:absolute;">B</div> 387 // <div style="position:absolute;">B</div>
370 // </div> 388 // </div>
371 // </div> 389 // </div>
372 // In this example "A" should be clipped if the filter was not present. 390 // In this example "A" should be clipped if the filter was not present.
373 // With the filter, "A" will be rastered without clipping, but instead 391 // With the filter, "A" will be rastered without clipping, but instead
374 // the blurred result will be clipped. 392 // the blurred result will be clipped.
375 // On the other hand, "B" should not be clipped because the overflow clip is 393 // On the other hand, "B" should not be clipped because the overflow clip is
376 // not in its containing block chain, but as the filter output will be 394 // not in its containing block chain, but as the filter output will be
377 // clipped, so a blurred "B" may still be invisible. 395 // clipped, so a blurred "B" may still be invisible.
378 if (!filter.isEmpty()) { 396 if (!filter.isEmpty()) {
379 effectNodeNeeded = true; 397 effectNodeNeeded = true;
380 outputClip = context.current.clip; 398 outputClip = context.current.clip;
381 399
382 // TODO(trchen): A filter may contain spatial operations such that an 400 // TODO(trchen): A filter may contain spatial operations such that an
383 // output pixel may depend on an input pixel outside of the output clip. 401 // output pixel may depend on an input pixel outside of the output clip.
384 // We should generate a special clip node to represent this expansion. 402 // We should generate a special clip node to represent this expansion.
385 } 403 }
386 404
387 if (effectNodeNeeded) { 405 if (effectNodeNeeded) {
388 object.getMutableForPainting().ensurePaintProperties().updateEffect( 406 object.getMutableForPainting().ensurePaintProperties().updateEffect(
389 context.currentEffect, context.current.transform, outputClip, 407 context.currentEffect, context.current.transform, outputClip,
390 std::move(filter), opacity); 408 std::move(filter), opacity);
391 } else { 409 } else {
392 if (auto* properties = object.getMutableForPainting().paintProperties()) 410 if (auto* properties = object.getMutableForPainting().paintProperties())
393 properties->clearEffect(); 411 properties->clearEffect();
412 }
394 } 413 }
395 414
396 const auto* properties = object.paintProperties(); 415 const auto* properties = object.paintProperties();
397 if (properties && properties->effect()) { 416 if (properties && properties->effect()) {
398 context.currentEffect = properties->effect(); 417 context.currentEffect = properties->effect();
399 // TODO(pdr): Once the expansion clip node is created above, it should be 418 // TODO(pdr): Once the expansion clip node is created above, it should be
400 // used here to update all current clip nodes; 419 // used here to update all current clip nodes;
401 const ClipPaintPropertyNode* expansionHint = context.current.clip; 420 const ClipPaintPropertyNode* expansionHint = context.current.clip;
402 context.current.clip = context.absolutePosition.clip = 421 context.current.clip = context.absolutePosition.clip =
403 context.fixedPosition.clip = expansionHint; 422 context.fixedPosition.clip = expansionHint;
404 } 423 }
405 } 424 }
406 425
407 void PaintPropertyTreeBuilder::updateCssClip( 426 void PaintPropertyTreeBuilder::updateCssClip(
408 const LayoutObject& object, 427 const LayoutObject& object,
409 PaintPropertyTreeBuilderContext& context) { 428 PaintPropertyTreeBuilderContext& context) {
410 if (object.hasClip()) { 429 if (object.needsPaintPropertyUpdate()) {
411 // Create clip node for descendants that are not fixed position. 430 if (object.hasClip()) {
412 // We don't have to setup context.absolutePosition.clip here because this 431 // Create clip node for descendants that are not fixed position.
413 // object must be a container for absolute position descendants, and will 432 // We don't have to setup context.absolutePosition.clip here because this
414 // copy from in-flow context later at updateOutOfFlowContext() step. 433 // object must be a container for absolute position descendants, and will
415 DCHECK(object.canContainAbsolutePositionObjects()); 434 // copy from in-flow context later at updateOutOfFlowContext() step.
416 LayoutRect clipRect = 435 DCHECK(object.canContainAbsolutePositionObjects());
417 toLayoutBox(object).clipRect(context.current.paintOffset); 436 LayoutRect clipRect =
418 object.getMutableForPainting().ensurePaintProperties().updateCssClip( 437 toLayoutBox(object).clipRect(context.current.paintOffset);
419 context.current.clip, context.current.transform, 438 object.getMutableForPainting().ensurePaintProperties().updateCssClip(
420 FloatRoundedRect(FloatRect(clipRect))); 439 context.current.clip, context.current.transform,
421 } else { 440 FloatRoundedRect(FloatRect(clipRect)));
422 if (auto* properties = object.getMutableForPainting().paintProperties()) 441 } else {
423 properties->clearCssClip(); 442 if (auto* properties = object.getMutableForPainting().paintProperties())
443 properties->clearCssClip();
444 }
424 } 445 }
425 446
426 const auto* properties = object.paintProperties(); 447 const auto* properties = object.paintProperties();
427 if (properties && properties->cssClip()) 448 if (properties && properties->cssClip())
428 context.current.clip = properties->cssClip(); 449 context.current.clip = properties->cssClip();
429 } 450 }
430 451
431 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( 452 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(
432 const LayoutObject& object, 453 const LayoutObject& object,
433 PaintPropertyTreeBuilderContext& context) { 454 PaintPropertyTreeBuilderContext& context) {
455 if (!object.needsPaintPropertyUpdate())
456 return;
457
434 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since 458 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since
435 // we don't need them at the moment. 459 // we don't need them at the moment.
436 if (!object.isBox() && !object.hasLayer()) { 460 if (!object.isBox() && !object.hasLayer()) {
437 if (auto* properties = object.getMutableForPainting().paintProperties()) 461 if (auto* properties = object.getMutableForPainting().paintProperties())
438 properties->clearLocalBorderBoxProperties(); 462 properties->clearLocalBorderBoxProperties();
439 } else { 463 } else {
440 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset> 464 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset>
441 borderBoxContext = 465 borderBoxContext =
442 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset( 466 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset(
443 context.current.paintOffset, 467 context.current.paintOffset,
444 PropertyTreeState(context.current.transform, 468 PropertyTreeState(context.current.transform,
445 context.current.clip, context.currentEffect, 469 context.current.clip, context.currentEffect,
446 context.current.scroll))); 470 context.current.scroll)));
447 object.getMutableForPainting() 471 object.getMutableForPainting()
448 .ensurePaintProperties() 472 .ensurePaintProperties()
449 .setLocalBorderBoxProperties(std::move(borderBoxContext)); 473 .setLocalBorderBoxProperties(std::move(borderBoxContext));
450 } 474 }
451 } 475 }
452 476
453 // TODO(trchen): Remove this once we bake the paint offset into frameRect. 477 // TODO(trchen): Remove this once we bake the paint offset into frameRect.
454 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( 478 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(
455 const LayoutObject& object, 479 const LayoutObject& object,
456 const PaintPropertyTreeBuilderContext& context) { 480 const PaintPropertyTreeBuilderContext& context) {
481 if (!object.needsPaintPropertyUpdate())
482 return;
483
457 bool needsScrollbarPaintOffset = false; 484 bool needsScrollbarPaintOffset = false;
458 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); 485 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
459 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { 486 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) {
460 if (auto* area = toLayoutBoxModelObject(object).getScrollableArea()) { 487 if (auto* area = toLayoutBoxModelObject(object).getScrollableArea()) {
461 if (area->horizontalScrollbar() || area->verticalScrollbar()) { 488 if (area->horizontalScrollbar() || area->verticalScrollbar()) {
462 auto paintOffset = TransformationMatrix().translate( 489 auto paintOffset = TransformationMatrix().translate(
463 roundedPaintOffset.x(), roundedPaintOffset.y()); 490 roundedPaintOffset.x(), roundedPaintOffset.y());
464 object.getMutableForPainting() 491 object.getMutableForPainting()
465 .ensurePaintProperties() 492 .ensurePaintProperties()
466 .updateScrollbarPaintOffset(context.current.transform, paintOffset, 493 .updateScrollbarPaintOffset(context.current.transform, paintOffset,
467 FloatPoint3D()); 494 FloatPoint3D());
468 needsScrollbarPaintOffset = true; 495 needsScrollbarPaintOffset = true;
469 } 496 }
470 } 497 }
471 } 498 }
472 499
473 auto* properties = object.getMutableForPainting().paintProperties(); 500 auto* properties = object.getMutableForPainting().paintProperties();
474 if (!needsScrollbarPaintOffset && properties) 501 if (!needsScrollbarPaintOffset && properties)
475 properties->clearScrollbarPaintOffset(); 502 properties->clearScrollbarPaintOffset();
476 } 503 }
477 504
478 void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons( 505 void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons(
479 const LayoutObject& object, 506 const LayoutObject& object,
480 PaintPropertyTreeBuilderContext& context) { 507 PaintPropertyTreeBuilderContext& context) {
508 // TODO(pdr): Mark properties as needing an update for main thread scroll
509 // reasons and ensure reason changes are propagated to ancestors to account
510 // for the parent walk below. https://crbug.com/664672.
511
481 if (context.current.scroll && 512 if (context.current.scroll &&
482 !object.document().settings()->threadedScrollingEnabled()) { 513 !object.document().settings()->threadedScrollingEnabled()) {
483 context.current.scroll->addMainThreadScrollingReasons( 514 context.current.scroll->addMainThreadScrollingReasons(
484 MainThreadScrollingReason::kThreadedScrollingDisabled); 515 MainThreadScrollingReason::kThreadedScrollingDisabled);
485 } 516 }
486 517
487 if (object.isBackgroundAttachmentFixedObject()) { 518 if (object.isBackgroundAttachmentFixedObject()) {
488 auto* scrollNode = context.current.scroll; 519 auto* scrollNode = context.current.scroll;
489 while ( 520 while (
490 scrollNode && 521 scrollNode &&
491 !scrollNode->hasMainThreadScrollingReasons( 522 !scrollNode->hasMainThreadScrollingReasons(
492 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)) { 523 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)) {
493 scrollNode->addMainThreadScrollingReasons( 524 scrollNode->addMainThreadScrollingReasons(
494 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); 525 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
495 scrollNode = scrollNode->parent(); 526 scrollNode = scrollNode->parent();
496 } 527 }
497 } 528 }
498 } 529 }
499 530
500 void PaintPropertyTreeBuilder::updateOverflowClip( 531 void PaintPropertyTreeBuilder::updateOverflowClip(
501 const LayoutObject& object, 532 const LayoutObject& object,
502 PaintPropertyTreeBuilderContext& context) { 533 PaintPropertyTreeBuilderContext& context) {
503 if (!object.isBox()) 534 if (!object.isBox())
504 return; 535 return;
505 const LayoutBox& box = toLayoutBox(object); 536
506 // The <input> elements can't have contents thus CSS overflow property 537 if (object.needsPaintPropertyUpdate()) {
507 // doesn't apply. However for layout purposes we do generate child layout 538 const LayoutBox& box = toLayoutBox(object);
508 // objects for them, e.g. button label. We should clip the overflow from 539 // The <input> elements can't have contents thus CSS overflow property
509 // those children. This is called control clip and we technically treat them 540 // doesn't apply. However for layout purposes we do generate child layout
510 // like overflow clip. 541 // objects for them, e.g. button label. We should clip the overflow from
511 LayoutRect clipRect; 542 // those children. This is called control clip and we technically treat them
512 if (box.hasControlClip()) { 543 // like overflow clip.
513 clipRect = box.controlClipRect(context.current.paintOffset); 544 LayoutRect clipRect;
514 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() || 545 if (box.hasControlClip()) {
515 (box.isSVGRoot() && 546 clipRect = box.controlClipRect(context.current.paintOffset);
516 toLayoutSVGRoot(box).shouldApplyViewportClip())) { 547 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() ||
517 clipRect = LayoutRect( 548 (box.isSVGRoot() &&
518 pixelSnappedIntRect(box.overflowClipRect(context.current.paintOffset))); 549 toLayoutSVGRoot(box).shouldApplyViewportClip())) {
519 } else { 550 clipRect = LayoutRect(pixelSnappedIntRect(
520 if (auto* properties = object.getMutableForPainting().paintProperties()) { 551 box.overflowClipRect(context.current.paintOffset)));
552 } else {
553 if (auto* properties = object.getMutableForPainting().paintProperties()) {
554 properties->clearInnerBorderRadiusClip();
555 properties->clearOverflowClip();
556 }
557 return;
558 }
559
560 const auto* currentClip = context.current.clip;
561 if (box.styleRef().hasBorderRadius()) {
562 auto innerBorder = box.styleRef().getRoundedInnerBorderFor(
563 LayoutRect(context.current.paintOffset, box.size()));
564 object.getMutableForPainting()
565 .ensurePaintProperties()
566 .updateInnerBorderRadiusClip(context.current.clip,
567 context.current.transform, innerBorder);
568 currentClip = object.paintProperties()->innerBorderRadiusClip();
569 } else if (auto* properties =
570 object.getMutableForPainting().paintProperties()) {
521 properties->clearInnerBorderRadiusClip(); 571 properties->clearInnerBorderRadiusClip();
522 properties->clearOverflowClip();
523 } 572 }
524 return; 573
574 object.getMutableForPainting().ensurePaintProperties().updateOverflowClip(
575 currentClip, context.current.transform,
576 FloatRoundedRect(FloatRect(clipRect)));
525 } 577 }
526 578
527 const auto* currentClip = context.current.clip;
528 if (box.styleRef().hasBorderRadius()) {
529 auto innerBorder = box.styleRef().getRoundedInnerBorderFor(
530 LayoutRect(context.current.paintOffset, box.size()));
531 object.getMutableForPainting()
532 .ensurePaintProperties()
533 .updateInnerBorderRadiusClip(context.current.clip,
534 context.current.transform, innerBorder);
535 currentClip = object.paintProperties()->innerBorderRadiusClip();
536 } else if (auto* properties =
537 object.getMutableForPainting().paintProperties()) {
538 properties->clearInnerBorderRadiusClip();
539 }
540
541 object.getMutableForPainting().ensurePaintProperties().updateOverflowClip(
542 currentClip, context.current.transform,
543 FloatRoundedRect(FloatRect(clipRect)));
544
545 const auto* properties = object.paintProperties(); 579 const auto* properties = object.paintProperties();
546 if (properties && properties->overflowClip()) 580 if (properties && properties->overflowClip())
547 context.current.clip = properties->overflowClip(); 581 context.current.clip = properties->overflowClip();
548 } 582 }
549 583
550 static FloatPoint perspectiveOrigin(const LayoutBox& box) { 584 static FloatPoint perspectiveOrigin(const LayoutBox& box) {
551 const ComputedStyle& style = box.styleRef(); 585 const ComputedStyle& style = box.styleRef();
552 FloatSize borderBoxSize(box.size()); 586 FloatSize borderBoxSize(box.size());
553 return FloatPoint( 587 return FloatPoint(
554 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), 588 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()),
555 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())); 589 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()));
556 } 590 }
557 591
558 void PaintPropertyTreeBuilder::updatePerspective( 592 void PaintPropertyTreeBuilder::updatePerspective(
559 const LayoutObject& object, 593 const LayoutObject& object,
560 PaintPropertyTreeBuilderContext& context) { 594 PaintPropertyTreeBuilderContext& context) {
561 const ComputedStyle& style = object.styleRef(); 595 if (object.needsPaintPropertyUpdate()) {
562 if (object.isBox() && style.hasPerspective()) { 596 const ComputedStyle& style = object.styleRef();
563 // The perspective node must not flatten (else nothing will get 597 if (object.isBox() && style.hasPerspective()) {
564 // perspective), but it should still extend the rendering context as 598 // The perspective node must not flatten (else nothing will get
565 // most transform nodes do. 599 // perspective), but it should still extend the rendering context as
566 TransformationMatrix matrix = 600 // most transform nodes do.
567 TransformationMatrix().applyPerspective(style.perspective()); 601 TransformationMatrix matrix =
568 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + 602 TransformationMatrix().applyPerspective(style.perspective());
569 toLayoutSize(context.current.paintOffset); 603 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) +
570 object.getMutableForPainting().ensurePaintProperties().updatePerspective( 604 toLayoutSize(context.current.paintOffset);
571 context.current.transform, matrix, origin, 605 object.getMutableForPainting().ensurePaintProperties().updatePerspective(
572 context.current.shouldFlattenInheritedTransform, 606 context.current.transform, matrix, origin,
573 context.current.renderingContextID); 607 context.current.shouldFlattenInheritedTransform,
574 } else { 608 context.current.renderingContextID);
575 if (auto* properties = object.getMutableForPainting().paintProperties()) 609 } else {
576 properties->clearPerspective(); 610 if (auto* properties = object.getMutableForPainting().paintProperties())
611 properties->clearPerspective();
612 }
577 } 613 }
578 614
579 const auto* properties = object.paintProperties(); 615 const auto* properties = object.paintProperties();
580 if (properties && properties->perspective()) { 616 if (properties && properties->perspective()) {
581 context.current.transform = properties->perspective(); 617 context.current.transform = properties->perspective();
582 context.current.shouldFlattenInheritedTransform = false; 618 context.current.shouldFlattenInheritedTransform = false;
583 } 619 }
584 } 620 }
585 621
586 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( 622 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(
587 const LayoutObject& object, 623 const LayoutObject& object,
588 PaintPropertyTreeBuilderContext& context) { 624 PaintPropertyTreeBuilderContext& context) {
589 if (!object.isSVGRoot()) 625 if (!object.isSVGRoot())
590 return; 626 return;
591 627
592 AffineTransform transformToBorderBox = 628 if (object.needsPaintPropertyUpdate()) {
593 SVGRootPainter(toLayoutSVGRoot(object)) 629 AffineTransform transformToBorderBox =
594 .transformToPixelSnappedBorderBox(context.current.paintOffset); 630 SVGRootPainter(toLayoutSVGRoot(object))
595 if (!transformToBorderBox.isIdentity()) { 631 .transformToPixelSnappedBorderBox(context.current.paintOffset);
596 object.getMutableForPainting() 632 if (!transformToBorderBox.isIdentity()) {
597 .ensurePaintProperties() 633 object.getMutableForPainting()
598 .updateSvgLocalToBorderBoxTransform( 634 .ensurePaintProperties()
599 context.current.transform, transformToBorderBox, FloatPoint3D()); 635 .updateSvgLocalToBorderBoxTransform(
600 } else { 636 context.current.transform, transformToBorderBox, FloatPoint3D());
601 if (auto* properties = object.getMutableForPainting().paintProperties()) 637 } else {
602 properties->clearSvgLocalToBorderBoxTransform(); 638 if (auto* properties = object.getMutableForPainting().paintProperties())
639 properties->clearSvgLocalToBorderBoxTransform();
640 }
603 } 641 }
604 642
605 const auto* properties = object.paintProperties(); 643 const auto* properties = object.paintProperties();
606 if (properties && properties->svgLocalToBorderBoxTransform()) { 644 if (properties && properties->svgLocalToBorderBoxTransform()) {
607 context.current.transform = properties->svgLocalToBorderBoxTransform(); 645 context.current.transform = properties->svgLocalToBorderBoxTransform();
608 context.current.shouldFlattenInheritedTransform = false; 646 context.current.shouldFlattenInheritedTransform = false;
609 context.current.renderingContextID = 0; 647 context.current.renderingContextID = 0;
610 } 648 }
611 // The paint offset is included in |transformToBorderBox| so SVG does not need 649 // The paint offset is included in |transformToBorderBox| so SVG does not need
612 // to handle paint offset internally. 650 // to handle paint offset internally.
613 context.current.paintOffset = LayoutPoint(); 651 context.current.paintOffset = LayoutPoint();
614 } 652 }
615 653
616 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( 654 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation(
617 const LayoutObject& object, 655 const LayoutObject& object,
618 PaintPropertyTreeBuilderContext& context) { 656 PaintPropertyTreeBuilderContext& context) {
619 if (object.hasOverflowClip()) { 657 if (object.needsPaintPropertyUpdate()) {
620 const LayoutBox& box = toLayoutBox(object); 658 if (object.hasOverflowClip()) {
621 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); 659 const LayoutBox& box = toLayoutBox(object);
622 IntSize scrollOffset = box.scrolledContentOffset(); 660 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea();
623 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { 661 IntSize scrollOffset = box.scrolledContentOffset();
624 TransformationMatrix matrix = TransformationMatrix().translate( 662 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) {
625 -scrollOffset.width(), -scrollOffset.height()); 663 TransformationMatrix matrix = TransformationMatrix().translate(
626 object.getMutableForPainting() 664 -scrollOffset.width(), -scrollOffset.height());
627 .ensurePaintProperties() 665 object.getMutableForPainting()
628 .updateScrollTranslation( 666 .ensurePaintProperties()
629 context.current.transform, matrix, FloatPoint3D(), 667 .updateScrollTranslation(
630 context.current.shouldFlattenInheritedTransform, 668 context.current.transform, matrix, FloatPoint3D(),
631 context.current.renderingContextID); 669 context.current.shouldFlattenInheritedTransform,
670 context.current.renderingContextID);
632 671
633 IntSize scrollClip = scrollableArea->visibleContentRect().size(); 672 IntSize scrollClip = scrollableArea->visibleContentRect().size();
634 IntSize scrollBounds = scrollableArea->contentsSize(); 673 IntSize scrollBounds = scrollableArea->contentsSize();
635 bool userScrollableHorizontal = 674 bool userScrollableHorizontal =
636 scrollableArea->userInputScrollable(HorizontalScrollbar); 675 scrollableArea->userInputScrollable(HorizontalScrollbar);
637 bool userScrollableVertical = 676 bool userScrollableVertical =
638 scrollableArea->userInputScrollable(VerticalScrollbar); 677 scrollableArea->userInputScrollable(VerticalScrollbar);
639 object.getMutableForPainting().ensurePaintProperties().updateScroll( 678 object.getMutableForPainting().ensurePaintProperties().updateScroll(
640 context.current.scroll, object.paintProperties()->scrollTranslation(), 679 context.current.scroll,
641 scrollClip, scrollBounds, userScrollableHorizontal, 680 object.paintProperties()->scrollTranslation(), scrollClip,
642 userScrollableVertical); 681 scrollBounds, userScrollableHorizontal, userScrollableVertical);
643 } else { 682 } else {
644 // Ensure pre-existing properties are cleared when there is no 683 // Ensure pre-existing properties are cleared when there is no
645 // scrolling. 684 // scrolling.
646 auto* properties = object.getMutableForPainting().paintProperties(); 685 auto* properties = object.getMutableForPainting().paintProperties();
647 if (properties) { 686 if (properties) {
648 properties->clearScrollTranslation(); 687 properties->clearScrollTranslation();
649 properties->clearScroll(); 688 properties->clearScroll();
689 }
650 } 690 }
651 } 691 }
652 } 692 }
653 693
654 if (object.paintProperties() && object.paintProperties()->scroll()) { 694 if (object.paintProperties() && object.paintProperties()->scroll()) {
655 context.current.transform = object.paintProperties()->scrollTranslation(); 695 context.current.transform = object.paintProperties()->scrollTranslation();
656 const auto* scroll = object.paintProperties()->scroll(); 696 const auto* scroll = object.paintProperties()->scroll();
657 // TODO(pdr): Remove this const cast. 697 // TODO(pdr): Remove this const cast.
658 context.current.scroll = const_cast<ScrollPaintPropertyNode*>(scroll); 698 context.current.scroll = const_cast<ScrollPaintPropertyNode*>(scroll);
659 context.current.shouldFlattenInheritedTransform = false; 699 context.current.shouldFlattenInheritedTransform = false;
(...skipping 29 matching lines...) Expand all
689 // absolute position container. However for fixed-position descendants we 729 // absolute position container. However for fixed-position descendants we
690 // need to insert the clip here if we are not a containing block ancestor of 730 // need to insert the clip here if we are not a containing block ancestor of
691 // them. 731 // them.
692 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip(); 732 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip();
693 733
694 // Before we actually create anything, check whether in-flow context and 734 // Before we actually create anything, check whether in-flow context and
695 // fixed-position context has exactly the same clip. Reuse if possible. 735 // fixed-position context has exactly the same clip. Reuse if possible.
696 if (context.fixedPosition.clip == cssClip->parent()) { 736 if (context.fixedPosition.clip == cssClip->parent()) {
697 context.fixedPosition.clip = cssClip; 737 context.fixedPosition.clip = cssClip;
698 } else { 738 } else {
699 object.getMutableForPainting() 739 if (object.needsPaintPropertyUpdate()) {
700 .ensurePaintProperties() 740 object.getMutableForPainting()
701 .updateCssClipFixedPosition(context.fixedPosition.clip, 741 .ensurePaintProperties()
702 const_cast<TransformPaintPropertyNode*>( 742 .updateCssClipFixedPosition(context.fixedPosition.clip,
703 cssClip->localTransformSpace()), 743 const_cast<TransformPaintPropertyNode*>(
704 cssClip->clipRect()); 744 cssClip->localTransformSpace()),
745 cssClip->clipRect());
746 }
705 const auto* properties = object.paintProperties(); 747 const auto* properties = object.paintProperties();
706 if (properties && properties->cssClipFixedPosition()) 748 if (properties && properties->cssClipFixedPosition())
707 context.fixedPosition.clip = properties->cssClipFixedPosition(); 749 context.fixedPosition.clip = properties->cssClipFixedPosition();
708 return; 750 return;
709 } 751 }
710 } 752 }
711 753
712 if (auto* properties = object.getMutableForPainting().paintProperties()) 754 if (object.needsPaintPropertyUpdate()) {
713 properties->clearCssClipFixedPosition(); 755 if (auto* properties = object.getMutableForPainting().paintProperties())
756 properties->clearCssClipFixedPosition();
757 }
714 } 758 }
715 759
716 // Override ContainingBlockContext based on the properties of a containing block 760 // Override ContainingBlockContext based on the properties of a containing block
717 // that was previously walked in a subtree other than the current subtree being 761 // that was previously walked in a subtree other than the current subtree being
718 // walked. Used for out-of-flow positioned descendants of multi-column spanner 762 // walked. Used for out-of-flow positioned descendants of multi-column spanner
719 // when the containing block is not in the normal tree walk order. 763 // when the containing block is not in the normal tree walk order.
720 // For example: 764 // For example:
721 // <div id="columns" style="columns: 2"> 765 // <div id="columns" style="columns: 2">
722 // <div id="relative" style="position: relative"> 766 // <div id="relative" style="position: relative">
723 // <div id="spanner" style="column-span: all"> 767 // <div id="spanner" style="column-span: all">
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). 872 // Similar adjustment is done in LayoutTableCell::offsetFromContainer().
829 if (boxModelObject.isTableCell()) { 873 if (boxModelObject.isTableCell()) {
830 LayoutObject* parentRow = boxModelObject.parent(); 874 LayoutObject* parentRow = boxModelObject.parent();
831 DCHECK(parentRow && parentRow->isTableRow()); 875 DCHECK(parentRow && parentRow->isTableRow());
832 context.current.paintOffset.moveBy( 876 context.current.paintOffset.moveBy(
833 -toLayoutBox(parentRow)->topLeftLocation()); 877 -toLayoutBox(parentRow)->topLeftLocation());
834 } 878 }
835 } 879 }
836 } 880 }
837 881
838 void PaintPropertyTreeBuilder::updatePropertiesAndContextForSelf( 882 void PaintPropertyTreeBuilder::updatePropertiesForSelf(
839 const LayoutObject& object, 883 const LayoutObject& object,
840 PaintPropertyTreeBuilderContext& context) { 884 PaintPropertyTreeBuilderContext& context) {
841 if (!object.isBoxModelObject() && !object.isSVG()) 885 if (!object.isBoxModelObject() && !object.isSVG())
842 return; 886 return;
843 887
888 #if DCHECK_IS_ON()
889 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object);
890 #endif
891
844 deriveBorderBoxFromContainerContext(object, context); 892 deriveBorderBoxFromContainerContext(object, context);
845 893
846 updatePaintOffsetTranslation(object, context); 894 updatePaintOffsetTranslation(object, context);
847 updateTransform(object, context); 895 updateTransform(object, context);
848 updateEffect(object, context); 896 updateEffect(object, context);
849 updateCssClip(object, context); 897 updateCssClip(object, context);
850 updateLocalBorderBoxContext(object, context); 898 updateLocalBorderBoxContext(object, context);
851 updateScrollbarPaintOffset(object, context); 899 updateScrollbarPaintOffset(object, context);
852 updateMainThreadScrollingReasons(object, context); 900 updateMainThreadScrollingReasons(object, context);
853 } 901 }
854 902
855 void PaintPropertyTreeBuilder::updatePropertiesAndContextForChildren( 903 void PaintPropertyTreeBuilder::updatePropertiesForChildren(
856 const LayoutObject& object, 904 const LayoutObject& object,
857 PaintPropertyTreeBuilderContext& context) { 905 PaintPropertyTreeBuilderContext& context) {
858 if (!object.isBoxModelObject() && !object.isSVG()) 906 if (!object.isBoxModelObject() && !object.isSVG())
859 return; 907 return;
860 908
909 #if DCHECK_IS_ON()
910 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object);
911 #endif
912
861 updateOverflowClip(object, context); 913 updateOverflowClip(object, context);
862 updatePerspective(object, context); 914 updatePerspective(object, context);
863 updateSvgLocalToBorderBoxTransform(object, context); 915 updateSvgLocalToBorderBoxTransform(object, context);
864 updateScrollAndScrollTranslation(object, context); 916 updateScrollAndScrollTranslation(object, context);
865 updateOutOfFlowContext(object, context); 917 updateOutOfFlowContext(object, context);
866 } 918 }
867 919
868 } // namespace blink 920 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698