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 |