Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp

Issue 2401343002: Tracking filter mutation via SVGElementProxy (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public 5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version. 7 * version 2 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details. 12 * Library General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU Library General Public License 14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to 15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA. 17 * Boston, MA 02110-1301, USA.
18 */ 18 */
19 19
20 #include "core/layout/svg/LayoutSVGResourceContainer.h" 20 #include "core/layout/svg/LayoutSVGResourceContainer.h"
21 21
22 #include "core/SVGElementTypeHelpers.h" 22 #include "core/SVGElementTypeHelpers.h"
23 #include "core/layout/svg/LayoutSVGResourceClipper.h" 23 #include "core/layout/svg/LayoutSVGResourceClipper.h"
24 #include "core/layout/svg/LayoutSVGResourceFilter.h" 24 #include "core/layout/svg/LayoutSVGResourceFilter.h"
25 #include "core/layout/svg/LayoutSVGResourceMasker.h" 25 #include "core/layout/svg/LayoutSVGResourceMasker.h"
26 #include "core/layout/svg/SVGResources.h" 26 #include "core/layout/svg/SVGResources.h"
27 #include "core/layout/svg/SVGResourcesCache.h" 27 #include "core/layout/svg/SVGResourcesCache.h"
28 #include "core/paint/PaintLayer.h" 28 #include "core/svg/SVGElementProxy.h"
29 #include "core/svg/SVGFilterElement.h"
30
31 #include "wtf/AutoReset.h" 29 #include "wtf/AutoReset.h"
32 30
33 namespace blink { 31 namespace blink {
34 32
35 static inline SVGDocumentExtensions& svgExtensionsFromElement( 33 static inline SVGDocumentExtensions& svgExtensionsFromElement(
36 Element* element) { 34 Element* element) {
37 ASSERT(element); 35 ASSERT(element);
38 return element->document().accessSVGExtensions(); 36 return element->document().accessSVGExtensions();
39 } 37 }
40 38
(...skipping 15 matching lines...) Expand all
56 if (m_isInLayout) 54 if (m_isInLayout)
57 return; 55 return;
58 56
59 AutoReset<bool> inLayoutChange(&m_isInLayout, true); 57 AutoReset<bool> inLayoutChange(&m_isInLayout, true);
60 58
61 LayoutSVGHiddenContainer::layout(); 59 LayoutSVGHiddenContainer::layout();
62 60
63 clearInvalidationMask(); 61 clearInvalidationMask();
64 } 62 }
65 63
64 void LayoutSVGResourceContainer::invalidateProxyClients(InvalidationMode) {
65 if (SVGElementProxyTracker* proxyTracker = elementProxyTracker())
66 proxyTracker->invalidateProxyClients();
67 }
68
69 void LayoutSVGResourceContainer::invalidateProxies() {
70 if (SVGElementProxyTracker* proxyTracker = elementProxyTracker())
71 proxyTracker->invalidateProxies();
72 }
73
66 void LayoutSVGResourceContainer::willBeDestroyed() { 74 void LayoutSVGResourceContainer::willBeDestroyed() {
67 // Detach all clients referring to this resource. If the resource itself is 75 // Detach all clients referring to this resource. If the resource itself is
68 // a client, it will be detached from any such resources by the call to 76 // a client, it will be detached from any such resources by the call to
69 // LayoutSVGHiddenContainer::willBeDestroyed() below. 77 // LayoutSVGHiddenContainer::willBeDestroyed() below.
70 detachAllClients(); 78 detachAllClients();
71 79 invalidateProxies();
72 for (SVGResourceClient* client : m_resourceClients)
73 client->filterWillBeDestroyed(toSVGFilterElement(element()));
74 m_resourceClients.clear();
75 80
76 LayoutSVGHiddenContainer::willBeDestroyed(); 81 LayoutSVGHiddenContainer::willBeDestroyed();
77 if (m_registered) 82 if (m_registered)
78 svgExtensionsFromElement(element()).removeResource(m_id); 83 svgExtensionsFromElement(element()).removeResource(m_id);
79 } 84 }
80 85
81 void LayoutSVGResourceContainer::styleDidChange(StyleDifference diff, 86 void LayoutSVGResourceContainer::styleDidChange(StyleDifference diff,
82 const ComputedStyle* oldStyle) { 87 const ComputedStyle* oldStyle) {
83 LayoutSVGHiddenContainer::styleDidChange(diff, oldStyle); 88 LayoutSVGHiddenContainer::styleDidChange(diff, oldStyle);
84 89
(...skipping 18 matching lines...) Expand all
103 svgExtensionsFromElement(clientElement) 108 svgExtensionsFromElement(clientElement)
104 .addPendingResource(m_id, clientElement); 109 .addPendingResource(m_id, clientElement);
105 } 110 }
106 111
107 removeAllClientsFromCache(); 112 removeAllClientsFromCache();
108 } 113 }
109 114
110 void LayoutSVGResourceContainer::idChanged() { 115 void LayoutSVGResourceContainer::idChanged() {
111 // Invalidate all our current clients. 116 // Invalidate all our current clients.
112 removeAllClientsFromCache(); 117 removeAllClientsFromCache();
118 invalidateProxies();
113 119
114 // Remove old id, that is guaranteed to be present in cache. 120 // Remove old id, that is guaranteed to be present in cache.
115 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element()); 121 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
116 extensions.removeResource(m_id); 122 extensions.removeResource(m_id);
117 m_id = element()->getIdAttribute(); 123 m_id = element()->getIdAttribute();
118 124
119 registerResource(); 125 registerResource();
126 extensions.invalidatePendingProxies(m_id);
120 } 127 }
121 128
122 void LayoutSVGResourceContainer::markAllClientsForInvalidation( 129 void LayoutSVGResourceContainer::markAllClientsForInvalidation(
123 InvalidationMode mode) { 130 InvalidationMode mode) {
124 if ((m_clients.isEmpty() && m_resourceClients.isEmpty()) || m_isInvalidating) 131 if (m_isInvalidating)
125 return; 132 return;
126 133 SVGElementProxyTracker* proxyTracker = elementProxyTracker();
134 if (m_clients.isEmpty() && (!proxyTracker || proxyTracker->isEmpty()))
135 return;
127 if (m_invalidationMask & mode) 136 if (m_invalidationMask & mode)
128 return; 137 return;
129 138
130 m_invalidationMask |= mode; 139 m_invalidationMask |= mode;
131 m_isInvalidating = true; 140 m_isInvalidating = true;
132 bool needsLayout = mode == LayoutAndBoundariesInvalidation; 141 bool needsLayout = mode == LayoutAndBoundariesInvalidation;
133 bool markForInvalidation = mode != ParentOnlyInvalidation; 142 bool markForInvalidation = mode != ParentOnlyInvalidation;
134 143
144 // Invalidate clients registered on the this object (via SVGResources).
135 for (auto* client : m_clients) { 145 for (auto* client : m_clients) {
146 DCHECK(client->isSVG());
136 if (client->isSVGResourceContainer()) { 147 if (client->isSVGResourceContainer()) {
137 toLayoutSVGResourceContainer(client)->removeAllClientsFromCache( 148 toLayoutSVGResourceContainer(client)->removeAllClientsFromCache(
138 markForInvalidation); 149 markForInvalidation);
139 continue; 150 continue;
140 } 151 }
141 152
142 if (markForInvalidation) 153 if (markForInvalidation)
143 markClientForInvalidation(client, mode); 154 markClientForInvalidation(client, mode);
144 155
145 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation( 156 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(
146 client, needsLayout); 157 client, needsLayout);
147 } 158 }
148 159
149 markAllResourceClientsForInvalidation(); 160 // Invalidate clients registered via an SVGElementProxy.
161 invalidateProxyClients(mode);
150 162
151 m_isInvalidating = false; 163 m_isInvalidating = false;
152 } 164 }
153 165
154 void LayoutSVGResourceContainer::markAllResourceClientsForInvalidation() {
155 for (SVGResourceClient* client : m_resourceClients)
156 client->filterNeedsInvalidation();
157 }
158
159 void LayoutSVGResourceContainer::markClientForInvalidation( 166 void LayoutSVGResourceContainer::markClientForInvalidation(
160 LayoutObject* client, 167 LayoutObject* client,
161 InvalidationMode mode) { 168 InvalidationMode mode) {
162 ASSERT(client); 169 ASSERT(client);
163 ASSERT(!m_clients.isEmpty()); 170 ASSERT(!m_clients.isEmpty());
164 171
165 switch (mode) { 172 switch (mode) {
166 case LayoutAndBoundariesInvalidation: 173 case LayoutAndBoundariesInvalidation:
167 case BoundariesInvalidation: 174 case BoundariesInvalidation:
168 client->setNeedsBoundariesUpdate(); 175 client->setNeedsBoundariesUpdate();
(...skipping 17 matching lines...) Expand all
186 m_clients.add(client); 193 m_clients.add(client);
187 clearInvalidationMask(); 194 clearInvalidationMask();
188 } 195 }
189 196
190 void LayoutSVGResourceContainer::removeClient(LayoutObject* client) { 197 void LayoutSVGResourceContainer::removeClient(LayoutObject* client) {
191 ASSERT(client); 198 ASSERT(client);
192 removeClientFromCache(client, false); 199 removeClientFromCache(client, false);
193 m_clients.remove(client); 200 m_clients.remove(client);
194 } 201 }
195 202
196 void LayoutSVGResourceContainer::addResourceClient(SVGResourceClient* client) {
197 ASSERT(client);
198 m_resourceClients.add(client);
199 clearInvalidationMask();
200 }
201
202 void LayoutSVGResourceContainer::removeResourceClient(
203 SVGResourceClient* client) {
204 ASSERT(client);
205 m_resourceClients.remove(client);
206 }
207
208 void LayoutSVGResourceContainer::invalidateCacheAndMarkForLayout( 203 void LayoutSVGResourceContainer::invalidateCacheAndMarkForLayout(
209 SubtreeLayoutScope* layoutScope) { 204 SubtreeLayoutScope* layoutScope) {
210 if (selfNeedsLayout()) 205 if (selfNeedsLayout())
211 return; 206 return;
212 207
213 setNeedsLayoutAndFullPaintInvalidation( 208 setNeedsLayoutAndFullPaintInvalidation(
214 LayoutInvalidationReason::SvgResourceInvalidated, MarkContainerChain, 209 LayoutInvalidationReason::SvgResourceInvalidated, MarkContainerChain,
215 layoutScope); 210 layoutScope);
216 211
217 if (everHadLayout()) 212 if (everHadLayout())
218 removeAllClientsFromCache(); 213 removeAllClientsFromCache();
219 } 214 }
220 215
221 void LayoutSVGResourceContainer::registerResource() { 216 void LayoutSVGResourceContainer::registerResource() {
222 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element()); 217 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
223 if (!extensions.hasPendingResource(m_id)) { 218 if (!extensions.hasPendingResource(m_id)) {
224 extensions.addResource(m_id, this); 219 extensions.addResource(m_id, this);
225 return; 220 return;
226 } 221 }
227 222
228 SVGDocumentExtensions::SVGPendingElements* clients( 223 SVGDocumentExtensions::SVGPendingElements* clients(
229 extensions.removePendingResource(m_id)); 224 extensions.removePendingResource(m_id));
230 225
231 // Cache us with the new id. 226 // Cache us with the new id.
232 extensions.addResource(m_id, this); 227 extensions.addResource(m_id, this);
233 228
234 // Update cached resources of pending clients. 229 // Update cached resources of pending clients.
235 for (const auto& pendingClient : *clients) { 230 for (const auto& pendingClient : *clients) {
236 ASSERT(pendingClient->hasPendingResources()); 231 DCHECK(pendingClient->hasPendingResources());
237 extensions.clearHasPendingResourcesIfPossible(pendingClient); 232 extensions.clearHasPendingResourcesIfPossible(pendingClient);
238 LayoutObject* layoutObject = pendingClient->layoutObject(); 233 LayoutObject* layoutObject = pendingClient->layoutObject();
239 if (!layoutObject) 234 if (!layoutObject)
240 continue; 235 continue;
241 236 DCHECK(layoutObject->isSVG() && (resourceType() != FilterResourceType ||
242 const ComputedStyle& style = layoutObject->styleRef(); 237 !layoutObject->isSVGRoot()));
243
244 // If the client has a layer (is a non-SVGElement) we need to signal
245 // invalidation in the same way as is done in
246 // markAllResourceClientsForInvalidation above.
247 if (layoutObject->hasLayer() && resourceType() == FilterResourceType) {
248 if (!style.hasFilter())
249 continue;
250 toLayoutBoxModelObject(layoutObject)
251 ->layer()
252 ->filterNeedsPaintInvalidation();
253 if (!layoutObject->isSVGRoot())
254 continue;
255 // A root SVG element with a filter, however, still needs to run
256 // the full invalidation step below.
257 }
258 238
259 StyleDifference diff; 239 StyleDifference diff;
260 diff.setNeedsFullLayout(); 240 diff.setNeedsFullLayout();
261 SVGResourcesCache::clientStyleChanged(layoutObject, diff, style); 241 SVGResourcesCache::clientStyleChanged(layoutObject, diff,
242 layoutObject->styleRef());
262 layoutObject->setNeedsLayoutAndFullPaintInvalidation( 243 layoutObject->setNeedsLayoutAndFullPaintInvalidation(
263 LayoutInvalidationReason::SvgResourceInvalidated); 244 LayoutInvalidationReason::SvgResourceInvalidated);
264 } 245 }
265 } 246 }
266 247
267 static inline void removeFromCacheAndInvalidateDependencies( 248 static inline void removeFromCacheAndInvalidateDependencies(
268 LayoutObject* object, 249 LayoutObject* object,
269 bool needsLayout) { 250 bool needsLayout) {
270 ASSERT(object); 251 ASSERT(object);
271 if (SVGResources* resources = 252 if (SVGResources* resources =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 // This will process the rest of the ancestors. 312 // This will process the rest of the ancestors.
332 toLayoutSVGResourceContainer(current)->removeAllClientsFromCache(); 313 toLayoutSVGResourceContainer(current)->removeAllClientsFromCache();
333 break; 314 break;
334 } 315 }
335 316
336 current = current->parent(); 317 current = current->parent();
337 } 318 }
338 } 319 }
339 320
340 } // namespace blink 321 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698