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( |