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