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/svg/LayoutSVGRoot.h" | |
| 12 #include "core/paint/ObjectPaintProperties.h" | 13 #include "core/paint/ObjectPaintProperties.h" |
| 13 #include "core/paint/PaintLayer.h" | 14 #include "core/paint/PaintLayer.h" |
| 14 #include "platform/transforms/TransformationMatrix.h" | 15 #include "platform/transforms/TransformationMatrix.h" |
| 15 | 16 |
| 16 namespace blink { | 17 namespace blink { |
| 17 | 18 |
| 18 void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPro pertyTreeBuilderContext& context) | 19 void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPro pertyTreeBuilderContext& context) |
| 19 { | 20 { |
| 20 // Only create extra root clip and transform nodes when RLS is enabled, beca use the main frame | 21 // Only create extra root clip and transform nodes when RLS is enabled, beca use the main frame |
| 21 // unconditionally create frame translation / clip nodes otherwise. | 22 // unconditionally create frame translation / clip nodes otherwise. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 context.paintOffsetForAbsolutePosition = LayoutPoint(); | 58 context.paintOffsetForAbsolutePosition = LayoutPoint(); |
| 58 context.containerForAbsolutePosition = nullptr; | 59 context.containerForAbsolutePosition = nullptr; |
| 59 | 60 |
| 60 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); | 61 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); |
| 61 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( )); | 62 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( )); |
| 62 frameView.setContentClip(newClipNodeForContentClip.release()); | 63 frameView.setContentClip(newClipNodeForContentClip.release()); |
| 63 } | 64 } |
| 64 | 65 |
| 65 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) | 66 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) |
| 66 { | 67 { |
| 67 bool shouldCreatePaintOffsetTranslationNode = false; | 68 if (object.isBoxModelObject()) { |
| 68 if (object.isSVGRoot()) { | |
| 69 // SVG doesn't use paint offset internally so emit a paint offset at the html->svg boundary. | |
| 70 shouldCreatePaintOffsetTranslationNode = true; | |
| 71 } else if (object.isBoxModelObject()) { | |
| 72 // TODO(trchen): Eliminate PaintLayer dependency. | 69 // TODO(trchen): Eliminate PaintLayer dependency. |
| 73 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 70 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 74 shouldCreatePaintOffsetTranslationNode = layer && layer->paintsWithTrans form(GlobalPaintNormalPhase); | 71 if (!layer || !layer->paintsWithTransform(GlobalPaintNormalPhase)) |
| 72 return; | |
| 75 } | 73 } |
| 76 | 74 |
| 77 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat ionNode) | 75 if (context.paintOffset == LayoutPoint()) |
| 78 return; | 76 return; |
| 79 | 77 |
| 80 RefPtr<TransformPaintPropertyNode> paintOffsetTranslation = TransformPaintPr opertyNode::create( | 78 RefPtr<TransformPaintPropertyNode> paintOffsetTranslation = TransformPaintPr opertyNode::create( |
| 81 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()), | 79 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()), |
| 82 FloatPoint3D(), context.currentTransform); | 80 FloatPoint3D(), context.currentTransform); |
| 83 context.currentTransform = paintOffsetTranslation.get(); | 81 context.currentTransform = paintOffsetTranslation.get(); |
| 84 context.paintOffset = LayoutPoint(); | 82 context.paintOffset = LayoutPoint(); |
| 85 object.getMutableForPainting().ensureObjectPaintProperties().setPaintOffsetT ranslation(paintOffsetTranslation.release()); | 83 object.getMutableForPainting().ensureObjectPaintProperties().setPaintOffsetT ranslation(paintOffsetTranslation.release()); |
| 86 } | 84 } |
| 87 | 85 |
| 88 static FloatPoint3D transformOrigin(const LayoutBox& box) | 86 static FloatPoint3D transformOrigin(const LayoutBox& box) |
| 89 { | 87 { |
| 90 const ComputedStyle& style = box.styleRef(); | 88 const ComputedStyle& style = box.styleRef(); |
| 91 FloatSize borderBoxSize(box.size()); | 89 FloatSize borderBoxSize(box.size()); |
| 92 return FloatPoint3D( | 90 return FloatPoint3D( |
| 93 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), | 91 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), |
| 94 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), | 92 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), |
| 95 style.transformOriginZ()); | 93 style.transformOriginZ()); |
| 96 } | 94 } |
| 97 | 95 |
| 98 void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint PropertyTreeBuilderContext& context) | 96 void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint PropertyTreeBuilderContext& context) |
| 99 { | 97 { |
| 98 if (object.isSVG() && !object.isSVGRoot()) { | |
| 99 // SVG does not use paint offset internally and the root should have alr eady accounted for | |
| 100 // any paint offset in the root's svgLocalToBorderBox transform. | |
| 101 DCHECK(context.paintOffset == LayoutPoint()); | |
| 102 | |
| 103 // TODO(pdr): Check for the presence of a transform instead of the value . Checking for an | |
| 104 // identity matrix will cause the property tree structure to change duri ng animations if | |
| 105 // the animation passes through the identity matrix. | |
| 106 const AffineTransform& transform = object.localToSVGParentTransform(); | |
| 107 if (transform.isIdentity()) | |
| 108 return; | |
| 109 | |
| 110 // The origin is included in the local transform, so use an empty origin . | |
| 111 RefPtr<TransformPaintPropertyNode> svgTransform = TransformPaintProperty Node::create( | |
| 112 transform, FloatPoint3D(0, 0, 0), context.currentTransform); | |
| 113 context.currentTransform = svgTransform.get(); | |
| 114 object.getMutableForPainting().ensureObjectPaintProperties().setTransfor m(svgTransform.release()); | |
| 115 return; | |
| 116 } | |
| 117 | |
| 100 const ComputedStyle& style = object.styleRef(); | 118 const ComputedStyle& style = object.styleRef(); |
| 101 if (!object.isBox() || !style.hasTransform()) | 119 if (!object.isBox() || !style.hasTransform()) |
| 102 return; | 120 return; |
| 103 ASSERT(context.paintOffset == LayoutPoint()); | 121 ASSERT(context.paintOffset == LayoutPoint()); |
| 104 | 122 |
| 105 TransformationMatrix matrix; | 123 TransformationMatrix matrix; |
| 106 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin, | 124 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin, |
| 107 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties); | 125 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties); |
| 108 RefPtr<TransformPaintPropertyNode> transformNode = TransformPaintPropertyNod e::create( | 126 RefPtr<TransformPaintPropertyNode> transformNode = TransformPaintPropertyNod e::create( |
| 109 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); | 127 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 return; | 243 return; |
| 226 | 244 |
| 227 RefPtr<TransformPaintPropertyNode> perspective = TransformPaintPropertyNode: :create( | 245 RefPtr<TransformPaintPropertyNode> perspective = TransformPaintPropertyNode: :create( |
| 228 TransformationMatrix().applyPerspective(style.perspective()), | 246 TransformationMatrix().applyPerspective(style.perspective()), |
| 229 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), | 247 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), |
| 230 context.currentTransform); | 248 context.currentTransform); |
| 231 context.currentTransform = perspective.get(); | 249 context.currentTransform = perspective.get(); |
| 232 object.getMutableForPainting().ensureObjectPaintProperties().setPerspective( perspective.release()); | 250 object.getMutableForPainting().ensureObjectPaintProperties().setPerspective( perspective.release()); |
| 233 } | 251 } |
| 234 | 252 |
| 235 void PaintPropertyTreeBuilder::updateSvgLocalTransform(const LayoutObject& objec t, PaintPropertyTreeBuilderContext& context) | 253 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb ject& object, PaintPropertyTreeBuilderContext& context) |
| 236 { | 254 { |
| 237 if (!object.isSVG()) | 255 if (!object.isSVGRoot()) |
| 238 return; | 256 return; |
| 239 | 257 |
| 240 const AffineTransform& transform = object.localToSVGParentTransform(); | 258 AffineTransform transform = AffineTransform::translation(context.paintOffset .x().toFloat(), context.paintOffset.y().toFloat()); |
| 259 transform *= toLayoutSVGRoot(object).localToBorderBoxTransform(); | |
| 241 if (transform.isIdentity()) | 260 if (transform.isIdentity()) |
| 242 return; | 261 return; |
| 243 | 262 |
| 244 // The origin is included in the local transform, so use an empty origin. | 263 RefPtr<TransformPaintPropertyNode> svgLocalToBorderBoxTransform = TransformP aintPropertyNode::create( |
| 245 RefPtr<TransformPaintPropertyNode> svgLocalTransform = TransformPaintPropert yNode::create( | |
| 246 transform, FloatPoint3D(0, 0, 0), context.currentTransform); | 264 transform, FloatPoint3D(0, 0, 0), context.currentTransform); |
| 247 context.currentTransform = svgLocalTransform.get(); | 265 context.currentTransform = svgLocalToBorderBoxTransform.get(); |
| 248 object.getMutableForPainting().ensureObjectPaintProperties().setSvgLocalTran sform(svgLocalTransform.release()); | 266 context.paintOffset = LayoutPoint(); |
| 267 object.getMutableForPainting().ensureObjectPaintProperties().setSvgLocalToBo rderBoxTransform(svgLocalToBorderBoxTransform.release()); | |
| 249 } | 268 } |
| 250 | 269 |
| 251 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec t, PaintPropertyTreeBuilderContext& context) | 270 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec t, PaintPropertyTreeBuilderContext& context) |
| 252 { | 271 { |
| 253 if (!object.isBoxModelObject() || !object.hasOverflowClip()) | 272 if (!object.isBoxModelObject() || !object.hasOverflowClip()) |
| 254 return; | 273 return; |
| 255 | 274 |
| 256 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 275 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 257 ASSERT(layer); | 276 ASSERT(layer); |
| 258 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); | 277 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 context.paintOffset += boxModelObject.offsetForInFlowPosition(); | 356 context.paintOffset += boxModelObject.offsetForInFlowPosition(); |
| 338 break; | 357 break; |
| 339 case FixedPosition: | 358 case FixedPosition: |
| 340 context.currentTransform = context.transformForFixedPosition; | 359 context.currentTransform = context.transformForFixedPosition; |
| 341 context.paintOffset = context.paintOffsetForFixedPosition; | 360 context.paintOffset = context.paintOffsetForFixedPosition; |
| 342 context.currentClip = context.clipForFixedPosition; | 361 context.currentClip = context.clipForFixedPosition; |
| 343 break; | 362 break; |
| 344 default: | 363 default: |
| 345 ASSERT_NOT_REACHED(); | 364 ASSERT_NOT_REACHED(); |
| 346 } | 365 } |
| 347 if (boxModelObject.isBox()) { | 366 if (boxModelObject.isBox() && (boxModelObject.isSVGRoot() || !boxModelObject .isSVG())) { |
|
jbroman
2016/06/10 18:33:52
premature optimization: consider putting the !isSV
pdr.
2016/06/10 19:45:46
Optimized!
Nevermind the TODO one line down about
| |
| 348 // TODO(pdr): Several calls in this function walk back up the tree to ca lculate containers | 367 // TODO(pdr): Several calls in this function walk back up the tree to ca lculate containers |
| 349 // (e.g., topLeftLocation, offsetForInFlowPosition*). The containing blo ck and other | 368 // (e.g., topLeftLocation, offsetForInFlowPosition*). The containing blo ck and other |
| 350 // containers can be stored on PaintPropertyTreeBuilderContext instead o f recomputing them. | 369 // containers can be stored on PaintPropertyTreeBuilderContext instead o f recomputing them. |
| 351 context.paintOffset.moveBy(toLayoutBox(boxModelObject).topLeftLocation() ); | 370 context.paintOffset.moveBy(toLayoutBox(boxModelObject).topLeftLocation() ); |
| 352 // This is a weird quirk that table cells paint as children of table row s, | 371 // This is a weird quirk that table cells paint as children of table row s, |
| 353 // but their location have the row's location baked-in. | 372 // but their location have the row's location baked-in. |
| 354 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). | 373 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). |
| 355 if (boxModelObject.isTableCell()) { | 374 if (boxModelObject.isTableCell()) { |
| 356 LayoutObject* parentRow = boxModelObject.parent(); | 375 LayoutObject* parentRow = boxModelObject.parent(); |
| 357 ASSERT(parentRow && parentRow->isTableRow()); | 376 ASSERT(parentRow && parentRow->isTableRow()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 372 updatePaintOffsetTranslation(object, context); | 391 updatePaintOffsetTranslation(object, context); |
| 373 updateTransform(object, context); | 392 updateTransform(object, context); |
| 374 updateEffect(object, context); | 393 updateEffect(object, context); |
| 375 updateCssClip(object, context); | 394 updateCssClip(object, context); |
| 376 updateLocalBorderBoxContext(object, context); | 395 updateLocalBorderBoxContext(object, context); |
| 377 updateScrollbarPaintOffset(object, context); | 396 updateScrollbarPaintOffset(object, context); |
| 378 updateOverflowClip(object, context); | 397 updateOverflowClip(object, context); |
| 379 // TODO(trchen): Insert flattening transform here, as specified by | 398 // TODO(trchen): Insert flattening transform here, as specified by |
| 380 // http://www.w3.org/TR/css3-transforms/#transform-style-property | 399 // http://www.w3.org/TR/css3-transforms/#transform-style-property |
| 381 updatePerspective(object, context); | 400 updatePerspective(object, context); |
| 382 updateSvgLocalTransform(object, context); | 401 updateSvgLocalToBorderBoxTransform(object, context); |
| 383 updateScrollTranslation(object, context); | 402 updateScrollTranslation(object, context); |
| 384 updateOutOfFlowContext(object, context); | 403 updateOutOfFlowContext(object, context); |
| 385 } | 404 } |
| 386 | 405 |
| 387 } // namespace blink | 406 } // namespace blink |
| OLD | NEW |