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

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

Issue 2247543003: Tweak priorities of paint invalidation reasons (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: - Created 4 years, 4 months 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/ObjectPaintInvalidator.h" 5 #include "core/paint/ObjectPaintInvalidator.h"
6 6
7 #include "core/layout/LayoutBlockFlow.h" 7 #include "core/layout/LayoutBlockFlow.h"
8 #include "core/paint/PaintInvalidator.h" 8 #include "core/paint/PaintInvalidator.h"
9 #include "core/paint/PaintLayer.h" 9 #include "core/paint/PaintLayer.h"
10 10
(...skipping 12 matching lines...) Expand all
23 selectionPaintInvalidationMap().remove(&object); 23 selectionPaintInvalidationMap().remove(&object);
24 else 24 else
25 selectionPaintInvalidationMap().set(&object, rect); 25 selectionPaintInvalidationMap().set(&object, rect);
26 } 26 }
27 27
28 void ObjectPaintInvalidator::objectWillBeDestroyed(const LayoutObject& object) 28 void ObjectPaintInvalidator::objectWillBeDestroyed(const LayoutObject& object)
29 { 29 {
30 selectionPaintInvalidationMap().remove(&object); 30 selectionPaintInvalidationMap().remove(&object);
31 } 31 }
32 32
33 void ObjectPaintInvalidator::incrementallyInvalidatePaint() 33 bool ObjectPaintInvalidator::incrementallyInvalidatePaint()
34 { 34 {
35 const LayoutRect& oldBounds = m_context.oldBounds; 35 const LayoutRect& oldBounds = m_context.oldBounds;
36 const LayoutRect& newBounds = m_context.newBounds; 36 const LayoutRect& newBounds = m_context.newBounds;
37 37
38 DCHECK(oldBounds.location() == newBounds.location()); 38 DCHECK(oldBounds.location() == newBounds.location());
39 39
40 LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX(); 40 LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
41 LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
42 if (!deltaRight && !deltaBottom)
43 return false;
44
41 if (deltaRight > 0) { 45 if (deltaRight > 0) {
42 LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()); 46 LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height());
43 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental); 47 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental);
44 } else if (deltaRight < 0) { 48 } else if (deltaRight < 0) {
45 LayoutRect invalidationRect(newBounds.maxX(), oldBounds.y(), -deltaRight , oldBounds.height()); 49 LayoutRect invalidationRect(newBounds.maxX(), oldBounds.y(), -deltaRight , oldBounds.height());
46 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental); 50 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental);
47 } 51 }
48 52
49 LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
50 if (deltaBottom > 0) { 53 if (deltaBottom > 0) {
51 LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.w idth(), deltaBottom); 54 LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.w idth(), deltaBottom);
52 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental); 55 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental);
53 } else if (deltaBottom < 0) { 56 } else if (deltaBottom < 0) {
54 LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.w idth(), -deltaBottom); 57 LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.w idth(), -deltaBottom);
55 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental); 58 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, PaintInvalidationIncremental);
56 } 59 }
60
61 return true;
57 } 62 }
58 63
59 void ObjectPaintInvalidator::fullyInvalidatePaint(PaintInvalidationReason reason , const LayoutRect& oldBounds, const LayoutRect& newBounds) 64 void ObjectPaintInvalidator::fullyInvalidatePaint(PaintInvalidationReason reason , const LayoutRect& oldBounds, const LayoutRect& newBounds)
60 { 65 {
61 // The following logic avoids invalidating twice if one set of bounds contai ns the other. 66 // The following logic avoids invalidating twice if one set of bounds contai ns the other.
62 if (!newBounds.contains(oldBounds)) { 67 if (!newBounds.contains(oldBounds)) {
63 LayoutRect invalidationRect = oldBounds; 68 LayoutRect invalidationRect = oldBounds;
64 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, reason); 69 m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationConta iner, invalidationRect, reason);
65 70
66 if (invalidationRect.contains(newBounds)) 71 if (invalidationRect.contains(newBounds))
(...skipping 12 matching lines...) Expand all
79 m_object.getMutableForPainting().setPreviousBackgroundObscured(backgroun dObscured); 84 m_object.getMutableForPainting().setPreviousBackgroundObscured(backgroun dObscured);
80 backgroundObscurationChanged = true; 85 backgroundObscurationChanged = true;
81 } 86 }
82 87
83 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::Forc edSubtreeFullInvalidation) 88 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::Forc edSubtreeFullInvalidation)
84 return PaintInvalidationSubtree; 89 return PaintInvalidationSubtree;
85 90
86 if (m_object.shouldDoFullPaintInvalidation()) 91 if (m_object.shouldDoFullPaintInvalidation())
87 return m_object.fullPaintInvalidationReason(); 92 return m_object.fullPaintInvalidationReason();
88 93
94 if (m_context.oldBounds.isEmpty() && m_context.newBounds.isEmpty())
95 return PaintInvalidationNone;
96
89 if (backgroundObscurationChanged) 97 if (backgroundObscurationChanged)
90 return PaintInvalidationBackgroundObscurationChange; 98 return PaintInvalidationBackgroundObscurationChange;
91 99
92 if (m_object.paintedOutputOfObjectHasNoEffect()) 100 if (m_object.paintedOutputOfObjectHasNoEffectRegardlessOfSize())
93 return PaintInvalidationNone; 101 return PaintInvalidationNone;
94 102
95 const ComputedStyle& style = m_object.styleRef(); 103 const ComputedStyle& style = m_object.styleRef();
96 104
97 // The outline may change shape because of position change of descendants. F or simplicity, 105 // The outline may change shape because of position change of descendants. F or simplicity,
98 // just force full paint invalidation if this object is marked for checking paint invalidation 106 // just force full paint invalidation if this object is marked for checking paint invalidation
99 // for any reason. 107 // for any reason.
100 // TODO(wangxianzhu): Optimize this. 108 // TODO(wangxianzhu): Optimize this.
101 if (style.hasOutline()) 109 if (style.hasOutline())
102 return PaintInvalidationOutline; 110 return PaintInvalidationOutline;
103 111
104 bool locationChanged = m_context.newLocation != m_context.oldLocation; 112 bool locationChanged = m_context.newLocation != m_context.oldLocation;
105 113
106 // If the bounds are the same then we know that none of the statements below 114 // If the bounds are the same then we know that none of the statements below
107 // can match, so we can early out. 115 // can match, so we can early out. However, we can't return PaintInvalidatio nNone even if
116 // !locationChagned, but conservatively return PaintInvalidationIncremental because we are
117 // not sure whether paint invalidation is actually needed just based on info rmation known
118 // to LayoutObject. For example, a LayoutBox may need paint invalidation if border box changes.
108 if (m_context.oldBounds == m_context.newBounds) 119 if (m_context.oldBounds == m_context.newBounds)
109 return locationChanged && !m_context.oldBounds.isEmpty() ? PaintInvalida tionLocationChange : PaintInvalidationNone; 120 return locationChanged ? PaintInvalidationLocationChange : PaintInvalida tionIncremental;
110
111 // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could
112 // be caused by some layout property (left / top) or some in-flow layoutObje ct inserted / removed before us in the tree.
113 if (m_context.newBounds.location() != m_context.oldBounds.location())
114 return PaintInvalidationBoundsChange;
115 121
116 // If the size is zero on one of our bounds then we know we're going to have 122 // If the size is zero on one of our bounds then we know we're going to have
117 // to do a full invalidation of either old bounds or new bounds. 123 // to do a full invalidation of either old bounds or new bounds.
118 if (m_context.oldBounds.isEmpty()) 124 if (m_context.oldBounds.isEmpty())
119 return PaintInvalidationBecameVisible; 125 return PaintInvalidationBecameVisible;
120 if (m_context.newBounds.isEmpty()) 126 if (m_context.newBounds.isEmpty())
121 return PaintInvalidationBecameInvisible; 127 return PaintInvalidationBecameInvisible;
122 128
129 // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could
130 // be caused by some layout property (left / top) or some in-flow layoutObje ct inserted / removed before us in the tree.
131 if (m_context.newBounds.location() != m_context.oldBounds.location())
132 return PaintInvalidationBoundsChange;
133
123 if (locationChanged) 134 if (locationChanged)
124 return PaintInvalidationLocationChange; 135 return PaintInvalidationLocationChange;
125 136
126 return PaintInvalidationIncremental; 137 return PaintInvalidationIncremental;
127 } 138 }
128 139
129 void ObjectPaintInvalidator::invalidateSelectionIfNeeded(PaintInvalidationReason reason) 140 void ObjectPaintInvalidator::invalidateSelectionIfNeeded(PaintInvalidationReason reason)
130 { 141 {
131 // Update selection rect when we are doing full invalidation (in case that t he object is moved, 142 // Update selection rect when we are doing full invalidation (in case that t he object is moved,
132 // composite status changed, etc.) or shouldInvalidationSelection is set (in case that the 143 // composite status changed, etc.) or shouldInvalidationSelection is set (in case that the
133 // selection itself changed). 144 // selection itself changed).
134 bool fullInvalidation = isFullPaintInvalidationReason(reason); 145 bool fullInvalidation = isImmediateFullPaintInvalidationReason(reason);
135 if (!fullInvalidation && !m_object.shouldInvalidateSelection()) 146 if (!fullInvalidation && !m_object.shouldInvalidateSelection())
136 return; 147 return;
137 148
138 LayoutRect oldSelectionRect = selectionPaintInvalidationMap().get(&m_object) ; 149 LayoutRect oldSelectionRect = selectionPaintInvalidationMap().get(&m_object) ;
139 LayoutRect newSelectionRect = m_object.localSelectionRect(); 150 LayoutRect newSelectionRect = m_object.localSelectionRect();
140 if (!newSelectionRect.isEmpty()) 151 if (!newSelectionRect.isEmpty())
141 m_context.mapLocalRectToPaintInvalidationBacking(m_object, newSelectionR ect); 152 m_context.mapLocalRectToPaintInvalidationBacking(m_object, newSelectionR ect);
142 153
143 newSelectionRect.move(m_object.scrollAdjustmentForPaintInvalidation(*m_conte xt.paintInvalidationContainer)); 154 newSelectionRect.move(m_object.scrollAdjustmentForPaintInvalidation(*m_conte xt.paintInvalidationContainer));
144 155
145 setPreviousSelectionPaintInvalidationRect(m_object, newSelectionRect); 156 setPreviousSelectionPaintInvalidationRect(m_object, newSelectionRect);
146 157
147 if (!fullInvalidation) { 158 if (!fullInvalidation) {
148 fullyInvalidatePaint(PaintInvalidationSelection, oldSelectionRect, newSe lectionRect); 159 fullyInvalidatePaint(PaintInvalidationSelection, oldSelectionRect, newSe lectionRect);
149 m_context.paintingLayer->setNeedsRepaint(); 160 m_context.paintingLayer->setNeedsRepaint();
150 m_object.invalidateDisplayItemClients(PaintInvalidationSelection); 161 m_object.invalidateDisplayItemClients(PaintInvalidationSelection);
151 } 162 }
152 } 163 }
153 164
154 PaintInvalidationReason ObjectPaintInvalidator::invalidatePaintIfNeededWithCompu tedReason(PaintInvalidationReason reason) 165 PaintInvalidationReason ObjectPaintInvalidator::invalidatePaintIfNeededWithCompu tedReason(PaintInvalidationReason reason)
155 { 166 {
156 // We need to invalidate the selection before checking for whether we are do ing a full invalidation. 167 // We need to invalidate the selection before checking for whether we are do ing a full invalidation.
157 // This is because we need to update the previous selection rect regardless. 168 // This is because we need to update the previous selection rect regardless.
158 invalidateSelectionIfNeeded(reason); 169 invalidateSelectionIfNeeded(reason);
159 170
171 if (reason == PaintInvalidationIncremental && !incrementallyInvalidatePaint( ))
172 reason = PaintInvalidationNone;
173
160 switch (reason) { 174 switch (reason) {
161 case PaintInvalidationNone: 175 case PaintInvalidationNone:
162 // TODO(trchen): Currently we don't keep track of paint offset of layout objects. 176 // TODO(trchen): Currently we don't keep track of paint offset of layout objects.
163 // There are corner cases that the display items need to be invalidated for paint offset 177 // There are corner cases that the display items need to be invalidated for paint offset
164 // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based 178 // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based
165 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. 179 // invalidation is issued. See crbug.com/508383 and crbug.com/515977.
166 // This is a workaround to force display items to update paint offset. 180 // This is a workaround to force display items to update paint offset.
167 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext:: ForcedSubtreeInvalidationChecking) { 181 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext:: ForcedSubtreeInvalidationChecking) {
168 reason = PaintInvalidationLocationChange; 182 reason = PaintInvalidationLocationChange;
169 break; 183 break;
170 } 184 }
171 return PaintInvalidationNone; 185 return PaintInvalidationNone;
172 case PaintInvalidationIncremental: 186 case PaintInvalidationIncremental:
173 incrementallyInvalidatePaint();
174 break; 187 break;
175 case PaintInvalidationDelayedFull: 188 case PaintInvalidationDelayedFull:
176 return PaintInvalidationDelayedFull; 189 return PaintInvalidationDelayedFull;
177 default: 190 default:
178 DCHECK(isFullPaintInvalidationReason(reason)); 191 DCHECK(isImmediateFullPaintInvalidationReason(reason));
179 fullyInvalidatePaint(reason, m_context.oldBounds, m_context.newBounds); 192 fullyInvalidatePaint(reason, m_context.oldBounds, m_context.newBounds);
180 } 193 }
181 194
182 m_context.paintingLayer->setNeedsRepaint(); 195 m_context.paintingLayer->setNeedsRepaint();
183 m_object.invalidateDisplayItemClients(reason); 196 m_object.invalidateDisplayItemClients(reason);
184 return reason; 197 return reason;
185 } 198 }
186 199
187 } // namespace blink 200 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698