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

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

Issue 1854123002: Rebuild layout attributes on layout instead of on layout tree updates (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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) 2006 Apple Computer, Inc. 2 * Copyright (C) 2006 Apple Computer, Inc.
3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> 3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
4 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> 4 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
5 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> 5 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
6 * Copyright (C) 2008 Rob Buis <buis@kde.org> 6 * Copyright (C) 2008 Rob Buis <buis@kde.org>
7 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 7 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
8 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved. 8 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
9 * Copyright (C) 2012 Google Inc. 9 * Copyright (C) 2012 Google Inc.
10 * 10 *
(...skipping 29 matching lines...) Expand all
40 #include "core/layout/svg/SVGLayoutSupport.h" 40 #include "core/layout/svg/SVGLayoutSupport.h"
41 #include "core/layout/svg/SVGResourcesCache.h" 41 #include "core/layout/svg/SVGResourcesCache.h"
42 #include "core/layout/svg/line/SVGRootInlineBox.h" 42 #include "core/layout/svg/line/SVGRootInlineBox.h"
43 #include "core/paint/SVGTextPainter.h" 43 #include "core/paint/SVGTextPainter.h"
44 #include "core/style/ShadowList.h" 44 #include "core/style/ShadowList.h"
45 #include "core/svg/SVGLengthList.h" 45 #include "core/svg/SVGLengthList.h"
46 #include "core/svg/SVGTextElement.h" 46 #include "core/svg/SVGTextElement.h"
47 #include "core/svg/SVGTransformList.h" 47 #include "core/svg/SVGTransformList.h"
48 #include "core/svg/SVGURIReference.h" 48 #include "core/svg/SVGURIReference.h"
49 #include "platform/FloatConversion.h" 49 #include "platform/FloatConversion.h"
50 #include "platform/fonts/FontCache.h"
51 #include "platform/fonts/SimpleFontData.h"
52 #include "platform/geometry/FloatQuad.h" 50 #include "platform/geometry/FloatQuad.h"
53 #include "platform/geometry/TransformState.h"
54 51
55 namespace blink { 52 namespace blink {
56 53
57 namespace { 54 namespace {
58 55
59 const LayoutSVGText* findTextRoot(const LayoutObject* start) 56 const LayoutSVGText* findTextRoot(const LayoutObject* start)
60 { 57 {
61 ASSERT(start); 58 ASSERT(start);
62 for (; start; start = start->parent()) { 59 for (; start; start = start->parent()) {
63 if (start->isSVGText()) 60 if (start->isSVGText())
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } 95 }
99 96
100 static inline void collectLayoutAttributes(LayoutObject* text, Vector<SVGTextLay outAttributes*>& attributes) 97 static inline void collectLayoutAttributes(LayoutObject* text, Vector<SVGTextLay outAttributes*>& attributes)
101 { 98 {
102 for (LayoutObject* descendant = text; descendant; descendant = descendant->n extInPreOrder(text)) { 99 for (LayoutObject* descendant = text; descendant; descendant = descendant->n extInPreOrder(text)) {
103 if (descendant->isSVGInlineText()) 100 if (descendant->isSVGInlineText())
104 attributes.append(toLayoutSVGInlineText(descendant)->layoutAttribute s()); 101 attributes.append(toLayoutSVGInlineText(descendant)->layoutAttribute s());
105 } 102 }
106 } 103 }
107 104
108 static inline bool findPreviousAndNextAttributes(LayoutSVGText* root, LayoutSVGI nlineText* locateElement, SVGTextLayoutAttributes*& previous, SVGTextLayoutAttri butes*& next)
109 {
110 ASSERT(root);
111 ASSERT(locateElement);
112 bool stopAfterNext = false;
113 LayoutObject* current = root->firstChild();
114 while (current) {
115 if (current->isSVGInlineText()) {
116 LayoutSVGInlineText* text = toLayoutSVGInlineText(current);
117 if (locateElement != text) {
118 if (stopAfterNext) {
119 next = text->layoutAttributes();
120 return true;
121 }
122
123 previous = text->layoutAttributes();
124 } else {
125 stopAfterNext = true;
126 }
127 } else if (current->isSVGInline()) {
128 // Descend into text content (if possible).
129 if (LayoutObject* child = toLayoutSVGInline(current)->firstChild()) {
130 current = child;
131 continue;
132 }
133 }
134
135 current = current->nextInPreOrderAfterChildren(root);
136 }
137 return false;
138 }
139
140 inline bool LayoutSVGText::shouldHandleSubtreeMutations() const 105 inline bool LayoutSVGText::shouldHandleSubtreeMutations() const
141 { 106 {
142 if (beingDestroyed() || !everHadLayout()) { 107 if (beingDestroyed() || !everHadLayout()) {
143 ASSERT(m_layoutAttributes.isEmpty()); 108 ASSERT(m_layoutAttributes.isEmpty());
144 ASSERT(!m_layoutAttributesBuilder.numberOfTextPositioningElements()); 109 ASSERT(!m_layoutAttributesBuilder.numberOfTextPositioningElements());
145 return false; 110 return false;
146 } 111 }
147 return true; 112 return true;
148 } 113 }
149 114
150 void LayoutSVGText::subtreeChildWasAdded(LayoutObject* child) 115 void LayoutSVGText::subtreeChildWasAdded(LayoutObject*)
151 { 116 {
152 ASSERT(child);
153 if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) 117 if (!shouldHandleSubtreeMutations() || documentBeingDestroyed())
154 return; 118 return;
155 119
156 // Always protect the cache before clearing text positioning elements when t he cache will subsequently be rebuilt.
157 FontCachePurgePreventer fontCachePurgePreventer;
158
159 // The positioning elements cache doesn't include the new 'child' yet. Clear the 120 // The positioning elements cache doesn't include the new 'child' yet. Clear the
160 // cache, as the next buildLayoutAttributesForText() call rebuilds it. 121 // cache, as the next buildLayoutAttributesForText() call rebuilds it.
161 m_layoutAttributesBuilder.clearTextPositioningElements(); 122 m_layoutAttributesBuilder.clearTextPositioningElements();
162 123 setNeedsPositioningValuesUpdate();
163 if (!child->isSVGInlineText() && !child->isSVGInline()) 124 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::ChildChange d);
164 return;
165
166 // Detect changes in layout attributes and only measure those text parts tha t have changed!
167 Vector<SVGTextLayoutAttributes*> newLayoutAttributes;
168 collectLayoutAttributes(this, newLayoutAttributes);
169 if (newLayoutAttributes.isEmpty()) {
170 ASSERT(m_layoutAttributes.isEmpty());
171 return;
172 }
173
174 // Compare m_layoutAttributes with newLayoutAttributes to figure out which a ttribute got added.
175 size_t size = newLayoutAttributes.size();
176 SVGTextLayoutAttributes* attributes = nullptr;
177 for (size_t i = 0; i < size; ++i) {
178 attributes = newLayoutAttributes[i];
179 if (m_layoutAttributes.find(attributes) == kNotFound) {
180 // Every time this is invoked, there's only a single new entry in th e newLayoutAttributes list, compared to the old in m_layoutAttributes.
181 SVGTextLayoutAttributes* previous = nullptr;
182 SVGTextLayoutAttributes* next = nullptr;
183 ASSERT_UNUSED(child, attributes->context() == child);
184 findPreviousAndNextAttributes(this, attributes->context(), previous, next);
185
186 if (previous)
187 m_layoutAttributesBuilder.buildLayoutAttributesForText(previous- >context());
188 m_layoutAttributesBuilder.buildLayoutAttributesForText(attributes->c ontext());
189 if (next)
190 m_layoutAttributesBuilder.buildLayoutAttributesForText(next->con text());
191 break;
192 }
193 }
194
195 #if ENABLE(ASSERT)
196 // Verify that m_layoutAttributes only differs by a maximum of one entry.
197 for (size_t i = 0; i < size; ++i)
198 ASSERT(m_layoutAttributes.find(newLayoutAttributes[i]) != kNotFound || n ewLayoutAttributes[i] == attributes);
199 #endif
200
201 m_layoutAttributes = newLayoutAttributes;
202 }
203
204 static inline void checkLayoutAttributesConsistency(LayoutSVGText* text, Vector< SVGTextLayoutAttributes*>& expectedLayoutAttributes)
205 {
206 #if ENABLE(ASSERT)
207 Vector<SVGTextLayoutAttributes*> newLayoutAttributes;
208 collectLayoutAttributes(text, newLayoutAttributes);
209 ASSERT(newLayoutAttributes == expectedLayoutAttributes);
210 #endif
211 } 125 }
212 126
213 void LayoutSVGText::willBeDestroyed() 127 void LayoutSVGText::willBeDestroyed()
214 { 128 {
215 m_layoutAttributes.clear(); 129 m_layoutAttributes.clear();
216 m_layoutAttributesBuilder.clearTextPositioningElements(); 130 m_layoutAttributesBuilder.clearTextPositioningElements();
217 131
218 LayoutSVGBlock::willBeDestroyed(); 132 LayoutSVGBlock::willBeDestroyed();
219 } 133 }
220 134
221 void LayoutSVGText::subtreeChildWillBeRemoved(LayoutObject* child, Vector<SVGTex tLayoutAttributes*, 2>& affectedAttributes) 135 void LayoutSVGText::subtreeChildWillBeRemoved(LayoutObject* child)
222 { 136 {
223 ASSERT(child); 137 ASSERT(child);
224 if (!shouldHandleSubtreeMutations()) 138 if (!shouldHandleSubtreeMutations())
225 return; 139 return;
226 140
227 checkLayoutAttributesConsistency(this, m_layoutAttributes); 141 // The positioning elements cache depends on the size of each text layoutObj ect in the
142 // subtree. If this changes, clear the cache. It will be rebuilt below on th e next layout.
143 m_layoutAttributesBuilder.clearTextPositioningElements();
144 setNeedsPositioningValuesUpdate();
145 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::ChildChange d);
228 146
229 // The positioning elements cache depends on the size of each text layoutObj ect in the
230 // subtree. If this changes, clear the cache. It's going to be rebuilt below .
231 m_layoutAttributesBuilder.clearTextPositioningElements();
232 if (m_layoutAttributes.isEmpty() || !child->isSVGInlineText()) 147 if (m_layoutAttributes.isEmpty() || !child->isSVGInlineText())
233 return; 148 return;
234 149
235 // This logic requires that the 'text' child is still inserted in the tree. 150 // Make sure that a text node (layout attribute) reference is not left
236 LayoutSVGInlineText* text = toLayoutSVGInlineText(child); 151 // dangling in |m_layoutAttributes|.
237 SVGTextLayoutAttributes* previous = nullptr; 152 size_t position = m_layoutAttributes.find(toLayoutSVGInlineText(child)->layo utAttributes());
238 SVGTextLayoutAttributes* next = nullptr;
239 if (!documentBeingDestroyed())
240 findPreviousAndNextAttributes(this, text, previous, next);
241
242 if (previous)
243 affectedAttributes.append(previous);
244 if (next)
245 affectedAttributes.append(next);
246
247 size_t position = m_layoutAttributes.find(text->layoutAttributes());
248 ASSERT(position != kNotFound); 153 ASSERT(position != kNotFound);
249 m_layoutAttributes.remove(position); 154 m_layoutAttributes.remove(position);
250 } 155 }
251 156
252 void LayoutSVGText::subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes* , 2>& affectedAttributes)
253 {
254 if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) {
255 ASSERT(affectedAttributes.isEmpty());
256 return;
257 }
258
259 // This is called immediately after subtreeChildWillBeDestroyed, once the La youtSVGInlineText::willBeDestroyed() method
260 // passes on to the base class, which removes us from the layout tree. At th is point we can update the layout attributes.
261 unsigned size = affectedAttributes.size();
262 for (unsigned i = 0; i < size; ++i)
263 m_layoutAttributesBuilder.buildLayoutAttributesForText(affectedAttribute s[i]->context());
264 }
265
266 void LayoutSVGText::subtreeTextDidChange(LayoutSVGInlineText* text) 157 void LayoutSVGText::subtreeTextDidChange(LayoutSVGInlineText* text)
267 { 158 {
268 ASSERT(text); 159 ASSERT(text);
269 ASSERT(!beingDestroyed()); 160 ASSERT(!beingDestroyed());
270 if (!everHadLayout()) { 161 if (!everHadLayout()) {
271 ASSERT(m_layoutAttributes.isEmpty()); 162 ASSERT(m_layoutAttributes.isEmpty());
272 ASSERT(!m_layoutAttributesBuilder.numberOfTextPositioningElements()); 163 ASSERT(!m_layoutAttributesBuilder.numberOfTextPositioningElements());
273 return; 164 return;
274 } 165 }
275 166
276 // The positioning elements cache depends on the size of each text object in 167 // The positioning elements cache depends on the size of each text object in
277 // the subtree. If this changes, clear the cache and mark it for rebuilding 168 // the subtree. If this changes, clear the cache and mark it for rebuilding
278 // in the next layout. 169 // in the next layout.
279 m_layoutAttributesBuilder.clearTextPositioningElements(); 170 m_layoutAttributesBuilder.clearTextPositioningElements();
280 setNeedsPositioningValuesUpdate(); 171 setNeedsPositioningValuesUpdate();
281 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::TextChanged ); 172 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::TextChanged );
282 } 173 }
283 174
284 static inline void updateFontInAllDescendants(LayoutObject* start, SVGTextLayout AttributesBuilder* builder = nullptr) 175 static inline void updateFontInAllDescendants(LayoutSVGText& textRoot, SVGTextLa youtAttributesBuilder* builder = nullptr)
285 { 176 {
286 for (LayoutObject* descendant = start; descendant; descendant = descendant-> nextInPreOrder(start)) { 177 for (LayoutObject* descendant = &textRoot; descendant; descendant = descenda nt->nextInPreOrder(&textRoot)) {
287 if (!descendant->isSVGInlineText()) 178 if (!descendant->isSVGInlineText())
288 continue; 179 continue;
289 LayoutSVGInlineText* text = toLayoutSVGInlineText(descendant); 180 LayoutSVGInlineText* text = toLayoutSVGInlineText(descendant);
290 text->updateScaledFont(); 181 text->updateScaledFont();
291 if (builder) 182 if (builder)
292 builder->rebuildMetricsForTextLayoutObject(text); 183 builder->rebuildMetricsForTextLayoutObject(textRoot, *text);
293 } 184 }
294 } 185 }
295 186
187 static inline void checkLayoutAttributesConsistency(LayoutSVGText* text, Vector< SVGTextLayoutAttributes*>& expectedLayoutAttributes)
188 {
189 #if ENABLE(ASSERT)
190 Vector<SVGTextLayoutAttributes*> newLayoutAttributes;
191 collectLayoutAttributes(text, newLayoutAttributes);
192 ASSERT(newLayoutAttributes == expectedLayoutAttributes);
193 #endif
194 }
195
296 void LayoutSVGText::layout() 196 void LayoutSVGText::layout()
297 { 197 {
298 ASSERT(needsLayout()); 198 ASSERT(needsLayout());
299 LayoutAnalyzer::Scope analyzer(*this); 199 LayoutAnalyzer::Scope analyzer(*this);
300 200
301 bool updateCachedBoundariesInParents = false; 201 bool updateCachedBoundariesInParents = false;
302 if (m_needsTransformUpdate) { 202 if (m_needsTransformUpdate) {
303 m_localTransform = toSVGTextElement(node())->calculateAnimatedLocalTrans form(); 203 m_localTransform = toSVGTextElement(node())->calculateAnimatedLocalTrans form();
304 m_needsTransformUpdate = false; 204 m_needsTransformUpdate = false;
305 updateCachedBoundariesInParents = true; 205 updateCachedBoundariesInParents = true;
306 } 206 }
307 207
308 if (!everHadLayout()) { 208 if (!everHadLayout()) {
309 // When laying out initially, collect all layout attributes, build the c haracter data map, 209 // When laying out initially, collect all layout attributes, build the c haracter data map,
310 // and propogate resulting SVGLayoutAttributes to all LayoutSVGInlineTex t children in the subtree. 210 // and propogate resulting SVGLayoutAttributes to all LayoutSVGInlineTex t children in the subtree.
311 ASSERT(m_layoutAttributes.isEmpty()); 211 ASSERT(m_layoutAttributes.isEmpty());
312 collectLayoutAttributes(this, m_layoutAttributes); 212 collectLayoutAttributes(this, m_layoutAttributes);
313 updateFontInAllDescendants(this); 213 updateFontInAllDescendants(*this);
314 m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); 214 m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this);
315 215
316 m_needsReordering = true; 216 m_needsReordering = true;
317 m_needsTextMetricsUpdate = false; 217 m_needsTextMetricsUpdate = false;
318 m_needsPositioningValuesUpdate = false; 218 m_needsPositioningValuesUpdate = false;
319 updateCachedBoundariesInParents = true; 219 updateCachedBoundariesInParents = true;
320 } else if (m_needsPositioningValuesUpdate) { 220 } else if (m_needsPositioningValuesUpdate) {
321 // When the x/y/dx/dy/rotate lists change, recompute the layout attribut es, and eventually 221 // When the x/y/dx/dy/rotate lists change, recompute the layout attribut es, and eventually
322 // update the on-screen font objects as well in all descendants. 222 // update the on-screen font objects as well in all descendants.
323 if (m_needsTextMetricsUpdate) { 223 if (m_needsTextMetricsUpdate) {
324 updateFontInAllDescendants(this); 224 updateFontInAllDescendants(*this);
325 m_needsTextMetricsUpdate = false; 225 m_needsTextMetricsUpdate = false;
326 } 226 }
327 227
228 m_layoutAttributes.clear();
fs 2016/04/04 20:04:13 Should probably just do this directly "on invalida
pdr. 2016/04/04 22:33:13 Followup sounds great
229 collectLayoutAttributes(this, m_layoutAttributes);
328 m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); 230 m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this);
329 m_needsReordering = true; 231 m_needsReordering = true;
330 m_needsPositioningValuesUpdate = false; 232 m_needsPositioningValuesUpdate = false;
331 updateCachedBoundariesInParents = true; 233 updateCachedBoundariesInParents = true;
332 } else if (m_needsTextMetricsUpdate || SVGLayoutSupport::findTreeRootObject( this)->isLayoutSizeChanged()) { 234 } else if (m_needsTextMetricsUpdate || SVGLayoutSupport::findTreeRootObject( this)->isLayoutSizeChanged()) {
333 // If the root layout size changed (eg. window size changes) or the tran sform to the root 235 // If the root layout size changed (eg. window size changes) or the tran sform to the root
334 // context has changed then recompute the on-screen font size. 236 // context has changed then recompute the on-screen font size.
335 updateFontInAllDescendants(this, &m_layoutAttributesBuilder); 237 updateFontInAllDescendants(*this, &m_layoutAttributesBuilder);
336 238
337 ASSERT(!m_needsReordering); 239 ASSERT(!m_needsReordering);
338 ASSERT(!m_needsPositioningValuesUpdate); 240 ASSERT(!m_needsPositioningValuesUpdate);
339 m_needsTextMetricsUpdate = false; 241 m_needsTextMetricsUpdate = false;
340 updateCachedBoundariesInParents = true; 242 updateCachedBoundariesInParents = true;
341 } 243 }
342 244
343 checkLayoutAttributesConsistency(this, m_layoutAttributes); 245 checkLayoutAttributesConsistency(this, m_layoutAttributes);
344 246
345 // Reduced version of LayoutBlock::layoutBlock(), which only takes care of S VG text. 247 // Reduced version of LayoutBlock::layoutBlock(), which only takes care of S VG text.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 { 389 {
488 LayoutSVGBlock::addChild(child, beforeChild); 390 LayoutSVGBlock::addChild(child, beforeChild);
489 391
490 SVGResourcesCache::clientWasAddedToTree(child, child->styleRef()); 392 SVGResourcesCache::clientWasAddedToTree(child, child->styleRef());
491 subtreeChildWasAdded(child); 393 subtreeChildWasAdded(child);
492 } 394 }
493 395
494 void LayoutSVGText::removeChild(LayoutObject* child) 396 void LayoutSVGText::removeChild(LayoutObject* child)
495 { 397 {
496 SVGResourcesCache::clientWillBeRemovedFromTree(child); 398 SVGResourcesCache::clientWillBeRemovedFromTree(child);
399 subtreeChildWillBeRemoved(child);
497 400
498 Vector<SVGTextLayoutAttributes*, 2> affectedAttributes;
499 FontCachePurgePreventer fontCachePurgePreventer;
500 subtreeChildWillBeRemoved(child, affectedAttributes);
501 LayoutSVGBlock::removeChild(child); 401 LayoutSVGBlock::removeChild(child);
502 subtreeChildWasRemoved(affectedAttributes);
503 } 402 }
504 403
505 void LayoutSVGText::invalidateTreeIfNeeded(const PaintInvalidationState& paintIn validationState) 404 void LayoutSVGText::invalidateTreeIfNeeded(const PaintInvalidationState& paintIn validationState)
506 { 405 {
507 ASSERT(!needsLayout()); 406 ASSERT(!needsLayout());
508 407
509 if (!shouldCheckForPaintInvalidation(paintInvalidationState)) 408 if (!shouldCheckForPaintInvalidation(paintInvalidationState))
510 return; 409 return;
511 410
512 PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *th is); 411 PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *th is);
513 PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidatio nState); 412 PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidatio nState);
514 clearPaintInvalidationFlags(newPaintInvalidationState); 413 clearPaintInvalidationFlags(newPaintInvalidationState);
515 414
516 if (reason == PaintInvalidationDelayedFull) 415 if (reason == PaintInvalidationDelayedFull)
517 paintInvalidationState.pushDelayedPaintInvalidationTarget(*this); 416 paintInvalidationState.pushDelayedPaintInvalidationTarget(*this);
518 417
519 // TODO(wangxianzhu): Move this to fast path if possible. crbug.com/391054. 418 // TODO(wangxianzhu): Move this to fast path if possible. crbug.com/391054.
520 ForceHorriblySlowRectMapping slowRectMapping(&newPaintInvalidationState); 419 ForceHorriblySlowRectMapping slowRectMapping(&newPaintInvalidationState);
521 if (reason == PaintInvalidationSVGResourceChange) 420 if (reason == PaintInvalidationSVGResourceChange)
522 newPaintInvalidationState.setForceSubtreeInvalidationWithinContainer(); 421 newPaintInvalidationState.setForceSubtreeInvalidationWithinContainer();
523 422
524 newPaintInvalidationState.updateForChildren(); 423 newPaintInvalidationState.updateForChildren();
525 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); 424 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState);
526 } 425 }
527 426
528 } // namespace blink 427 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698