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 20 matching lines...) Expand all Loading... | |
| 31 ClipPaintPropertyNode* rootClipNode() { | 31 ClipPaintPropertyNode* rootClipNode() { |
| 32 DEFINE_STATIC_REF(ClipPaintPropertyNode, rootClip, | 32 DEFINE_STATIC_REF(ClipPaintPropertyNode, rootClip, |
| 33 (ClipPaintPropertyNode::create( | 33 (ClipPaintPropertyNode::create( |
| 34 nullptr, rootTransformNode(), | 34 nullptr, rootTransformNode(), |
| 35 FloatRoundedRect(LayoutRect::infiniteIntRect())))); | 35 FloatRoundedRect(LayoutRect::infiniteIntRect())))); |
| 36 return rootClip; | 36 return rootClip; |
| 37 } | 37 } |
| 38 | 38 |
| 39 EffectPaintPropertyNode* rootEffectNode() { | 39 EffectPaintPropertyNode* rootEffectNode() { |
| 40 DEFINE_STATIC_REF(EffectPaintPropertyNode, rootEffect, | 40 DEFINE_STATIC_REF(EffectPaintPropertyNode, rootEffect, |
| 41 (EffectPaintPropertyNode::create(nullptr, 1.0))); | 41 (EffectPaintPropertyNode::create( |
| 42 nullptr, rootTransformNode(), rootClipNode(), | |
| 43 CompositorFilterOperations(), 1.0))); | |
| 42 return rootEffect; | 44 return rootEffect; |
| 43 } | 45 } |
| 44 | 46 |
| 45 ScrollPaintPropertyNode* rootScrollNode() { | 47 ScrollPaintPropertyNode* rootScrollNode() { |
| 46 DEFINE_STATIC_REF( | 48 DEFINE_STATIC_REF( |
| 47 ScrollPaintPropertyNode, rootScroll, | 49 ScrollPaintPropertyNode, rootScroll, |
| 48 (ScrollPaintPropertyNode::create(nullptr, rootTransformNode(), IntSize(), | 50 (ScrollPaintPropertyNode::create(nullptr, rootTransformNode(), IntSize(), |
| 49 IntSize(), false, false))); | 51 IntSize(), false, false))); |
| 50 return rootScroll; | 52 return rootScroll; |
| 51 } | 53 } |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 } | 342 } |
| 341 | 343 |
| 342 if (ObjectPaintProperties* properties = | 344 if (ObjectPaintProperties* properties = |
| 343 object.getMutableForPainting().objectPaintProperties()) | 345 object.getMutableForPainting().objectPaintProperties()) |
| 344 properties->clearTransform(); | 346 properties->clearTransform(); |
| 345 } | 347 } |
| 346 | 348 |
| 347 void PaintPropertyTreeBuilder::updateEffect( | 349 void PaintPropertyTreeBuilder::updateEffect( |
| 348 const LayoutObject& object, | 350 const LayoutObject& object, |
| 349 PaintPropertyTreeBuilderContext& context) { | 351 PaintPropertyTreeBuilderContext& context) { |
| 350 if (!object.styleRef().hasOpacity()) { | 352 const ComputedStyle& style = object.styleRef(); |
| 353 | |
| 354 if (!style.isStackingContext()) { | |
|
pdr.
2016/10/22 03:58:37
Is this needed? It seems to include hasOpacity() a
trchen
2016/10/24 21:53:20
I've thought about whether to make it a DCHECK or
| |
| 351 if (ObjectPaintProperties* properties = | 355 if (ObjectPaintProperties* properties = |
| 352 object.getMutableForPainting().objectPaintProperties()) | 356 object.getMutableForPainting().objectPaintProperties()) |
| 353 properties->clearEffect(); | 357 properties->clearEffect(); |
| 358 return; | |
| 359 } | |
| 360 | |
| 361 // TODO(trchen): Can't omit effect node if we have 3D children. | |
| 362 // TODO(trchen): Can't omit effect node if we have blending children. | |
| 363 bool effectNodeNeeded = false; | |
| 364 | |
| 365 float opacity = style.opacity(); | |
| 366 if (opacity != 1.0f) | |
| 367 effectNodeNeeded = true; | |
| 368 | |
| 369 CompositorFilterOperations filter; | |
|
pdr.
2016/10/22 03:58:37
Could the following avoid the duplicated clearing
trchen
2016/10/24 21:53:20
I'm thinking something like this:
bool PPTB::find
| |
| 370 if (object.isSVG() && !object.isSVGRoot()) { | |
| 371 // TODO(trchen): SVG caches filters in SVGResources. Implement it. | |
| 372 } else { | |
| 373 // TODO(trchen): Eliminate PaintLayer dependency. | |
| 374 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | |
| 375 DCHECK(layer); | |
| 376 filter = layer->createCompositorFilterOperationsForFilter(style); | |
| 377 if (!filter.isEmpty()) | |
| 378 effectNodeNeeded = true; | |
| 379 } | |
| 380 | |
| 381 const ClipPaintPropertyNode* outputClip = rootClipNode(); | |
| 382 // The CSS filter spec didn't specify how filters interact with overflow | |
| 383 // clips. The implementation here mimics the old Blink/WebKit behavior for | |
| 384 // backward compatibility. | |
| 385 // Basically the output of the filter will be affected by clips that applies | |
| 386 // to the current element. The descendants that paints into the input of the | |
| 387 // filter ignores any clips collected so far. For example: | |
| 388 // <div style="overflow:scroll"> | |
| 389 // <div style="filter:blur(1px);"> | |
| 390 // <div>A</div> | |
| 391 // <div style="position:absolute;">B</div> | |
| 392 // </div> | |
| 393 // </div> | |
| 394 // In this example "A" should be clipped if the filter was not present. | |
| 395 // With the filter, "A" will be rastered without clipping, but instead | |
| 396 // the blurred result will be clipped. | |
| 397 // On the other hand, "B" should not be clipped because the overflow clip is | |
| 398 // not in its containing block chain, but as the filter output will be | |
| 399 // clipped, so a blurred "B" may still be invisible. | |
| 400 if (!filter.isEmpty()) { | |
| 401 outputClip = context.current.clip; | |
| 402 | |
| 403 // TODO(trchen): A filter may contain spatial operations such that an output | |
| 404 // pixel may depend on an input pixel outside of the output clip. Need to | |
| 405 // generate special clip node to hint how to expand clip / cull rect. | |
| 406 const ClipPaintPropertyNode* expansionHint = context.current.clip; | |
| 407 context.current.clip = context.absolutePosition.clip = | |
| 408 context.fixedPosition.clip = expansionHint; | |
| 409 } | |
| 410 | |
| 411 if (!effectNodeNeeded) { | |
| 412 if (ObjectPaintProperties* properties = | |
| 413 object.getMutableForPainting().objectPaintProperties()) | |
| 414 properties->clearEffect(); | |
| 354 return; | 415 return; |
| 355 } | 416 } |
| 356 | 417 |
| 357 context.currentEffect = | 418 context.currentEffect = |
| 358 object.getMutableForPainting() | 419 object.getMutableForPainting() |
| 359 .ensureObjectPaintProperties() | 420 .ensureObjectPaintProperties() |
| 360 .createOrUpdateEffect(context.currentEffect, | 421 .createOrUpdateEffect(context.currentEffect, |
| 361 object.styleRef().opacity()); | 422 context.current.transform, outputClip, |
| 423 std::move(filter), object.styleRef().opacity()); | |
| 362 } | 424 } |
| 363 | 425 |
| 364 void PaintPropertyTreeBuilder::updateCssClip( | 426 void PaintPropertyTreeBuilder::updateCssClip( |
| 365 const LayoutObject& object, | 427 const LayoutObject& object, |
| 366 PaintPropertyTreeBuilderContext& context) { | 428 PaintPropertyTreeBuilderContext& context) { |
| 367 if (object.hasClip()) { | 429 if (object.hasClip()) { |
| 368 // Create clip node for descendants that are not fixed position. | 430 // Create clip node for descendants that are not fixed position. |
| 369 // We don't have to setup context.absolutePosition.clip here because this | 431 // We don't have to setup context.absolutePosition.clip here because this |
| 370 // object must be a container for absolute position descendants, and will | 432 // object must be a container for absolute position descendants, and will |
| 371 // copy from in-flow context later at updateOutOfFlowContext() step. | 433 // copy from in-flow context later at updateOutOfFlowContext() step. |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 return; | 874 return; |
| 813 | 875 |
| 814 updateOverflowClip(object, context); | 876 updateOverflowClip(object, context); |
| 815 updatePerspective(object, context); | 877 updatePerspective(object, context); |
| 816 updateSvgLocalToBorderBoxTransform(object, context); | 878 updateSvgLocalToBorderBoxTransform(object, context); |
| 817 updateScrollAndScrollTranslation(object, context); | 879 updateScrollAndScrollTranslation(object, context); |
| 818 updateOutOfFlowContext(object, context); | 880 updateOutOfFlowContext(object, context); |
| 819 } | 881 } |
| 820 | 882 |
| 821 } // namespace blink | 883 } // namespace blink |
| OLD | NEW |