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/layout/LayoutPart.h" | 8 #include "core/layout/LayoutPart.h" |
| 9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
| 10 #include "core/paint/ObjectPaintProperties.h" | 10 #include "core/paint/ObjectPaintProperties.h" |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context) | 207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context) |
| 208 { | 208 { |
| 209 const ComputedStyle& style = object.styleRef(); | 209 const ComputedStyle& style = object.styleRef(); |
| 210 if (!style.hasOpacity()) | 210 if (!style.hasOpacity()) |
| 211 return nullptr; | 211 return nullptr; |
| 212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); | 212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); |
| 213 context.currentEffect = newEffectNode.get(); | 213 context.currentEffect = newEffectNode.get(); |
| 214 return newEffectNode.release(); | 214 return newEffectNode.release(); |
| 215 } | 215 } |
| 216 | 216 |
| 217 static PassRefPtr<ClipPaintPropertyNode> createCSSClipIfNeeded(const LayoutObjec t& object, PaintPropertyTreeBuilderContext& context) | |
| 218 { | |
| 219 if (!object.hasClip()) | |
| 220 return nullptr; | |
| 221 ASSERT(object.canContainAbsolutePositionObjects()); | |
| 222 | |
| 223 // Create clip node for descendants that are not fixed position. | |
| 224 // We don't have to setup context.clipForAbsolutePosition here because this object must be | |
| 225 // a container for absolute position descendants, and will copy from in-flow context later | |
| 226 // at updateOutOfFlowContext() step. | |
| 227 LayoutRect clipRect = toLayoutBox(object).clipRect(context.paintOffset); | |
| 228 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = ClipPaintPropertyNode: :create( | |
| 229 context.currentTransform, | |
| 230 FloatRoundedRect(FloatRect(clipRect)), | |
| 231 context.currentClip); | |
| 232 context.currentClip = newClipNodeForCSSClip.get(); | |
| 233 | |
| 234 return newClipNodeForCSSClip.release(); | |
| 235 } | |
| 236 | |
| 217 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 237 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
| 218 static PassRefPtr<TransformPaintPropertyNode> createScrollbarPaintOffsetIfNeeded (const LayoutObject& object, PaintPropertyTreeBuilderContext& context) | 238 static PassRefPtr<TransformPaintPropertyNode> createScrollbarPaintOffsetIfNeeded (const LayoutObject& object, PaintPropertyTreeBuilderContext& context) |
| 219 { | 239 { |
| 220 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); | 240 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); |
| 221 if (roundedPaintOffset == IntPoint()) | 241 if (roundedPaintOffset == IntPoint()) |
| 222 return nullptr; | 242 return nullptr; |
| 223 | 243 |
| 224 if (!object.isBoxModelObject()) | 244 if (!object.isBoxModelObject()) |
| 225 return nullptr; | 245 return nullptr; |
| 226 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge tScrollableArea(); | 246 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge tScrollableArea(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 if (scrollOffset.isZero() && !layer->scrollsOverflow()) | 322 if (scrollOffset.isZero() && !layer->scrollsOverflow()) |
| 303 return nullptr; | 323 return nullptr; |
| 304 | 324 |
| 305 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( | 325 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( |
| 306 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), | 326 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), |
| 307 FloatPoint3D(), context.currentTransform); | 327 FloatPoint3D(), context.currentTransform); |
| 308 context.currentTransform = newTransformNodeForScrollTranslation.get(); | 328 context.currentTransform = newTransformNodeForScrollTranslation.get(); |
| 309 return newTransformNodeForScrollTranslation.release(); | 329 return newTransformNodeForScrollTranslation.release(); |
| 310 } | 330 } |
| 311 | 331 |
| 312 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree BuilderContext& context) | 332 static void updateOutOfFlowContext(RefPtr<ClipPaintPropertyNode>& newClipNodeFor CSSClipFixedPosition, const LayoutObject& object, PaintPropertyTreeBuilderContex t& context, ClipPaintPropertyNode* newClipNodeForCSSClip) |
|
jbroman
2016/03/23 17:16:51
This argument order is very surprising to me. Norm
trchen
2016/03/24 00:53:58
Done.
I learned Intel syntax when I was young and
| |
| 313 { | 333 { |
| 314 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the currentTransform is | 334 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the currentTransform is |
| 315 // up-to-date for all children of the svg root element. Additionally, inside SVG, all positioning | 335 // up-to-date for all children of the svg root element. Additionally, inside SVG, all positioning |
| 316 // uses transforms. Therefore, we only need to check createdNewTransform and isSVGRoot() to | 336 // uses transforms. Therefore, we only need to check createdNewTransform and isSVGRoot() to |
| 317 // ensure out-of-flow and fixed positioning is correct at the svg->html boun dary. | 337 // ensure out-of-flow and fixed positioning is correct at the svg->html boun dary. |
| 318 | 338 |
| 319 if (object.canContainAbsolutePositionObjects()) { | 339 if (object.canContainAbsolutePositionObjects()) { |
| 320 context.transformForAbsolutePosition = context.currentTransform; | 340 context.transformForAbsolutePosition = context.currentTransform; |
| 321 context.paintOffsetForAbsolutePosition = context.paintOffset; | 341 context.paintOffsetForAbsolutePosition = context.paintOffset; |
| 322 context.clipForAbsolutePosition = context.currentClip; | 342 context.clipForAbsolutePosition = context.currentClip; |
| 323 } | 343 } |
| 324 | 344 |
| 325 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram eView | 345 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram eView |
| 326 // paint properties for rootLayerScrolls. | 346 // paint properties for rootLayerScrolls. |
| 327 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { | 347 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { |
| 328 context.transformForFixedPosition = context.currentTransform; | 348 context.transformForFixedPosition = context.currentTransform; |
| 329 context.paintOffsetForFixedPosition = context.paintOffset; | 349 context.paintOffsetForFixedPosition = context.paintOffset; |
| 330 context.clipForFixedPosition = context.currentClip; | 350 context.clipForFixedPosition = context.currentClip; |
| 351 } else if (newClipNodeForCSSClip) { | |
| 352 // CSS clip applies to all descendants, even if this object is not a con taining block | |
| 353 // ancestor of the descendant. It is okay for absolute-position descenda nts because | |
| 354 // having CSS clip implies being absolute position container. However fo r fixed-position | |
| 355 // descendants we need to insert the clip here if we are not a containin g block ancestor | |
| 356 // of them. | |
| 357 | |
| 358 // Before we actually create anything, check whether in-flow context and fixed-position | |
| 359 // context has exactly the same clip. Reuse if possible. | |
| 360 if (context.clipForFixedPosition == newClipNodeForCSSClip->parent()) { | |
| 361 context.clipForFixedPosition = newClipNodeForCSSClip; | |
| 362 return; | |
| 363 } | |
| 364 | |
| 365 newClipNodeForCSSClipFixedPosition = ClipPaintPropertyNode::create( | |
| 366 const_cast<TransformPaintPropertyNode*>(newClipNodeForCSSClip->local TransformSpace()), | |
|
jbroman
2016/03/23 17:16:51
const_cast makes me sad. I suspect one of these th
trchen
2016/03/24 00:53:58
I don't know... We need it non-const only for refe
jbroman
2016/03/24 01:03:39
Oh, weird. Both Chromium's and Skia's have it as m
| |
| 367 newClipNodeForCSSClip->clipRect(), | |
| 368 context.clipForFixedPosition); | |
| 369 context.clipForFixedPosition = newClipNodeForCSSClipFixedPosition.get(); | |
| 331 } | 370 } |
| 332 } | 371 } |
| 333 | 372 |
| 334 static PassOwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordTreeCon textIfNeeded(LayoutObject& object, const PaintPropertyTreeBuilderContext& contex t) | 373 static PassOwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordTreeCon textIfNeeded(LayoutObject& object, const PaintPropertyTreeBuilderContext& contex t) |
| 335 { | 374 { |
| 336 // Note: Currently only layer painter makes use of the pre-computed context. | 375 // Note: Currently only layer painter makes use of the pre-computed context. |
| 337 // This condition may be loosened with no adverse effects beside memory use. | 376 // This condition may be loosened with no adverse effects beside memory use. |
| 338 if (!object.hasLayer()) | 377 if (!object.hasLayer()) |
| 339 return nullptr; | 378 return nullptr; |
| 340 | 379 |
| 341 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordedContext = ad optPtr(new ObjectPaintProperties::LocalBorderBoxProperties); | 380 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordedContext = ad optPtr(new ObjectPaintProperties::LocalBorderBoxProperties); |
| 342 recordedContext->paintOffset = context.paintOffset; | 381 recordedContext->paintOffset = context.paintOffset; |
| 343 recordedContext->transform = context.currentTransform; | 382 recordedContext->transform = context.currentTransform; |
| 344 recordedContext->clip = context.currentClip; | 383 recordedContext->clip = context.currentClip; |
| 345 recordedContext->effect = context.currentEffect; | 384 recordedContext->effect = context.currentEffect; |
| 346 return recordedContext.release(); | 385 return recordedContext.release(); |
| 347 } | 386 } |
| 348 | 387 |
| 349 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre eBuilderContext& context) | 388 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre eBuilderContext& context) |
| 350 { | 389 { |
| 351 PaintPropertyTreeBuilderContext localContext(context); | 390 PaintPropertyTreeBuilderContext localContext(context); |
| 352 | 391 |
| 353 deriveBorderBoxFromContainerContext(object, localContext); | 392 deriveBorderBoxFromContainerContext(object, localContext); |
| 354 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); | 393 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); |
| 355 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); | 394 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); |
| 356 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); | 395 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); |
| 396 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = createCSSClipIfNeeded( object, localContext); | |
| 357 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext = recordTreeContextIfNeeded(object, localContext); | 397 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext = recordTreeContextIfNeeded(object, localContext); |
| 358 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset = createScrollbarPaintOffsetIfNeeded(object, localContext); | 398 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset = createScrollbarPaintOffsetIfNeeded(object, localContext); |
| 359 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli pIfNeeded(object, localContext); | 399 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli pIfNeeded(object, localContext); |
| 360 // TODO(trchen): Insert flattening transform here, as specified by | 400 // TODO(trchen): Insert flattening transform here, as specified by |
| 361 // http://www.w3.org/TR/css3-transforms/#transform-style-property | 401 // http://www.w3.org/TR/css3-transforms/#transform-style-property |
| 362 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); | 402 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); |
| 363 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); | 403 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); |
| 364 updateOutOfFlowContext(object, localContext); | 404 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClipFixedPosition; |
| 405 updateOutOfFlowContext(newClipNodeForCSSClipFixedPosition, object, localCont ext, newClipNodeForCSSClip.get()); | |
| 365 | 406 |
| 366 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newClipNodeForOverflowClip || newTransformNodeForPerspecti ve || newTransformNodeForScrollTranslation || newTransformNodeForScrollbarPaintO ffset || newRecordedContext) { | 407 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newClipNodeForCSSClip || newClipNodeForCSSClipFixedPositio n || newClipNodeForOverflowClip || newTransformNodeForPerspective || newTransfor mNodeForScrollTranslation || newTransformNodeForScrollbarPaintOffset || newRecor dedContext) { |
| 367 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( | 408 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( |
| 368 newTransformNodeForPaintOffsetTranslation.release(), | 409 newTransformNodeForPaintOffsetTranslation.release(), |
| 369 newTransformNodeForTransform.release(), | 410 newTransformNodeForTransform.release(), |
| 370 newEffectNode.release(), | 411 newEffectNode.release(), |
| 412 newClipNodeForCSSClip.release(), | |
| 413 newClipNodeForCSSClipFixedPosition.release(), | |
| 371 newClipNodeForOverflowClip.release(), | 414 newClipNodeForOverflowClip.release(), |
| 372 newTransformNodeForPerspective.release(), | 415 newTransformNodeForPerspective.release(), |
| 373 newTransformNodeForScrollTranslation.release(), | 416 newTransformNodeForScrollTranslation.release(), |
| 374 newTransformNodeForScrollbarPaintOffset.release(), | 417 newTransformNodeForScrollbarPaintOffset.release(), |
| 375 newRecordedContext.release()); | 418 newRecordedContext.release()); |
| 376 object.setObjectPaintProperties(updatedPaintProperties.release()); | 419 object.setObjectPaintProperties(updatedPaintProperties.release()); |
| 377 } else { | 420 } else { |
| 378 object.clearObjectPaintProperties(); | 421 object.clearObjectPaintProperties(); |
| 379 } | 422 } |
| 380 | 423 |
| 381 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { | 424 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { |
| 382 if (child->isBoxModelObject() || child->isSVG()) | 425 if (child->isBoxModelObject() || child->isSVG()) |
| 383 walk(*child, localContext); | 426 walk(*child, localContext); |
| 384 } | 427 } |
| 385 | 428 |
| 386 if (object.isLayoutPart()) { | 429 if (object.isLayoutPart()) { |
| 387 Widget* widget = toLayoutPart(object).widget(); | 430 Widget* widget = toLayoutPart(object).widget(); |
| 388 if (widget && widget->isFrameView()) | 431 if (widget && widget->isFrameView()) |
| 389 walk(*toFrameView(widget), localContext); | 432 walk(*toFrameView(widget), localContext); |
| 390 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | 433 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
| 391 } | 434 } |
| 392 } | 435 } |
| 393 | 436 |
| 394 } // namespace blink | 437 } // namespace blink |
| OLD | NEW |