| 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 7d8cc1a7c9af5f96fc11f4fe0f6e479e44cf0e89..e89f69a809021bf015f878445a7b1595d3c7fee5 100644
 | 
| --- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
 | 
| +++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
 | 
| @@ -49,11 +49,9 @@
 | 
|  #include "core/css/PseudoStyleRequest.h"
 | 
|  #include "core/dom/Document.h"
 | 
|  #include "core/dom/shadow/ShadowRoot.h"
 | 
| -#include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
 | 
|  #include "core/frame/FrameView.h"
 | 
|  #include "core/frame/LocalFrame.h"
 | 
|  #include "core/frame/Settings.h"
 | 
| -#include "core/html/HTMLFrameElement.h"
 | 
|  #include "core/layout/FragmentainerIterator.h"
 | 
|  #include "core/layout/HitTestRequest.h"
 | 
|  #include "core/layout/HitTestResult.h"
 | 
| @@ -82,11 +80,8 @@
 | 
|  #include "platform/geometry/TransformState.h"
 | 
|  #include "platform/graphics/CompositorFilterOperations.h"
 | 
|  #include "platform/graphics/filters/Filter.h"
 | 
| -#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
 | 
|  #include "platform/tracing/TraceEvent.h"
 | 
| -#include "platform/transforms/ScaleTransformOperation.h"
 | 
|  #include "platform/transforms/TransformationMatrix.h"
 | 
| -#include "platform/transforms/TranslateTransformOperation.h"
 | 
|  #include "wtf/PtrUtil.h"
 | 
|  #include "wtf/StdLibExtras.h"
 | 
|  #include "wtf/allocator/Partitions.h"
 | 
| @@ -184,8 +179,10 @@ PaintLayer::PaintLayer(LayoutBoxModelObject* layoutObject)
 | 
|  }
 | 
|  
 | 
|  PaintLayer::~PaintLayer() {
 | 
| -  if (m_rareData && m_rareData->filterInfo)
 | 
| +  if (m_rareData && m_rareData->filterInfo) {
 | 
| +    layoutObject()->styleRef().filter().removeClient(m_rareData->filterInfo);
 | 
|      m_rareData->filterInfo->clearLayer();
 | 
| +  }
 | 
|    if (layoutObject()->frame() && layoutObject()->frame()->page()) {
 | 
|      if (ScrollingCoordinator* scrollingCoordinator =
 | 
|              layoutObject()->frame()->page()->scrollingCoordinator())
 | 
| @@ -2642,7 +2639,8 @@ void PaintLayer::ensureCompositedLayerMapping() {
 | 
|    m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate(
 | 
|        GraphicsLayerUpdateSubtree);
 | 
|  
 | 
| -  updateOrRemoveFilterEffect();
 | 
| +  if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
 | 
| +    filterInfo->invalidateFilterChain();
 | 
|  }
 | 
|  
 | 
|  void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) {
 | 
| @@ -2660,8 +2658,11 @@ void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) {
 | 
|    if (m_rareData)
 | 
|      m_rareData->compositedLayerMapping.reset();
 | 
|  
 | 
| -  if (!layerBeingDestroyed)
 | 
| -    updateOrRemoveFilterEffect();
 | 
| +  if (layerBeingDestroyed)
 | 
| +    return;
 | 
| +
 | 
| +  if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
 | 
| +    filterInfo->invalidateFilterChain();
 | 
|  }
 | 
|  
 | 
|  void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping,
 | 
| @@ -2864,9 +2865,17 @@ void PaintLayer::updateFilters(const ComputedStyle* oldStyle,
 | 
|    if (!newStyle.hasFilterInducingProperty() &&
 | 
|        (!oldStyle || !oldStyle->hasFilterInducingProperty()))
 | 
|      return;
 | 
| -
 | 
| -  updateOrRemoveFilterClients();
 | 
| -  updateOrRemoveFilterEffect();
 | 
| +  const bool hadFilterInfo = filterInfo();
 | 
| +  if (newStyle.hasFilterInducingProperty())
 | 
| +    newStyle.filter().addClient(&ensureFilterInfo());
 | 
| +  if (hadFilterInfo && oldStyle)
 | 
| +    oldStyle->filter().removeClient(filterInfo());
 | 
| +  if (!newStyle.hasFilterInducingProperty()) {
 | 
| +    removeFilterInfo();
 | 
| +    return;
 | 
| +  }
 | 
| +  if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
 | 
| +    filterInfo->invalidateFilterChain();
 | 
|  }
 | 
|  
 | 
|  bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff,
 | 
| @@ -2890,14 +2899,6 @@ bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff,
 | 
|    if (potentialCompositingReasonsFromStyle() !=
 | 
|        oldPotentialCompositingReasonsFromStyle)
 | 
|      return false;
 | 
| -  // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't
 | 
| -  // perform a direct compositing update because the filters code is going
 | 
| -  // to produce different output this time around. We can remove this code
 | 
| -  // once we fix the chicken/egg bugs in the filters code and delete the
 | 
| -  // scheduleSVGFilterLayerUpdateHack().
 | 
| -  if (layoutObject()->node() &&
 | 
| -      layoutObject()->node()->svgFilterNeedsLayerUpdate())
 | 
| -    return false;
 | 
|    if (!m_rareData || !m_rareData->compositedLayerMapping)
 | 
|      return false;
 | 
|  
 | 
| @@ -3011,6 +3012,13 @@ PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() {
 | 
|    return *rareData.filterInfo;
 | 
|  }
 | 
|  
 | 
| +void PaintLayer::removeFilterInfo() {
 | 
| +  if (!m_rareData || !m_rareData->filterInfo)
 | 
| +    return;
 | 
| +  m_rareData->filterInfo->clearLayer();
 | 
| +  m_rareData->filterInfo = nullptr;
 | 
| +}
 | 
| +
 | 
|  void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) {
 | 
|    // If the current ancestor overflow layer does not match the removed layer
 | 
|    // the ancestor overflow layer has changed so we can stop searching.
 | 
| @@ -3033,27 +3041,11 @@ void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -void PaintLayer::updateOrRemoveFilterClients() {
 | 
| -  const auto& filter = layoutObject()->style()->filter();
 | 
| -  if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) {
 | 
| -    m_rareData->filterInfo->clearLayer();
 | 
| -    m_rareData->filterInfo = nullptr;
 | 
| -  } else if (filter.hasReferenceFilter()) {
 | 
| -    ensureFilterInfo().updateReferenceFilterClients(filter);
 | 
| -  } else if (filterInfo()) {
 | 
| -    filterInfo()->clearFilterReferences();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -FilterEffect* PaintLayer::updateFilterEffect() const {
 | 
| +FilterEffect* PaintLayer::lastFilterEffect() const {
 | 
|    // TODO(chrishtr): ensure (and assert) that compositing is clean here.
 | 
| -
 | 
|    if (!paintsWithFilters())
 | 
|      return nullptr;
 | 
| -
 | 
|    PaintLayerFilterInfo* filterInfo = this->filterInfo();
 | 
| -
 | 
| -  // Should have been added by updateOrRemoveFilterEffect().
 | 
|    DCHECK(filterInfo);
 | 
|  
 | 
|    if (filterInfo->lastEffect())
 | 
| @@ -3070,16 +3062,13 @@ FilterEffect* PaintLayer::updateFilterEffect() const {
 | 
|    return filterInfo->lastEffect();
 | 
|  }
 | 
|  
 | 
| -FilterEffect* PaintLayer::lastFilterEffect() const {
 | 
| -  return updateFilterEffect();
 | 
| -}
 | 
| -
 | 
|  FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const {
 | 
|    if (!hasFilterThatMovesPixels())
 | 
|      return rect;
 | 
|  
 | 
|    // Ensure the filter-chain is refreshed wrt reference filters.
 | 
| -  updateFilterEffect();
 | 
| +  // TODO(fs): Avoid having this side-effect inducing call.
 | 
| +  lastFilterEffect();
 | 
|  
 | 
|    FilterOperations filterOperations =
 | 
|        addReflectionToFilterOperations(layoutObject()->styleRef());
 | 
| @@ -3103,37 +3092,6 @@ bool PaintLayer::hasFilterThatMovesPixels() const {
 | 
|    return false;
 | 
|  }
 | 
|  
 | 
| -void PaintLayer::updateOrRemoveFilterEffect() {
 | 
| -  // FilterEffectBuilder is only used to render the filters in software mode,
 | 
| -  // so we always need to run updateOrRemoveFilterEffect after the composited
 | 
| -  // mode might have changed for this layer.
 | 
| -  if (!paintsWithFilters()) {
 | 
| -    if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
 | 
| -      filterInfo->setLastEffect(nullptr);
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  ensureFilterInfo().setLastEffect(nullptr);
 | 
| -}
 | 
| -
 | 
| -void PaintLayer::filterNeedsPaintInvalidation() {
 | 
| -  {
 | 
| -    DeprecatedScheduleStyleRecalcDuringLayout marker(
 | 
| -        layoutObject()->document().lifecycle());
 | 
| -    // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style
 | 
| -    // recalc, which is a problem because this function can be called right
 | 
| -    // before performing layout but after style recalc.
 | 
| -    //
 | 
| -    // See LayoutView::layout() and the call to
 | 
| -    // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is
 | 
| -    // worked around in FrameView::updateStyleAndLayoutIfNeededRecursive() by
 | 
| -    // doing an extra style recalc and layout in case it's needed.
 | 
| -    toElement(layoutObject()->node())->scheduleSVGFilterLayerUpdateHack();
 | 
| -  }
 | 
| -
 | 
| -  layoutObject()->setShouldDoFullPaintInvalidation();
 | 
| -}
 | 
| -
 | 
|  void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const {
 | 
|    computeSelfHitTestRects(rects);
 | 
|    for (PaintLayer* child = firstChild(); child; child = child->nextSibling())
 | 
| 
 |