Chromium Code Reviews| Index: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| index 0562e435d4508f7484a7187c7de6c0e47041ef81..8bd507b7882f330245444c49d263e18b9062a639 100644 |
| --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| @@ -38,7 +38,7 @@ ClipPaintPropertyNode* rootClipNode() { |
| EffectPaintPropertyNode* rootEffectNode() { |
| DEFINE_STATIC_REF(EffectPaintPropertyNode, rootEffect, |
| - (EffectPaintPropertyNode::create(nullptr, 1.0))); |
| + (EffectPaintPropertyNode::create(nullptr, rootTransformNode(), rootClipNode(), 1.0, CompositorFilterOperations()))); |
| return rootEffect; |
| } |
| @@ -347,7 +347,56 @@ void PaintPropertyTreeBuilder::updateTransform( |
| void PaintPropertyTreeBuilder::updateEffect( |
| const LayoutObject& object, |
| PaintPropertyTreeBuilderContext& context) { |
| - if (!object.styleRef().hasOpacity()) { |
| + const ComputedStyle& style = object.styleRef(); |
| + |
| + if (!style.isStackingContext()) { |
| + if (ObjectPaintProperties* properties = |
| + object.getMutableForPainting().objectPaintProperties()) |
| + properties->clearEffect(); |
| + return; |
| + } |
| + |
| + // TODO(trchen): Can't omit effect node if we have 3D children. |
| + // TODO(trchen): Can't omit effect node if we have blending children. |
| + bool effectNodeNeeded = false; |
| + |
| + float opacity = style.opacity(); |
| + if (opacity != 1.0f) |
| + effectNodeNeeded = true; |
| + |
| + // TODO(trchen): Eliminate PaintLayer dependency. |
| + PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| + DCHECK(layer); |
| + CompositorFilterOperations filter = layer->createCompositorFilterOperationsForFilter(style); |
| + if (!filter.isEmpty()) |
| + effectNodeNeeded = true; |
| + |
| + const ClipPaintPropertyNode* outputClip = rootClipNode(); |
| + // The CSS filter spec didn't specify how filters interact with overflow |
| + // clips. The implementation here mimics the old Blink/WebKit behavior for |
| + // backward compatibility. |
| + // Basically the output of the filter will be affected by clips that applies |
| + // to the current element. The descendants that paints into the input of the |
| + // filter ignores any clips collected so far. For example: |
| + // <div style="overflow:scroll"> |
| + // <div style="filter:blur(1px);"> |
| + // <div>A</div> |
| + // <div style="position:absolute;">B</div> |
| + // </div> |
| + // </div> |
| + // In this example "A" should be clipped if the filter did not present. |
|
pdr.
2016/10/19 17:44:43
Nit: did not -> is not
trchen
2016/10/21 23:26:39
Done.
|
| + // With the filter, "A" will be rastered without clipping, but instead |
| + // the blurred result will be clipped. |
| + // On the other hand, "B" should not be clipped because the overflow clip is |
| + // not in its containing block chain, but as the filter output will be |
| + // clipped, so a blurred "B" may still be invisible. |
|
pdr.
2016/10/19 17:44:43
This description is good and helped me understand
|
| + if (!filter.isEmpty()) { |
| + outputClip = context.current.clip; |
| + context.current.clip = context.absolutePosition.clip = |
| + context.fixedPosition.clip = rootClipNode(); |
| + } |
| + |
| + if (!effectNodeNeeded) { |
| if (ObjectPaintProperties* properties = |
| object.getMutableForPainting().objectPaintProperties()) |
| properties->clearEffect(); |
| @@ -358,7 +407,10 @@ void PaintPropertyTreeBuilder::updateEffect( |
| object.getMutableForPainting() |
| .ensureObjectPaintProperties() |
| .createOrUpdateEffect(context.currentEffect, |
| - object.styleRef().opacity()); |
| + context.current.transform, |
| + outputClip, |
| + object.styleRef().opacity(), |
| + std::move(filter)); |
| } |
| void PaintPropertyTreeBuilder::updateCssClip( |