| Index: third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp
|
| index 3fc824844162e8b2c778f0f81c03ce12890a9b92..0d3edd3cd90d08a7564b4c5a0e523ca03ffe124b 100644
|
| --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp
|
| @@ -25,7 +25,9 @@
|
| #include "core/layout/svg/LayoutSVGResourceMasker.h"
|
| #include "core/layout/svg/SVGResources.h"
|
| #include "core/layout/svg/SVGResourcesCache.h"
|
| -#include "core/svg/SVGElementProxy.h"
|
| +#include "core/paint/PaintLayer.h"
|
| +#include "core/svg/SVGFilterElement.h"
|
| +
|
| #include "wtf/AutoReset.h"
|
|
|
| namespace blink {
|
| @@ -61,16 +63,15 @@
|
| clearInvalidationMask();
|
| }
|
|
|
| -void LayoutSVGResourceContainer::notifyContentChanged() {
|
| - if (SVGElementProxySet* proxySet = elementProxySet())
|
| - proxySet->notifyContentChanged(element()->treeScope());
|
| -}
|
| -
|
| void LayoutSVGResourceContainer::willBeDestroyed() {
|
| // Detach all clients referring to this resource. If the resource itself is
|
| // a client, it will be detached from any such resources by the call to
|
| // LayoutSVGHiddenContainer::willBeDestroyed() below.
|
| detachAllClients();
|
| +
|
| + for (SVGResourceClient* client : m_resourceClients)
|
| + client->filterWillBeDestroyed(toSVGFilterElement(element()));
|
| + m_resourceClients.clear();
|
|
|
| LayoutSVGHiddenContainer::willBeDestroyed();
|
| if (m_registered)
|
| @@ -120,11 +121,9 @@
|
|
|
| void LayoutSVGResourceContainer::markAllClientsForInvalidation(
|
| InvalidationMode mode) {
|
| - if (m_isInvalidating)
|
| - return;
|
| - SVGElementProxySet* proxySet = elementProxySet();
|
| - if (m_clients.isEmpty() && (!proxySet || proxySet->isEmpty()))
|
| - return;
|
| + if ((m_clients.isEmpty() && m_resourceClients.isEmpty()) || m_isInvalidating)
|
| + return;
|
| +
|
| if (m_invalidationMask & mode)
|
| return;
|
|
|
| @@ -133,9 +132,7 @@
|
| bool needsLayout = mode == LayoutAndBoundariesInvalidation;
|
| bool markForInvalidation = mode != ParentOnlyInvalidation;
|
|
|
| - // Invalidate clients registered on the this object (via SVGResources).
|
| for (auto* client : m_clients) {
|
| - DCHECK(client->isSVG());
|
| if (client->isSVGResourceContainer()) {
|
| toLayoutSVGResourceContainer(client)->removeAllClientsFromCache(
|
| markForInvalidation);
|
| @@ -149,10 +146,14 @@
|
| client, needsLayout);
|
| }
|
|
|
| - // Invalidate clients registered via an SVGElementProxy.
|
| - notifyContentChanged();
|
| + markAllResourceClientsForInvalidation();
|
|
|
| m_isInvalidating = false;
|
| +}
|
| +
|
| +void LayoutSVGResourceContainer::markAllResourceClientsForInvalidation() {
|
| + for (SVGResourceClient* client : m_resourceClients)
|
| + client->filterNeedsInvalidation();
|
| }
|
|
|
| void LayoutSVGResourceContainer::markClientForInvalidation(
|
| @@ -192,6 +193,18 @@
|
| m_clients.remove(client);
|
| }
|
|
|
| +void LayoutSVGResourceContainer::addResourceClient(SVGResourceClient* client) {
|
| + ASSERT(client);
|
| + m_resourceClients.add(client);
|
| + clearInvalidationMask();
|
| +}
|
| +
|
| +void LayoutSVGResourceContainer::removeResourceClient(
|
| + SVGResourceClient* client) {
|
| + ASSERT(client);
|
| + m_resourceClients.remove(client);
|
| +}
|
| +
|
| void LayoutSVGResourceContainer::invalidateCacheAndMarkForLayout(
|
| SubtreeLayoutScope* layoutScope) {
|
| if (selfNeedsLayout())
|
| @@ -220,18 +233,32 @@
|
|
|
| // Update cached resources of pending clients.
|
| for (const auto& pendingClient : *clients) {
|
| - DCHECK(pendingClient->hasPendingResources());
|
| + ASSERT(pendingClient->hasPendingResources());
|
| extensions.clearHasPendingResourcesIfPossible(pendingClient);
|
| LayoutObject* layoutObject = pendingClient->layoutObject();
|
| if (!layoutObject)
|
| continue;
|
| - DCHECK(layoutObject->isSVG() && (resourceType() != FilterResourceType ||
|
| - !layoutObject->isSVGRoot()));
|
| +
|
| + const ComputedStyle& style = layoutObject->styleRef();
|
| +
|
| + // If the client has a layer (is a non-SVGElement) we need to signal
|
| + // invalidation in the same way as is done in
|
| + // markAllResourceClientsForInvalidation above.
|
| + if (layoutObject->hasLayer() && resourceType() == FilterResourceType) {
|
| + if (!style.hasFilter())
|
| + continue;
|
| + toLayoutBoxModelObject(layoutObject)
|
| + ->layer()
|
| + ->filterNeedsPaintInvalidation();
|
| + if (!layoutObject->isSVGRoot())
|
| + continue;
|
| + // A root SVG element with a filter, however, still needs to run
|
| + // the full invalidation step below.
|
| + }
|
|
|
| StyleDifference diff;
|
| diff.setNeedsFullLayout();
|
| - SVGResourcesCache::clientStyleChanged(layoutObject, diff,
|
| - layoutObject->styleRef());
|
| + SVGResourcesCache::clientStyleChanged(layoutObject, diff, style);
|
| layoutObject->setNeedsLayoutAndFullPaintInvalidation(
|
| LayoutInvalidationReason::SvgResourceInvalidated);
|
| }
|
|
|