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" |
11 #include "core/layout/LayoutBlockFlow.h" | 11 #include "core/layout/LayoutBlockFlow.h" |
12 #include "core/layout/LayoutObject.h" | 12 #include "core/layout/LayoutObject.h" |
13 #include "core/layout/LayoutTable.h" | 13 #include "core/layout/LayoutTable.h" |
14 #include "core/layout/LayoutView.h" | 14 #include "core/layout/LayoutView.h" |
15 #include "core/layout/svg/SVGLayoutSupport.h" | 15 #include "core/layout/svg/SVGLayoutSupport.h" |
16 #include "core/paint/ObjectPaintProperties.h" | 16 #include "core/paint/ObjectPaintProperties.h" |
17 #include "core/paint/PaintLayer.h" | 17 #include "core/paint/PaintLayer.h" |
18 #include "core/paint/PaintLayerScrollableArea.h" | 18 #include "core/paint/PaintLayerScrollableArea.h" |
19 #include "core/paint/PaintPropertyTreeBuilder.h" | 19 #include "core/paint/PaintPropertyTreeBuilder.h" |
20 | 20 |
21 namespace blink { | 21 namespace blink { |
22 | 22 |
| 23 template <typename Rect> |
23 static LayoutRect slowMapToVisualRectInAncestorSpace( | 24 static LayoutRect slowMapToVisualRectInAncestorSpace( |
24 const LayoutObject& object, | 25 const LayoutObject& object, |
25 const LayoutBoxModelObject& ancestor, | 26 const LayoutBoxModelObject& ancestor, |
26 const FloatRect& rect) { | 27 const Rect& rect) { |
27 if (object.isSVGChild()) { | 28 if (object.isSVGChild()) { |
28 LayoutRect result; | 29 LayoutRect result; |
29 SVGLayoutSupport::mapToVisualRectInAncestorSpace(object, &ancestor, rect, | 30 SVGLayoutSupport::mapToVisualRectInAncestorSpace(object, &ancestor, |
30 result); | 31 FloatRect(rect), result); |
31 return result; | 32 return result; |
32 } | 33 } |
33 | 34 |
34 LayoutRect result(rect); | 35 LayoutRect result(rect); |
35 if (object.isLayoutView()) | 36 if (object.isLayoutView()) |
36 toLayoutView(object).mapToVisualRectInAncestorSpace( | 37 toLayoutView(object).mapToVisualRectInAncestorSpace( |
37 &ancestor, result, InputIsInFrameCoordinates, DefaultVisualRectFlags); | 38 &ancestor, result, InputIsInFrameCoordinates, DefaultVisualRectFlags); |
38 else | 39 else |
39 object.mapToVisualRectInAncestorSpace(&ancestor, result); | 40 object.mapToVisualRectInAncestorSpace(&ancestor, result); |
40 return result; | 41 return result; |
41 } | 42 } |
42 | 43 |
43 // TODO(wangxianzhu): Combine this into | 44 // TODO(wangxianzhu): Combine this into |
44 // PaintInvalidator::mapLocalRectToBacking() when removing | 45 // PaintInvalidator::mapLocalRectToBacking() when removing |
45 // PaintInvalidationState. | 46 // PaintInvalidationState. |
| 47 // This function is templatized to avoid FloatRect<->LayoutRect conversions |
| 48 // which affect performance. |
| 49 template <typename Rect, typename Point> |
46 static LayoutRect mapLocalRectToPaintInvalidationBacking( | 50 static LayoutRect mapLocalRectToPaintInvalidationBacking( |
47 GeometryMapper& geometryMapper, | 51 GeometryMapper& geometryMapper, |
48 const LayoutObject& object, | 52 const LayoutObject& object, |
49 const FloatRect& localRect, | 53 const Rect& localRect, |
50 const PaintInvalidatorContext& context) { | 54 const PaintInvalidatorContext& context) { |
51 bool isSVGChild = object.isSVGChild(); | 55 bool isSVGChild = object.isSVGChild(); |
52 | 56 |
53 // TODO(wkorman): The flip below is required because visual rects are | 57 // TODO(wkorman): The flip below is required because visual rects are |
54 // currently in "physical coordinates with flipped block-flow direction" | 58 // currently in "physical coordinates with flipped block-flow direction" |
55 // (see LayoutBoxModelObject.h) but we need them to be in physical | 59 // (see LayoutBoxModelObject.h) but we need them to be in physical |
56 // coordinates. | 60 // coordinates. |
57 FloatRect rect = localRect; | 61 Rect rect = localRect; |
58 // Writing-mode flipping doesn't apply to non-root SVG. | 62 // Writing-mode flipping doesn't apply to non-root SVG. |
59 if (!isSVGChild) { | 63 if (!isSVGChild) { |
60 if (object.isBox()) { | 64 if (object.isBox()) { |
61 toLayoutBox(object).flipForWritingMode(rect); | 65 toLayoutBox(object).flipForWritingMode(rect); |
62 } else if (!(context.forcedSubtreeInvalidationFlags & | 66 } else if (!(context.forcedSubtreeInvalidationFlags & |
63 PaintInvalidatorContext::ForcedSubtreeSlowPathRect)) { | 67 PaintInvalidatorContext::ForcedSubtreeSlowPathRect)) { |
64 // For SPv2 and the GeometryMapper path, we also need to convert the rect | 68 // For SPv2 and the GeometryMapper path, we also need to convert the rect |
65 // for non-boxes into physical coordinates before applying paint offset. | 69 // for non-boxes into physical coordinates before applying paint offset. |
66 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires | 70 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires |
67 // physical coordinates for boxes, but "physical coordinates with flipped | 71 // physical coordinates for boxes, but "physical coordinates with flipped |
68 // block-flow direction" for non-boxes for which we don't need to flip.) | 72 // block-flow direction" for non-boxes for which we don't need to flip.) |
69 // TODO(wangxianzhu): Avoid containingBlock(). | 73 // TODO(wangxianzhu): Avoid containingBlock(). |
70 object.containingBlock()->flipForWritingMode(rect); | 74 object.containingBlock()->flipForWritingMode(rect); |
71 } | 75 } |
72 } | 76 } |
73 | 77 |
74 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 78 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
75 // In SPv2, visual rects are in the space of their local transform node. | 79 // In SPv2, visual rects are in the space of their local transform node. |
76 // For SVG, the input rect is in local SVG coordinates in which paint | 80 // For SVG, the input rect is in local SVG coordinates in which paint |
77 // offset doesn't apply. | 81 // offset doesn't apply. |
78 if (!isSVGChild) | 82 if (!isSVGChild) |
79 rect.moveBy(FloatPoint(object.paintOffset())); | 83 rect.moveBy(Point(object.paintOffset())); |
80 // Use enclosingIntRect to ensure the final visual rect will cover the | 84 // Use enclosingIntRect to ensure the final visual rect will cover the |
81 // rect in source coordinates no matter if the painting will use pixel | 85 // rect in source coordinates no matter if the painting will use pixel |
82 // snapping. | 86 // snapping. |
83 return LayoutRect(enclosingIntRect(rect)); | 87 return LayoutRect(enclosingIntRect(rect)); |
84 } | 88 } |
85 | 89 |
86 LayoutRect result; | 90 LayoutRect result; |
87 if (context.forcedSubtreeInvalidationFlags & | 91 if (context.forcedSubtreeInvalidationFlags & |
88 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { | 92 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { |
89 result = slowMapToVisualRectInAncestorSpace( | 93 result = slowMapToVisualRectInAncestorSpace( |
90 object, *context.paintInvalidationContainer, rect); | 94 object, *context.paintInvalidationContainer, rect); |
91 } else if (object == context.paintInvalidationContainer) { | 95 } else if (object == context.paintInvalidationContainer) { |
92 result = LayoutRect(rect); | 96 result = LayoutRect(rect); |
93 } else { | 97 } else { |
94 // For non-root SVG, the input rect is in local SVG coordinates in which | 98 // For non-root SVG, the input rect is in local SVG coordinates in which |
95 // paint offset doesn't apply. | 99 // paint offset doesn't apply. |
96 if (!isSVGChild) { | 100 if (!isSVGChild) { |
97 rect.moveBy(FloatPoint(object.paintOffset())); | 101 rect.moveBy(Point(object.paintOffset())); |
98 // Use enclosingIntRect to ensure the final visual rect will cover the | 102 // Use enclosingIntRect to ensure the final visual rect will cover the |
99 // rect in source coordinates no matter if the painting will use pixel | 103 // rect in source coordinates no matter if the painting will use pixel |
100 // snapping. | 104 // snapping. |
101 rect = enclosingIntRect(rect); | 105 rect = Rect(enclosingIntRect(rect)); |
102 } | 106 } |
103 | 107 |
104 const auto* containerContentsProperties = | 108 const auto* containerContentsProperties = |
105 context.paintInvalidationContainer->paintProperties() | 109 context.paintInvalidationContainer->paintProperties() |
106 ->contentsProperties(); | 110 ->contentsProperties(); |
107 if (context.treeBuilderContext.current.transform == | 111 if (context.treeBuilderContext.current.transform == |
108 containerContentsProperties->transform() && | 112 containerContentsProperties->transform() && |
109 context.treeBuilderContext.current.clip == | 113 context.treeBuilderContext.current.clip == |
110 containerContentsProperties->clip()) { | 114 containerContentsProperties->clip()) { |
111 result = LayoutRect(rect); | 115 result = LayoutRect(rect); |
112 } else { | 116 } else { |
113 PropertyTreeState currentTreeState( | 117 PropertyTreeState currentTreeState( |
114 context.treeBuilderContext.current.transform, | 118 context.treeBuilderContext.current.transform, |
115 context.treeBuilderContext.current.clip, nullptr, nullptr); | 119 context.treeBuilderContext.current.clip, nullptr, nullptr); |
116 result = LayoutRect(geometryMapper.sourceToDestinationVisualRect( | 120 result = LayoutRect(geometryMapper.sourceToDestinationVisualRect( |
117 rect, currentTreeState, *containerContentsProperties)); | 121 FloatRect(rect), currentTreeState, *containerContentsProperties)); |
118 } | 122 } |
119 | 123 |
120 // Convert the result to the container's contents space. | 124 // Convert the result to the container's contents space. |
121 result.moveBy(-context.paintInvalidationContainer->paintOffset()); | 125 result.moveBy(-context.paintInvalidationContainer->paintOffset()); |
122 } | 126 } |
123 | 127 |
124 object.adjustVisualRectForRasterEffects(result); | 128 object.adjustVisualRectForRasterEffects(result); |
125 | 129 |
126 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 130 PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
127 *context.paintInvalidationContainer, result); | 131 *context.paintInvalidationContainer, result); |
128 | 132 |
129 return result; | 133 return result; |
130 } | 134 } |
131 | 135 |
132 void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( | 136 void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( |
133 const LayoutObject& object, | 137 const LayoutObject& object, |
134 LayoutRect& rect) const { | 138 LayoutRect& rect) const { |
135 GeometryMapper geometryMapper; | 139 GeometryMapper geometryMapper; |
136 rect = blink::mapLocalRectToPaintInvalidationBacking(geometryMapper, object, | 140 rect = blink::mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>( |
137 FloatRect(rect), *this); | 141 geometryMapper, object, rect, *this); |
138 } | |
139 | |
140 LayoutRect PaintInvalidator::mapLocalRectToPaintInvalidationBacking( | |
141 const LayoutObject& object, | |
142 const FloatRect& localRect, | |
143 const PaintInvalidatorContext& context) { | |
144 return blink::mapLocalRectToPaintInvalidationBacking(m_geometryMapper, object, | |
145 localRect, context); | |
146 } | 142 } |
147 | 143 |
148 LayoutRect PaintInvalidator::computeVisualRectInBacking( | 144 LayoutRect PaintInvalidator::computeVisualRectInBacking( |
149 const LayoutObject& object, | 145 const LayoutObject& object, |
150 const PaintInvalidatorContext& context) { | 146 const PaintInvalidatorContext& context) { |
151 FloatRect localRect; | 147 if (object.isSVGChild()) { |
152 if (object.isSVGChild()) | 148 FloatRect localRect = SVGLayoutSupport::localVisualRect(object); |
153 localRect = SVGLayoutSupport::localVisualRect(object); | 149 return mapLocalRectToPaintInvalidationBacking<FloatRect, FloatPoint>( |
154 else | 150 m_geometryMapper, object, localRect, context); |
155 localRect = FloatRect(object.localVisualRect()); | 151 } |
156 | 152 return mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>( |
157 return mapLocalRectToPaintInvalidationBacking(object, localRect, context); | 153 m_geometryMapper, object, object.localVisualRect(), context); |
158 } | 154 } |
159 | 155 |
160 LayoutPoint PaintInvalidator::computeLocationInBacking( | 156 LayoutPoint PaintInvalidator::computeLocationInBacking( |
161 const LayoutObject& object, | 157 const LayoutObject& object, |
162 const PaintInvalidatorContext& context) { | 158 const PaintInvalidatorContext& context) { |
163 // Use visual rect location for LayoutTexts because it suffices to check | 159 // Use visual rect location for LayoutTexts because it suffices to check |
164 // visual rect change for layout caused invalidation. | 160 // visual rect change for layout caused invalidation. |
165 if (object.isText()) | 161 if (object.isText()) |
166 return context.newVisualRect.location(); | 162 return context.newVisualRect.location(); |
167 | 163 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 448 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
453 } | 449 } |
454 | 450 |
455 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 451 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
456 for (auto target : m_pendingDelayedPaintInvalidations) | 452 for (auto target : m_pendingDelayedPaintInvalidations) |
457 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 453 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
458 PaintInvalidationDelayedFull); | 454 PaintInvalidationDelayedFull); |
459 } | 455 } |
460 | 456 |
461 } // namespace blink | 457 } // namespace blink |
OLD | NEW |