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

Side by Side Diff: third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp

Issue 2689213013: Move previous border box size out of global map into LayoutBox::m_previousSize (Closed)
Patch Set: - Created 3 years, 10 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 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/BoxPaintInvalidator.h" 5 #include "core/paint/BoxPaintInvalidator.h"
6 6
7 #include "core/frame/Settings.h" 7 #include "core/frame/Settings.h"
8 #include "core/layout/LayoutView.h" 8 #include "core/layout/LayoutView.h"
9 #include "core/layout/compositing/CompositedLayerMapping.h" 9 #include "core/layout/compositing/CompositedLayerMapping.h"
10 #include "core/paint/ObjectPaintInvalidator.h" 10 #include "core/paint/ObjectPaintInvalidator.h"
11 #include "core/paint/PaintInvalidator.h" 11 #include "core/paint/PaintInvalidator.h"
12 #include "core/paint/PaintLayer.h" 12 #include "core/paint/PaintLayer.h"
13 #include "core/paint/PaintLayerScrollableArea.h" 13 #include "core/paint/PaintLayerScrollableArea.h"
14 #include "platform/geometry/LayoutRect.h" 14 #include "platform/geometry/LayoutRect.h"
15 15
16 namespace blink { 16 namespace blink {
17 17
18 struct PreviousBoxGeometries { 18 struct PreviousBoxGeometries {
19 LayoutSize borderBoxSize;
20 LayoutRect contentBoxRect; 19 LayoutRect contentBoxRect;
21 LayoutRect layoutOverflowRect; 20 LayoutRect layoutOverflowRect;
22 }; 21 };
23 22
24 typedef HashMap<const LayoutBox*, PreviousBoxGeometries> 23 typedef HashMap<const LayoutBox*, PreviousBoxGeometries>
25 PreviousBoxGeometriesMap; 24 PreviousBoxGeometriesMap;
26 static PreviousBoxGeometriesMap& previousBoxGeometriesMap() { 25 static PreviousBoxGeometriesMap& previousBoxGeometriesMap() {
27 DEFINE_STATIC_LOCAL(PreviousBoxGeometriesMap, map, ()); 26 DEFINE_STATIC_LOCAL(PreviousBoxGeometriesMap, map, ());
28 return map; 27 return map;
29 } 28 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 115 }
117 116
118 const ComputedStyle& style = m_box.styleRef(); 117 const ComputedStyle& style = m_box.styleRef();
119 118
120 if ((style.backgroundLayers().thisOrNextLayersUseContentBox() || 119 if ((style.backgroundLayers().thisOrNextLayersUseContentBox() ||
121 style.maskLayers().thisOrNextLayersUseContentBox() || 120 style.maskLayers().thisOrNextLayersUseContentBox() ||
122 style.boxSizing() == EBoxSizing::kBorderBox) && 121 style.boxSizing() == EBoxSizing::kBorderBox) &&
123 previousContentBoxRect() != m_box.contentBoxRect()) 122 previousContentBoxRect() != m_box.contentBoxRect())
124 return PaintInvalidationContentBoxChange; 123 return PaintInvalidationContentBoxChange;
125 124
126 LayoutSize oldBorderBoxSize = 125 LayoutSize oldBorderBoxSize = m_box.previousSize();
127 previousBorderBoxSize(m_box, m_context.oldVisualRect.size());
128 LayoutSize newBorderBoxSize = m_box.size(); 126 LayoutSize newBorderBoxSize = m_box.size();
129 bool borderBoxChanged = oldBorderBoxSize != newBorderBoxSize; 127 bool borderBoxChanged = oldBorderBoxSize != newBorderBoxSize;
130 if (!borderBoxChanged && m_context.oldVisualRect == m_context.newVisualRect) 128 if (!borderBoxChanged && m_context.oldVisualRect == m_context.newVisualRect)
131 return PaintInvalidationNone; 129 return PaintInvalidationNone;
132 130
133 // If either border box changed or bounds changed, and old or new border box 131 // If either border box changed or bounds changed, and old or new border box
134 // doesn't equal old or new bounds, incremental invalidation is not 132 // doesn't equal old or new bounds, incremental invalidation is not
135 // applicable. This captures the following cases: 133 // applicable. This captures the following cases:
136 // - pixel snapping of paint invalidation bounds, 134 // - pixel snapping of paint invalidation bounds,
137 // - scale, rotate, skew etc. transforms, 135 // - scale, rotate, skew etc. transforms,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 223
226 bool shouldFullyInvalidateOnScrollingContentsLayer = false; 224 bool shouldFullyInvalidateOnScrollingContentsLayer = false;
227 if (m_box.backgroundChangedSinceLastPaintInvalidation()) { 225 if (m_box.backgroundChangedSinceLastPaintInvalidation()) {
228 if (!paintsOntoScrollingContentsLayer) { 226 if (!paintsOntoScrollingContentsLayer) {
229 // The box should have been set needing full invalidation on style change. 227 // The box should have been set needing full invalidation on style change.
230 DCHECK(m_box.shouldDoFullPaintInvalidation()); 228 DCHECK(m_box.shouldDoFullPaintInvalidation());
231 return; 229 return;
232 } 230 }
233 shouldFullyInvalidateOnScrollingContentsLayer = true; 231 shouldFullyInvalidateOnScrollingContentsLayer = true;
234 } else { 232 } else {
235 // Check change of layout overflow for incremental invalidation. 233 // Check change of layout overflow for full or incremental invalidation.
236 if (!m_box.hasPreviousBoxGeometries() || 234 if (newLayoutOverflow == oldLayoutOverflow)
237 newLayoutOverflow == oldLayoutOverflow)
238 return; 235 return;
236 bool shouldFullyInvalidate =
237 shouldFullyInvalidateBackgroundOnLayoutOverflowChange(
238 oldLayoutOverflow, newLayoutOverflow);
239 if (!paintsOntoScrollingContentsLayer) { 239 if (!paintsOntoScrollingContentsLayer) {
240 if (shouldFullyInvalidateBackgroundOnLayoutOverflowChange( 240 if (shouldFullyInvalidate) {
241 oldLayoutOverflow, newLayoutOverflow)) {
242 m_box.getMutableForPainting().setShouldDoFullPaintInvalidation( 241 m_box.getMutableForPainting().setShouldDoFullPaintInvalidation(
243 PaintInvalidationLayoutOverflowBoxChange); 242 PaintInvalidationLayoutOverflowBoxChange);
244 } 243 }
245 return; 244 return;
246 } 245 }
247 shouldFullyInvalidateOnScrollingContentsLayer = 246 shouldFullyInvalidateOnScrollingContentsLayer = shouldFullyInvalidate;
248 shouldFullyInvalidateBackgroundOnLayoutOverflowChange(
249 oldLayoutOverflow, newLayoutOverflow);
250 } 247 }
251 248
252 if (shouldFullyInvalidateOnScrollingContentsLayer) { 249 if (shouldFullyInvalidateOnScrollingContentsLayer) {
253 ObjectPaintInvalidatorWithContext(m_box, m_context) 250 ObjectPaintInvalidatorWithContext(m_box, m_context)
254 .fullyInvalidatePaint( 251 .fullyInvalidatePaint(
255 PaintInvalidationBackgroundOnScrollingContentsLayer, 252 PaintInvalidationBackgroundOnScrollingContentsLayer,
256 oldLayoutOverflow, newLayoutOverflow); 253 oldLayoutOverflow, newLayoutOverflow);
257 } else { 254 } else {
258 incrementallyInvalidatePaint( 255 incrementallyInvalidatePaint(
259 PaintInvalidationBackgroundOnScrollingContentsLayer, oldLayoutOverflow, 256 PaintInvalidationBackgroundOnScrollingContentsLayer, oldLayoutOverflow,
(...skipping 13 matching lines...) Expand all
273 270
274 PaintInvalidationReason reason = computePaintInvalidationReason(); 271 PaintInvalidationReason reason = computePaintInvalidationReason();
275 if (reason == PaintInvalidationIncremental) { 272 if (reason == PaintInvalidationIncremental) {
276 bool invalidated; 273 bool invalidated;
277 if (m_box.isLayoutView() && 274 if (m_box.isLayoutView() &&
278 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { 275 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
279 invalidated = incrementallyInvalidatePaint( 276 invalidated = incrementallyInvalidatePaint(
280 reason, m_context.oldVisualRect, m_context.newVisualRect); 277 reason, m_context.oldVisualRect, m_context.newVisualRect);
281 } else { 278 } else {
282 invalidated = incrementallyInvalidatePaint( 279 invalidated = incrementallyInvalidatePaint(
283 reason, LayoutRect(m_context.oldLocation, 280 reason, LayoutRect(m_context.oldLocation, m_box.previousSize()),
284 previousBorderBoxSize(
285 m_box, m_context.oldVisualRect.size())),
286 LayoutRect(m_context.newLocation, m_box.size())); 281 LayoutRect(m_context.newLocation, m_box.size()));
287 } 282 }
288 if (invalidated) { 283 if (invalidated) {
289 m_context.paintingLayer->setNeedsRepaint(); 284 m_context.paintingLayer->setNeedsRepaint();
290 m_box.invalidateDisplayItemClients(reason); 285 m_box.invalidateDisplayItemClients(reason);
291 } else { 286 } else {
292 reason = PaintInvalidationNone; 287 reason = PaintInvalidationNone;
293 } 288 }
294 289
295 // Though we have done incremental invalidation, we still need to call 290 // Though we have done incremental invalidation, we still need to call
(...skipping 11 matching lines...) Expand all
307 if (PaintLayerScrollableArea* area = m_box.getScrollableArea()) 302 if (PaintLayerScrollableArea* area = m_box.getScrollableArea())
308 area->invalidatePaintOfScrollControlsIfNeeded(m_context); 303 area->invalidatePaintOfScrollControlsIfNeeded(m_context);
309 304
310 // This is for the next invalidatePaintIfNeeded so must be at the end. 305 // This is for the next invalidatePaintIfNeeded so must be at the end.
311 savePreviousBoxGeometriesIfNeeded(); 306 savePreviousBoxGeometriesIfNeeded();
312 307
313 return reason; 308 return reason;
314 } 309 }
315 310
316 bool BoxPaintInvalidator::needsToSavePreviousBoxGeometries() { 311 bool BoxPaintInvalidator::needsToSavePreviousBoxGeometries() {
317 LayoutSize paintInvalidationSize = m_context.newVisualRect.size(); 312 // Don't save old box geometries if the paint rect is empty because we'll
313 // fully invalidate once the paint rect becomes non-empty.
314 if (m_context.newVisualRect.isEmpty())
315 return false;
318 316
319 // The shortcuts doesn't apply to HTML element. ViewPaintInvalidator needs to 317 if (m_box.paintedOutputOfObjectHasNoEffectRegardlessOfSize())
320 // know its previous border box size even if it has visibility:hidden (causing 318 return false;
321 // empty paintInvalidationSize) or has no painted output.
322 if (!m_box.node() || !m_box.node()->isHTMLElement()) {
323 // Don't save old box geometries if the paint rect is empty because we'll
324 // fully invalidate once the paint rect becomes non-empty.
325 if (paintInvalidationSize.isEmpty())
326 return false;
327
328 if (m_box.paintedOutputOfObjectHasNoEffectRegardlessOfSize())
329 return false;
330 }
331 319
332 const ComputedStyle& style = m_box.styleRef(); 320 const ComputedStyle& style = m_box.styleRef();
333 321
334 // If we use border-box sizing we need to track changes in the size of the 322 // If we use border-box sizing we need to track changes in the size of the
335 // content box. 323 // content box.
336 if (style.boxSizing() == EBoxSizing::kBorderBox) 324 if (style.boxSizing() == EBoxSizing::kBorderBox)
337 return true; 325 return true;
338 326
339 // No need to save old border box size if we can use size of the old paint
340 // rect as the old border box size in the next invalidation.
341 if (paintInvalidationSize != m_box.size())
342 return true;
343
344 // Background and mask layers can depend on other boxes than border box. See 327 // Background and mask layers can depend on other boxes than border box. See
345 // crbug.com/490533 328 // crbug.com/490533
346 if (style.backgroundLayers().thisOrNextLayersUseContentBox() || 329 if (style.backgroundLayers().thisOrNextLayersUseContentBox() ||
347 style.maskLayers().thisOrNextLayersUseContentBox() || 330 style.maskLayers().thisOrNextLayersUseContentBox() ||
348 backgroundGeometryDependsOnLayoutOverflowRect() || 331 backgroundGeometryDependsOnLayoutOverflowRect() ||
349 backgroundPaintsOntoScrollingContentsLayer()) 332 backgroundPaintsOntoScrollingContentsLayer())
350 return true; 333 return true;
351 334
352 return false; 335 return false;
353 } 336 }
354 337
355 void BoxPaintInvalidator::savePreviousBoxGeometriesIfNeeded() { 338 void BoxPaintInvalidator::savePreviousBoxGeometriesIfNeeded() {
339 m_box.getMutableForPainting().setPreviousSize(m_box.size());
340
356 DCHECK(m_box.hasPreviousBoxGeometries() == 341 DCHECK(m_box.hasPreviousBoxGeometries() ==
357 previousBoxGeometriesMap().contains(&m_box)); 342 previousBoxGeometriesMap().contains(&m_box));
358 if (!needsToSavePreviousBoxGeometries()) { 343 if (!needsToSavePreviousBoxGeometries()) {
359 if (m_box.hasPreviousBoxGeometries()) { 344 if (m_box.hasPreviousBoxGeometries()) {
360 previousBoxGeometriesMap().erase(&m_box); 345 previousBoxGeometriesMap().erase(&m_box);
361 m_box.getMutableForPainting().setHasPreviousBoxGeometries(false); 346 m_box.getMutableForPainting().setHasPreviousBoxGeometries(false);
362 } 347 }
363 return; 348 return;
364 } 349 }
365 350
366 PreviousBoxGeometries geometries = {m_box.size(), m_box.contentBoxRect(), 351 PreviousBoxGeometries geometries = {m_box.contentBoxRect(),
367 m_box.layoutOverflowRect()}; 352 m_box.layoutOverflowRect()};
368 previousBoxGeometriesMap().set(&m_box, geometries); 353 previousBoxGeometriesMap().set(&m_box, geometries);
369 m_box.getMutableForPainting().setHasPreviousBoxGeometries(true); 354 m_box.getMutableForPainting().setHasPreviousBoxGeometries(true);
370 } 355 }
371 356
372 LayoutSize BoxPaintInvalidator::previousBorderBoxSize(
373 const LayoutBox& box,
374 const LayoutSize& defaultSize) {
375 DCHECK(box.hasPreviousBoxGeometries() ==
376 previousBoxGeometriesMap().contains(&box));
377 if (box.hasPreviousBoxGeometries())
378 return previousBoxGeometriesMap().get(&box).borderBoxSize;
379 return defaultSize;
380 }
381
382 LayoutRect BoxPaintInvalidator::previousContentBoxRect() { 357 LayoutRect BoxPaintInvalidator::previousContentBoxRect() {
383 DCHECK(m_box.hasPreviousBoxGeometries() == 358 DCHECK(m_box.hasPreviousBoxGeometries() ==
384 previousBoxGeometriesMap().contains(&m_box)); 359 previousBoxGeometriesMap().contains(&m_box));
385 return m_box.hasPreviousBoxGeometries() 360 return m_box.hasPreviousBoxGeometries()
386 ? previousBoxGeometriesMap().get(&m_box).contentBoxRect 361 ? previousBoxGeometriesMap().get(&m_box).contentBoxRect
387 : LayoutRect(); 362 : LayoutRect(LayoutPoint(), m_box.previousSize());
388 } 363 }
389 364
390 LayoutRect BoxPaintInvalidator::previousLayoutOverflowRect() { 365 LayoutRect BoxPaintInvalidator::previousLayoutOverflowRect() {
391 DCHECK(m_box.hasPreviousBoxGeometries() == 366 DCHECK(m_box.hasPreviousBoxGeometries() ==
392 previousBoxGeometriesMap().contains(&m_box)); 367 previousBoxGeometriesMap().contains(&m_box));
393 return m_box.hasPreviousBoxGeometries() 368 return m_box.hasPreviousBoxGeometries()
394 ? previousBoxGeometriesMap().get(&m_box).layoutOverflowRect 369 ? previousBoxGeometriesMap().get(&m_box).layoutOverflowRect
395 : LayoutRect(); 370 : LayoutRect(LayoutPoint(), m_box.previousSize());
396 } 371 }
397 372
398 } // namespace blink 373 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698