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/PaintInvalidator.h" | 5 #include "core/paint/PaintInvalidator.h" |
6 | 6 |
7 #include "core/editing/FrameSelection.h" | 7 #include "core/editing/FrameSelection.h" |
8 #include "core/frame/FrameView.h" | 8 #include "core/frame/FrameView.h" |
9 #include "core/frame/LocalFrame.h" | 9 #include "core/frame/LocalFrame.h" |
10 #include "core/frame/Settings.h" | 10 #include "core/frame/Settings.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 object.mapToVisualRectInAncestorSpace(&ancestor, result); | 42 object.mapToVisualRectInAncestorSpace(&ancestor, result); |
43 return result; | 43 return result; |
44 } | 44 } |
45 | 45 |
46 // TODO(wangxianzhu): Combine this into | 46 // TODO(wangxianzhu): Combine this into |
47 // PaintInvalidator::mapLocalRectToBacking() when removing | 47 // PaintInvalidator::mapLocalRectToBacking() when removing |
48 // PaintInvalidationState. | 48 // PaintInvalidationState. |
49 // This function is templatized to avoid FloatRect<->LayoutRect conversions | 49 // This function is templatized to avoid FloatRect<->LayoutRect conversions |
50 // which affect performance. | 50 // which affect performance. |
51 template <typename Rect, typename Point> | 51 template <typename Rect, typename Point> |
52 static LayoutRect mapLocalRectToVisualRectInBacking( | 52 LayoutRect PaintInvalidator::mapLocalRectToVisualRectInBacking( |
53 const LayoutObject& object, | 53 const LayoutObject& object, |
54 const Rect& localRect, | 54 const Rect& localRect, |
55 const PaintInvalidatorContext& context) { | 55 const PaintInvalidatorContext& context) { |
56 if (localRect.isEmpty()) | 56 if (localRect.isEmpty()) |
57 return LayoutRect(); | 57 return LayoutRect(); |
58 | 58 |
59 bool isSVGChild = object.isSVGChild(); | 59 bool isSVGChild = object.isSVGChild(); |
60 | 60 |
61 // TODO(wkorman): The flip below is required because visual rects are | 61 // TODO(wkorman): The flip below is required because visual rects are |
62 // currently in "physical coordinates with flipped block-flow direction" | 62 // currently in "physical coordinates with flipped block-flow direction" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 } else { | 101 } else { |
102 // For non-root SVG, the input rect is in local SVG coordinates in which | 102 // For non-root SVG, the input rect is in local SVG coordinates in which |
103 // paint offset doesn't apply. | 103 // paint offset doesn't apply. |
104 if (!isSVGChild) | 104 if (!isSVGChild) |
105 rect.moveBy(Point(object.paintOffset())); | 105 rect.moveBy(Point(object.paintOffset())); |
106 | 106 |
107 const auto* containerContentsProperties = | 107 const auto* containerContentsProperties = |
108 context.paintInvalidationContainer->paintProperties() | 108 context.paintInvalidationContainer->paintProperties() |
109 ->contentsProperties(); | 109 ->contentsProperties(); |
110 | 110 |
111 if (context.treeBuilderContext.current.transform == | 111 if (context.m_treeBuilderContext.current.transform == |
112 containerContentsProperties->transform() && | 112 containerContentsProperties->transform() && |
113 context.treeBuilderContext.current.clip == | 113 context.m_treeBuilderContext.current.clip == |
114 containerContentsProperties->clip()) { | 114 containerContentsProperties->clip()) { |
115 result = LayoutRect(rect); | 115 result = LayoutRect(rect); |
116 } else { | 116 } else { |
117 // Use enclosingIntRect to ensure the final visual rect will cover the | 117 // Use enclosingIntRect to ensure the final visual rect will cover the |
118 // rect in source coordinates no matter if the painting will use pixel | 118 // rect in source coordinates no matter if the painting will use pixel |
119 // snapping, when transforms are applied. If there is no transform, | 119 // snapping, when transforms are applied. If there is no transform, |
120 // enclosingIntRect is applied in the last step of paint invalidation | 120 // enclosingIntRect is applied in the last step of paint invalidation |
121 // (see CompositedLayerMapping::setContentsNeedDisplayInRect()). | 121 // (see CompositedLayerMapping::setContentsNeedDisplayInRect()). |
122 if (!isSVGChild && | 122 if (!isSVGChild && context.m_treeBuilderContext.current.transform != |
123 context.treeBuilderContext.current.transform != | 123 containerContentsProperties->transform()) |
124 containerContentsProperties->transform()) | |
125 rect = Rect(enclosingIntRect(rect)); | 124 rect = Rect(enclosingIntRect(rect)); |
126 | 125 |
127 PropertyTreeState currentTreeState( | 126 PropertyTreeState currentTreeState( |
128 context.treeBuilderContext.current.transform, | 127 context.m_treeBuilderContext.current.transform, |
129 context.treeBuilderContext.current.clip, nullptr); | 128 context.m_treeBuilderContext.current.clip, nullptr); |
130 | 129 |
131 FloatRect floatRect(rect); | 130 FloatRect floatRect(rect); |
132 context.geometryMapper.sourceToDestinationVisualRect( | 131 context.m_geometryMapper.sourceToDestinationVisualRect( |
133 currentTreeState, *containerContentsProperties, floatRect); | 132 currentTreeState, *containerContentsProperties, floatRect); |
134 result = LayoutRect(floatRect); | 133 result = LayoutRect(floatRect); |
135 } | 134 } |
136 | 135 |
137 // Convert the result to the container's contents space. | 136 // Convert the result to the container's contents space. |
138 result.moveBy(-context.paintInvalidationContainer->paintOffset()); | 137 result.moveBy(-context.paintInvalidationContainer->paintOffset()); |
139 } | 138 } |
140 | 139 |
141 object.adjustVisualRectForRasterEffects(result); | 140 object.adjustVisualRectForRasterEffects(result); |
142 | 141 |
143 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 142 PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
144 *context.paintInvalidationContainer, result); | 143 *context.paintInvalidationContainer, result); |
145 | 144 |
146 result.move(object.scrollAdjustmentForPaintInvalidation( | 145 result.move(object.scrollAdjustmentForPaintInvalidation( |
147 *context.paintInvalidationContainer)); | 146 *context.paintInvalidationContainer)); |
148 | 147 |
149 return result; | 148 return result; |
150 } | 149 } |
151 | 150 |
152 void PaintInvalidatorContext::mapLocalRectToVisualRectInBacking( | 151 void PaintInvalidatorContext::mapLocalRectToVisualRectInBacking( |
153 const LayoutObject& object, | 152 const LayoutObject& object, |
154 LayoutRect& rect) const { | 153 LayoutRect& rect) const { |
155 rect = blink::mapLocalRectToVisualRectInBacking<LayoutRect, LayoutPoint>( | 154 rect = PaintInvalidator::mapLocalRectToVisualRectInBacking<LayoutRect, |
| 155 LayoutPoint>( |
156 object, rect, *this); | 156 object, rect, *this); |
157 } | 157 } |
158 | 158 |
159 LayoutRect PaintInvalidator::computeVisualRectInBacking( | 159 LayoutRect PaintInvalidator::computeVisualRectInBacking( |
160 const LayoutObject& object, | 160 const LayoutObject& object, |
161 const PaintInvalidatorContext& context) { | 161 const PaintInvalidatorContext& context) { |
162 if (object.isSVGChild()) { | 162 if (object.isSVGChild()) { |
163 FloatRect localRect = SVGLayoutSupport::localVisualRect(object); | 163 FloatRect localRect = SVGLayoutSupport::localVisualRect(object); |
164 return mapLocalRectToVisualRectInBacking<FloatRect, FloatPoint>( | 164 return mapLocalRectToVisualRectInBacking<FloatRect, FloatPoint>( |
165 object, localRect, context); | 165 object, localRect, context); |
(...skipping 10 matching lines...) Expand all Loading... |
176 return object.paintOffset(); | 176 return object.paintOffset(); |
177 | 177 |
178 LayoutPoint point; | 178 LayoutPoint point; |
179 if (object != context.paintInvalidationContainer) { | 179 if (object != context.paintInvalidationContainer) { |
180 point.moveBy(object.paintOffset()); | 180 point.moveBy(object.paintOffset()); |
181 | 181 |
182 const auto* containerTransform = | 182 const auto* containerTransform = |
183 context.paintInvalidationContainer->paintProperties() | 183 context.paintInvalidationContainer->paintProperties() |
184 ->contentsProperties() | 184 ->contentsProperties() |
185 ->transform(); | 185 ->transform(); |
186 if (context.treeBuilderContext.current.transform != containerTransform) { | 186 if (context.m_treeBuilderContext.current.transform != containerTransform) { |
187 FloatRect rect = FloatRect(FloatPoint(point), FloatSize()); | 187 FloatRect rect = FloatRect(FloatPoint(point), FloatSize()); |
188 context.geometryMapper.sourceToDestinationRect( | 188 context.m_geometryMapper.sourceToDestinationRect( |
189 context.treeBuilderContext.current.transform, containerTransform, | 189 context.m_treeBuilderContext.current.transform, containerTransform, |
190 rect); | 190 rect); |
191 point = LayoutPoint(rect.location()); | 191 point = LayoutPoint(rect.location()); |
192 } | 192 } |
193 | 193 |
194 // Convert the result to the container's contents space. | 194 // Convert the result to the container's contents space. |
195 point.moveBy(-context.paintInvalidationContainer->paintOffset()); | 195 point.moveBy(-context.paintInvalidationContainer->paintOffset()); |
196 } | 196 } |
197 | 197 |
198 if (context.paintInvalidationContainer->layer()->groupedMapping()) { | 198 if (context.paintInvalidationContainer->layer()->groupedMapping()) { |
199 FloatPoint floatPoint(point); | 199 FloatPoint floatPoint(point); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 248 |
249 namespace { | 249 namespace { |
250 | 250 |
251 // This is temporary to workaround paint invalidation issues in | 251 // This is temporary to workaround paint invalidation issues in |
252 // non-rootLayerScrolls mode. | 252 // non-rootLayerScrolls mode. |
253 // It undoes FrameView's content clip and scroll for paint invalidation of frame | 253 // It undoes FrameView's content clip and scroll for paint invalidation of frame |
254 // scroll controls and the LayoutView to which the content clip and scroll don't | 254 // scroll controls and the LayoutView to which the content clip and scroll don't |
255 // apply. | 255 // apply. |
256 class ScopedUndoFrameViewContentClipAndScroll { | 256 class ScopedUndoFrameViewContentClipAndScroll { |
257 public: | 257 public: |
258 ScopedUndoFrameViewContentClipAndScroll(const FrameView& frameView, | 258 ScopedUndoFrameViewContentClipAndScroll( |
259 PaintInvalidatorContext& context) | 259 const FrameView& frameView, |
260 : m_treeBuilderContext(const_cast<PaintPropertyTreeBuilderContext&>( | 260 const PaintPropertyTreeBuilderContext& treeBuilderContext) |
261 context.treeBuilderContext)), | 261 : m_treeBuilderContext( |
| 262 const_cast<PaintPropertyTreeBuilderContext&>(treeBuilderContext)), |
262 m_savedContext(m_treeBuilderContext.current) { | 263 m_savedContext(m_treeBuilderContext.current) { |
263 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); | 264 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); |
264 | 265 |
265 if (frameView.contentClip() == m_savedContext.clip) | 266 if (frameView.contentClip() == m_savedContext.clip) |
266 m_treeBuilderContext.current.clip = m_savedContext.clip->parent(); | 267 m_treeBuilderContext.current.clip = m_savedContext.clip->parent(); |
267 if (const auto* scrollTranslation = frameView.scrollTranslation()) { | 268 if (const auto* scrollTranslation = frameView.scrollTranslation()) { |
268 if (scrollTranslation->scrollNode() == m_savedContext.scroll) | 269 if (scrollTranslation->scrollNode() == m_savedContext.scroll) |
269 m_treeBuilderContext.current.scroll = m_savedContext.scroll->parent(); | 270 m_treeBuilderContext.current.scroll = m_savedContext.scroll->parent(); |
270 if (scrollTranslation == m_savedContext.transform) { | 271 if (scrollTranslation == m_savedContext.transform) { |
271 m_treeBuilderContext.current.transform = | 272 m_treeBuilderContext.current.transform = |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 } | 348 } |
348 | 349 |
349 void PaintInvalidator::updateVisualRect(const LayoutObject& object, | 350 void PaintInvalidator::updateVisualRect(const LayoutObject& object, |
350 PaintInvalidatorContext& context) { | 351 PaintInvalidatorContext& context) { |
351 Optional<ScopedUndoFrameViewContentClipAndScroll> | 352 Optional<ScopedUndoFrameViewContentClipAndScroll> |
352 undoFrameViewContentClipAndScroll; | 353 undoFrameViewContentClipAndScroll; |
353 | 354 |
354 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && | 355 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
355 object.isLayoutView() && !object.isPaintInvalidationContainer()) { | 356 object.isLayoutView() && !object.isPaintInvalidationContainer()) { |
356 undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(), | 357 undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(), |
357 context); | 358 context.m_treeBuilderContext); |
358 } | 359 } |
359 | 360 |
360 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter | 361 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter |
361 // geometry effects, after skia optimizes filter's mapRect operation. | 362 // geometry effects, after skia optimizes filter's mapRect operation. |
362 // TODO(crbug.com/648274): This is a workaround for multi-column contents. | 363 // TODO(crbug.com/648274): This is a workaround for multi-column contents. |
363 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { | 364 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { |
364 context.forcedSubtreeInvalidationFlags |= | 365 context.forcedSubtreeInvalidationFlags |= |
365 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; | 366 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
366 } | 367 } |
367 | 368 |
(...skipping 25 matching lines...) Expand all Loading... |
393 PaintInvalidatorContext& context) { | 394 PaintInvalidatorContext& context) { |
394 LayoutView* layoutView = frameView.layoutView(); | 395 LayoutView* layoutView = frameView.layoutView(); |
395 CHECK(layoutView); | 396 CHECK(layoutView); |
396 | 397 |
397 context.paintInvalidationContainer = | 398 context.paintInvalidationContainer = |
398 context.paintInvalidationContainerForStackedContents = | 399 context.paintInvalidationContainerForStackedContents = |
399 &layoutView->containerForPaintInvalidation(); | 400 &layoutView->containerForPaintInvalidation(); |
400 context.paintingLayer = layoutView->layer(); | 401 context.paintingLayer = layoutView->layer(); |
401 | 402 |
402 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 403 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
403 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); | 404 ScopedUndoFrameViewContentClipAndScroll undo(frameView, |
| 405 context.m_treeBuilderContext); |
404 frameView.invalidatePaintOfScrollControlsIfNeeded(context); | 406 frameView.invalidatePaintOfScrollControlsIfNeeded(context); |
405 } | 407 } |
406 } | 408 } |
407 | 409 |
408 void PaintInvalidator::invalidatePaintIfNeeded( | 410 void PaintInvalidator::invalidatePaintIfNeeded( |
409 const LayoutObject& object, | 411 const LayoutObject& object, |
410 PaintInvalidatorContext& context) { | 412 PaintInvalidatorContext& context) { |
411 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), | 413 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), |
412 "PaintInvalidator::invalidatePaintIfNeeded()", "object", | 414 "PaintInvalidator::invalidatePaintIfNeeded()", "object", |
413 object.debugName().ascii()); | 415 object.debugName().ascii()); |
414 | 416 |
415 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); | 417 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); |
416 | 418 |
417 // The paint offset should already be updated through | 419 // The paint offset should already be updated through |
418 // PaintPropertyTreeBuilder::updatePropertiesForSelf. | 420 // PaintPropertyTreeBuilder::updatePropertiesForSelf. |
419 DCHECK(context.treeBuilderContext.current.paintOffset == | 421 DCHECK(context.m_treeBuilderContext.current.paintOffset == |
420 object.paintOffset()); | 422 object.paintOffset()); |
421 | 423 |
422 updatePaintingLayer(object, context); | 424 updatePaintingLayer(object, context); |
423 | 425 |
424 if (object.document().printing() && | 426 if (object.document().printing() && |
425 !RuntimeEnabledFeatures::printBrowserEnabled()) | 427 !RuntimeEnabledFeatures::printBrowserEnabled()) |
426 return; // Don't invalidate paints if we're printing. | 428 return; // Don't invalidate paints if we're printing. |
427 | 429 |
428 updatePaintInvalidationContainer(object, context); | 430 updatePaintInvalidationContainer(object, context); |
429 | 431 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 } | 491 } |
490 } | 492 } |
491 | 493 |
492 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 494 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
493 for (auto target : m_pendingDelayedPaintInvalidations) | 495 for (auto target : m_pendingDelayedPaintInvalidations) |
494 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 496 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
495 PaintInvalidationDelayedFull); | 497 PaintInvalidationDelayedFull); |
496 } | 498 } |
497 | 499 |
498 } // namespace blink | 500 } // namespace blink |
OLD | NEW |