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

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

Issue 2784963002: Optimize the pre-paint tree walk and ClipRects (Closed)
Patch Set: none Created 3 years, 8 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"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 // sticky layer position, so we need to update it again here. 104 // sticky layer position, so we need to update it again here.
105 // TODO(flackr): This should be refactored in the future to be clearer (i.e. 105 // TODO(flackr): This should be refactored in the future to be clearer (i.e.
106 // update layer position and ancestor inputs updates in the same walk). 106 // update layer position and ancestor inputs updates in the same walk).
107 paintLayer->updateLayerPosition(); 107 paintLayer->updateLayerPosition();
108 } 108 }
109 109
110 if (paintLayer->isRootLayer() || object.hasOverflowClip()) 110 if (paintLayer->isRootLayer() || object.hasOverflowClip())
111 context.ancestorOverflowPaintLayer = paintLayer; 111 context.ancestorOverflowPaintLayer = paintLayer;
112 } 112 }
113 113
114 // Returns whether |a| is an ancestor of or equal to |b|.
115 static bool isAncestorOfOrEqualTo(const ClipPaintPropertyNode* a,
116 const ClipPaintPropertyNode* b) {
117 while (b && b != a) {
118 b = b->parent();
119 }
120 return b == a;
121 }
122
123 void PrePaintTreeWalk::computeClipRectForContext( 114 void PrePaintTreeWalk::computeClipRectForContext(
124 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context, 115 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context,
125 const EffectPaintPropertyNode* effect, 116 const EffectPaintPropertyNode* effect,
126 const PropertyTreeState& ancestorState, 117 const PropertyTreeState& ancestorState,
127 const LayoutPoint& ancestorPaintOffset, 118 const LayoutPoint& ancestorPaintOffset,
128 bool& hasClip,
129 FloatClipRect& clipRect) { 119 FloatClipRect& clipRect) {
130 // Only return a non-infinite clip if clips differ, or the "ancestor" state is
131 // actually an ancestor clip. This ensures no accuracy issues due to
132 // transforms applied to infinite rects.
133 if (isAncestorOfOrEqualTo(context.clip, ancestorState.clip()))
134 clipRect = FloatClipRect();
135
136 hasClip = true;
137 PropertyTreeState localState(context.transform, context.clip, effect); 120 PropertyTreeState localState(context.transform, context.clip, effect);
138
139 clipRect = 121 clipRect =
140 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState); 122 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState);
141 clipRect.moveBy(-FloatPoint(ancestorPaintOffset)); 123 clipRect.moveBy(-FloatPoint(ancestorPaintOffset));
142 } 124 }
143 125
144 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( 126 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded(
145 const LayoutObject& object, 127 const LayoutObject& object,
146 PrePaintTreeWalkContext& context) { 128 PrePaintTreeWalkContext& context) {
147 if (!object.hasLayer()) 129 if (!object.hasLayer())
148 return; 130 return;
(...skipping 22 matching lines...) Expand all
171 #endif 153 #endif
172 } 154 }
173 155
174 #ifdef CHECK_CLIP_RECTS 156 #ifdef CHECK_CLIP_RECTS
175 ClipRects& oldClipRects = 157 ClipRects& oldClipRects =
176 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper) 158 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper)
177 .paintingClipRects(&ancestorTransformedOrRootPaintLayer, 159 .paintingClipRects(&ancestorTransformedOrRootPaintLayer,
178 respectOverflowClip, LayoutSize()); 160 respectOverflowClip, LayoutSize());
179 #endif 161 #endif
180 162
181 bool hasClip = false; 163 ClipRects clipRects;
182 RefPtr<ClipRects> clipRects = ClipRects::create();
183 const LayoutPoint& ancestorPaintOffset = 164 const LayoutPoint& ancestorPaintOffset =
184 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); 165 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset();
185 166
186 FloatClipRect clipRect; 167 FloatClipRect clipRect;
187 const EffectPaintPropertyNode* effect = 168 const EffectPaintPropertyNode* effect =
188 context.treeBuilderContext->currentEffect; 169 context.treeBuilderContext->currentEffect;
189 computeClipRectForContext(context.treeBuilderContext->current, effect, 170 computeClipRectForContext(context.treeBuilderContext->current, effect,
190 ancestorState, ancestorPaintOffset, hasClip, 171 ancestorState, ancestorPaintOffset, clipRect);
191 clipRect); 172 clipRects.setOverflowClipRect(clipRect);
192 clipRects->setOverflowClipRect(clipRect);
193 #ifdef CHECK_CLIP_RECTS 173 #ifdef CHECK_CLIP_RECTS
194 CHECK(!hasClip || 174 CHECK(clipRects->overflowClipRect() == oldClipRects.overflowClipRect())
195 clipRects->overflowClipRect() == oldClipRects.overflowClipRect())
196 << "rect= " << clipRects->overflowClipRect().toString(); 175 << "rect= " << clipRects->overflowClipRect().toString();
197 #endif 176 #endif
198 177
199 computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect, 178 computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect,
200 ancestorState, ancestorPaintOffset, hasClip, 179 ancestorState, ancestorPaintOffset, clipRect);
201 clipRect); 180 clipRects.setFixedClipRect(clipRect);
202 clipRects->setFixedClipRect(clipRect);
203 #ifdef CHECK_CLIP_RECTS 181 #ifdef CHECK_CLIP_RECTS
204 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) 182 CHECK(clipRects->fixedClipRect() == oldClipRects.fixedClipRect())
205 << " fixed=" << clipRects->fixedClipRect().toString(); 183 << " fixed=" << clipRects->fixedClipRect().toString();
206 #endif 184 #endif
207 185
208 computeClipRectForContext(context.treeBuilderContext->absolutePosition, 186 computeClipRectForContext(context.treeBuilderContext->absolutePosition,
209 effect, ancestorState, ancestorPaintOffset, hasClip, 187 effect, ancestorState, ancestorPaintOffset,
210 clipRect); 188 clipRect);
211 clipRects->setPosClipRect(clipRect); 189 clipRects.setPosClipRect(clipRect);
212 #ifdef CHECK_CLIP_RECTS 190 #ifdef CHECK_CLIP_RECTS
213 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect()) 191 CHECK(clipRects->posClipRect() == oldClipRects.posClipRect())
214 << " abs=" << clipRects->posClipRect().toString(); 192 << " abs=" << clipRects->posClipRect().toString();
215 #endif 193 #endif
216 194
217 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); 195 if (!paintLayer.hasPreviousPaintingClipRects() ||
218 196 clipRects != paintLayer.previousPaintingClipRects()) {
219 if (!previousClipRects || *clipRects != *previousClipRects) {
220 paintLayer.setNeedsRepaint(); 197 paintLayer.setNeedsRepaint();
221 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); 198 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false);
222 paintLayer.setPreviousPaintPhaseFloatEmpty(false); 199 paintLayer.setPreviousPaintPhaseFloatEmpty(false);
223 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); 200 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false);
224 // All subsequences which are contained below this paintLayer must also 201 // All subsequences which are contained below this paintLayer must also
225 // be checked. 202 // be checked.
226 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |= 203 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |=
227 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; 204 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate;
228 } 205 }
229 206
230 paintLayer.setPreviousPaintingClipRects(*clipRects); 207 paintLayer.setPreviousPaintingClipRects(clipRects);
231 } 208 }
232 209
233 bool PrePaintTreeWalk::shouldEndWalkBefore( 210 bool PrePaintTreeWalk::shouldEndWalkBefore(
234 const LayoutObject& object, 211 const LayoutObject& object,
235 const PrePaintTreeWalkContext& context) { 212 const PrePaintTreeWalkContext& context) {
236 return !object.needsPaintPropertyUpdate() && 213 return !object.needsPaintPropertyUpdate() &&
237 !object.descendantNeedsPaintPropertyUpdate() && 214 !object.descendantNeedsPaintPropertyUpdate() &&
238 !context.treeBuilderContext->forceSubtreeUpdate && 215 !context.treeBuilderContext->forceSubtreeUpdate &&
239 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && 216 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags &&
240 !object.shouldCheckForPaintInvalidation(); 217 !object.shouldCheckForPaintInvalidation();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 roundedIntPoint(context.treeBuilderContext->current.paintOffset); 257 roundedIntPoint(context.treeBuilderContext->current.paintOffset);
281 walk(*toFrameView(frameViewBase), context); 258 walk(*toFrameView(frameViewBase), context);
282 } 259 }
283 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 260 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
284 } 261 }
285 262
286 object.getMutableForPainting().clearPaintFlags(); 263 object.getMutableForPainting().clearPaintFlags();
287 } 264 }
288 265
289 } // namespace blink 266 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698