Index: third_party/WebKit/Source/core/paint/PaintLayer.cpp |
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp |
index 1472bd7a0c9add71dfc51db858bf1b6dae99dbb3..6a167f1f4fa678277aee1676f4ff605bf8e34abe 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp |
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp |
@@ -2074,6 +2074,12 @@ PaintLayer* PaintLayer::hitTestChildren(ChildrenIteration childrentoVisit, Paint |
return resultLayer; |
} |
+FloatRect PaintLayer::boxForFilter() const |
+{ |
+ return FloatRect(physicalBoundingBoxIncludingReflectionAndStackingChildren( |
+ LayoutPoint(), PaintLayer::CalculateBoundsOptions::IncludeTransformsAndCompositedChildLayers)); |
+} |
+ |
LayoutRect PaintLayer::boxForClipPath() const |
{ |
if (!layoutObject()->isBox()) { |
@@ -2685,42 +2691,47 @@ bool PaintLayer::scrollsOverflow() const |
namespace { |
-FilterOperations resolveReferenceFilters(const FilterOperations& filters, float effectiveZoom, Node* enclosingNode) |
-{ |
- if (filters.hasReferenceFilter()) { |
- for (size_t i = 0; i < filters.size(); ++i) { |
- FilterOperation* filterOperation = filters.operations().at(i).get(); |
- if (filterOperation->type() != FilterOperation::REFERENCE) |
- continue; |
- ReferenceFilterOperation& referenceOperation = toReferenceFilterOperation(*filterOperation); |
- // FIXME: Cache the Filter if it didn't change. |
- Filter* referenceFilter = FilterEffectBuilder::buildReferenceFilter(referenceOperation, nullptr, nullptr, nullptr, *toElement(enclosingNode), nullptr, effectiveZoom); |
- referenceOperation.setFilter(referenceFilter); |
- } |
+FilterOperations resolveReferenceFilters( |
+ const FilterOperations& filters, float effectiveZoom, Element& element, const FloatRect& zoomedReferenceBox) |
+{ |
+ DCHECK(filters.hasReferenceFilter()); |
+ |
+ for (FilterOperation* filterOperation : filters.operations()) { |
+ if (filterOperation->type() != FilterOperation::REFERENCE) |
+ continue; |
+ ReferenceFilterOperation& referenceOperation = toReferenceFilterOperation(*filterOperation); |
+ // TODO(fs): Cache the Filter if it didn't change. |
+ Filter* referenceFilter = FilterEffectBuilder::buildReferenceFilter(referenceOperation, zoomedReferenceBox, nullptr, nullptr, element, nullptr, effectiveZoom); |
+ referenceOperation.setFilter(referenceFilter); |
} |
return filters; |
} |
} // unnamed namespace |
-FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style) const |
+FilterOperations PaintLayer::addReflectionToFilterOperations(const ComputedStyle& style) const |
{ |
FilterOperations filterOperations = style.filter(); |
if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->hasReflection() && layoutObject()->isBox()) { |
BoxReflection reflection = boxReflectionForPaintLayer(*this, style); |
filterOperations.operations().append(BoxReflectFilterOperation::create(reflection)); |
} |
- return resolveReferenceFilters(filterOperations, style.effectiveZoom(), enclosingNode()); |
+ return filterOperations; |
} |
CompositorFilterOperations PaintLayer::createCompositorFilterOperationsForFilter(const ComputedStyle& style) |
{ |
- return SkiaImageFilterBuilder::buildFilterOperations(computeFilterOperations(style)); |
+ FilterOperations filterOperations = addReflectionToFilterOperations(style); |
+ if (filterOperations.hasReferenceFilter()) |
+ filterOperations = resolveReferenceFilters(filterOperations, style.effectiveZoom(), toElement(*enclosingNode()), boxForFilter()); |
+ return SkiaImageFilterBuilder::buildFilterOperations(filterOperations); |
} |
CompositorFilterOperations PaintLayer::createCompositorFilterOperationsForBackdropFilter(const ComputedStyle& style) |
{ |
- FilterOperations operations = resolveReferenceFilters(style.backdropFilter(), style.effectiveZoom(), enclosingNode()); |
+ FilterOperations operations = style.backdropFilter(); |
+ if (operations.hasReferenceFilter()) |
+ operations = resolveReferenceFilters(operations, style.effectiveZoom(), toElement(*enclosingNode()), boxForFilter()); |
return SkiaImageFilterBuilder::buildFilterOperations(operations); |
} |
@@ -2780,7 +2791,14 @@ FilterEffectBuilder* PaintLayer::updateFilterEffectBuilder() const |
filterInfo->setBuilder(FilterEffectBuilder::create()); |
const ComputedStyle& style = layoutObject()->styleRef(); |
- if (!filterInfo->builder()->build(toElement(enclosingNode()), computeFilterOperations(style), style.effectiveZoom())) |
+ Element* element = toElement(enclosingNode()); |
+ FilterOperations operations = addReflectionToFilterOperations(style); |
+ FloatRect zoomedReferenceBox; |
+ if (style.filter().hasReferenceFilter()) { |
+ zoomedReferenceBox = boxForFilter(); |
+ operations = resolveReferenceFilters(operations, style.effectiveZoom(), *element, zoomedReferenceBox); |
+ } |
+ if (!filterInfo->builder()->build(element, operations, style.effectiveZoom(), zoomedReferenceBox)) |
filterInfo->setBuilder(nullptr); |
return filterInfo->builder(); |
@@ -2798,10 +2816,11 @@ FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const |
{ |
if (!hasFilterThatMovesPixels()) |
return rect; |
+ |
// Ensure the filter-chain is refreshed wrt reference filters. |
updateFilterEffectBuilder(); |
- FilterOperations filterOperations = computeFilterOperations(layoutObject()->styleRef()); |
+ FilterOperations filterOperations = addReflectionToFilterOperations(layoutObject()->styleRef()); |
Stephen White
2016/09/16 19:14:23
Isn't this already handled by the call to updateFi
Stephen White
2016/09/16 19:16:54
Oh, I see now that the computed filter operations
fs
2016/09/16 19:20:37
It isn't handled because there (in updateFilterEff
|
return filterOperations.mapRect(rect); |
} |