| OLD | NEW |
| 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 { | |
| 19 LayoutRect contentBoxRect; | |
| 20 LayoutRect layoutOverflowRect; | |
| 21 }; | |
| 22 | |
| 23 typedef HashMap<const LayoutBox*, PreviousBoxGeometries> | |
| 24 PreviousBoxGeometriesMap; | |
| 25 static PreviousBoxGeometriesMap& previousBoxGeometriesMap() { | |
| 26 DEFINE_STATIC_LOCAL(PreviousBoxGeometriesMap, map, ()); | |
| 27 return map; | |
| 28 } | |
| 29 | |
| 30 void BoxPaintInvalidator::boxWillBeDestroyed(const LayoutBox& box) { | |
| 31 DCHECK(box.hasPreviousBoxGeometries() == | |
| 32 previousBoxGeometriesMap().contains(&box)); | |
| 33 if (box.hasPreviousBoxGeometries()) | |
| 34 previousBoxGeometriesMap().erase(&box); | |
| 35 } | |
| 36 | |
| 37 static LayoutRect computeRightDelta(const LayoutPoint& location, | 18 static LayoutRect computeRightDelta(const LayoutPoint& location, |
| 38 const LayoutSize& oldSize, | 19 const LayoutSize& oldSize, |
| 39 const LayoutSize& newSize, | 20 const LayoutSize& newSize, |
| 40 const LayoutUnit& extraWidth) { | 21 const LayoutUnit& extraWidth) { |
| 41 LayoutUnit delta = newSize.width() - oldSize.width(); | 22 LayoutUnit delta = newSize.width() - oldSize.width(); |
| 42 if (delta > 0) { | 23 if (delta > 0) { |
| 43 return LayoutRect(location.x() + oldSize.width() - extraWidth, location.y(), | 24 return LayoutRect(location.x() + oldSize.width() - extraWidth, location.y(), |
| 44 delta + extraWidth, newSize.height()); | 25 delta + extraWidth, newSize.height()); |
| 45 } | 26 } |
| 46 if (delta < 0) { | 27 if (delta < 0) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 // can safely exit here. | 92 // can safely exit here. |
| 112 if (layoutView.usesCompositing() && | 93 if (layoutView.usesCompositing() && |
| 113 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) | 94 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) |
| 114 return reason; | 95 return reason; |
| 115 } | 96 } |
| 116 | 97 |
| 117 const ComputedStyle& style = m_box.styleRef(); | 98 const ComputedStyle& style = m_box.styleRef(); |
| 118 | 99 |
| 119 if ((style.backgroundLayers().thisOrNextLayersUseContentBox() || | 100 if ((style.backgroundLayers().thisOrNextLayersUseContentBox() || |
| 120 style.maskLayers().thisOrNextLayersUseContentBox()) && | 101 style.maskLayers().thisOrNextLayersUseContentBox()) && |
| 121 previousContentBoxRect() != m_box.contentBoxRect()) | 102 m_box.previousContentBoxSize() != m_box.contentBoxRect().size()) |
| 122 return PaintInvalidationContentBoxChange; | 103 return PaintInvalidationContentBoxChange; |
| 123 | 104 |
| 124 LayoutSize oldBorderBoxSize = m_box.previousSize(); | 105 LayoutSize oldBorderBoxSize = m_box.previousSize(); |
| 125 LayoutSize newBorderBoxSize = m_box.size(); | 106 LayoutSize newBorderBoxSize = m_box.size(); |
| 126 bool borderBoxChanged = oldBorderBoxSize != newBorderBoxSize; | 107 bool borderBoxChanged = oldBorderBoxSize != newBorderBoxSize; |
| 127 if (!borderBoxChanged && m_context.oldVisualRect == m_context.newVisualRect) | 108 if (!borderBoxChanged && m_context.oldVisualRect == m_context.newVisualRect) |
| 128 return PaintInvalidationNone; | 109 return PaintInvalidationNone; |
| 129 | 110 |
| 130 // If either border box changed or bounds changed, and old or new border box | 111 // If either border box changed or bounds changed, and old or new border box |
| 131 // doesn't equal old or new bounds, incremental invalidation is not | 112 // doesn't equal old or new bounds, incremental invalidation is not |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 return false; | 191 return false; |
| 211 } | 192 } |
| 212 | 193 |
| 213 void BoxPaintInvalidator::invalidateScrollingContentsBackgroundIfNeeded() { | 194 void BoxPaintInvalidator::invalidateScrollingContentsBackgroundIfNeeded() { |
| 214 bool paintsOntoScrollingContentsLayer = | 195 bool paintsOntoScrollingContentsLayer = |
| 215 backgroundPaintsOntoScrollingContentsLayer(); | 196 backgroundPaintsOntoScrollingContentsLayer(); |
| 216 if (!paintsOntoScrollingContentsLayer && | 197 if (!paintsOntoScrollingContentsLayer && |
| 217 !backgroundGeometryDependsOnLayoutOverflowRect()) | 198 !backgroundGeometryDependsOnLayoutOverflowRect()) |
| 218 return; | 199 return; |
| 219 | 200 |
| 220 const LayoutRect& oldLayoutOverflow = previousLayoutOverflowRect(); | 201 const LayoutRect& oldLayoutOverflow = m_box.previousLayoutOverflowRect(); |
| 221 LayoutRect newLayoutOverflow = m_box.layoutOverflowRect(); | 202 LayoutRect newLayoutOverflow = m_box.layoutOverflowRect(); |
| 222 | 203 |
| 223 bool shouldFullyInvalidateOnScrollingContentsLayer = false; | 204 bool shouldFullyInvalidateOnScrollingContentsLayer = false; |
| 224 if (m_box.backgroundChangedSinceLastPaintInvalidation()) { | 205 if (m_box.backgroundChangedSinceLastPaintInvalidation()) { |
| 225 if (!paintsOntoScrollingContentsLayer) { | 206 if (!paintsOntoScrollingContentsLayer) { |
| 226 // The box should have been set needing full invalidation on style change. | 207 // The box should have been set needing full invalidation on style change. |
| 227 DCHECK(m_box.shouldDoFullPaintInvalidation()); | 208 DCHECK(m_box.shouldDoFullPaintInvalidation()); |
| 228 return; | 209 return; |
| 229 } | 210 } |
| 230 shouldFullyInvalidateOnScrollingContentsLayer = true; | 211 shouldFullyInvalidateOnScrollingContentsLayer = true; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 | 281 |
| 301 if (PaintLayerScrollableArea* area = m_box.getScrollableArea()) | 282 if (PaintLayerScrollableArea* area = m_box.getScrollableArea()) |
| 302 area->invalidatePaintOfScrollControlsIfNeeded(m_context); | 283 area->invalidatePaintOfScrollControlsIfNeeded(m_context); |
| 303 | 284 |
| 304 // This is for the next invalidatePaintIfNeeded so must be at the end. | 285 // This is for the next invalidatePaintIfNeeded so must be at the end. |
| 305 savePreviousBoxGeometriesIfNeeded(); | 286 savePreviousBoxGeometriesIfNeeded(); |
| 306 | 287 |
| 307 return reason; | 288 return reason; |
| 308 } | 289 } |
| 309 | 290 |
| 310 bool BoxPaintInvalidator::needsToSavePreviousBoxGeometries() { | 291 bool BoxPaintInvalidator::needsToSavePreviousOtherBoxGeometries() { |
| 311 // Don't save old box geometries if the paint rect is empty because we'll | 292 // Don't save old box geometries if the paint rect is empty because we'll |
| 312 // fully invalidate once the paint rect becomes non-empty. | 293 // fully invalidate once the paint rect becomes non-empty. |
| 313 if (m_context.newVisualRect.isEmpty()) | 294 if (m_context.newVisualRect.isEmpty()) |
| 314 return false; | 295 return false; |
| 315 | 296 |
| 316 if (m_box.paintedOutputOfObjectHasNoEffectRegardlessOfSize()) | 297 if (m_box.paintedOutputOfObjectHasNoEffectRegardlessOfSize()) |
| 317 return false; | 298 return false; |
| 318 | 299 |
| 319 const ComputedStyle& style = m_box.styleRef(); | 300 const ComputedStyle& style = m_box.styleRef(); |
| 320 | 301 |
| 321 // Background and mask layers can depend on other boxes than border box. See | 302 // Background and mask layers can depend on other boxes than border box. See |
| 322 // crbug.com/490533 | 303 // crbug.com/490533 |
| 323 if (style.backgroundLayers().thisOrNextLayersUseContentBox() || | 304 if ((style.backgroundLayers().thisOrNextLayersUseContentBox() || |
| 324 style.maskLayers().thisOrNextLayersUseContentBox() || | 305 style.maskLayers().thisOrNextLayersUseContentBox()) && |
| 325 backgroundGeometryDependsOnLayoutOverflowRect() || | 306 m_box.contentBoxRect().size() != m_box.size()) |
| 326 backgroundPaintsOntoScrollingContentsLayer()) | 307 return true; |
| 308 if ((backgroundGeometryDependsOnLayoutOverflowRect() || |
| 309 backgroundPaintsOntoScrollingContentsLayer()) && |
| 310 m_box.layoutOverflowRect() != m_box.borderBoxRect()) |
| 327 return true; | 311 return true; |
| 328 | 312 |
| 329 return false; | 313 return false; |
| 330 } | 314 } |
| 331 | 315 |
| 332 void BoxPaintInvalidator::savePreviousBoxGeometriesIfNeeded() { | 316 void BoxPaintInvalidator::savePreviousBoxGeometriesIfNeeded() { |
| 333 m_box.getMutableForPainting().setPreviousSize(m_box.size()); | 317 m_box.getMutableForPainting().savePreviousSize(); |
| 334 | 318 |
| 335 DCHECK(m_box.hasPreviousBoxGeometries() == | 319 if (needsToSavePreviousOtherBoxGeometries()) |
| 336 previousBoxGeometriesMap().contains(&m_box)); | 320 m_box.getMutableForPainting().savePreviousOtherBoxGeometries(); |
| 337 if (!needsToSavePreviousBoxGeometries()) { | 321 else |
| 338 if (m_box.hasPreviousBoxGeometries()) { | 322 m_box.getMutableForPainting().clearPreviousOtherBoxGeometries(); |
| 339 previousBoxGeometriesMap().erase(&m_box); | |
| 340 m_box.getMutableForPainting().setHasPreviousBoxGeometries(false); | |
| 341 } | |
| 342 return; | |
| 343 } | |
| 344 | |
| 345 PreviousBoxGeometries geometries = {m_box.contentBoxRect(), | |
| 346 m_box.layoutOverflowRect()}; | |
| 347 previousBoxGeometriesMap().set(&m_box, geometries); | |
| 348 m_box.getMutableForPainting().setHasPreviousBoxGeometries(true); | |
| 349 } | |
| 350 | |
| 351 LayoutRect BoxPaintInvalidator::previousContentBoxRect() { | |
| 352 DCHECK(m_box.hasPreviousBoxGeometries() == | |
| 353 previousBoxGeometriesMap().contains(&m_box)); | |
| 354 return m_box.hasPreviousBoxGeometries() | |
| 355 ? previousBoxGeometriesMap().get(&m_box).contentBoxRect | |
| 356 : LayoutRect(LayoutPoint(), m_box.previousSize()); | |
| 357 } | |
| 358 | |
| 359 LayoutRect BoxPaintInvalidator::previousLayoutOverflowRect() { | |
| 360 DCHECK(m_box.hasPreviousBoxGeometries() == | |
| 361 previousBoxGeometriesMap().contains(&m_box)); | |
| 362 return m_box.hasPreviousBoxGeometries() | |
| 363 ? previousBoxGeometriesMap().get(&m_box).layoutOverflowRect | |
| 364 : LayoutRect(LayoutPoint(), m_box.previousSize()); | |
| 365 } | 323 } |
| 366 | 324 |
| 367 } // namespace blink | 325 } // namespace blink |
| OLD | NEW |