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

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

Issue 2449953005: [SPInvalidation] Handle pixel-snapping of paint invalidation rects (Closed)
Patch Set: PaintInvalidationRectInBacking struct Created 4 years, 1 month 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/paint/ObjectPaintInvalidator.h" 9 #include "core/paint/ObjectPaintInvalidator.h"
10 #include "core/paint/PaintInvalidator.h" 10 #include "core/paint/PaintInvalidator.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 } 58 }
59 if (delta < 0) { 59 if (delta < 0) {
60 return LayoutRect(location.x(), 60 return LayoutRect(location.x(),
61 location.y() + newSize.height() - extraHeight, 61 location.y() + newSize.height() - extraHeight,
62 oldSize.width(), -delta + extraHeight); 62 oldSize.width(), -delta + extraHeight);
63 } 63 }
64 return LayoutRect(); 64 return LayoutRect();
65 } 65 }
66 66
67 bool BoxPaintInvalidator::incrementallyInvalidatePaint() { 67 bool BoxPaintInvalidator::incrementallyInvalidatePaint() {
68 DCHECK(m_context.oldBounds.location() == m_context.newBounds.location()); 68 const LayoutRect& oldRect = m_context.oldBounds.rect;
69 LayoutRect rightDelta = computeRightDelta(m_context.newBounds.location(), 69 const LayoutRect& newRect = m_context.newBounds.rect;
70 m_context.oldBounds.size(), 70 DCHECK(oldRect.location() == newRect.location());
71 m_context.newBounds.size(), 0); 71 LayoutRect rightDelta =
72 LayoutRect bottomDelta = computeBottomDelta(m_context.newBounds.location(), 72 computeRightDelta(newRect.location(), oldRect.size(), newRect.size(), 0);
73 m_context.oldBounds.size(), 73 LayoutRect bottomDelta =
74 m_context.newBounds.size(), 0); 74 computeBottomDelta(newRect.location(), oldRect.size(), newRect.size(), 0);
75 75
76 if (m_box.styleRef().hasBorder() || m_box.styleRef().hasBackground()) { 76 if (m_box.styleRef().hasBorder() || m_box.styleRef().hasBackground()) {
77 LayoutSize oldBorderBoxSize = 77 LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(oldRect.size());
78 computePreviousBorderBoxSize(m_context.oldBounds.size());
79 LayoutSize newBorderBoxSize = m_box.size(); 78 LayoutSize newBorderBoxSize = m_box.size();
80 DCHECK(m_context.oldLocation == m_context.newLocation); 79 DCHECK(m_context.oldLocation == m_context.newLocation);
81 rightDelta.unite(computeRightDelta(m_context.newLocation, oldBorderBoxSize, 80 rightDelta.unite(computeRightDelta(m_context.newLocation, oldBorderBoxSize,
82 newBorderBoxSize, m_box.borderRight())); 81 newBorderBoxSize, m_box.borderRight()));
83 bottomDelta.unite(computeBottomDelta(m_context.newLocation, 82 bottomDelta.unite(computeBottomDelta(m_context.newLocation,
84 oldBorderBoxSize, newBorderBoxSize, 83 oldBorderBoxSize, newBorderBoxSize,
85 m_box.borderBottom())); 84 m_box.borderBottom()));
86 } 85 }
87 86
88 if (rightDelta.isEmpty() && bottomDelta.isEmpty()) 87 if (rightDelta.isEmpty() && bottomDelta.isEmpty())
89 return false; 88 return false;
90 89
91 invalidatePaintRectClippedByOldAndNewBounds(rightDelta); 90 invalidatePaintRectClippedByOldAndNewBounds(rightDelta);
92 invalidatePaintRectClippedByOldAndNewBounds(bottomDelta); 91 invalidatePaintRectClippedByOldAndNewBounds(bottomDelta);
93 return true; 92 return true;
94 } 93 }
95 94
96 void BoxPaintInvalidator::invalidatePaintRectClippedByOldAndNewBounds( 95 void BoxPaintInvalidator::invalidatePaintRectClippedByOldAndNewBounds(
97 const LayoutRect& rect) { 96 const LayoutRect& rect) {
98 if (rect.isEmpty()) 97 if (rect.isEmpty())
99 return; 98 return;
100 99
101 ObjectPaintInvalidator objectPaintInvalidator(m_box); 100 ObjectPaintInvalidator objectPaintInvalidator(m_box);
102 LayoutRect rectClippedByOldBounds = intersection(rect, m_context.oldBounds); 101 LayoutRect rectClippedByOldBounds =
103 LayoutRect rectClippedByNewBounds = intersection(rect, m_context.newBounds); 102 intersection(rect, m_context.oldBounds.rect);
103 LayoutRect rectClippedByNewBounds =
104 intersection(rect, m_context.newBounds.rect);
104 // Invalidate only once if the clipped rects equal. 105 // Invalidate only once if the clipped rects equal.
105 if (rectClippedByOldBounds == rectClippedByNewBounds) { 106 if (rectClippedByOldBounds == rectClippedByNewBounds) {
106 objectPaintInvalidator.invalidatePaintUsingContainer( 107 objectPaintInvalidator.invalidatePaintUsingContainer(
107 *m_context.paintInvalidationContainer, rectClippedByOldBounds, 108 *m_context.paintInvalidationContainer, rectClippedByOldBounds,
108 PaintInvalidationIncremental); 109 PaintInvalidationIncremental);
109 return; 110 return;
110 } 111 }
111 // Invalidate the bigger one if one contains another. Otherwise invalidate 112 // Invalidate the bigger one if one contains another. Otherwise invalidate
112 // both. 113 // both.
113 if (!rectClippedByNewBounds.contains(rectClippedByOldBounds)) 114 if (!rectClippedByNewBounds.contains(rectClippedByOldBounds))
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // invalidated for box changes, because the background always covers the 151 // invalidated for box changes, because the background always covers the
151 // whole document rect and clipping is done by 152 // whole document rect and clipping is done by
152 // compositor()->m_containerLayer. Also the scrollbars are always 153 // compositor()->m_containerLayer. Also the scrollbars are always
153 // composited. There are no other box decoration on the LayoutView thus we 154 // composited. There are no other box decoration on the LayoutView thus we
154 // can safely exit here. 155 // can safely exit here.
155 if (layoutView.usesCompositing() && 156 if (layoutView.usesCompositing() &&
156 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) 157 !RuntimeEnabledFeatures::rootLayerScrollingEnabled())
157 return reason; 158 return reason;
158 } 159 }
159 160
160 // If the transform is not identity or translation, incremental invalidation
161 // is not applicable because the difference between oldBounds and newBounds
162 // doesn't cover all area needing invalidation.
163 // FIXME: Should also consider ancestor transforms since
164 // paintInvalidationContainer. crbug.com/426111.
165 if (reason == PaintInvalidationIncremental && 161 if (reason == PaintInvalidationIncremental &&
166 m_context.oldBounds != m_context.newBounds && 162 m_context.oldBounds.rect != m_context.newBounds.rect) {
167 m_context.paintInvalidationContainer != m_box && m_box.hasLayer() && 163 if (m_context.newBounds.coversExtraPixels ||
168 m_box.layer()->transform() && 164 m_context.oldBounds.coversExtraPixels) {
169 !m_box.layer()->transform()->isIdentityOrTranslation()) 165 // Incremental invalidation is not applicable because the difference
170 return PaintInvalidationBoundsChange; 166 // between oldBounds and newBounds may not cover all changed pixels along
167 // the edges.
168 return PaintInvalidationBoundsChange;
169 }
170
171 // If the transform is not identity or translation, incremental invalidation
172 // is not applicable because the difference between oldBounds and newBounds
173 // doesn't cover all area needing invalidation.
174 // TODO(crbug.com/426111): Should also consider ancestor transforms
175 // since paintInvalidationContainer. Combine this logic into the above
176 // boundsCoversExtraPixels logic.
177 if (m_context.paintInvalidationContainer != m_box && m_box.hasLayer() &&
178 m_box.layer()->transform() &&
179 !m_box.layer()->transform()->isIdentityOrTranslation())
180 return PaintInvalidationBoundsChange;
181 }
171 182
172 const ComputedStyle& style = m_box.styleRef(); 183 const ComputedStyle& style = m_box.styleRef();
173 if (style.backgroundLayers().thisOrNextLayersUseContentBox() || 184 if (style.backgroundLayers().thisOrNextLayersUseContentBox() ||
174 style.maskLayers().thisOrNextLayersUseContentBox() || 185 style.maskLayers().thisOrNextLayersUseContentBox() ||
175 style.boxSizing() == BoxSizingBorderBox) { 186 style.boxSizing() == BoxSizingBorderBox) {
176 if (previousBoxSizesMap().get(&m_box).contentBoxRect != 187 if (previousBoxSizesMap().get(&m_box).contentBoxRect !=
177 m_box.contentBoxRect()) 188 m_box.contentBoxRect())
178 return PaintInvalidationContentBoxChange; 189 return PaintInvalidationContentBoxChange;
179 } 190 }
180 191
181 if (!style.hasBackground() && !style.hasBoxDecorations()) { 192 if (!style.hasBackground() && !style.hasBoxDecorations()) {
182 if (reason == PaintInvalidationIncremental && 193 if (reason == PaintInvalidationIncremental &&
183 m_context.oldBounds != m_context.newBounds && 194 m_context.oldBounds.rect != m_context.newBounds.rect &&
184 m_box.hasNonCompositedScrollbars()) 195 m_box.hasNonCompositedScrollbars())
185 return PaintInvalidationBorderBoxChange; 196 return PaintInvalidationBorderBoxChange;
186 return reason; 197 return reason;
187 } 198 }
188 199
189 if (style.backgroundLayers().thisOrNextLayersHaveLocalAttachment()) { 200 if (style.backgroundLayers().thisOrNextLayersHaveLocalAttachment()) {
190 if (previousBoxSizesMap().get(&m_box).layoutOverflowRect != 201 if (previousBoxSizesMap().get(&m_box).layoutOverflowRect !=
191 m_box.layoutOverflowRect()) 202 m_box.layoutOverflowRect())
192 return PaintInvalidationLayoutOverflowBoxChange; 203 return PaintInvalidationLayoutOverflowBoxChange;
193 } 204 }
194 205
195 LayoutSize oldBorderBoxSize = 206 LayoutSize oldBorderBoxSize =
196 computePreviousBorderBoxSize(m_context.oldBounds.size()); 207 computePreviousBorderBoxSize(m_context.oldBounds.rect.size());
197 LayoutSize newBorderBoxSize = m_box.size(); 208 LayoutSize newBorderBoxSize = m_box.size();
198 209
199 if (oldBorderBoxSize == newBorderBoxSize) 210 if (oldBorderBoxSize == newBorderBoxSize)
200 return reason; 211 return reason;
201 212
202 // See another hasNonCompositedScrollbars() callsite above. 213 // See another hasNonCompositedScrollbars() callsite above.
203 if (m_box.hasNonCompositedScrollbars()) 214 if (m_box.hasNonCompositedScrollbars())
204 return PaintInvalidationBorderBoxChange; 215 return PaintInvalidationBorderBoxChange;
205 216
206 if (style.hasVisualOverflowingEffect() || style.hasAppearance() || 217 if (style.hasVisualOverflowingEffect() || style.hasAppearance() ||
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 if (PaintLayerScrollableArea* area = m_box.getScrollableArea()) 255 if (PaintLayerScrollableArea* area = m_box.getScrollableArea())
245 area->invalidatePaintOfScrollControlsIfNeeded(m_context); 256 area->invalidatePaintOfScrollControlsIfNeeded(m_context);
246 257
247 // This is for the next invalidatePaintIfNeeded so must be at the end. 258 // This is for the next invalidatePaintIfNeeded so must be at the end.
248 savePreviousBoxSizesIfNeeded(); 259 savePreviousBoxSizesIfNeeded();
249 260
250 return reason; 261 return reason;
251 } 262 }
252 263
253 bool BoxPaintInvalidator::needsToSavePreviousBoxSizes() { 264 bool BoxPaintInvalidator::needsToSavePreviousBoxSizes() {
254 LayoutSize paintInvalidationSize = m_context.newBounds.size(); 265 LayoutSize paintInvalidationSize = m_context.newBounds.rect.size();
255 // Don't save old box sizes if the paint rect is empty because we'll 266 // Don't save old box sizes if the paint rect is empty because we'll
256 // full invalidate once the paint rect becomes non-empty. 267 // full invalidate once the paint rect becomes non-empty.
257 if (paintInvalidationSize.isEmpty()) 268 if (paintInvalidationSize.isEmpty())
258 return false; 269 return false;
259 270
260 const ComputedStyle& style = m_box.styleRef(); 271 const ComputedStyle& style = m_box.styleRef();
261 272
262 // If we use border-box sizing we need to track changes in the size of the 273 // If we use border-box sizing we need to track changes in the size of the
263 // content box. 274 // content box.
264 if (style.boxSizing() == BoxSizingBorderBox) 275 if (style.boxSizing() == BoxSizingBorderBox)
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 auto it = previousBoxSizesMap().find(&m_box); 318 auto it = previousBoxSizesMap().find(&m_box);
308 if (it != previousBoxSizesMap().end()) 319 if (it != previousBoxSizesMap().end())
309 return it->value.borderBoxSize; 320 return it->value.borderBoxSize;
310 321
311 // We didn't save the old border box size because it was the same as the size 322 // We didn't save the old border box size because it was the same as the size
312 // of oldBounds. 323 // of oldBounds.
313 return previousBoundsSize; 324 return previousBoundsSize;
314 } 325 }
315 326
316 } // namespace blink 327 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698