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" |
| 11 #include "core/layout/LayoutPart.h" | 11 #include "core/layout/LayoutPart.h" |
| 12 #include "core/layout/LayoutView.h" | 12 #include "core/layout/LayoutView.h" |
| 13 #include "core/layout/svg/LayoutSVGRoot.h" | 13 #include "core/layout/svg/LayoutSVGRoot.h" |
| 14 #include "core/paint/ObjectPaintProperties.h" | 14 #include "core/paint/ObjectPaintProperties.h" |
| 15 #include "core/paint/PaintLayer.h" | 15 #include "core/paint/PaintLayer.h" |
| 16 #include "core/paint/PaintPropertyUnderInvalidationChecks.h" | |
| 16 #include "core/paint/SVGRootPainter.h" | 17 #include "core/paint/SVGRootPainter.h" |
| 17 #include "platform/transforms/TransformationMatrix.h" | 18 #include "platform/transforms/TransformationMatrix.h" |
| 18 #include "wtf/PtrUtil.h" | 19 #include "wtf/PtrUtil.h" |
| 19 #include <memory> | 20 #include <memory> |
| 20 | 21 |
| 21 namespace blink { | 22 namespace blink { |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 TransformPaintPropertyNode* rootTransformNode() { | 25 TransformPaintPropertyNode* rootTransformNode() { |
| 25 DEFINE_STATIC_REF(TransformPaintPropertyNode, rootTransform, | 26 DEFINE_STATIC_REF(TransformPaintPropertyNode, rootTransform, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 existingScroll->update(std::move(parent), std::move(scrollOffset), clip, | 129 existingScroll->update(std::move(parent), std::move(scrollOffset), clip, |
| 129 bounds, userScrollableHorizontal, | 130 bounds, userScrollableHorizontal, |
| 130 userScrollableVertical); | 131 userScrollableVertical); |
| 131 else | 132 else |
| 132 frameView.setScroll(ScrollPaintPropertyNode::create( | 133 frameView.setScroll(ScrollPaintPropertyNode::create( |
| 133 std::move(parent), std::move(scrollOffset), clip, bounds, | 134 std::move(parent), std::move(scrollOffset), clip, bounds, |
| 134 userScrollableHorizontal, userScrollableVertical)); | 135 userScrollableHorizontal, userScrollableVertical)); |
| 135 return frameView.scroll(); | 136 return frameView.scroll(); |
| 136 } | 137 } |
| 137 | 138 |
| 138 void PaintPropertyTreeBuilder::buildTreeNodes( | 139 void PaintPropertyTreeBuilder::updateProperties( |
| 139 FrameView& frameView, | 140 FrameView& frameView, |
| 140 PaintPropertyTreeBuilderContext& context) { | 141 PaintPropertyTreeBuilderContext& context) { |
| 141 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 142 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 142 LayoutView* layoutView = frameView.layoutView(); | 143 LayoutView* layoutView = frameView.layoutView(); |
| 143 if (!layoutView) | 144 if (!layoutView) |
| 144 return; | 145 return; |
| 145 | 146 |
| 146 TransformationMatrix frameTranslate; | 147 #ifndef NDEBUG |
|
chrishtr
2016/10/21 22:03:09
#if DCHECK_IS_ON
pdr.
2016/10/26 03:10:48
Done
| |
| 147 frameTranslate.translate(frameView.x() + layoutView->location().x() + | 148 auto underInvalidationChecker = |
| 148 context.current.paintOffset.x(), | 149 ObjectUnderInvalidationCheckScope::createIfNeeded(*layoutView); |
| 149 frameView.y() + layoutView->location().y() + | 150 #endif |
| 150 context.current.paintOffset.y()); | 151 |
| 151 context.current.transform = | 152 if (layoutView->paintPropertiesValid()) { |
| 152 layoutView->getMutableForPainting() | 153 // No invalidation so update the context using existing properties. |
| 153 .ensurePaintProperties() | 154 const auto* properties = layoutView->paintProperties(); |
| 154 .updatePaintOffsetTranslation(context.current.transform, | 155 if (properties && properties->paintOffsetTranslation()) |
|
chrishtr
2016/10/21 22:03:09
This conditional is not needed, and therefore line
pdr.
2016/10/26 03:10:48
This approach is very nice.
Done.
| |
| 155 frameTranslate, FloatPoint3D()); | 156 context.current.transform = properties->paintOffsetTranslation(); |
| 157 } else { | |
| 158 TransformationMatrix frameTranslate; | |
| 159 frameTranslate.translate(frameView.x() + layoutView->location().x() + | |
| 160 context.current.paintOffset.x(), | |
| 161 frameView.y() + layoutView->location().y() + | |
| 162 context.current.paintOffset.y()); | |
| 163 context.current.transform = | |
| 164 layoutView->getMutableForPainting() | |
| 165 .ensurePaintProperties() | |
| 166 .updatePaintOffsetTranslation(context.current.transform, | |
| 167 frameTranslate, FloatPoint3D()); | |
| 168 } | |
| 156 context.current.paintOffset = LayoutPoint(); | 169 context.current.paintOffset = LayoutPoint(); |
| 157 context.current.renderingContextID = 0; | 170 context.current.renderingContextID = 0; |
| 158 context.current.shouldFlattenInheritedTransform = true; | 171 context.current.shouldFlattenInheritedTransform = true; |
| 159 context.absolutePosition = context.current; | 172 context.absolutePosition = context.current; |
| 160 context.containerForAbsolutePosition = | 173 context.containerForAbsolutePosition = |
| 161 nullptr; // This will get set in updateOutOfFlowContext(). | 174 nullptr; // This will get set in updateOutOfFlowContext(). |
| 162 context.fixedPosition = context.current; | 175 context.fixedPosition = context.current; |
| 163 return; | 176 return; |
| 164 } | 177 } |
| 165 | 178 |
| 166 TransformationMatrix frameTranslate; | 179 #ifndef NDEBUG |
| 167 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), | 180 auto underInvalidationChecker = |
| 168 frameView.y() + context.current.paintOffset.y()); | 181 FrameViewUnderInvalidationCheckScope::createIfNeeded(&frameView); |
| 169 context.current.transform = updateFrameViewPreTranslation( | 182 #endif |
| 170 frameView, context.current.transform, frameTranslate, FloatPoint3D()); | |
| 171 | 183 |
| 172 FloatRoundedRect contentClip( | 184 const auto* initialTransformNode = context.current.transform; |
| 173 IntRect(IntPoint(), frameView.visibleContentSize())); | 185 auto* initialScrollNode = context.current.scroll; |
| 174 context.current.clip = updateFrameViewContentClip( | |
| 175 frameView, context.current.clip, frameView.preTranslation(), contentClip); | |
| 176 | 186 |
| 177 // Record the fixed properties before any scrolling occurs. | 187 if (frameView.paintPropertiesValid()) { |
| 178 const auto* fixedTransformNode = context.current.transform; | 188 // No invalidation so update the context using existing properties. |
| 179 auto* fixedScrollNode = context.current.scroll; | 189 if (const auto* preTranslation = frameView.preTranslation()) |
| 190 context.current.transform = preTranslation; | |
| 191 if (const auto* clip = frameView.contentClip()) | |
| 192 context.current.clip = clip; | |
| 193 if (const auto* scrollTranslation = frameView.scrollTranslation()) | |
| 194 context.current.transform = scrollTranslation; | |
| 195 if (auto* scroll = frameView.scroll()) | |
| 196 context.current.scroll = scroll; | |
| 197 } else { | |
| 198 TransformationMatrix frameTranslate; | |
| 199 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), | |
| 200 frameView.y() + context.current.paintOffset.y()); | |
| 201 context.current.transform = updateFrameViewPreTranslation( | |
| 202 frameView, context.current.transform, frameTranslate, FloatPoint3D()); | |
| 180 | 203 |
| 181 ScrollOffset scrollOffset = frameView.scrollOffset(); | 204 FloatRoundedRect contentClip( |
| 182 if (frameView.isScrollable() || !scrollOffset.isZero()) { | 205 IntRect(IntPoint(), frameView.visibleContentSize())); |
| 183 TransformationMatrix frameScroll; | 206 context.current.clip = |
| 184 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); | 207 updateFrameViewContentClip(frameView, context.current.clip, |
| 185 context.current.transform = updateFrameViewScrollTranslation( | 208 frameView.preTranslation(), contentClip); |
| 186 frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); | |
| 187 | 209 |
| 188 IntSize scrollClip = frameView.visibleContentSize(); | 210 ScrollOffset scrollOffset = frameView.scrollOffset(); |
| 189 IntSize scrollBounds = frameView.contentsSize(); | 211 if (frameView.isScrollable() || !scrollOffset.isZero()) { |
| 190 bool userScrollableHorizontal = | 212 TransformationMatrix frameScroll; |
| 191 frameView.userInputScrollable(HorizontalScrollbar); | 213 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); |
| 192 bool userScrollableVertical = | 214 context.current.transform = updateFrameViewScrollTranslation( |
| 193 frameView.userInputScrollable(VerticalScrollbar); | 215 frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); |
| 194 context.current.scroll = updateFrameViewScroll( | 216 |
| 195 frameView, context.current.scroll, frameView.scrollTranslation(), | 217 IntSize scrollClip = frameView.visibleContentSize(); |
| 196 scrollClip, scrollBounds, userScrollableHorizontal, | 218 IntSize scrollBounds = frameView.contentsSize(); |
| 197 userScrollableVertical); | 219 bool userScrollableHorizontal = |
| 198 } else { | 220 frameView.userInputScrollable(HorizontalScrollbar); |
| 199 // Ensure pre-existing properties are cleared when there is no scrolling. | 221 bool userScrollableVertical = |
| 200 frameView.setScrollTranslation(nullptr); | 222 frameView.userInputScrollable(VerticalScrollbar); |
| 201 frameView.setScroll(nullptr); | 223 context.current.scroll = updateFrameViewScroll( |
| 224 frameView, context.current.scroll, frameView.scrollTranslation(), | |
| 225 scrollClip, scrollBounds, userScrollableHorizontal, | |
| 226 userScrollableVertical); | |
| 227 } else { | |
| 228 // Ensure pre-existing properties are cleared when there is no scrolling. | |
| 229 frameView.setScrollTranslation(nullptr); | |
| 230 frameView.setScroll(nullptr); | |
| 231 } | |
| 202 } | 232 } |
| 203 | 233 |
| 204 // Initialize the context for current, absolute and fixed position cases. | 234 // Initialize the context for current, absolute and fixed position cases. |
| 205 // They are the same, except that scroll translation does not apply to | 235 // They are the same, except that scroll translation does not apply to |
| 206 // fixed position descendants. | 236 // fixed position descendants. |
| 207 context.current.paintOffset = LayoutPoint(); | 237 context.current.paintOffset = LayoutPoint(); |
| 208 context.current.renderingContextID = 0; | 238 context.current.renderingContextID = 0; |
| 209 context.current.shouldFlattenInheritedTransform = true; | 239 context.current.shouldFlattenInheritedTransform = true; |
| 210 context.absolutePosition = context.current; | 240 context.absolutePosition = context.current; |
| 211 context.containerForAbsolutePosition = nullptr; | 241 context.containerForAbsolutePosition = nullptr; |
| 212 context.fixedPosition = context.current; | 242 context.fixedPosition = context.current; |
| 213 context.fixedPosition.transform = fixedTransformNode; | 243 context.fixedPosition.transform = frameView.preTranslation() |
| 214 context.fixedPosition.scroll = fixedScrollNode; | 244 ? frameView.preTranslation() |
| 245 : initialTransformNode; | |
| 246 context.fixedPosition.scroll = initialScrollNode; | |
| 215 | 247 |
| 216 std::unique_ptr<PropertyTreeState> contentsState( | 248 std::unique_ptr<PropertyTreeState> contentsState( |
| 217 new PropertyTreeState(context.current.transform, context.current.clip, | 249 new PropertyTreeState(context.current.transform, context.current.clip, |
| 218 context.currentEffect, context.current.scroll)); | 250 context.currentEffect, context.current.scroll)); |
| 219 frameView.setTotalPropertyTreeStateForContents(std::move(contentsState)); | 251 frameView.setTotalPropertyTreeStateForContents(std::move(contentsState)); |
| 220 } | 252 } |
| 221 | 253 |
| 222 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( | 254 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( |
| 223 const LayoutObject& object, | 255 const LayoutObject& object, |
| 224 PaintPropertyTreeBuilderContext& context) { | 256 PaintPropertyTreeBuilderContext& context) { |
| 225 if (object.isBoxModelObject() && | 257 if (object.isBoxModelObject() && |
| 226 context.current.paintOffset != LayoutPoint()) { | 258 context.current.paintOffset != LayoutPoint()) { |
| 227 // TODO(trchen): Eliminate PaintLayer dependency. | 259 // TODO(trchen): Eliminate PaintLayer dependency. |
| 228 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 260 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 229 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { | 261 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { |
| 230 // We should use the same subpixel paint offset values for snapping | 262 // We should use the same subpixel paint offset values for snapping |
| 231 // regardless of whether a transform is present. If there is a transform | 263 // regardless of whether a transform is present. If there is a transform |
| 232 // we round the paint offset but keep around the residual fractional | 264 // we round the paint offset but keep around the residual fractional |
| 233 // component for the transformed content to paint with. In spv1 this was | 265 // component for the transformed content to paint with. In spv1 this was |
| 234 // called "subpixel accumulation". For more information, see | 266 // called "subpixel accumulation". For more information, see |
| 235 // PaintLayer::subpixelAccumulation() and | 267 // PaintLayer::subpixelAccumulation() and |
| 236 // PaintLayerPainter::paintFragmentByApplyingTransform. | 268 // PaintLayerPainter::paintFragmentByApplyingTransform. |
| 237 IntPoint roundedPaintOffset = | 269 IntPoint roundedPaintOffset = |
| 238 roundedIntPoint(context.current.paintOffset); | 270 roundedIntPoint(context.current.paintOffset); |
| 239 LayoutPoint fractionalPaintOffset = | 271 LayoutPoint fractionalPaintOffset = |
| 240 LayoutPoint(context.current.paintOffset - roundedPaintOffset); | 272 LayoutPoint(context.current.paintOffset - roundedPaintOffset); |
| 241 | 273 |
| 242 context.current.transform = | 274 // TODO(pdr): Refactor this check to be higher so the layer and |
| 243 object.getMutableForPainting() | 275 // paintsWithTransform checks can be skipped if there's no invalidation. |
| 244 .ensurePaintProperties() | 276 if (object.paintPropertiesValid()) { |
| 245 .updatePaintOffsetTranslation( | 277 // No invalidation so update the context using existing properties. |
| 246 context.current.transform, | 278 const auto* properties = object.paintProperties(); |
| 247 TransformationMatrix().translate(roundedPaintOffset.x(), | 279 if (properties && properties->paintOffsetTranslation()) |
| 248 roundedPaintOffset.y()), | 280 context.current.transform = properties->paintOffsetTranslation(); |
| 249 FloatPoint3D(), | 281 } else { |
| 250 context.current.shouldFlattenInheritedTransform, | 282 context.current.transform = |
| 251 context.current.renderingContextID); | 283 object.getMutableForPainting() |
| 284 .ensurePaintProperties() | |
| 285 .updatePaintOffsetTranslation( | |
| 286 context.current.transform, | |
| 287 TransformationMatrix().translate(roundedPaintOffset.x(), | |
| 288 roundedPaintOffset.y()), | |
| 289 FloatPoint3D(), | |
| 290 context.current.shouldFlattenInheritedTransform, | |
| 291 context.current.renderingContextID); | |
| 292 } | |
| 252 context.current.paintOffset = fractionalPaintOffset; | 293 context.current.paintOffset = fractionalPaintOffset; |
| 253 return; | 294 return; |
| 254 } | 295 } |
| 255 } | 296 } |
| 256 | 297 |
| 257 if (object.isLayoutView()) | 298 if (object.isLayoutView()) |
| 258 return; | 299 return; |
| 259 | 300 |
| 260 if (auto* properties = object.getMutableForPainting().paintProperties()) | 301 if (!object.paintPropertiesValid()) { |
| 261 properties->clearPaintOffsetTranslation(); | 302 if (auto* properties = object.getMutableForPainting().paintProperties()) |
| 303 properties->clearPaintOffsetTranslation(); | |
| 304 } | |
| 262 } | 305 } |
| 263 | 306 |
| 264 static FloatPoint3D transformOrigin(const LayoutBox& box) { | 307 static FloatPoint3D transformOrigin(const LayoutBox& box) { |
|
chrishtr
2016/10/21 22:03:09
This method is now getting very long, refactor it?
pdr.
2016/10/26 03:10:48
Done. Split out the svg-specific code into its own
| |
| 265 const ComputedStyle& style = box.styleRef(); | 308 const ComputedStyle& style = box.styleRef(); |
| 266 FloatSize borderBoxSize(box.size()); | 309 FloatSize borderBoxSize(box.size()); |
| 267 return FloatPoint3D( | 310 return FloatPoint3D( |
| 268 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), | 311 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), |
| 269 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), | 312 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), |
| 270 style.transformOriginZ()); | 313 style.transformOriginZ()); |
| 271 } | 314 } |
| 272 | 315 |
| 273 void PaintPropertyTreeBuilder::updateTransform( | 316 void PaintPropertyTreeBuilder::updateTransform( |
| 274 const LayoutObject& object, | 317 const LayoutObject& object, |
| 275 PaintPropertyTreeBuilderContext& context) { | 318 PaintPropertyTreeBuilderContext& context) { |
| 276 if (object.isSVG() && !object.isSVGRoot()) { | 319 if (object.isSVG() && !object.isSVGRoot()) { |
| 277 // SVG (other than SVGForeignObject) does not use paint offset internally. | 320 // SVG (other than SVGForeignObject) does not use paint offset internally. |
| 278 DCHECK(object.isSVGForeignObject() || | 321 DCHECK(object.isSVGForeignObject() || |
| 279 context.current.paintOffset == LayoutPoint()); | 322 context.current.paintOffset == LayoutPoint()); |
| 280 | 323 |
| 281 // FIXME(pdr): Check for the presence of a transform instead of the value. | 324 if (object.paintPropertiesValid()) { |
| 282 // Checking for an identity matrix will cause the property tree structure to | 325 // No invalidation so update the context using existing properties. |
| 283 // change during animations if the animation passes through the identity | 326 if (object.paintProperties() && object.paintProperties()->transform()) { |
| 284 // matrix. | 327 context.current.transform = object.paintProperties()->transform(); |
| 285 // FIXME(pdr): Refactor this so all non-root SVG objects use the same | 328 context.current.shouldFlattenInheritedTransform = false; |
| 286 // transform function. | 329 context.current.renderingContextID = 0; |
| 287 const AffineTransform& transform = object.isSVGForeignObject() | 330 } |
| 288 ? object.localSVGTransform() | 331 } else { |
| 289 : object.localToSVGParentTransform(); | 332 // FIXME(pdr): Check for the presence of a transform instead of the value. |
| 290 if (!transform.isIdentity()) { | 333 // Checking for an identity matrix will cause the property tree structure |
| 291 // The origin is included in the local transform, so leave origin empty. | 334 // to change during animations if the animation passes through the |
| 292 context.current.transform = | 335 // identity matrix. |
| 293 object.getMutableForPainting() | 336 // FIXME(pdr): Refactor this so all non-root SVG objects use the same |
| 294 .ensurePaintProperties() | 337 // transform function. |
| 295 .updateTransform(context.current.transform, | 338 const AffineTransform& transform = |
| 296 TransformationMatrix(transform), FloatPoint3D()); | 339 object.isSVGForeignObject() ? object.localSVGTransform() |
| 297 context.current.renderingContextID = 0; | 340 : object.localToSVGParentTransform(); |
| 298 context.current.shouldFlattenInheritedTransform = false; | 341 if (!transform.isIdentity()) { |
| 299 return; | 342 // The origin is included in the local transform, so leave origin empty. |
| 343 context.current.transform = | |
| 344 object.getMutableForPainting() | |
| 345 .ensurePaintProperties() | |
| 346 .updateTransform(context.current.transform, | |
| 347 TransformationMatrix(transform), | |
| 348 FloatPoint3D()); | |
| 349 context.current.shouldFlattenInheritedTransform = false; | |
| 350 context.current.renderingContextID = 0; | |
| 351 } else { | |
| 352 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 353 properties->clearTransform(); | |
| 354 } | |
| 300 } | 355 } |
| 301 } else { | 356 return; |
| 302 const ComputedStyle& style = object.styleRef(); | 357 } |
| 303 if (object.isBox() && (style.hasTransform() || style.preserves3D())) { | 358 |
| 359 const ComputedStyle& style = object.styleRef(); | |
| 360 if (object.isBox() && (style.hasTransform() || style.preserves3D())) { | |
| 361 unsigned renderingContextID = context.current.renderingContextID; | |
| 362 unsigned renderingContextIDForChildren = 0; | |
| 363 bool flattensInheritedTransform = | |
| 364 context.current.shouldFlattenInheritedTransform; | |
| 365 bool childrenFlattenInheritedTransform = true; | |
| 366 | |
| 367 // TODO(trchen): transform-style should only be respected if a PaintLayer | |
| 368 // is created. | |
| 369 if (style.preserves3D()) { | |
| 370 // If a node with transform-style: preserve-3d does not exist in an | |
| 371 // existing rendering context, it establishes a new one. | |
| 372 if (!renderingContextID) | |
| 373 renderingContextID = PtrHash<const LayoutObject>::hash(&object); | |
| 374 renderingContextIDForChildren = renderingContextID; | |
| 375 childrenFlattenInheritedTransform = false; | |
| 376 } | |
| 377 context.current.renderingContextID = renderingContextIDForChildren; | |
| 378 context.current.shouldFlattenInheritedTransform = | |
| 379 childrenFlattenInheritedTransform; | |
| 380 | |
| 381 if (object.paintPropertiesValid()) { | |
| 382 // No invalidation so update the context using existing properties. | |
| 383 if (object.paintProperties() && object.paintProperties()->transform()) | |
| 384 context.current.transform = object.paintProperties()->transform(); | |
| 385 } else { | |
| 304 TransformationMatrix matrix; | 386 TransformationMatrix matrix; |
| 305 style.applyTransform( | 387 style.applyTransform( |
| 306 matrix, toLayoutBox(object).size(), | 388 matrix, toLayoutBox(object).size(), |
| 307 ComputedStyle::ExcludeTransformOrigin, | 389 ComputedStyle::ExcludeTransformOrigin, |
| 308 ComputedStyle::IncludeMotionPath, | 390 ComputedStyle::IncludeMotionPath, |
| 309 ComputedStyle::IncludeIndependentTransformProperties); | 391 ComputedStyle::IncludeIndependentTransformProperties); |
| 310 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); | 392 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); |
| 311 | |
| 312 unsigned renderingContextID = context.current.renderingContextID; | |
| 313 unsigned renderingContextIDForChildren = 0; | |
| 314 bool flattensInheritedTransform = | |
| 315 context.current.shouldFlattenInheritedTransform; | |
| 316 bool childrenFlattenInheritedTransform = true; | |
| 317 | |
| 318 // TODO(trchen): transform-style should only be respected if a PaintLayer | |
| 319 // is created. | |
| 320 if (style.preserves3D()) { | |
| 321 // If a node with transform-style: preserve-3d does not exist in an | |
| 322 // existing rendering context, it establishes a new one. | |
| 323 if (!renderingContextID) | |
| 324 renderingContextID = PtrHash<const LayoutObject>::hash(&object); | |
| 325 renderingContextIDForChildren = renderingContextID; | |
| 326 childrenFlattenInheritedTransform = false; | |
| 327 } | |
| 328 | |
| 329 context.current.transform = | 393 context.current.transform = |
| 330 object.getMutableForPainting() | 394 object.getMutableForPainting() |
| 331 .ensurePaintProperties() | 395 .ensurePaintProperties() |
| 332 .updateTransform(context.current.transform, matrix, origin, | 396 .updateTransform(context.current.transform, matrix, origin, |
| 333 flattensInheritedTransform, renderingContextID); | 397 flattensInheritedTransform, renderingContextID); |
| 334 context.current.renderingContextID = renderingContextIDForChildren; | 398 } |
| 335 context.current.shouldFlattenInheritedTransform = | 399 } else { |
| 336 childrenFlattenInheritedTransform; | 400 if (!object.paintPropertiesValid()) { |
| 337 return; | 401 if (auto* properties = object.getMutableForPainting().paintProperties()) |
| 402 properties->clearTransform(); | |
| 338 } | 403 } |
| 339 } | 404 } |
| 340 | |
| 341 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 342 properties->clearTransform(); | |
| 343 } | 405 } |
| 344 | 406 |
| 345 void PaintPropertyTreeBuilder::updateEffect( | 407 void PaintPropertyTreeBuilder::updateEffect( |
| 346 const LayoutObject& object, | 408 const LayoutObject& object, |
| 347 PaintPropertyTreeBuilderContext& context) { | 409 PaintPropertyTreeBuilderContext& context) { |
| 348 if (!object.styleRef().hasOpacity()) { | 410 if (object.paintPropertiesValid()) { |
| 349 if (auto* properties = object.getMutableForPainting().paintProperties()) | 411 // No invalidation so update the context using existing properties. |
| 350 properties->clearEffect(); | 412 if (object.paintProperties() && object.paintProperties()->effect()) |
| 351 return; | 413 context.currentEffect = object.paintProperties()->effect(); |
| 414 } else { | |
| 415 if (object.styleRef().hasOpacity()) { | |
| 416 context.currentEffect = | |
| 417 object.getMutableForPainting().ensurePaintProperties().updateEffect( | |
| 418 context.currentEffect, object.styleRef().opacity()); | |
| 419 } else { | |
| 420 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 421 properties->clearEffect(); | |
| 422 } | |
| 352 } | 423 } |
| 353 | |
| 354 context.currentEffect = | |
| 355 object.getMutableForPainting().ensurePaintProperties().updateEffect( | |
| 356 context.currentEffect, object.styleRef().opacity()); | |
| 357 } | 424 } |
| 358 | 425 |
| 359 void PaintPropertyTreeBuilder::updateCssClip( | 426 void PaintPropertyTreeBuilder::updateCssClip( |
| 360 const LayoutObject& object, | 427 const LayoutObject& object, |
| 361 PaintPropertyTreeBuilderContext& context) { | 428 PaintPropertyTreeBuilderContext& context) { |
| 362 if (object.hasClip()) { | 429 if (object.paintPropertiesValid()) { |
| 363 // Create clip node for descendants that are not fixed position. | 430 // No invalidation so update the context using existing properties. |
| 364 // We don't have to setup context.absolutePosition.clip here because this | 431 if (object.paintProperties() && object.paintProperties()->cssClip()) |
| 365 // object must be a container for absolute position descendants, and will | 432 context.current.clip = object.paintProperties()->cssClip(); |
| 366 // copy from in-flow context later at updateOutOfFlowContext() step. | 433 } else { |
| 367 DCHECK(object.canContainAbsolutePositionObjects()); | 434 if (object.hasClip()) { |
| 368 LayoutRect clipRect = | 435 // Create clip node for descendants that are not fixed position. |
| 369 toLayoutBox(object).clipRect(context.current.paintOffset); | 436 // We don't have to setup context.absolutePosition.clip here because this |
| 370 context.current.clip = | 437 // object must be a container for absolute position descendants, and will |
| 371 object.getMutableForPainting().ensurePaintProperties().updateCssClip( | 438 // copy from in-flow context later at updateOutOfFlowContext() step. |
| 372 context.current.clip, context.current.transform, | 439 DCHECK(object.canContainAbsolutePositionObjects()); |
| 373 FloatRoundedRect(FloatRect(clipRect))); | 440 LayoutRect clipRect = |
| 374 return; | 441 toLayoutBox(object).clipRect(context.current.paintOffset); |
| 442 context.current.clip = | |
| 443 object.getMutableForPainting().ensurePaintProperties().updateCssClip( | |
| 444 context.current.clip, context.current.transform, | |
| 445 FloatRoundedRect(FloatRect(clipRect))); | |
| 446 } else { | |
| 447 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 448 properties->clearCssClip(); | |
| 449 } | |
| 375 } | 450 } |
| 376 | |
| 377 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 378 properties->clearCssClip(); | |
| 379 } | 451 } |
| 380 | 452 |
| 381 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( | 453 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( |
| 382 const LayoutObject& object, | 454 const LayoutObject& object, |
| 383 PaintPropertyTreeBuilderContext& context) { | 455 PaintPropertyTreeBuilderContext& context) { |
| 456 if (object.paintPropertiesValid()) | |
| 457 return; | |
| 458 | |
| 384 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since | 459 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since |
| 385 // we don't need them at the moment. | 460 // we don't need them at the moment. |
| 386 if (!object.isBox() && !object.hasLayer()) | 461 if (!object.isBox() && !object.hasLayer()) { |
| 462 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 463 properties->clearLocalBorderBoxProperties(); | |
|
chrishtr
2016/10/21 22:03:09
Why is this change needed but wasn't in the old co
pdr.
2016/10/26 03:10:48
This is just a cleanup so we don't leave unnecessa
| |
| 387 return; | 464 return; |
| 465 } | |
| 388 | 466 |
| 389 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset> | 467 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset> |
| 390 borderBoxContext = | 468 borderBoxContext = |
| 391 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset( | 469 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset( |
| 392 context.current.paintOffset, | 470 context.current.paintOffset, |
| 393 PropertyTreeState(context.current.transform, context.current.clip, | 471 PropertyTreeState(context.current.transform, context.current.clip, |
| 394 context.currentEffect, | 472 context.currentEffect, |
| 395 context.current.scroll))); | 473 context.current.scroll))); |
| 396 object.getMutableForPainting() | 474 object.getMutableForPainting() |
| 397 .ensurePaintProperties() | 475 .ensurePaintProperties() |
| 398 .setLocalBorderBoxProperties(std::move(borderBoxContext)); | 476 .setLocalBorderBoxProperties(std::move(borderBoxContext)); |
| 399 } | 477 } |
| 400 | 478 |
| 401 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 479 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
| 402 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( | 480 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( |
| 403 const LayoutObject& object, | 481 const LayoutObject& object, |
| 404 const PaintPropertyTreeBuilderContext& context) { | 482 const PaintPropertyTreeBuilderContext& context) { |
| 483 if (object.paintPropertiesValid()) | |
| 484 return; | |
| 485 | |
| 405 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); | 486 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); |
| 406 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { | 487 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { |
| 407 if (PaintLayerScrollableArea* scrollableArea = | 488 if (PaintLayerScrollableArea* scrollableArea = |
| 408 toLayoutBoxModelObject(object).getScrollableArea()) { | 489 toLayoutBoxModelObject(object).getScrollableArea()) { |
| 409 if (scrollableArea->horizontalScrollbar() || | 490 if (scrollableArea->horizontalScrollbar() || |
| 410 scrollableArea->verticalScrollbar()) { | 491 scrollableArea->verticalScrollbar()) { |
| 411 auto paintOffset = TransformationMatrix().translate( | 492 auto paintOffset = TransformationMatrix().translate( |
| 412 roundedPaintOffset.x(), roundedPaintOffset.y()); | 493 roundedPaintOffset.x(), roundedPaintOffset.y()); |
| 413 object.getMutableForPainting() | 494 object.getMutableForPainting() |
| 414 .ensurePaintProperties() | 495 .ensurePaintProperties() |
| 415 .updateScrollbarPaintOffset(context.current.transform, paintOffset, | 496 .updateScrollbarPaintOffset(context.current.transform, paintOffset, |
| 416 FloatPoint3D()); | 497 FloatPoint3D()); |
| 417 return; | 498 return; |
| 418 } | 499 } |
| 419 } | 500 } |
| 420 } | 501 } |
| 421 | 502 |
| 422 if (auto* properties = object.getMutableForPainting().paintProperties()) | 503 if (auto* properties = object.getMutableForPainting().paintProperties()) |
| 423 properties->clearScrollbarPaintOffset(); | 504 properties->clearScrollbarPaintOffset(); |
| 424 } | 505 } |
| 425 | 506 |
| 426 void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons( | 507 void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons( |
| 427 const LayoutObject& object, | 508 const LayoutObject& object, |
| 428 PaintPropertyTreeBuilderContext& context) { | 509 PaintPropertyTreeBuilderContext& context) { |
| 510 // TODO(pdr): Add property under-invalidation checking for main thread scroll | |
| 511 // reasons and ensure reason changes invalidate property trees. | |
| 429 if (context.current.scroll && | 512 if (context.current.scroll && |
| 430 !object.document().settings()->threadedScrollingEnabled()) | 513 !object.document().settings()->threadedScrollingEnabled()) { |
| 431 context.current.scroll->addMainThreadScrollingReasons( | 514 context.current.scroll->addMainThreadScrollingReasons( |
| 432 MainThreadScrollingReason::kThreadedScrollingDisabled); | 515 MainThreadScrollingReason::kThreadedScrollingDisabled); |
| 516 } | |
| 433 | 517 |
| 434 if (object.isBackgroundAttachmentFixedObject()) { | 518 if (object.isBackgroundAttachmentFixedObject()) { |
| 435 auto* scrollNode = context.current.scroll; | 519 auto* scrollNode = context.current.scroll; |
| 436 while ( | 520 while ( |
| 437 scrollNode && | 521 scrollNode && |
| 438 !scrollNode->hasMainThreadScrollingReasons( | 522 !scrollNode->hasMainThreadScrollingReasons( |
| 439 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)) { | 523 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)) { |
| 440 scrollNode->addMainThreadScrollingReasons( | 524 scrollNode->addMainThreadScrollingReasons( |
| 441 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); | 525 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); |
| 442 scrollNode = scrollNode->parent(); | 526 scrollNode = scrollNode->parent(); |
| 443 } | 527 } |
| 444 } | 528 } |
| 445 } | 529 } |
| 446 | 530 |
| 447 void PaintPropertyTreeBuilder::updateOverflowClip( | 531 void PaintPropertyTreeBuilder::updateOverflowClip( |
| 448 const LayoutObject& object, | 532 const LayoutObject& object, |
| 449 PaintPropertyTreeBuilderContext& context) { | 533 PaintPropertyTreeBuilderContext& context) { |
| 450 if (!object.isBox()) | 534 if (!object.isBox()) |
| 451 return; | 535 return; |
| 452 const LayoutBox& box = toLayoutBox(object); | 536 const LayoutBox& box = toLayoutBox(object); |
| 453 | 537 |
| 538 if (object.paintPropertiesValid()) { | |
| 539 // No invalidation so update the context using existing properties. | |
| 540 const auto* properties = object.paintProperties(); | |
| 541 if (properties && properties->overflowClip()) | |
| 542 context.current.clip = properties->overflowClip(); | |
| 543 return; | |
| 544 } | |
| 545 | |
| 454 // The <input> elements can't have contents thus CSS overflow property doesn't | 546 // The <input> elements can't have contents thus CSS overflow property doesn't |
| 455 // apply. However for layout purposes we do generate child layout objects for | 547 // apply. However for layout purposes we do generate child layout objects for |
| 456 // them, e.g. button label. We should clip the overflow from those children. | 548 // them, e.g. button label. We should clip the overflow from those children. |
| 457 // This is called control clip and we technically treat them like overflow | 549 // This is called control clip and we technically treat them like overflow |
| 458 // clip. | 550 // clip. |
| 459 LayoutRect clipRect; | 551 LayoutRect clipRect; |
| 460 if (box.hasControlClip()) { | 552 if (box.hasControlClip()) { |
| 461 clipRect = box.controlClipRect(context.current.paintOffset); | 553 clipRect = box.controlClipRect(context.current.paintOffset); |
| 462 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() || | 554 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() || |
| 463 (box.isSVGRoot() && | 555 (box.isSVGRoot() && |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 return FloatPoint( | 588 return FloatPoint( |
| 497 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), | 589 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), |
| 498 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())); | 590 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())); |
| 499 } | 591 } |
| 500 | 592 |
| 501 void PaintPropertyTreeBuilder::updatePerspective( | 593 void PaintPropertyTreeBuilder::updatePerspective( |
| 502 const LayoutObject& object, | 594 const LayoutObject& object, |
| 503 PaintPropertyTreeBuilderContext& context) { | 595 PaintPropertyTreeBuilderContext& context) { |
| 504 const ComputedStyle& style = object.styleRef(); | 596 const ComputedStyle& style = object.styleRef(); |
| 505 if (!object.isBox() || !style.hasPerspective()) { | 597 if (!object.isBox() || !style.hasPerspective()) { |
| 506 if (auto* properties = object.getMutableForPainting().paintProperties()) | 598 if (!object.paintPropertiesValid()) { |
| 507 properties->clearPerspective(); | 599 if (auto* properties = object.getMutableForPainting().paintProperties()) |
| 600 properties->clearPerspective(); | |
| 601 } | |
| 508 return; | 602 return; |
| 509 } | 603 } |
| 510 | 604 |
| 511 // The perspective node must not flatten (else nothing will get | 605 if (object.paintPropertiesValid()) { |
| 512 // perspective), but it should still extend the rendering context as most | 606 // No invalidation so update the context using existing properties. |
| 513 // transform nodes do. | 607 if (object.paintProperties() && object.paintProperties()->perspective()) |
| 514 TransformationMatrix matrix = | 608 context.current.transform = object.paintProperties()->perspective(); |
| 515 TransformationMatrix().applyPerspective(style.perspective()); | 609 } else { |
| 516 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + | 610 // The perspective node must not flatten (else nothing will get |
| 517 toLayoutSize(context.current.paintOffset); | 611 // perspective), but it should still extend the rendering context as most |
| 518 context.current.transform = | 612 // transform nodes do. |
| 519 object.getMutableForPainting().ensurePaintProperties().updatePerspective( | 613 TransformationMatrix matrix = |
| 520 context.current.transform, matrix, origin, | 614 TransformationMatrix().applyPerspective(style.perspective()); |
| 521 context.current.shouldFlattenInheritedTransform, | 615 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + |
| 522 context.current.renderingContextID); | 616 toLayoutSize(context.current.paintOffset); |
| 617 context.current.transform = | |
| 618 object.getMutableForPainting() | |
| 619 .ensurePaintProperties() | |
| 620 .updatePerspective(context.current.transform, matrix, origin, | |
| 621 context.current.shouldFlattenInheritedTransform, | |
| 622 context.current.renderingContextID); | |
| 623 } | |
| 523 context.current.shouldFlattenInheritedTransform = false; | 624 context.current.shouldFlattenInheritedTransform = false; |
| 524 } | 625 } |
| 525 | 626 |
| 526 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( | 627 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( |
| 527 const LayoutObject& object, | 628 const LayoutObject& object, |
| 528 PaintPropertyTreeBuilderContext& context) { | 629 PaintPropertyTreeBuilderContext& context) { |
| 529 if (!object.isSVGRoot()) | 630 if (!object.isSVGRoot()) |
| 530 return; | 631 return; |
| 531 | 632 |
| 532 AffineTransform transformToBorderBox = | 633 if (object.paintPropertiesValid()) { |
| 533 SVGRootPainter(toLayoutSVGRoot(object)) | 634 // No invalidation so update the context using existing properties. |
| 534 .transformToPixelSnappedBorderBox(context.current.paintOffset); | 635 const auto* properties = object.paintProperties(); |
| 636 if (properties && properties->svgLocalToBorderBoxTransform()) { | |
| 637 context.current.transform = properties->svgLocalToBorderBoxTransform(); | |
| 638 context.current.shouldFlattenInheritedTransform = false; | |
| 639 context.current.renderingContextID = 0; | |
| 640 } | |
| 641 } else { | |
| 642 AffineTransform transformToBorderBox = | |
| 643 SVGRootPainter(toLayoutSVGRoot(object)) | |
| 644 .transformToPixelSnappedBorderBox(context.current.paintOffset); | |
| 645 | |
| 646 if (transformToBorderBox.isIdentity()) { | |
| 647 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 648 properties->clearSvgLocalToBorderBoxTransform(); | |
| 649 } else { | |
| 650 context.current.transform = object.getMutableForPainting() | |
| 651 .ensurePaintProperties() | |
| 652 .updateSvgLocalToBorderBoxTransform( | |
| 653 context.current.transform, | |
| 654 transformToBorderBox, FloatPoint3D()); | |
| 655 context.current.shouldFlattenInheritedTransform = false; | |
| 656 context.current.renderingContextID = 0; | |
| 657 } | |
| 658 } | |
| 535 | 659 |
| 536 // The paint offset is included in |transformToBorderBox| so SVG does not need | 660 // The paint offset is included in |transformToBorderBox| so SVG does not need |
| 537 // to handle paint offset internally. | 661 // to handle paint offset internally. |
| 538 context.current.paintOffset = LayoutPoint(); | 662 context.current.paintOffset = LayoutPoint(); |
| 539 | |
| 540 if (transformToBorderBox.isIdentity()) { | |
| 541 if (auto* properties = object.getMutableForPainting().paintProperties()) | |
| 542 properties->clearSvgLocalToBorderBoxTransform(); | |
| 543 return; | |
| 544 } | |
| 545 | |
| 546 context.current.transform = | |
| 547 object.getMutableForPainting() | |
| 548 .ensurePaintProperties() | |
| 549 .updateSvgLocalToBorderBoxTransform( | |
| 550 context.current.transform, transformToBorderBox, FloatPoint3D()); | |
| 551 context.current.shouldFlattenInheritedTransform = false; | |
| 552 context.current.renderingContextID = 0; | |
| 553 } | 663 } |
| 554 | 664 |
| 555 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( | 665 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( |
| 556 const LayoutObject& object, | 666 const LayoutObject& object, |
| 557 PaintPropertyTreeBuilderContext& context) { | 667 PaintPropertyTreeBuilderContext& context) { |
| 668 if (object.paintPropertiesValid()) { | |
| 669 // No invalidation so update the context using existing properties. | |
| 670 if (object.paintProperties() && object.paintProperties()->scroll()) { | |
| 671 context.current.transform = object.paintProperties()->transform(); | |
| 672 const auto* scroll = object.paintProperties()->scroll(); | |
| 673 // TODO(pdr): Remove this const cast. | |
| 674 context.current.scroll = const_cast<ScrollPaintPropertyNode*>(scroll); | |
| 675 context.current.shouldFlattenInheritedTransform = false; | |
| 676 } | |
| 677 return; | |
| 678 } | |
| 679 | |
| 558 if (object.hasOverflowClip()) { | 680 if (object.hasOverflowClip()) { |
| 559 const LayoutBox& box = toLayoutBox(object); | 681 const LayoutBox& box = toLayoutBox(object); |
| 560 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); | 682 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); |
| 561 IntSize scrollOffset = box.scrolledContentOffset(); | 683 IntSize scrollOffset = box.scrolledContentOffset(); |
| 562 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { | 684 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { |
| 563 TransformationMatrix matrix = TransformationMatrix().translate( | 685 TransformationMatrix matrix = TransformationMatrix().translate( |
| 564 -scrollOffset.width(), -scrollOffset.height()); | 686 -scrollOffset.width(), -scrollOffset.height()); |
| 565 context.current.transform = | 687 context.current.transform = |
| 566 object.getMutableForPainting() | 688 object.getMutableForPainting() |
| 567 .ensurePaintProperties() | 689 .ensurePaintProperties() |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 // absolute position container. However for fixed-position descendants we | 743 // absolute position container. However for fixed-position descendants we |
| 622 // need to insert the clip here if we are not a containing block ancestor of | 744 // need to insert the clip here if we are not a containing block ancestor of |
| 623 // them. | 745 // them. |
| 624 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip(); | 746 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip(); |
| 625 | 747 |
| 626 // Before we actually create anything, check whether in-flow context and | 748 // Before we actually create anything, check whether in-flow context and |
| 627 // fixed-position context has exactly the same clip. Reuse if possible. | 749 // fixed-position context has exactly the same clip. Reuse if possible. |
| 628 if (context.fixedPosition.clip == cssClip->parent()) { | 750 if (context.fixedPosition.clip == cssClip->parent()) { |
| 629 context.fixedPosition.clip = cssClip; | 751 context.fixedPosition.clip = cssClip; |
| 630 } else { | 752 } else { |
| 631 context.fixedPosition.clip = | 753 if (object.paintPropertiesValid()) { |
| 632 object.getMutableForPainting() | 754 // No invalidation so update the context using existing properties. |
| 633 .ensurePaintProperties() | 755 const auto* properties = object.paintProperties(); |
| 634 .updateCssClipFixedPosition( | 756 if (properties && properties->cssClipFixedPosition()) |
| 635 context.fixedPosition.clip, | 757 context.fixedPosition.clip = properties->cssClipFixedPosition(); |
| 636 const_cast<TransformPaintPropertyNode*>( | 758 } else { |
| 637 cssClip->localTransformSpace()), | 759 context.fixedPosition.clip = |
| 638 cssClip->clipRect()); | 760 object.getMutableForPainting() |
| 761 .ensurePaintProperties() | |
| 762 .updateCssClipFixedPosition( | |
| 763 context.fixedPosition.clip, | |
| 764 const_cast<TransformPaintPropertyNode*>( | |
| 765 cssClip->localTransformSpace()), | |
| 766 cssClip->clipRect()); | |
| 767 } | |
| 639 return; | 768 return; |
| 640 } | 769 } |
| 641 } | 770 } |
| 642 | 771 |
| 643 if (auto* properties = object.getMutableForPainting().paintProperties()) | 772 if (!object.paintPropertiesValid()) { |
| 644 properties->clearCssClipFixedPosition(); | 773 if (auto* properties = object.getMutableForPainting().paintProperties()) |
| 774 properties->clearCssClipFixedPosition(); | |
| 775 } | |
| 645 } | 776 } |
| 646 | 777 |
| 647 // Override ContainingBlockContext based on the properties of a containing block | 778 // Override ContainingBlockContext based on the properties of a containing block |
| 648 // that was previously walked in a subtree other than the current subtree being | 779 // that was previously walked in a subtree other than the current subtree being |
| 649 // walked. Used for out-of-flow positioned descendants of multi-column spanner | 780 // walked. Used for out-of-flow positioned descendants of multi-column spanner |
| 650 // when the containing block is not in the normal tree walk order. | 781 // when the containing block is not in the normal tree walk order. |
| 651 // For example: | 782 // For example: |
| 652 // <div id="columns" style="columns: 2"> | 783 // <div id="columns" style="columns: 2"> |
| 653 // <div id="relative" style="position: relative"> | 784 // <div id="relative" style="position: relative"> |
| 654 // <div id="spanner" style="column-span: all"> | 785 // <div id="spanner" style="column-span: all"> |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). | 890 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). |
| 760 if (boxModelObject.isTableCell()) { | 891 if (boxModelObject.isTableCell()) { |
| 761 LayoutObject* parentRow = boxModelObject.parent(); | 892 LayoutObject* parentRow = boxModelObject.parent(); |
| 762 ASSERT(parentRow && parentRow->isTableRow()); | 893 ASSERT(parentRow && parentRow->isTableRow()); |
| 763 context.current.paintOffset.moveBy( | 894 context.current.paintOffset.moveBy( |
| 764 -toLayoutBox(parentRow)->topLeftLocation()); | 895 -toLayoutBox(parentRow)->topLeftLocation()); |
| 765 } | 896 } |
| 766 } | 897 } |
| 767 } | 898 } |
| 768 | 899 |
| 769 void PaintPropertyTreeBuilder::buildTreeNodesForSelf( | 900 void PaintPropertyTreeBuilder::updatePropertiesForSelf( |
| 770 const LayoutObject& object, | 901 const LayoutObject& object, |
| 771 PaintPropertyTreeBuilderContext& context) { | 902 PaintPropertyTreeBuilderContext& context) { |
| 772 if (!object.isBoxModelObject() && !object.isSVG()) | 903 if (!object.isBoxModelObject() && !object.isSVG()) |
| 773 return; | 904 return; |
| 774 | 905 |
| 906 #ifndef NDEBUG | |
| 907 auto underInvalidationChecker = | |
| 908 ObjectUnderInvalidationCheckScope::createIfNeeded(object); | |
| 909 #endif | |
| 910 | |
| 775 deriveBorderBoxFromContainerContext(object, context); | 911 deriveBorderBoxFromContainerContext(object, context); |
| 776 | 912 |
| 777 updatePaintOffsetTranslation(object, context); | 913 updatePaintOffsetTranslation(object, context); |
| 778 updateTransform(object, context); | 914 updateTransform(object, context); |
| 779 updateEffect(object, context); | 915 updateEffect(object, context); |
| 780 updateCssClip(object, context); | 916 updateCssClip(object, context); |
| 781 updateLocalBorderBoxContext(object, context); | 917 updateLocalBorderBoxContext(object, context); |
| 782 updateScrollbarPaintOffset(object, context); | 918 updateScrollbarPaintOffset(object, context); |
| 783 updateMainThreadScrollingReasons(object, context); | 919 updateMainThreadScrollingReasons(object, context); |
| 784 } | 920 } |
| 785 | 921 |
| 786 void PaintPropertyTreeBuilder::buildTreeNodesForChildren( | 922 void PaintPropertyTreeBuilder::updatePropertiesForChildren( |
| 787 const LayoutObject& object, | 923 const LayoutObject& object, |
| 788 PaintPropertyTreeBuilderContext& context) { | 924 PaintPropertyTreeBuilderContext& context) { |
| 789 if (!object.isBoxModelObject() && !object.isSVG()) | 925 if (!object.isBoxModelObject() && !object.isSVG()) |
| 790 return; | 926 return; |
| 791 | 927 |
| 928 #ifndef NDEBUG | |
| 929 auto underInvalidationChecker = | |
| 930 ObjectUnderInvalidationCheckScope::createIfNeeded(object); | |
| 931 #endif | |
| 932 | |
| 792 updateOverflowClip(object, context); | 933 updateOverflowClip(object, context); |
| 793 updatePerspective(object, context); | 934 updatePerspective(object, context); |
| 794 updateSvgLocalToBorderBoxTransform(object, context); | 935 updateSvgLocalToBorderBoxTransform(object, context); |
| 795 updateScrollAndScrollTranslation(object, context); | 936 updateScrollAndScrollTranslation(object, context); |
| 796 updateOutOfFlowContext(object, context); | 937 updateOutOfFlowContext(object, context); |
| 797 } | 938 } |
| 798 | 939 |
| 799 } // namespace blink | 940 } // namespace blink |
| OLD | NEW |