Commit 0dc62d25 authored by fs's avatar fs Committed by Commit bot

Let clients of FilterEffectBuilder compute/provide the reference-box

Rather than having code to compute the reference box for the various
clients that use FilterEffectBuilder in the class itself, let clients
compute the desired reference box themselves and pass it along.
This separates concerns, and makes code for computing the reference box
less defensive. It also eliminates the need to add even more cases in
the future (like for SVG shorthand support.)

Also push calls to resolveReferenceFilters() in PaintLayer closer to the
filter-building calls, and rename computeFilterOperations to
addReflectionToFilterOperations. This allows us to eliminate a redundant
call to resolveReferenceFilters() in the mapRectForFilter() code-path.

BUG=439970
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2

Review-Url: https://codereview.chromium.org/2343173002
Cr-Commit-Position: refs/heads/master@{#419290}
parent 60196b08
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "core/paint/FilterEffectBuilder.h" #include "core/paint/FilterEffectBuilder.h"
#include "core/layout/svg/ReferenceFilterBuilder.h" #include "core/layout/svg/ReferenceFilterBuilder.h"
#include "core/paint/PaintLayer.h"
#include "core/svg/SVGFilterElement.h" #include "core/svg/SVGFilterElement.h"
#include "core/svg/SVGLengthContext.h" #include "core/svg/SVGLengthContext.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h" #include "core/svg/graphics/filters/SVGFilterBuilder.h"
...@@ -119,18 +118,6 @@ Vector<float> sepiaMatrix(double amount) ...@@ -119,18 +118,6 @@ Vector<float> sepiaMatrix(double amount)
return matrix; return matrix;
} }
FloatRect computeReferenceBox(const Element& element, const FloatSize* zoomedReferenceBoxSize, float zoom)
{
FloatRect box;
if (zoomedReferenceBoxSize) {
box = FloatRect(FloatPoint(), *zoomedReferenceBoxSize);
} else if (element.isConnected() && element.layoutObject() && element.layoutObject()->enclosingLayer()) {
box = FloatRect(element.layoutObject()->enclosingLayer()->physicalBoundingBoxIncludingReflectionAndStackingChildren(LayoutPoint(), PaintLayer::CalculateBoundsOptions::IncludeTransformsAndCompositedChildLayers));
}
box.scale(1.0f / zoom);
return box;
}
} // namespace } // namespace
FilterEffectBuilder::FilterEffectBuilder() FilterEffectBuilder::FilterEffectBuilder()
...@@ -146,7 +133,7 @@ DEFINE_TRACE(FilterEffectBuilder) ...@@ -146,7 +133,7 @@ DEFINE_TRACE(FilterEffectBuilder)
visitor->trace(m_lastEffect); visitor->trace(m_lastEffect);
} }
bool FilterEffectBuilder::build(Element* element, const FilterOperations& operations, float zoom, const FloatSize* zoomedReferenceBoxSize, const SkPaint* fillPaint, const SkPaint* strokePaint) bool FilterEffectBuilder::build(Element* element, const FilterOperations& operations, float zoom, const FloatRect& zoomedReferenceBox, const SkPaint* fillPaint, const SkPaint* strokePaint)
{ {
// Create a parent filter for shorthand filters. These have already been scaled by the CSS code for page zoom, so scale is 1.0 here. // Create a parent filter for shorthand filters. These have already been scaled by the CSS code for page zoom, so scale is 1.0 here.
Filter* parentFilter = Filter::create(1.0f); Filter* parentFilter = Filter::create(1.0f);
...@@ -156,7 +143,7 @@ bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat ...@@ -156,7 +143,7 @@ bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat
FilterOperation* filterOperation = operations.operations().at(i).get(); FilterOperation* filterOperation = operations.operations().at(i).get();
switch (filterOperation->type()) { switch (filterOperation->type()) {
case FilterOperation::REFERENCE: { case FilterOperation::REFERENCE: {
Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOperation(*filterOperation), zoomedReferenceBoxSize, fillPaint, strokePaint, *element, previousEffect, zoom); Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOperation(*filterOperation), zoomedReferenceBox, fillPaint, strokePaint, *element, previousEffect, zoom);
if (referenceFilter) if (referenceFilter)
effect = referenceFilter->lastEffect(); effect = referenceFilter->lastEffect();
break; break;
...@@ -277,7 +264,7 @@ bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat ...@@ -277,7 +264,7 @@ bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat
Filter* FilterEffectBuilder::buildReferenceFilter( Filter* FilterEffectBuilder::buildReferenceFilter(
const ReferenceFilterOperation& referenceOperation, const ReferenceFilterOperation& referenceOperation,
const FloatSize* zoomedReferenceBoxSize, const FloatRect& zoomedReferenceBox,
const SkPaint* fillPaint, const SkPaint* fillPaint,
const SkPaint* strokePaint, const SkPaint* strokePaint,
Element& element, Element& element,
...@@ -287,8 +274,8 @@ Filter* FilterEffectBuilder::buildReferenceFilter( ...@@ -287,8 +274,8 @@ Filter* FilterEffectBuilder::buildReferenceFilter(
SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterReference(referenceOperation, element); SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterReference(referenceOperation, element);
if (!filterElement) if (!filterElement)
return nullptr; return nullptr;
FloatRect referenceBox = zoomedReferenceBox;
const FloatRect referenceBox = computeReferenceBox(element, zoomedReferenceBoxSize, zoom); referenceBox.scale(1.0f / zoom);
return buildReferenceFilter(*filterElement, referenceBox, fillPaint, strokePaint, previousEffect, zoom); return buildReferenceFilter(*filterElement, referenceBox, fillPaint, strokePaint, previousEffect, zoom);
} }
......
...@@ -50,10 +50,10 @@ public: ...@@ -50,10 +50,10 @@ public:
virtual ~FilterEffectBuilder(); virtual ~FilterEffectBuilder();
DECLARE_TRACE(); DECLARE_TRACE();
static Filter* buildReferenceFilter(const ReferenceFilterOperation&, const FloatSize* zoomedReferenceBoxSize, const SkPaint* fillPaint, const SkPaint* strokePaint, Element&, FilterEffect* previousEffect, float zoom); static Filter* buildReferenceFilter(const ReferenceFilterOperation&, const FloatRect& zoomedReferenceBox, const SkPaint* fillPaint, const SkPaint* strokePaint, Element&, FilterEffect* previousEffect, float zoom);
static Filter* buildReferenceFilter(SVGFilterElement&, const FloatRect& referenceBox, const SkPaint* fillPaint, const SkPaint* strokePaint, FilterEffect* previousEffect, float zoom, SVGFilterGraphNodeMap* = nullptr); static Filter* buildReferenceFilter(SVGFilterElement&, const FloatRect& referenceBox, const SkPaint* fillPaint, const SkPaint* strokePaint, FilterEffect* previousEffect, float zoom, SVGFilterGraphNodeMap* = nullptr);
bool build(Element*, const FilterOperations&, float zoom, const FloatSize* zoomedReferenceBoxSize = nullptr, const SkPaint* fillPaint = nullptr, const SkPaint* strokePaint = nullptr); bool build(Element*, const FilterOperations&, float zoom, const FloatRect& zoomedReferenceBox, const SkPaint* fillPaint = nullptr, const SkPaint* strokePaint = nullptr);
FilterEffect* lastEffect() const FilterEffect* lastEffect() const
{ {
......
...@@ -2074,6 +2074,12 @@ PaintLayer* PaintLayer::hitTestChildren(ChildrenIteration childrentoVisit, Paint ...@@ -2074,6 +2074,12 @@ PaintLayer* PaintLayer::hitTestChildren(ChildrenIteration childrentoVisit, Paint
return resultLayer; return resultLayer;
} }
FloatRect PaintLayer::boxForFilter() const
{
return FloatRect(physicalBoundingBoxIncludingReflectionAndStackingChildren(
LayoutPoint(), PaintLayer::CalculateBoundsOptions::IncludeTransformsAndCompositedChildLayers));
}
LayoutRect PaintLayer::boxForClipPath() const LayoutRect PaintLayer::boxForClipPath() const
{ {
if (!layoutObject()->isBox()) { if (!layoutObject()->isBox()) {
...@@ -2685,42 +2691,47 @@ bool PaintLayer::scrollsOverflow() const ...@@ -2685,42 +2691,47 @@ bool PaintLayer::scrollsOverflow() const
namespace { namespace {
FilterOperations resolveReferenceFilters(const FilterOperations& filters, float effectiveZoom, Node* enclosingNode) FilterOperations resolveReferenceFilters(
{ const FilterOperations& filters, float effectiveZoom, Element& element, const FloatRect& zoomedReferenceBox)
if (filters.hasReferenceFilter()) { {
for (size_t i = 0; i < filters.size(); ++i) { DCHECK(filters.hasReferenceFilter());
FilterOperation* filterOperation = filters.operations().at(i).get();
if (filterOperation->type() != FilterOperation::REFERENCE) for (FilterOperation* filterOperation : filters.operations()) {
continue; if (filterOperation->type() != FilterOperation::REFERENCE)
ReferenceFilterOperation& referenceOperation = toReferenceFilterOperation(*filterOperation); continue;
// FIXME: Cache the Filter if it didn't change. ReferenceFilterOperation& referenceOperation = toReferenceFilterOperation(*filterOperation);
Filter* referenceFilter = FilterEffectBuilder::buildReferenceFilter(referenceOperation, nullptr, nullptr, nullptr, *toElement(enclosingNode), nullptr, effectiveZoom); // TODO(fs): Cache the Filter if it didn't change.
referenceOperation.setFilter(referenceFilter); Filter* referenceFilter = FilterEffectBuilder::buildReferenceFilter(referenceOperation, zoomedReferenceBox, nullptr, nullptr, element, nullptr, effectiveZoom);
} referenceOperation.setFilter(referenceFilter);
} }
return filters; return filters;
} }
} // unnamed namespace } // unnamed namespace
FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style) const FilterOperations PaintLayer::addReflectionToFilterOperations(const ComputedStyle& style) const
{ {
FilterOperations filterOperations = style.filter(); FilterOperations filterOperations = style.filter();
if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->hasReflection() && layoutObject()->isBox()) { if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->hasReflection() && layoutObject()->isBox()) {
BoxReflection reflection = boxReflectionForPaintLayer(*this, style); BoxReflection reflection = boxReflectionForPaintLayer(*this, style);
filterOperations.operations().append(BoxReflectFilterOperation::create(reflection)); filterOperations.operations().append(BoxReflectFilterOperation::create(reflection));
} }
return resolveReferenceFilters(filterOperations, style.effectiveZoom(), enclosingNode()); return filterOperations;
} }
CompositorFilterOperations PaintLayer::createCompositorFilterOperationsForFilter(const ComputedStyle& style) 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) 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); return SkiaImageFilterBuilder::buildFilterOperations(operations);
} }
...@@ -2780,7 +2791,14 @@ FilterEffectBuilder* PaintLayer::updateFilterEffectBuilder() const ...@@ -2780,7 +2791,14 @@ FilterEffectBuilder* PaintLayer::updateFilterEffectBuilder() const
filterInfo->setBuilder(FilterEffectBuilder::create()); filterInfo->setBuilder(FilterEffectBuilder::create());
const ComputedStyle& style = layoutObject()->styleRef(); 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); filterInfo->setBuilder(nullptr);
return filterInfo->builder(); return filterInfo->builder();
...@@ -2798,10 +2816,11 @@ FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const ...@@ -2798,10 +2816,11 @@ FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const
{ {
if (!hasFilterThatMovesPixels()) if (!hasFilterThatMovesPixels())
return rect; return rect;
// Ensure the filter-chain is refreshed wrt reference filters. // Ensure the filter-chain is refreshed wrt reference filters.
updateFilterEffectBuilder(); updateFilterEffectBuilder();
FilterOperations filterOperations = computeFilterOperations(layoutObject()->styleRef()); FilterOperations filterOperations = addReflectionToFilterOperations(layoutObject()->styleRef());
return filterOperations.mapRect(rect); return filterOperations.mapRect(rect);
} }
......
...@@ -373,6 +373,7 @@ public: ...@@ -373,6 +373,7 @@ public:
LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const LayoutPoint& offsetFromRoot, CalculateBoundsOptions = MaybeIncludeTransformForAncestorLayer) const; LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const LayoutPoint& offsetFromRoot, CalculateBoundsOptions = MaybeIncludeTransformForAncestorLayer) const;
LayoutRect fragmentsBoundingBox(const PaintLayer* ancestorLayer) const; LayoutRect fragmentsBoundingBox(const PaintLayer* ancestorLayer) const;
FloatRect boxForFilter() const;
LayoutRect boxForClipPath() const; LayoutRect boxForClipPath() const;
LayoutRect boundingBoxForCompositingOverlapTest() const; LayoutRect boundingBoxForCompositingOverlapTest() const;
...@@ -788,7 +789,7 @@ private: ...@@ -788,7 +789,7 @@ private:
bool requiresStackingNode() const { return true; } bool requiresStackingNode() const { return true; }
void updateStackingNode(); void updateStackingNode();
FilterOperations computeFilterOperations(const ComputedStyle&) const; FilterOperations addReflectionToFilterOperations(const ComputedStyle&) const;
void updateReflectionInfo(const ComputedStyle*); void updateReflectionInfo(const ComputedStyle*);
FilterEffectBuilder* updateFilterEffectBuilder() const; FilterEffectBuilder* updateFilterEffectBuilder() const;
......
...@@ -318,9 +318,9 @@ SkImageFilter* CanvasRenderingContext2DState::getFilter(Element* styleResolution ...@@ -318,9 +318,9 @@ SkImageFilter* CanvasRenderingContext2DState::getFilter(Element* styleResolution
m_strokeStyle->applyToPaint(strokePaintForFilter); m_strokeStyle->applyToPaint(strokePaintForFilter);
fillPaintForFilter.setColor(m_fillStyle->paintColor()); fillPaintForFilter.setColor(m_fillStyle->paintColor());
strokePaintForFilter.setColor(m_strokeStyle->paintColor()); strokePaintForFilter.setColor(m_strokeStyle->paintColor());
FloatSize floatCanvasSize(canvasSize); FloatRect referenceBox((FloatPoint()), FloatSize(canvasSize));
const double effectiveZoom = 1.0; // Deliberately ignore zoom on the canvas element const double effectiveZoom = 1.0; // Deliberately ignore zoom on the canvas element
filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), effectiveZoom, &floatCanvasSize, &fillPaintForFilter, &strokePaintForFilter); filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), effectiveZoom, referenceBox, &fillPaintForFilter, &strokePaintForFilter);
if (FilterEffect* lastEffect = filterEffectBuilder->lastEffect()) { if (FilterEffect* lastEffect = filterEffectBuilder->lastEffect()) {
m_resolvedFilter = SkiaImageFilterBuilder::build(lastEffect, ColorSpaceDeviceRGB); m_resolvedFilter = SkiaImageFilterBuilder::build(lastEffect, ColorSpaceDeviceRGB);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment