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

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

Issue 2702883002: Remove force-update when visual rects change. (Closed)
Patch Set: - Created 3 years, 10 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/PrePaintTreeWalk.h" 5 #include "core/paint/PrePaintTreeWalk.h"
6 6
7 #include "core/dom/DocumentLifecycle.h" 7 #include "core/dom/DocumentLifecycle.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/layout/LayoutMultiColumnSpannerPlaceholder.h" 10 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h"
11 #include "core/layout/LayoutPart.h" 11 #include "core/layout/LayoutPart.h"
12 #include "core/layout/LayoutView.h" 12 #include "core/layout/LayoutView.h"
13 #include "core/paint/PaintLayer.h" 13 #include "core/paint/PaintLayer.h"
14 14
15 namespace blink { 15 namespace blink {
16 16
17 struct PrePaintTreeWalkContext { 17 struct PrePaintTreeWalkContext {
18 PrePaintTreeWalkContext() 18 PrePaintTreeWalkContext()
19 : paintInvalidatorContext(treeBuilderContext), 19 : paintInvalidatorContext(treeBuilderContext),
20 ancestorOverflowPaintLayer(nullptr) {} 20 ancestorOverflowPaintLayer(nullptr),
21 ancestorTransformedOrRootPaintLayer(nullptr) {}
21 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext) 22 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext)
22 : treeBuilderContext(parentContext.treeBuilderContext), 23 : treeBuilderContext(parentContext.treeBuilderContext),
23 paintInvalidatorContext(treeBuilderContext, 24 paintInvalidatorContext(treeBuilderContext,
24 parentContext.paintInvalidatorContext), 25 parentContext.paintInvalidatorContext),
25 ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer), 26 ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer),
26 ancestorTransformedOrRootPaintLayer( 27 ancestorTransformedOrRootPaintLayer(
27 parentContext.ancestorTransformedOrRootPaintLayer) {} 28 parentContext.ancestorTransformedOrRootPaintLayer) {}
28 29
29 PaintPropertyTreeBuilderContext treeBuilderContext; 30 PaintPropertyTreeBuilderContext treeBuilderContext;
30 PaintInvalidatorContext paintInvalidatorContext; 31 PaintInvalidatorContext paintInvalidatorContext;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 124
124 FloatClipRect rect( 125 FloatClipRect rect(
125 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState)); 126 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState));
126 127
127 rect.moveBy(-FloatPoint(ancestorPaintOffset)); 128 rect.moveBy(-FloatPoint(ancestorPaintOffset));
128 return rect; 129 return rect;
129 } 130 }
130 131
131 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( 132 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded(
132 const LayoutObject& object, 133 const LayoutObject& object,
133 const PaintLayer& ancestorTransformedOrRootPaintLayer, 134 PrePaintTreeWalkContext& context) {
134 PaintPropertyTreeBuilderContext& context) {
135 if (!object.hasLayer()) 135 if (!object.hasLayer())
136 return; 136 return;
137 137
138 PaintLayer& paintLayer = *toLayoutBoxModelObject(object).layer(); 138 PaintLayer& paintLayer = *toLayoutBoxModelObject(object).layer();
139 if (object.styleRef().hasTransform() ||
140 &object == context.paintInvalidatorContext.paintInvalidationContainer) {
141 context.ancestorTransformedOrRootPaintLayer = &paintLayer;
142 }
143
139 const ObjectPaintProperties& ancestorPaintProperties = 144 const ObjectPaintProperties& ancestorPaintProperties =
140 *ancestorTransformedOrRootPaintLayer.layoutObject().paintProperties(); 145 *context.ancestorTransformedOrRootPaintLayer->layoutObject()
146 .paintProperties();
141 PropertyTreeState ancestorState = 147 PropertyTreeState ancestorState =
142 *ancestorPaintProperties.localBorderBoxProperties(); 148 *ancestorPaintProperties.localBorderBoxProperties();
149 const EffectPaintPropertyNode* effect =
150 context.treeBuilderContext.currentEffect;
143 151
144 #ifdef CHECK_CLIP_RECTS 152 #ifdef CHECK_CLIP_RECTS
145 ShouldRespectOverflowClipType respectOverflowClip = RespectOverflowClip; 153 ShouldRespectOverflowClipType respectOverflowClip = RespectOverflowClip;
146 #endif 154 #endif
147 if (ancestorTransformedOrRootPaintLayer.compositingState() == 155 if (context.ancestorTransformedOrRootPaintLayer->compositingState() ==
148 PaintsIntoOwnBacking && 156 PaintsIntoOwnBacking &&
149 ancestorPaintProperties.overflowClip()) { 157 ancestorPaintProperties.overflowClip()) {
150 ancestorState.setClip(ancestorPaintProperties.overflowClip()); 158 ancestorState.setClip(ancestorPaintProperties.overflowClip());
151 #ifdef CHECK_CLIP_RECTS 159 #ifdef CHECK_CLIP_RECTS
152 respectOverflowClip = IgnoreOverflowClip; 160 respectOverflowClip = IgnoreOverflowClip;
153 #endif 161 #endif
154 } 162 }
155 163
156 #ifdef CHECK_CLIP_RECTS 164 #ifdef CHECK_CLIP_RECTS
157 ClipRects& oldClipRects = paintLayer.clipper().paintingClipRects( 165 ClipRects& oldClipRects =
158 &ancestorTransformedOrRootPaintLayer, respectOverflowClip, LayoutSize()); 166 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper)
167 .paintingClipRects(&ancestorTransformedOrRootPaintLayer,
168 respectOverflowClip, LayoutSize());
159 #endif 169 #endif
160 170
161 bool hasClip = false; 171 bool hasClip = false;
162 RefPtr<ClipRects> clipRects = ClipRects::create(); 172 RefPtr<ClipRects> clipRects = ClipRects::create();
163 const LayoutPoint& ancestorPaintOffset = 173 const LayoutPoint& ancestorPaintOffset =
164 ancestorTransformedOrRootPaintLayer.layoutObject().paintOffset(); 174 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset();
165 clipRects->setOverflowClipRect( 175 clipRects->setOverflowClipRect(
166 clipRectForContext(context.current, context.currentEffect, ancestorState, 176 clipRectForContext(context.treeBuilderContext.current, effect,
167 ancestorPaintOffset, hasClip)); 177 ancestorState, ancestorPaintOffset, hasClip));
168 #ifdef CHECK_CLIP_RECTS 178 #ifdef CHECK_CLIP_RECTS
169 CHECK(!hasClip || 179 CHECK(!hasClip ||
170 clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) 180 clipRects->overflowClipRect() == oldClipRects.overflowClipRect())
171 << "rect= " << clipRects->overflowClipRect().toString(); 181 << "rect= " << clipRects->overflowClipRect().toString();
172 #endif 182 #endif
173 183
174 clipRects->setFixedClipRect( 184 clipRects->setFixedClipRect(
175 clipRectForContext(context.fixedPosition, context.currentEffect, 185 clipRectForContext(context.treeBuilderContext.fixedPosition, effect,
176 ancestorState, ancestorPaintOffset, hasClip)); 186 ancestorState, ancestorPaintOffset, hasClip));
177 #ifdef CHECK_CLIP_RECTS 187 #ifdef CHECK_CLIP_RECTS
178 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) 188 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect())
179 << " fixed=" << clipRects->fixedClipRect().toString(); 189 << " fixed=" << clipRects->fixedClipRect().toString();
180 #endif 190 #endif
181 191
182 clipRects->setPosClipRect( 192 clipRects->setPosClipRect(
183 clipRectForContext(context.absolutePosition, context.currentEffect, 193 clipRectForContext(context.treeBuilderContext.absolutePosition, effect,
184 ancestorState, ancestorPaintOffset, hasClip)); 194 ancestorState, ancestorPaintOffset, hasClip));
185 #ifdef CHECK_CLIP_RECTS 195 #ifdef CHECK_CLIP_RECTS
186 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect()) 196 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect())
187 << " abs=" << clipRects->posClipRect().toString(); 197 << " abs=" << clipRects->posClipRect().toString();
188 #endif 198 #endif
189 199
190 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); 200 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects();
191 201
192 if (!previousClipRects || *clipRects != *previousClipRects) { 202 if (!previousClipRects || *clipRects != *previousClipRects) {
193 paintLayer.setNeedsRepaint(); 203 paintLayer.setNeedsRepaint();
194 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); 204 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false);
195 paintLayer.setPreviousPaintPhaseFloatEmpty(false); 205 paintLayer.setPreviousPaintPhaseFloatEmpty(false);
196 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); 206 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false);
197 // All subsequences which are contained below this paintLayer must also 207 // All subsequences which are contained below this paintLayer must also
198 // be checked. 208 // be checked.
199 context.forceSubtreeUpdate = true; 209 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |=
210 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate;
200 } 211 }
201 212
202 paintLayer.setPreviousPaintingClipRects(*clipRects); 213 paintLayer.setPreviousPaintingClipRects(*clipRects);
203 } 214 }
204 215
205 void PrePaintTreeWalk::walk(const LayoutObject& object, 216 void PrePaintTreeWalk::walk(const LayoutObject& object,
206 const PrePaintTreeWalkContext& parentContext) { 217 const PrePaintTreeWalkContext& parentContext) {
207 PrePaintTreeWalkContext context(parentContext); 218 PrePaintTreeWalkContext context(parentContext);
208 219
209 // Early out from the treewalk if possible. 220 // Early out from the treewalk if possible.
210 if (!object.needsPaintPropertyUpdate() && 221 if (!object.needsPaintPropertyUpdate() &&
211 !object.descendantNeedsPaintPropertyUpdate() && 222 !object.descendantNeedsPaintPropertyUpdate() &&
212 !context.treeBuilderContext.forceSubtreeUpdate && 223 !context.treeBuilderContext.forceSubtreeUpdate &&
213 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && 224 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags &&
214 !object 225 !object
215 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) 226 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState())
216 return; 227 return;
217 228
218 // This must happen before updatePropertiesForSelf, because the latter reads 229 // This must happen before updatePropertiesForSelf, because the latter reads
219 // some of the state computed here. 230 // some of the state computed here.
220 updateAuxiliaryObjectProperties(object, context); 231 updateAuxiliaryObjectProperties(object, context);
221 232
222 m_propertyTreeBuilder.updatePropertiesForSelf(object, 233 m_propertyTreeBuilder.updatePropertiesForSelf(object,
223 context.treeBuilderContext); 234 context.treeBuilderContext);
224 m_paintInvalidator.invalidatePaintIfNeeded(object, 235 m_paintInvalidator.invalidatePaintIfNeeded(object,
225 context.paintInvalidatorContext); 236 context.paintInvalidatorContext);
226 m_propertyTreeBuilder.updatePropertiesForChildren(object, 237 m_propertyTreeBuilder.updatePropertiesForChildren(object,
227 context.treeBuilderContext); 238 context.treeBuilderContext);
228 239
229 if (object.isBoxModelObject() && object.hasLayer()) { 240 invalidatePaintLayerOptimizationsIfNeeded(object, context);
230 if (object.styleRef().hasTransform() ||
231 &object == context.paintInvalidatorContext.paintInvalidationContainer) {
232 context.ancestorTransformedOrRootPaintLayer =
233 toLayoutBoxModelObject(object).layer();
234 }
235 }
236
237 invalidatePaintLayerOptimizationsIfNeeded(
238 object, *context.ancestorTransformedOrRootPaintLayer,
239 context.treeBuilderContext);
240 241
241 for (const LayoutObject* child = object.slowFirstChild(); child; 242 for (const LayoutObject* child = object.slowFirstChild(); child;
242 child = child->nextSibling()) { 243 child = child->nextSibling()) {
243 if (child->isLayoutMultiColumnSpannerPlaceholder()) { 244 if (child->isLayoutMultiColumnSpannerPlaceholder()) {
244 child->getMutableForPainting().clearPaintFlags(); 245 child->getMutableForPainting().clearPaintFlags();
245 continue; 246 continue;
246 } 247 }
247 walk(*child, context); 248 walk(*child, context);
248 } 249 }
249 250
250 if (object.isLayoutPart()) { 251 if (object.isLayoutPart()) {
251 const LayoutPart& layoutPart = toLayoutPart(object); 252 const LayoutPart& layoutPart = toLayoutPart(object);
252 Widget* widget = layoutPart.widget(); 253 Widget* widget = layoutPart.widget();
253 if (widget && widget->isFrameView()) { 254 if (widget && widget->isFrameView()) {
254 context.treeBuilderContext.current.paintOffset += 255 context.treeBuilderContext.current.paintOffset +=
255 layoutPart.replacedContentRect().location() - 256 layoutPart.replacedContentRect().location() -
256 widget->frameRect().location(); 257 widget->frameRect().location();
257 context.treeBuilderContext.current.paintOffset = 258 context.treeBuilderContext.current.paintOffset =
258 roundedIntPoint(context.treeBuilderContext.current.paintOffset); 259 roundedIntPoint(context.treeBuilderContext.current.paintOffset);
259 walk(*toFrameView(widget), context); 260 walk(*toFrameView(widget), context);
260 } 261 }
261 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 262 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
262 } 263 }
263 264
264 object.getMutableForPainting().clearPaintFlags(); 265 object.getMutableForPainting().clearPaintFlags();
265 } 266 }
266 267
267 } // namespace blink 268 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698