| 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 |