OLD | NEW |
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 Loading... |
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 |
OLD | NEW |