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..cc0dcb715882ce200f77764b3c17f3455589d7e3 100644 |
| --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| @@ -38,7 +38,9 @@ ClipPaintPropertyNode* rootClipNode() { |
| EffectPaintPropertyNode* rootEffectNode() { |
| DEFINE_STATIC_REF(EffectPaintPropertyNode, rootEffect, |
| - (EffectPaintPropertyNode::create(nullptr, 1.0))); |
| + (EffectPaintPropertyNode::create( |
| + nullptr, rootTransformNode(), rootClipNode(), |
| + CompositorFilterOperations(), 1.0))); |
| return rootEffect; |
| } |
| @@ -347,7 +349,66 @@ void PaintPropertyTreeBuilder::updateTransform( |
| void PaintPropertyTreeBuilder::updateEffect( |
| const LayoutObject& object, |
| PaintPropertyTreeBuilderContext& context) { |
| - if (!object.styleRef().hasOpacity()) { |
| + const ComputedStyle& style = object.styleRef(); |
| + |
| + 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
|
| + 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; |
| + |
| + 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
|
| + if (object.isSVG() && !object.isSVGRoot()) { |
| + // TODO(trchen): SVG caches filters in SVGResources. Implement it. |
| + } else { |
| + // TODO(trchen): Eliminate PaintLayer dependency. |
| + PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| + DCHECK(layer); |
| + 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 was not present. |
| + // 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. |
| + if (!filter.isEmpty()) { |
| + outputClip = context.current.clip; |
| + |
| + // TODO(trchen): A filter may contain spatial operations such that an output |
| + // pixel may depend on an input pixel outside of the output clip. Need to |
| + // generate special clip node to hint how to expand clip / cull rect. |
| + const ClipPaintPropertyNode* expansionHint = context.current.clip; |
| + context.current.clip = context.absolutePosition.clip = |
| + context.fixedPosition.clip = expansionHint; |
| + } |
| + |
| + if (!effectNodeNeeded) { |
| if (ObjectPaintProperties* properties = |
| object.getMutableForPainting().objectPaintProperties()) |
| properties->clearEffect(); |
| @@ -358,7 +419,8 @@ void PaintPropertyTreeBuilder::updateEffect( |
| object.getMutableForPainting() |
| .ensureObjectPaintProperties() |
| .createOrUpdateEffect(context.currentEffect, |
| - object.styleRef().opacity()); |
| + context.current.transform, outputClip, |
| + std::move(filter), object.styleRef().opacity()); |
| } |
| void PaintPropertyTreeBuilder::updateCssClip( |