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

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

Issue 2490163002: Reland of "Tracking reference filter mutation via SVGElementProxy" (Closed)
Patch Set: Fix double observer unregistration; simplify scope selection; add tests Created 4 years, 1 month 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::notifyContentChanged() {
65 if (SVGElementProxySet* proxySet = elementProxySet())
66 proxySet->notifyContentChanged(element()->treeScope());
67 }
68
66 void LayoutSVGResourceContainer::willBeDestroyed() { 69 void LayoutSVGResourceContainer::willBeDestroyed() {
67 // Detach all clients referring to this resource. If the resource itself is 70 // 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 71 // a client, it will be detached from any such resources by the call to
69 // LayoutSVGHiddenContainer::willBeDestroyed() below. 72 // LayoutSVGHiddenContainer::willBeDestroyed() below.
70 detachAllClients(); 73 detachAllClients();
71 74
72 for (SVGResourceClient* client : m_resourceClients)
73 client->filterWillBeDestroyed(toSVGFilterElement(element()));
74 m_resourceClients.clear();
75
76 LayoutSVGHiddenContainer::willBeDestroyed(); 75 LayoutSVGHiddenContainer::willBeDestroyed();
77 if (m_registered) 76 if (m_registered)
78 svgExtensionsFromElement(element()).removeResource(m_id); 77 svgExtensionsFromElement(element()).removeResource(m_id);
79 } 78 }
80 79
81 void LayoutSVGResourceContainer::styleDidChange(StyleDifference diff, 80 void LayoutSVGResourceContainer::styleDidChange(StyleDifference diff,
82 const ComputedStyle* oldStyle) { 81 const ComputedStyle* oldStyle) {
83 LayoutSVGHiddenContainer::styleDidChange(diff, oldStyle); 82 LayoutSVGHiddenContainer::styleDidChange(diff, oldStyle);
84 83
85 if (!m_registered) { 84 if (!m_registered) {
(...skipping 28 matching lines...) Expand all
114 // Remove old id, that is guaranteed to be present in cache. 113 // Remove old id, that is guaranteed to be present in cache.
115 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element()); 114 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
116 extensions.removeResource(m_id); 115 extensions.removeResource(m_id);
117 m_id = element()->getIdAttribute(); 116 m_id = element()->getIdAttribute();
118 117
119 registerResource(); 118 registerResource();
120 } 119 }
121 120
122 void LayoutSVGResourceContainer::markAllClientsForInvalidation( 121 void LayoutSVGResourceContainer::markAllClientsForInvalidation(
123 InvalidationMode mode) { 122 InvalidationMode mode) {
124 if ((m_clients.isEmpty() && m_resourceClients.isEmpty()) || m_isInvalidating) 123 if (m_isInvalidating)
125 return; 124 return;
126 125 SVGElementProxySet* proxySet = elementProxySet();
126 if (m_clients.isEmpty() && (!proxySet || proxySet->isEmpty()))
127 return;
127 if (m_invalidationMask & mode) 128 if (m_invalidationMask & mode)
128 return; 129 return;
129 130
130 m_invalidationMask |= mode; 131 m_invalidationMask |= mode;
131 m_isInvalidating = true; 132 m_isInvalidating = true;
132 bool needsLayout = mode == LayoutAndBoundariesInvalidation; 133 bool needsLayout = mode == LayoutAndBoundariesInvalidation;
133 bool markForInvalidation = mode != ParentOnlyInvalidation; 134 bool markForInvalidation = mode != ParentOnlyInvalidation;
134 135
136 // Invalidate clients registered on the this object (via SVGResources).
135 for (auto* client : m_clients) { 137 for (auto* client : m_clients) {
138 DCHECK(client->isSVG());
136 if (client->isSVGResourceContainer()) { 139 if (client->isSVGResourceContainer()) {
137 toLayoutSVGResourceContainer(client)->removeAllClientsFromCache( 140 toLayoutSVGResourceContainer(client)->removeAllClientsFromCache(
138 markForInvalidation); 141 markForInvalidation);
139 continue; 142 continue;
140 } 143 }
141 144
142 if (markForInvalidation) 145 if (markForInvalidation)
143 markClientForInvalidation(client, mode); 146 markClientForInvalidation(client, mode);
144 147
145 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation( 148 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(
146 client, needsLayout); 149 client, needsLayout);
147 } 150 }
148 151
149 markAllResourceClientsForInvalidation(); 152 // Invalidate clients registered via an SVGElementProxy.
153 notifyContentChanged();
150 154
151 m_isInvalidating = false; 155 m_isInvalidating = false;
152 } 156 }
153 157
154 void LayoutSVGResourceContainer::markAllResourceClientsForInvalidation() {
155 for (SVGResourceClient* client : m_resourceClients)
156 client->filterNeedsInvalidation();
157 }
158
159 void LayoutSVGResourceContainer::markClientForInvalidation( 158 void LayoutSVGResourceContainer::markClientForInvalidation(
160 LayoutObject* client, 159 LayoutObject* client,
161 InvalidationMode mode) { 160 InvalidationMode mode) {
162 ASSERT(client); 161 ASSERT(client);
163 ASSERT(!m_clients.isEmpty()); 162 ASSERT(!m_clients.isEmpty());
164 163
165 switch (mode) { 164 switch (mode) {
166 case LayoutAndBoundariesInvalidation: 165 case LayoutAndBoundariesInvalidation:
167 case BoundariesInvalidation: 166 case BoundariesInvalidation:
168 client->setNeedsBoundariesUpdate(); 167 client->setNeedsBoundariesUpdate();
(...skipping 17 matching lines...) Expand all
186 m_clients.add(client); 185 m_clients.add(client);
187 clearInvalidationMask(); 186 clearInvalidationMask();
188 } 187 }
189 188
190 void LayoutSVGResourceContainer::removeClient(LayoutObject* client) { 189 void LayoutSVGResourceContainer::removeClient(LayoutObject* client) {
191 ASSERT(client); 190 ASSERT(client);
192 removeClientFromCache(client, false); 191 removeClientFromCache(client, false);
193 m_clients.remove(client); 192 m_clients.remove(client);
194 } 193 }
195 194
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( 195 void LayoutSVGResourceContainer::invalidateCacheAndMarkForLayout(
209 SubtreeLayoutScope* layoutScope) { 196 SubtreeLayoutScope* layoutScope) {
210 if (selfNeedsLayout()) 197 if (selfNeedsLayout())
211 return; 198 return;
212 199
213 setNeedsLayoutAndFullPaintInvalidation( 200 setNeedsLayoutAndFullPaintInvalidation(
214 LayoutInvalidationReason::SvgResourceInvalidated, MarkContainerChain, 201 LayoutInvalidationReason::SvgResourceInvalidated, MarkContainerChain,
215 layoutScope); 202 layoutScope);
216 203
217 if (everHadLayout()) 204 if (everHadLayout())
218 removeAllClientsFromCache(); 205 removeAllClientsFromCache();
219 } 206 }
220 207
221 void LayoutSVGResourceContainer::registerResource() { 208 void LayoutSVGResourceContainer::registerResource() {
222 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element()); 209 SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
223 if (!extensions.hasPendingResource(m_id)) { 210 if (!extensions.hasPendingResource(m_id)) {
224 extensions.addResource(m_id, this); 211 extensions.addResource(m_id, this);
225 return; 212 return;
226 } 213 }
227 214
228 SVGDocumentExtensions::SVGPendingElements* clients( 215 SVGDocumentExtensions::SVGPendingElements* clients(
229 extensions.removePendingResource(m_id)); 216 extensions.removePendingResource(m_id));
230 217
231 // Cache us with the new id. 218 // Cache us with the new id.
232 extensions.addResource(m_id, this); 219 extensions.addResource(m_id, this);
233 220
234 // Update cached resources of pending clients. 221 // Update cached resources of pending clients.
235 for (const auto& pendingClient : *clients) { 222 for (const auto& pendingClient : *clients) {
236 ASSERT(pendingClient->hasPendingResources()); 223 DCHECK(pendingClient->hasPendingResources());
237 extensions.clearHasPendingResourcesIfPossible(pendingClient); 224 extensions.clearHasPendingResourcesIfPossible(pendingClient);
238 LayoutObject* layoutObject = pendingClient->layoutObject(); 225 LayoutObject* layoutObject = pendingClient->layoutObject();
239 if (!layoutObject) 226 if (!layoutObject)
240 continue; 227 continue;
241 228 DCHECK(layoutObject->isSVG() && (resourceType() != FilterResourceType ||
242 const ComputedStyle& style = layoutObject->styleRef(); 229 !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 230
259 StyleDifference diff; 231 StyleDifference diff;
260 diff.setNeedsFullLayout(); 232 diff.setNeedsFullLayout();
261 SVGResourcesCache::clientStyleChanged(layoutObject, diff, style); 233 SVGResourcesCache::clientStyleChanged(layoutObject, diff,
234 layoutObject->styleRef());
262 layoutObject->setNeedsLayoutAndFullPaintInvalidation( 235 layoutObject->setNeedsLayoutAndFullPaintInvalidation(
263 LayoutInvalidationReason::SvgResourceInvalidated); 236 LayoutInvalidationReason::SvgResourceInvalidated);
264 } 237 }
265 } 238 }
266 239
267 static inline void removeFromCacheAndInvalidateDependencies( 240 static inline void removeFromCacheAndInvalidateDependencies(
268 LayoutObject* object, 241 LayoutObject* object,
269 bool needsLayout) { 242 bool needsLayout) {
270 ASSERT(object); 243 ASSERT(object);
271 if (SVGResources* resources = 244 if (SVGResources* resources =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 // This will process the rest of the ancestors. 304 // This will process the rest of the ancestors.
332 toLayoutSVGResourceContainer(current)->removeAllClientsFromCache(); 305 toLayoutSVGResourceContainer(current)->removeAllClientsFromCache();
333 break; 306 break;
334 } 307 }
335 308
336 current = current->parent(); 309 current = current->parent();
337 } 310 }
338 } 311 }
339 312
340 } // namespace blink 313 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698