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/PaintPropertyTreeBuilder.h" | 5 #include "core/paint/PaintPropertyTreeBuilder.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include "core/dom/DOMNodeIds.h" | 8 #include "core/dom/DOMNodeIds.h" |
9 #include "core/frame/FrameView.h" | 9 #include "core/frame/FrameView.h" |
10 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
11 #include "core/frame/Settings.h" | 11 #include "core/frame/Settings.h" |
12 #include "core/layout/LayoutInline.h" | 12 #include "core/layout/LayoutInline.h" |
13 #include "core/layout/LayoutView.h" | 13 #include "core/layout/LayoutView.h" |
14 #include "core/layout/compositing/CompositingReasonFinder.h" | 14 #include "core/layout/compositing/CompositingReasonFinder.h" |
15 #include "core/layout/svg/LayoutSVGResourceMasker.h" | 15 #include "core/layout/svg/LayoutSVGResourceMasker.h" |
16 #include "core/layout/svg/LayoutSVGRoot.h" | 16 #include "core/layout/svg/LayoutSVGRoot.h" |
17 #include "core/layout/svg/SVGLayoutSupport.h" | 17 #include "core/layout/svg/SVGLayoutSupport.h" |
18 #include "core/layout/svg/SVGResources.h" | 18 #include "core/layout/svg/SVGResources.h" |
19 #include "core/layout/svg/SVGResourcesCache.h" | 19 #include "core/layout/svg/SVGResourcesCache.h" |
20 #include "core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h" | 20 #include "core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h" |
21 #include "core/paint/FindPropertiesNeedingUpdate.h" | 21 #include "core/paint/FindPropertiesNeedingUpdate.h" |
22 #include "core/paint/ObjectPaintProperties.h" | 22 #include "core/paint/ObjectPaintProperties.h" |
23 #include "core/paint/PaintLayer.h" | 23 #include "core/paint/PaintLayer.h" |
24 #include "core/paint/SVGRootPainter.h" | 24 #include "core/paint/SVGRootPainter.h" |
25 #include "platform/transforms/TransformationMatrix.h" | 25 #include "platform/transforms/TransformationMatrix.h" |
26 #include "platform/wtf/PtrUtil.h" | 26 #include "platform/wtf/PtrUtil.h" |
27 | 27 |
28 namespace blink { | 28 namespace blink { |
29 | 29 |
30 PaintPropertyTreeBuilderContext::PaintPropertyTreeBuilderContext() | 30 PaintPropertyTreeBuilderFragmentContext:: |
31 : container_for_absolute_position(nullptr), | 31 PaintPropertyTreeBuilderFragmentContext() |
32 current_effect(EffectPaintPropertyNode::Root()), | 32 : current_effect(EffectPaintPropertyNode::Root()), |
33 input_clip_of_current_effect(ClipPaintPropertyNode::Root()), | 33 input_clip_of_current_effect(ClipPaintPropertyNode::Root()) { |
34 force_subtree_update(false) { | |
35 current.clip = absolute_position.clip = fixed_position.clip = | 34 current.clip = absolute_position.clip = fixed_position.clip = |
36 ClipPaintPropertyNode::Root(); | 35 ClipPaintPropertyNode::Root(); |
37 current.transform = absolute_position.transform = fixed_position.transform = | 36 current.transform = absolute_position.transform = fixed_position.transform = |
38 TransformPaintPropertyNode::Root(); | 37 TransformPaintPropertyNode::Root(); |
39 current.scroll = absolute_position.scroll = fixed_position.scroll = | 38 current.scroll = absolute_position.scroll = fixed_position.scroll = |
40 ScrollPaintPropertyNode::Root(); | 39 ScrollPaintPropertyNode::Root(); |
41 } | 40 } |
42 | 41 |
43 // True if a new property was created, false if an existing one was updated. | 42 // True if a new property was created, false if an existing one was updated. |
44 static bool UpdatePreTranslation( | 43 static bool UpdatePreTranslation( |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 auto reasons = ancestor_reasons; | 122 auto reasons = ancestor_reasons; |
124 if (!frame_view.GetFrame().GetSettings()->GetThreadedScrollingEnabled()) | 123 if (!frame_view.GetFrame().GetSettings()->GetThreadedScrollingEnabled()) |
125 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; | 124 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; |
126 if (frame_view.HasBackgroundAttachmentFixedObjects()) | 125 if (frame_view.HasBackgroundAttachmentFixedObjects()) |
127 reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; | 126 reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; |
128 return reasons; | 127 return reasons; |
129 } | 128 } |
130 | 129 |
131 void PaintPropertyTreeBuilder::UpdateProperties( | 130 void PaintPropertyTreeBuilder::UpdateProperties( |
132 FrameView& frame_view, | 131 FrameView& frame_view, |
133 PaintPropertyTreeBuilderContext& context) { | 132 PaintPropertyTreeBuilderContext& full_context) { |
| 133 if (full_context.fragments.IsEmpty()) |
| 134 full_context.fragments.push_back(PaintPropertyTreeBuilderFragmentContext()); |
| 135 |
| 136 PaintPropertyTreeBuilderFragmentContext& context = full_context.fragments[0]; |
134 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 137 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
135 // With root layer scrolling, the LayoutView (a LayoutObject) properties are | 138 // With root layer scrolling, the LayoutView (a LayoutObject) properties are |
136 // updated like other objects (see updatePropertiesAndContextForSelf and | 139 // updated like other objects (see updatePropertiesAndContextForSelf and |
137 // updatePropertiesAndContextForChildren) instead of needing LayoutView- | 140 // updatePropertiesAndContextForChildren) instead of needing LayoutView- |
138 // specific property updates here. | 141 // specific property updates here. |
139 context.current.paint_offset.MoveBy(frame_view.Location()); | 142 context.current.paint_offset.MoveBy(frame_view.Location()); |
140 context.current.rendering_context_id = 0; | 143 context.current.rendering_context_id = 0; |
141 context.current.should_flatten_inherited_transform = true; | 144 context.current.should_flatten_inherited_transform = true; |
142 context.absolute_position = context.current; | 145 context.absolute_position = context.current; |
143 context.container_for_absolute_position = nullptr; | 146 full_context.container_for_absolute_position = nullptr; |
144 context.fixed_position = context.current; | 147 context.fixed_position = context.current; |
145 return; | 148 return; |
146 } | 149 } |
147 | 150 |
148 #if DCHECK_IS_ON() | 151 #if DCHECK_IS_ON() |
149 FindFrameViewPropertiesNeedingUpdateScope check_scope(&frame_view, context); | 152 FindFrameViewPropertiesNeedingUpdateScope check_scope( |
| 153 &frame_view, full_context.is_actually_needed); |
150 #endif | 154 #endif |
151 | 155 |
152 if (frame_view.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 156 if (frame_view.NeedsPaintPropertyUpdate() || |
| 157 full_context.force_subtree_update) { |
153 TransformationMatrix frame_translate; | 158 TransformationMatrix frame_translate; |
154 frame_translate.Translate( | 159 frame_translate.Translate( |
155 frame_view.X() + context.current.paint_offset.X(), | 160 frame_view.X() + context.current.paint_offset.X(), |
156 frame_view.Y() + context.current.paint_offset.Y()); | 161 frame_view.Y() + context.current.paint_offset.Y()); |
157 context.force_subtree_update |= UpdatePreTranslation( | 162 full_context.force_subtree_update |= UpdatePreTranslation( |
158 frame_view, context.current.transform, frame_translate, FloatPoint3D()); | 163 frame_view, context.current.transform, frame_translate, FloatPoint3D()); |
159 | 164 |
160 FloatRoundedRect content_clip( | 165 FloatRoundedRect content_clip( |
161 IntRect(IntPoint(), frame_view.VisibleContentSize())); | 166 IntRect(IntPoint(), frame_view.VisibleContentSize())); |
162 context.force_subtree_update |= | 167 full_context.force_subtree_update |= |
163 UpdateContentClip(frame_view, context.current.clip, | 168 UpdateContentClip(frame_view, context.current.clip, |
164 frame_view.PreTranslation(), content_clip); | 169 frame_view.PreTranslation(), content_clip); |
165 | 170 |
166 ScrollOffset scroll_offset = frame_view.GetScrollOffset(); | 171 ScrollOffset scroll_offset = frame_view.GetScrollOffset(); |
167 if (frame_view.IsScrollable() || !scroll_offset.IsZero()) { | 172 if (frame_view.IsScrollable() || !scroll_offset.IsZero()) { |
168 TransformationMatrix frame_scroll; | 173 TransformationMatrix frame_scroll; |
169 frame_scroll.Translate(-scroll_offset.Width(), -scroll_offset.Height()); | 174 frame_scroll.Translate(-scroll_offset.Width(), -scroll_offset.Height()); |
170 | 175 |
171 IntSize scroll_clip = frame_view.VisibleContentSize(); | 176 IntSize scroll_clip = frame_view.VisibleContentSize(); |
172 IntSize scroll_bounds = frame_view.ContentsSize(); | 177 IntSize scroll_bounds = frame_view.ContentsSize(); |
173 bool user_scrollable_horizontal = | 178 bool user_scrollable_horizontal = |
174 frame_view.UserInputScrollable(kHorizontalScrollbar); | 179 frame_view.UserInputScrollable(kHorizontalScrollbar); |
175 bool user_scrollable_vertical = | 180 bool user_scrollable_vertical = |
176 frame_view.UserInputScrollable(kVerticalScrollbar); | 181 frame_view.UserInputScrollable(kVerticalScrollbar); |
177 | 182 |
178 auto ancestor_reasons = | 183 auto ancestor_reasons = |
179 context.current.scroll->GetMainThreadScrollingReasons(); | 184 context.current.scroll->GetMainThreadScrollingReasons(); |
180 auto reasons = | 185 auto reasons = |
181 GetMainThreadScrollingReasons(frame_view, ancestor_reasons); | 186 GetMainThreadScrollingReasons(frame_view, ancestor_reasons); |
182 | 187 |
183 context.force_subtree_update |= UpdateScrollTranslation( | 188 full_context.force_subtree_update |= UpdateScrollTranslation( |
184 frame_view, frame_view.PreTranslation(), frame_scroll, FloatPoint3D(), | 189 frame_view, frame_view.PreTranslation(), frame_scroll, FloatPoint3D(), |
185 context.current.scroll, scroll_clip, scroll_bounds, | 190 context.current.scroll, scroll_clip, scroll_bounds, |
186 user_scrollable_horizontal, user_scrollable_vertical, reasons, | 191 user_scrollable_horizontal, user_scrollable_vertical, reasons, |
187 frame_view.GetScrollableArea()); | 192 frame_view.GetScrollableArea()); |
188 } else { | 193 } else { |
189 if (frame_view.ScrollTranslation()) { | 194 if (frame_view.ScrollTranslation()) { |
190 // Ensure pre-existing properties are cleared if there is no scrolling. | 195 // Ensure pre-existing properties are cleared if there is no scrolling. |
191 frame_view.SetScrollTranslation(nullptr); | 196 frame_view.SetScrollTranslation(nullptr); |
192 // Rebuild all descendant properties because a property was removed. | 197 // Rebuild all descendant properties because a property was removed. |
193 context.force_subtree_update = true; | 198 full_context.force_subtree_update = true; |
194 } | 199 } |
195 } | 200 } |
196 } | 201 } |
197 | 202 |
198 // Initialize the context for current, absolute and fixed position cases. | 203 // Initialize the context for current, absolute and fixed position cases. |
199 // They are the same, except that scroll translation does not apply to | 204 // They are the same, except that scroll translation does not apply to |
200 // fixed position descendants. | 205 // fixed position descendants. |
201 const auto* fixed_transform_node = frame_view.PreTranslation() | 206 const auto* fixed_transform_node = frame_view.PreTranslation() |
202 ? frame_view.PreTranslation() | 207 ? frame_view.PreTranslation() |
203 : context.current.transform; | 208 : context.current.transform; |
204 auto* fixed_scroll_node = context.current.scroll; | 209 auto* fixed_scroll_node = context.current.scroll; |
205 DCHECK(frame_view.PreTranslation()); | 210 DCHECK(frame_view.PreTranslation()); |
206 context.current.transform = frame_view.PreTranslation(); | 211 context.current.transform = frame_view.PreTranslation(); |
207 DCHECK(frame_view.ContentClip()); | 212 DCHECK(frame_view.ContentClip()); |
208 context.current.clip = frame_view.ContentClip(); | 213 context.current.clip = frame_view.ContentClip(); |
209 if (const auto* scroll_translation = frame_view.ScrollTranslation()) { | 214 if (const auto* scroll_translation = frame_view.ScrollTranslation()) { |
210 context.current.transform = scroll_translation; | 215 context.current.transform = scroll_translation; |
211 context.current.scroll = scroll_translation->ScrollNode(); | 216 context.current.scroll = scroll_translation->ScrollNode(); |
212 } | 217 } |
213 context.current.paint_offset = LayoutPoint(); | 218 context.current.paint_offset = LayoutPoint(); |
214 context.current.rendering_context_id = 0; | 219 context.current.rendering_context_id = 0; |
215 context.current.should_flatten_inherited_transform = true; | 220 context.current.should_flatten_inherited_transform = true; |
216 context.absolute_position = context.current; | 221 context.absolute_position = context.current; |
217 context.container_for_absolute_position = nullptr; | 222 full_context.container_for_absolute_position = nullptr; |
218 context.fixed_position = context.current; | 223 context.fixed_position = context.current; |
219 context.fixed_position.transform = fixed_transform_node; | 224 context.fixed_position.transform = fixed_transform_node; |
220 context.fixed_position.scroll = fixed_scroll_node; | 225 context.fixed_position.scroll = fixed_scroll_node; |
221 | 226 |
222 std::unique_ptr<PropertyTreeState> contents_state(new PropertyTreeState( | 227 std::unique_ptr<PropertyTreeState> contents_state(new PropertyTreeState( |
223 context.current.transform, context.current.clip, context.current_effect)); | 228 context.current.transform, context.current.clip, context.current_effect)); |
224 frame_view.SetTotalPropertyTreeStateForContents(std::move(contents_state)); | 229 frame_view.SetTotalPropertyTreeStateForContents(std::move(contents_state)); |
225 } | 230 } |
226 | 231 |
227 static bool NeedsPaintOffsetTranslation(const LayoutObject& object) { | 232 static bool NeedsPaintOffsetTranslation(const LayoutObject& object) { |
228 if (!object.IsBoxModelObject()) | 233 if (!object.IsBoxModelObject()) |
229 return false; | 234 return false; |
230 const LayoutBoxModelObject& box_model = ToLayoutBoxModelObject(object); | 235 const LayoutBoxModelObject& box_model = ToLayoutBoxModelObject(object); |
231 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && | 236 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
232 box_model.IsLayoutView()) { | 237 box_model.IsLayoutView()) { |
233 // Root layer scrolling always creates a translation node for LayoutView to | 238 // Root layer scrolling always creates a translation node for LayoutView to |
234 // ensure fixed and absolute contexts use the correct transform space. | 239 // ensure fixed and absolute contexts use the correct transform space. |
235 return true; | 240 return true; |
236 } else if (box_model.HasLayer() && | 241 } else if (box_model.HasLayer() && |
237 box_model.Layer()->PaintsWithTransform( | 242 box_model.Layer()->PaintsWithTransform( |
238 kGlobalPaintFlattenCompositingLayers)) { | 243 kGlobalPaintFlattenCompositingLayers)) { |
239 return true; | 244 return true; |
240 } | 245 } |
241 return false; | 246 return false; |
242 } | 247 } |
243 | 248 |
244 void PaintPropertyTreeBuilder::UpdatePaintOffsetTranslation( | 249 void PaintPropertyTreeBuilder::UpdatePaintOffsetTranslation( |
245 const LayoutBoxModelObject& object, | 250 const LayoutBoxModelObject& object, |
246 PaintPropertyTreeBuilderContext& context) { | 251 PaintPropertyTreeBuilderFragmentContext& context, |
| 252 bool& force_subtree_update) { |
247 if (NeedsPaintOffsetTranslation(object) && | 253 if (NeedsPaintOffsetTranslation(object) && |
248 // As an optimization, skip these paint offset translation nodes when | 254 // As an optimization, skip these paint offset translation nodes when |
249 // the offset is an identity. An exception is the layout view because root | 255 // the offset is an identity. An exception is the layout view because root |
250 // layer scrolling needs a transform node to ensure fixed and absolute | 256 // layer scrolling needs a transform node to ensure fixed and absolute |
251 // descendants use the correct transform space. | 257 // descendants use the correct transform space. |
252 (object.IsLayoutView() || | 258 (object.IsLayoutView() || |
253 context.current.paint_offset != LayoutPoint())) { | 259 context.current.paint_offset != LayoutPoint())) { |
254 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 260 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
255 // We should use the same subpixel paint offset values for snapping | 261 // We should use the same subpixel paint offset values for snapping |
256 // regardless of whether a transform is present. If there is a transform | 262 // regardless of whether a transform is present. If there is a transform |
257 // we round the paint offset but keep around the residual fractional | 263 // we round the paint offset but keep around the residual fractional |
258 // component for the transformed content to paint with. In spv1 this was | 264 // component for the transformed content to paint with. In spv1 this was |
259 // called "subpixel accumulation". For more information, see | 265 // called "subpixel accumulation". For more information, see |
260 // PaintLayer::subpixelAccumulation() and | 266 // PaintLayer::subpixelAccumulation() and |
261 // PaintLayerPainter::paintFragmentByApplyingTransform. | 267 // PaintLayerPainter::paintFragmentByApplyingTransform. |
262 IntPoint rounded_paint_offset = | 268 IntPoint rounded_paint_offset = |
263 RoundedIntPoint(context.current.paint_offset); | 269 RoundedIntPoint(context.current.paint_offset); |
264 LayoutPoint fractional_paint_offset = | 270 LayoutPoint fractional_paint_offset = |
265 LayoutPoint(context.current.paint_offset - rounded_paint_offset); | 271 LayoutPoint(context.current.paint_offset - rounded_paint_offset); |
266 | 272 |
267 context.force_subtree_update |= properties.UpdatePaintOffsetTranslation( | 273 force_subtree_update |= properties.UpdatePaintOffsetTranslation( |
268 context.current.transform, | 274 context.current.transform, |
269 TransformationMatrix().Translate(rounded_paint_offset.X(), | 275 TransformationMatrix().Translate(rounded_paint_offset.X(), |
270 rounded_paint_offset.Y()), | 276 rounded_paint_offset.Y()), |
271 FloatPoint3D(), context.current.should_flatten_inherited_transform, | 277 FloatPoint3D(), context.current.should_flatten_inherited_transform, |
272 context.current.rendering_context_id); | 278 context.current.rendering_context_id); |
273 | 279 |
274 context.current.transform = properties.PaintOffsetTranslation(); | 280 context.current.transform = properties.PaintOffsetTranslation(); |
275 context.current.paint_offset = fractional_paint_offset; | 281 context.current.paint_offset = fractional_paint_offset; |
276 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && | 282 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
277 object.IsLayoutView()) { | 283 object.IsLayoutView()) { |
278 context.absolute_position.transform = properties.PaintOffsetTranslation(); | 284 context.absolute_position.transform = properties.PaintOffsetTranslation(); |
279 context.fixed_position.transform = properties.PaintOffsetTranslation(); | 285 context.fixed_position.transform = properties.PaintOffsetTranslation(); |
280 context.absolute_position.paint_offset = LayoutPoint(); | 286 context.absolute_position.paint_offset = LayoutPoint(); |
281 context.fixed_position.paint_offset = LayoutPoint(); | 287 context.fixed_position.paint_offset = LayoutPoint(); |
282 } | 288 } |
283 } else { | 289 } else { |
284 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 290 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
285 context.force_subtree_update |= properties->ClearPaintOffsetTranslation(); | 291 force_subtree_update |= properties->ClearPaintOffsetTranslation(); |
286 } | 292 } |
287 } | 293 } |
288 | 294 |
289 static bool NeedsTransformForNonRootSVG(const LayoutObject& object) { | 295 static bool NeedsTransformForNonRootSVG(const LayoutObject& object) { |
290 // TODO(pdr): Check for the presence of a transform instead of the value. | 296 // TODO(pdr): Check for the presence of a transform instead of the value. |
291 // Checking for an identity matrix will cause the property tree structure | 297 // Checking for an identity matrix will cause the property tree structure |
292 // to change during animations if the animation passes through the | 298 // to change during animations if the animation passes through the |
293 // identity matrix. | 299 // identity matrix. |
294 return object.IsSVGChild() && | 300 return object.IsSVGChild() && |
295 !object.LocalToSVGParentTransform().IsIdentity(); | 301 !object.LocalToSVGParentTransform().IsIdentity(); |
296 } | 302 } |
297 | 303 |
298 // SVG does not use the general transform update of |updateTransform|, instead | 304 // SVG does not use the general transform update of |updateTransform|, instead |
299 // creating a transform node for SVG-specific transforms without 3D. | 305 // creating a transform node for SVG-specific transforms without 3D. |
300 void PaintPropertyTreeBuilder::UpdateTransformForNonRootSVG( | 306 void PaintPropertyTreeBuilder::UpdateTransformForNonRootSVG( |
301 const LayoutObject& object, | 307 const LayoutObject& object, |
302 PaintPropertyTreeBuilderContext& context) { | 308 PaintPropertyTreeBuilderFragmentContext& context, |
| 309 bool& force_subtree_update) { |
303 DCHECK(object.IsSVGChild()); | 310 DCHECK(object.IsSVGChild()); |
304 // SVG does not use paint offset internally, except for SVGForeignObject which | 311 // SVG does not use paint offset internally, except for SVGForeignObject which |
305 // has different SVG and HTML coordinate spaces. | 312 // has different SVG and HTML coordinate spaces. |
306 DCHECK(object.IsSVGForeignObject() || | 313 DCHECK(object.IsSVGForeignObject() || |
307 context.current.paint_offset == LayoutPoint()); | 314 context.current.paint_offset == LayoutPoint()); |
308 | 315 |
309 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 316 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
310 AffineTransform transform = object.LocalToSVGParentTransform(); | 317 AffineTransform transform = object.LocalToSVGParentTransform(); |
311 if (NeedsTransformForNonRootSVG(object)) { | 318 if (NeedsTransformForNonRootSVG(object)) { |
312 // The origin is included in the local transform, so leave origin empty. | 319 // The origin is included in the local transform, so leave origin empty. |
313 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 320 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
314 context.force_subtree_update |= properties.UpdateTransform( | 321 force_subtree_update |= properties.UpdateTransform( |
315 context.current.transform, TransformationMatrix(transform), | 322 context.current.transform, TransformationMatrix(transform), |
316 FloatPoint3D()); | 323 FloatPoint3D()); |
317 } else { | 324 } else { |
318 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 325 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
319 context.force_subtree_update |= properties->ClearTransform(); | 326 force_subtree_update |= properties->ClearTransform(); |
320 } | 327 } |
321 } | 328 } |
322 | 329 |
323 if (object.PaintProperties() && object.PaintProperties()->Transform()) { | 330 if (object.PaintProperties() && object.PaintProperties()->Transform()) { |
324 context.current.transform = object.PaintProperties()->Transform(); | 331 context.current.transform = object.PaintProperties()->Transform(); |
325 context.current.should_flatten_inherited_transform = false; | 332 context.current.should_flatten_inherited_transform = false; |
326 context.current.rendering_context_id = 0; | 333 context.current.rendering_context_id = 0; |
327 } | 334 } |
328 } | 335 } |
329 | 336 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 static bool NeedsTransform(const LayoutObject& object) { | 372 static bool NeedsTransform(const LayoutObject& object) { |
366 if (!object.IsBox()) | 373 if (!object.IsBox()) |
367 return false; | 374 return false; |
368 return object.StyleRef().HasTransform() || object.StyleRef().Preserves3D() || | 375 return object.StyleRef().HasTransform() || object.StyleRef().Preserves3D() || |
369 CompositingReasonsForTransform(ToLayoutBox(object)) != | 376 CompositingReasonsForTransform(ToLayoutBox(object)) != |
370 kCompositingReasonNone; | 377 kCompositingReasonNone; |
371 } | 378 } |
372 | 379 |
373 void PaintPropertyTreeBuilder::UpdateTransform( | 380 void PaintPropertyTreeBuilder::UpdateTransform( |
374 const LayoutObject& object, | 381 const LayoutObject& object, |
375 PaintPropertyTreeBuilderContext& context) { | 382 PaintPropertyTreeBuilderFragmentContext& context, |
| 383 bool& force_subtree_update) { |
376 if (object.IsSVGChild()) { | 384 if (object.IsSVGChild()) { |
377 UpdateTransformForNonRootSVG(object, context); | 385 UpdateTransformForNonRootSVG(object, context, force_subtree_update); |
378 return; | 386 return; |
379 } | 387 } |
380 | 388 |
381 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 389 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
382 const ComputedStyle& style = object.StyleRef(); | 390 const ComputedStyle& style = object.StyleRef(); |
383 | 391 |
384 // A transform node is allocated for transforms, preserves-3d and any | 392 // A transform node is allocated for transforms, preserves-3d and any |
385 // direct compositing reason. The latter is required because this is the | 393 // direct compositing reason. The latter is required because this is the |
386 // only way to represent compositing both an element and its stacking | 394 // only way to represent compositing both an element and its stacking |
387 // descendants. | 395 // descendants. |
388 if (NeedsTransform(object)) { | 396 if (NeedsTransform(object)) { |
389 auto& box = ToLayoutBox(object); | 397 auto& box = ToLayoutBox(object); |
390 | 398 |
391 CompositingReasons compositing_reasons = | 399 CompositingReasons compositing_reasons = |
(...skipping 12 matching lines...) Expand all Loading... |
404 unsigned rendering_context_id = context.current.rendering_context_id; | 412 unsigned rendering_context_id = context.current.rendering_context_id; |
405 if (style.Preserves3D() && !rendering_context_id) | 413 if (style.Preserves3D() && !rendering_context_id) |
406 rendering_context_id = PtrHash<const LayoutObject>::GetHash(&object); | 414 rendering_context_id = PtrHash<const LayoutObject>::GetHash(&object); |
407 | 415 |
408 CompositorElementId compositor_element_id = | 416 CompositorElementId compositor_element_id = |
409 style.HasCurrentTransformAnimation() | 417 style.HasCurrentTransformAnimation() |
410 ? CreateDomNodeBasedCompositorElementId(object) | 418 ? CreateDomNodeBasedCompositorElementId(object) |
411 : CompositorElementId(); | 419 : CompositorElementId(); |
412 | 420 |
413 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 421 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
414 context.force_subtree_update |= properties.UpdateTransform( | 422 force_subtree_update |= properties.UpdateTransform( |
415 context.current.transform, matrix, TransformOrigin(box), | 423 context.current.transform, matrix, TransformOrigin(box), |
416 context.current.should_flatten_inherited_transform, | 424 context.current.should_flatten_inherited_transform, |
417 rendering_context_id, compositing_reasons, compositor_element_id); | 425 rendering_context_id, compositing_reasons, compositor_element_id); |
418 } else { | 426 } else { |
419 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 427 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
420 context.force_subtree_update |= properties->ClearTransform(); | 428 force_subtree_update |= properties->ClearTransform(); |
421 } | 429 } |
422 } | 430 } |
423 | 431 |
424 const auto* properties = object.PaintProperties(); | 432 const auto* properties = object.PaintProperties(); |
425 if (properties && properties->Transform()) { | 433 if (properties && properties->Transform()) { |
426 context.current.transform = properties->Transform(); | 434 context.current.transform = properties->Transform(); |
427 if (object.StyleRef().Preserves3D()) { | 435 if (object.StyleRef().Preserves3D()) { |
428 context.current.rendering_context_id = | 436 context.current.rendering_context_id = |
429 properties->Transform()->RenderingContextId(); | 437 properties->Transform()->RenderingContextId(); |
430 context.current.should_flatten_inherited_transform = false; | 438 context.current.should_flatten_inherited_transform = false; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 } | 530 } |
523 | 531 |
524 if (object.StyleRef().HasMask()) | 532 if (object.StyleRef().HasMask()) |
525 return true; | 533 return true; |
526 | 534 |
527 return false; | 535 return false; |
528 } | 536 } |
529 | 537 |
530 void PaintPropertyTreeBuilder::UpdateEffect( | 538 void PaintPropertyTreeBuilder::UpdateEffect( |
531 const LayoutObject& object, | 539 const LayoutObject& object, |
532 PaintPropertyTreeBuilderContext& context) { | 540 PaintPropertyTreeBuilderFragmentContext& context, |
| 541 bool& force_subtree_update) { |
533 const ComputedStyle& style = object.StyleRef(); | 542 const ComputedStyle& style = object.StyleRef(); |
534 | 543 |
535 // TODO(trchen): Can't omit effect node if we have 3D children. | 544 // TODO(trchen): Can't omit effect node if we have 3D children. |
536 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 545 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
537 const ClipPaintPropertyNode* output_clip = | 546 const ClipPaintPropertyNode* output_clip = |
538 context.input_clip_of_current_effect; | 547 context.input_clip_of_current_effect; |
539 | 548 |
540 if (NeedsEffect(object)) { | 549 if (NeedsEffect(object)) { |
541 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 550 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
542 | 551 |
543 // We may begin to composite our subtree prior to an animation starts, | 552 // We may begin to composite our subtree prior to an animation starts, |
544 // but a compositor element ID is only needed when an animation is | 553 // but a compositor element ID is only needed when an animation is |
545 // current. | 554 // current. |
546 CompositingReasons compositing_reasons = kCompositingReasonNone; | 555 CompositingReasons compositing_reasons = kCompositingReasonNone; |
547 if (CompositingReasonFinder::RequiresCompositingForOpacityAnimation( | 556 if (CompositingReasonFinder::RequiresCompositingForOpacityAnimation( |
548 style)) { | 557 style)) { |
549 compositing_reasons = kCompositingReasonActiveAnimation; | 558 compositing_reasons = kCompositingReasonActiveAnimation; |
550 } | 559 } |
551 | 560 |
552 IntRect mask_clip; | 561 IntRect mask_clip; |
553 ColorFilter mask_color_filter; | 562 ColorFilter mask_color_filter; |
554 bool has_mask = ComputeMaskParameters( | 563 bool has_mask = ComputeMaskParameters( |
555 mask_clip, mask_color_filter, object, context.current.paint_offset); | 564 mask_clip, mask_color_filter, object, context.current.paint_offset); |
556 if (has_mask) { | 565 if (has_mask) { |
557 context.force_subtree_update |= properties.UpdateMaskClip( | 566 force_subtree_update |= properties.UpdateMaskClip( |
558 context.current.clip, context.current.transform, | 567 context.current.clip, context.current.transform, |
559 FloatRoundedRect(mask_clip)); | 568 FloatRoundedRect(mask_clip)); |
560 output_clip = properties.MaskClip(); | 569 output_clip = properties.MaskClip(); |
561 | 570 |
562 // TODO(crbug.com/683425): PaintArtifactCompositor does not handle | 571 // TODO(crbug.com/683425): PaintArtifactCompositor does not handle |
563 // grouping (i.e. descendant-dependent compositing reason) properly | 572 // grouping (i.e. descendant-dependent compositing reason) properly |
564 // yet. This forces masked subtree always create a layer for now. | 573 // yet. This forces masked subtree always create a layer for now. |
565 compositing_reasons |= kCompositingReasonIsolateCompositedDescendants; | 574 compositing_reasons |= kCompositingReasonIsolateCompositedDescendants; |
566 } else { | 575 } else { |
567 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 576 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
568 context.force_subtree_update |= properties->ClearMaskClip(); | 577 force_subtree_update |= properties->ClearMaskClip(); |
569 } | 578 } |
570 | 579 |
571 SkBlendMode blend_mode = | 580 SkBlendMode blend_mode = |
572 object.IsBlendingAllowed() | 581 object.IsBlendingAllowed() |
573 ? WebCoreCompositeToSkiaComposite(kCompositeSourceOver, | 582 ? WebCoreCompositeToSkiaComposite(kCompositeSourceOver, |
574 style.BlendMode()) | 583 style.BlendMode()) |
575 : SkBlendMode::kSrcOver; | 584 : SkBlendMode::kSrcOver; |
576 | 585 |
577 CompositorElementId compositor_element_id = | 586 CompositorElementId compositor_element_id = |
578 style.HasCurrentOpacityAnimation() | 587 style.HasCurrentOpacityAnimation() |
579 ? CreateDomNodeBasedCompositorElementId(object) | 588 ? CreateDomNodeBasedCompositorElementId(object) |
580 : CompositorElementId(); | 589 : CompositorElementId(); |
581 | 590 |
582 DCHECK(!style.HasCurrentOpacityAnimation() || | 591 DCHECK(!style.HasCurrentOpacityAnimation() || |
583 compositing_reasons != kCompositingReasonNone); | 592 compositing_reasons != kCompositingReasonNone); |
584 | 593 |
585 context.force_subtree_update |= properties.UpdateEffect( | 594 force_subtree_update |= properties.UpdateEffect( |
586 context.current_effect, context.current.transform, output_clip, | 595 context.current_effect, context.current.transform, output_clip, |
587 kColorFilterNone, CompositorFilterOperations(), style.Opacity(), | 596 kColorFilterNone, CompositorFilterOperations(), style.Opacity(), |
588 blend_mode, compositing_reasons, compositor_element_id); | 597 blend_mode, compositing_reasons, compositor_element_id); |
589 if (has_mask) { | 598 if (has_mask) { |
590 // TODO(crbug.com/683425): PaintArtifactCompositor does not handle | 599 // TODO(crbug.com/683425): PaintArtifactCompositor does not handle |
591 // grouping (i.e. descendant-dependent compositing reason) properly | 600 // grouping (i.e. descendant-dependent compositing reason) properly |
592 // yet. Adding CompositingReasonSquashingDisallowed forces mask not | 601 // yet. Adding CompositingReasonSquashingDisallowed forces mask not |
593 // getting squashed into a child effect. Have no compositing reason | 602 // getting squashed into a child effect. Have no compositing reason |
594 // otherwise. | 603 // otherwise. |
595 context.force_subtree_update |= properties.UpdateMask( | 604 force_subtree_update |= properties.UpdateMask( |
596 properties.Effect(), context.current.transform, output_clip, | 605 properties.Effect(), context.current.transform, output_clip, |
597 mask_color_filter, CompositorFilterOperations(), 1.f, | 606 mask_color_filter, CompositorFilterOperations(), 1.f, |
598 SkBlendMode::kDstIn, kCompositingReasonSquashingDisallowed, | 607 SkBlendMode::kDstIn, kCompositingReasonSquashingDisallowed, |
599 CompositorElementId()); | 608 CompositorElementId()); |
600 } else { | 609 } else { |
601 context.force_subtree_update |= properties.ClearMask(); | 610 force_subtree_update |= properties.ClearMask(); |
602 } | 611 } |
603 } else { | 612 } else { |
604 if (auto* properties = object.GetMutableForPainting().PaintProperties()) { | 613 if (auto* properties = object.GetMutableForPainting().PaintProperties()) { |
605 context.force_subtree_update |= properties->ClearEffect(); | 614 force_subtree_update |= properties->ClearEffect(); |
606 context.force_subtree_update |= properties->ClearMask(); | 615 force_subtree_update |= properties->ClearMask(); |
607 context.force_subtree_update |= properties->ClearMaskClip(); | 616 force_subtree_update |= properties->ClearMaskClip(); |
608 } | 617 } |
609 } | 618 } |
610 } | 619 } |
611 | 620 |
612 const auto* properties = object.PaintProperties(); | 621 const auto* properties = object.PaintProperties(); |
613 if (properties && properties->Effect()) { | 622 if (properties && properties->Effect()) { |
614 context.current_effect = properties->Effect(); | 623 context.current_effect = properties->Effect(); |
615 if (properties->MaskClip()) { | 624 if (properties->MaskClip()) { |
616 context.input_clip_of_current_effect = context.current.clip = | 625 context.input_clip_of_current_effect = context.current.clip = |
617 context.absolute_position.clip = context.fixed_position.clip = | 626 context.absolute_position.clip = context.fixed_position.clip = |
618 properties->MaskClip(); | 627 properties->MaskClip(); |
619 } | 628 } |
620 } | 629 } |
621 } | 630 } |
622 | 631 |
623 static bool NeedsFilter(const LayoutObject& object) { | 632 static bool NeedsFilter(const LayoutObject& object) { |
624 // TODO(trchen): SVG caches filters in SVGResources. Implement it. | 633 // TODO(trchen): SVG caches filters in SVGResources. Implement it. |
625 return object.IsBoxModelObject() && ToLayoutBoxModelObject(object).Layer() && | 634 return object.IsBoxModelObject() && ToLayoutBoxModelObject(object).Layer() && |
626 (object.StyleRef().HasFilter() || object.HasReflection()); | 635 (object.StyleRef().HasFilter() || object.HasReflection()); |
627 } | 636 } |
628 | 637 |
629 void PaintPropertyTreeBuilder::UpdateFilter( | 638 void PaintPropertyTreeBuilder::UpdateFilter( |
630 const LayoutObject& object, | 639 const LayoutObject& object, |
631 PaintPropertyTreeBuilderContext& context) { | 640 PaintPropertyTreeBuilderFragmentContext& context, |
| 641 bool& force_subtree_update) { |
632 const ComputedStyle& style = object.StyleRef(); | 642 const ComputedStyle& style = object.StyleRef(); |
633 | 643 |
634 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 644 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
635 if (NeedsFilter(object)) { | 645 if (NeedsFilter(object)) { |
636 CompositorFilterOperations filter = | 646 CompositorFilterOperations filter = |
637 ToLayoutBoxModelObject(object) | 647 ToLayoutBoxModelObject(object) |
638 .Layer() | 648 .Layer() |
639 ->CreateCompositorFilterOperationsForFilter(style); | 649 ->CreateCompositorFilterOperationsForFilter(style); |
640 | 650 |
641 // The CSS filter spec didn't specify how filters interact with overflow | 651 // The CSS filter spec didn't specify how filters interact with overflow |
642 // clips. The implementation here mimics the old Blink/WebKit behavior for | 652 // clips. The implementation here mimics the old Blink/WebKit behavior for |
643 // backward compatibility. | 653 // backward compatibility. |
644 // Basically the output of the filter will be affected by clips that | 654 // Basically the output of the filter will be affected by clips that |
(...skipping 25 matching lines...) Expand all Loading... |
670 ? CreateDomNodeBasedCompositorElementId(object) | 680 ? CreateDomNodeBasedCompositorElementId(object) |
671 : CompositorElementId(); | 681 : CompositorElementId(); |
672 CompositingReasons compositing_reasons = | 682 CompositingReasons compositing_reasons = |
673 CompositingReasonFinder::RequiresCompositingForFilterAnimation(style) | 683 CompositingReasonFinder::RequiresCompositingForFilterAnimation(style) |
674 ? kCompositingReasonActiveAnimation | 684 ? kCompositingReasonActiveAnimation |
675 : kCompositingReasonNone; | 685 : kCompositingReasonNone; |
676 DCHECK(!style.HasCurrentFilterAnimation() || | 686 DCHECK(!style.HasCurrentFilterAnimation() || |
677 compositing_reasons != kCompositingReasonNone); | 687 compositing_reasons != kCompositingReasonNone); |
678 | 688 |
679 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 689 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
680 context.force_subtree_update |= properties.UpdateFilter( | 690 force_subtree_update |= properties.UpdateFilter( |
681 context.current_effect, context.current.transform, output_clip, | 691 context.current_effect, context.current.transform, output_clip, |
682 kColorFilterNone, std::move(filter), 1.f, SkBlendMode::kSrcOver, | 692 kColorFilterNone, std::move(filter), 1.f, SkBlendMode::kSrcOver, |
683 compositing_reasons, compositor_element_id); | 693 compositing_reasons, compositor_element_id); |
684 } else { | 694 } else { |
685 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 695 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
686 context.force_subtree_update |= properties->ClearFilter(); | 696 force_subtree_update |= properties->ClearFilter(); |
687 } | 697 } |
688 } | 698 } |
689 | 699 |
690 const auto* properties = object.PaintProperties(); | 700 const auto* properties = object.PaintProperties(); |
691 if (properties && properties->Filter()) { | 701 if (properties && properties->Filter()) { |
692 context.current_effect = properties->Filter(); | 702 context.current_effect = properties->Filter(); |
693 // TODO(trchen): Change input clip to expansion hint once implemented. | 703 // TODO(trchen): Change input clip to expansion hint once implemented. |
694 const ClipPaintPropertyNode* input_clip = | 704 const ClipPaintPropertyNode* input_clip = |
695 properties->Filter()->OutputClip(); | 705 properties->Filter()->OutputClip(); |
696 context.input_clip_of_current_effect = context.current.clip = | 706 context.input_clip_of_current_effect = context.current.clip = |
697 context.absolute_position.clip = context.fixed_position.clip = | 707 context.absolute_position.clip = context.fixed_position.clip = |
698 input_clip; | 708 input_clip; |
699 } | 709 } |
700 } | 710 } |
701 | 711 |
702 static bool NeedsCssClip(const LayoutObject& object) { | 712 static bool NeedsCssClip(const LayoutObject& object) { |
703 return object.HasClip(); | 713 return object.HasClip(); |
704 } | 714 } |
705 | 715 |
706 void PaintPropertyTreeBuilder::UpdateCssClip( | 716 void PaintPropertyTreeBuilder::UpdateCssClip( |
707 const LayoutObject& object, | 717 const LayoutObject& object, |
708 PaintPropertyTreeBuilderContext& context) { | 718 PaintPropertyTreeBuilderFragmentContext& context, |
709 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 719 bool& force_subtree_update) { |
| 720 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
710 if (NeedsCssClip(object)) { | 721 if (NeedsCssClip(object)) { |
711 // Create clip node for descendants that are not fixed position. | 722 // Create clip node for descendants that are not fixed position. |
712 // We don't have to setup context.absolutePosition.clip here because this | 723 // We don't have to setup context.absolutePosition.clip here because this |
713 // object must be a container for absolute position descendants, and will | 724 // object must be a container for absolute position descendants, and will |
714 // copy from in-flow context later at updateOutOfFlowContext() step. | 725 // copy from in-flow context later at updateOutOfFlowContext() step. |
715 DCHECK(object.CanContainAbsolutePositionObjects()); | 726 DCHECK(object.CanContainAbsolutePositionObjects()); |
716 LayoutRect clip_rect = | 727 LayoutRect clip_rect = |
717 ToLayoutBox(object).ClipRect(context.current.paint_offset); | 728 ToLayoutBox(object).ClipRect(context.current.paint_offset); |
718 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 729 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
719 context.force_subtree_update |= properties.UpdateCssClip( | 730 force_subtree_update |= properties.UpdateCssClip( |
720 context.current.clip, context.current.transform, | 731 context.current.clip, context.current.transform, |
721 FloatRoundedRect(FloatRect(clip_rect))); | 732 FloatRoundedRect(FloatRect(clip_rect))); |
722 } else { | 733 } else { |
723 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 734 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
724 context.force_subtree_update |= properties->ClearCssClip(); | 735 force_subtree_update |= properties->ClearCssClip(); |
725 } | 736 } |
726 } | 737 } |
727 | 738 |
728 const auto* properties = object.PaintProperties(); | 739 const auto* properties = object.PaintProperties(); |
729 if (properties && properties->CssClip()) | 740 if (properties && properties->CssClip()) |
730 context.current.clip = properties->CssClip(); | 741 context.current.clip = properties->CssClip(); |
731 } | 742 } |
732 | 743 |
733 void PaintPropertyTreeBuilder::UpdateLocalBorderBoxContext( | 744 void PaintPropertyTreeBuilder::UpdateLocalBorderBoxContext( |
734 const LayoutObject& object, | 745 const LayoutObject& object, |
735 PaintPropertyTreeBuilderContext& context) { | 746 PaintPropertyTreeBuilderFragmentContext& context, |
736 if (!object.NeedsPaintPropertyUpdate() && !context.force_subtree_update) | 747 bool& force_subtree_update) { |
| 748 if (!object.NeedsPaintPropertyUpdate() && !force_subtree_update) |
737 return; | 749 return; |
738 | 750 |
739 // We only need to cache the local border box properties for layered objects. | 751 // We only need to cache the local border box properties for layered objects. |
740 if (!object.HasLayer()) { | 752 if (!object.HasLayer()) { |
741 object.GetMutableForPainting().ClearLocalBorderBoxProperties(); | 753 object.GetMutableForPainting().ClearLocalBorderBoxProperties(); |
742 } else { | 754 } else { |
743 PropertyTreeState local_border_box = | 755 PropertyTreeState local_border_box = |
744 PropertyTreeState(context.current.transform, context.current.clip, | 756 PropertyTreeState(context.current.transform, context.current.clip, |
745 context.current_effect); | 757 context.current_effect); |
746 object.GetMutableForPainting().SetLocalBorderBoxProperties( | 758 object.GetMutableForPainting().SetLocalBorderBoxProperties( |
747 local_border_box); | 759 local_border_box); |
748 } | 760 } |
749 } | 761 } |
750 | 762 |
751 static bool NeedsScrollbarPaintOffset(const LayoutObject& object) { | 763 static bool NeedsScrollbarPaintOffset(const LayoutObject& object) { |
752 if (object.IsBoxModelObject()) { | 764 if (object.IsBoxModelObject()) { |
753 if (auto* area = ToLayoutBoxModelObject(object).GetScrollableArea()) { | 765 if (auto* area = ToLayoutBoxModelObject(object).GetScrollableArea()) { |
754 if (area->HorizontalScrollbar() || area->VerticalScrollbar()) | 766 if (area->HorizontalScrollbar() || area->VerticalScrollbar()) |
755 return true; | 767 return true; |
756 } | 768 } |
757 } | 769 } |
758 return false; | 770 return false; |
759 } | 771 } |
760 | 772 |
761 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 773 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
762 void PaintPropertyTreeBuilder::UpdateScrollbarPaintOffset( | 774 void PaintPropertyTreeBuilder::UpdateScrollbarPaintOffset( |
763 const LayoutObject& object, | 775 const LayoutObject& object, |
764 PaintPropertyTreeBuilderContext& context) { | 776 PaintPropertyTreeBuilderFragmentContext& context, |
765 if (!object.NeedsPaintPropertyUpdate() && !context.force_subtree_update) | 777 bool& force_subtree_update) { |
| 778 if (!object.NeedsPaintPropertyUpdate() && !force_subtree_update) |
766 return; | 779 return; |
767 | 780 |
768 if (NeedsScrollbarPaintOffset(object)) { | 781 if (NeedsScrollbarPaintOffset(object)) { |
769 IntPoint rounded_paint_offset = | 782 IntPoint rounded_paint_offset = |
770 RoundedIntPoint(context.current.paint_offset); | 783 RoundedIntPoint(context.current.paint_offset); |
771 auto paint_offset = TransformationMatrix().Translate( | 784 auto paint_offset = TransformationMatrix().Translate( |
772 rounded_paint_offset.X(), rounded_paint_offset.Y()); | 785 rounded_paint_offset.X(), rounded_paint_offset.Y()); |
773 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 786 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
774 context.force_subtree_update |= properties.UpdateScrollbarPaintOffset( | 787 force_subtree_update |= properties.UpdateScrollbarPaintOffset( |
775 context.current.transform, paint_offset, FloatPoint3D()); | 788 context.current.transform, paint_offset, FloatPoint3D()); |
776 } else { | 789 } else { |
777 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 790 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
778 context.force_subtree_update |= properties->ClearScrollbarPaintOffset(); | 791 force_subtree_update |= properties->ClearScrollbarPaintOffset(); |
779 } | 792 } |
780 } | 793 } |
781 | 794 |
782 static bool NeedsOverflowScroll(const LayoutObject& object) { | 795 static bool NeedsOverflowScroll(const LayoutObject& object) { |
783 return object.IsBox() && ToLayoutBox(object).ShouldClipOverflow(); | 796 return object.IsBox() && ToLayoutBox(object).ShouldClipOverflow(); |
784 } | 797 } |
785 | 798 |
786 void PaintPropertyTreeBuilder::UpdateOverflowClip( | 799 void PaintPropertyTreeBuilder::UpdateOverflowClip( |
787 const LayoutObject& object, | 800 const LayoutObject& object, |
788 PaintPropertyTreeBuilderContext& context) { | 801 PaintPropertyTreeBuilderFragmentContext& context, |
789 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 802 bool& force_subtree_update) { |
| 803 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
790 if (NeedsOverflowScroll(object)) { | 804 if (NeedsOverflowScroll(object)) { |
791 const LayoutBox& box = ToLayoutBox(object); | 805 const LayoutBox& box = ToLayoutBox(object); |
792 LayoutRect clip_rect; | 806 LayoutRect clip_rect; |
793 clip_rect = | 807 clip_rect = |
794 LayoutRect(box.OverflowClipRect(context.current.paint_offset)); | 808 LayoutRect(box.OverflowClipRect(context.current.paint_offset)); |
795 | 809 |
796 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 810 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
797 const auto* current_clip = context.current.clip; | 811 const auto* current_clip = context.current.clip; |
798 if (box.StyleRef().HasBorderRadius()) { | 812 if (box.StyleRef().HasBorderRadius()) { |
799 auto inner_border = box.StyleRef().GetRoundedInnerBorderFor( | 813 auto inner_border = box.StyleRef().GetRoundedInnerBorderFor( |
800 LayoutRect(context.current.paint_offset, box.Size())); | 814 LayoutRect(context.current.paint_offset, box.Size())); |
801 context.force_subtree_update |= properties.UpdateInnerBorderRadiusClip( | 815 force_subtree_update |= properties.UpdateInnerBorderRadiusClip( |
802 context.current.clip, context.current.transform, inner_border); | 816 context.current.clip, context.current.transform, inner_border); |
803 current_clip = properties.InnerBorderRadiusClip(); | 817 current_clip = properties.InnerBorderRadiusClip(); |
804 } else { | 818 } else { |
805 context.force_subtree_update |= properties.ClearInnerBorderRadiusClip(); | 819 force_subtree_update |= properties.ClearInnerBorderRadiusClip(); |
806 } | 820 } |
807 | 821 |
808 context.force_subtree_update |= | 822 force_subtree_update |= |
809 properties.UpdateOverflowClip(current_clip, context.current.transform, | 823 properties.UpdateOverflowClip(current_clip, context.current.transform, |
810 FloatRoundedRect(FloatRect(clip_rect))); | 824 FloatRoundedRect(FloatRect(clip_rect))); |
811 } else { | 825 } else { |
812 if (auto* properties = object.GetMutableForPainting().PaintProperties()) { | 826 if (auto* properties = object.GetMutableForPainting().PaintProperties()) { |
813 context.force_subtree_update |= | 827 force_subtree_update |= properties->ClearInnerBorderRadiusClip(); |
814 properties->ClearInnerBorderRadiusClip(); | 828 force_subtree_update |= properties->ClearOverflowClip(); |
815 context.force_subtree_update |= properties->ClearOverflowClip(); | |
816 } | 829 } |
817 return; | 830 return; |
818 } | 831 } |
819 } | 832 } |
820 | 833 |
821 const auto* properties = object.PaintProperties(); | 834 const auto* properties = object.PaintProperties(); |
822 if (properties && properties->OverflowClip()) | 835 if (properties && properties->OverflowClip()) |
823 context.current.clip = properties->OverflowClip(); | 836 context.current.clip = properties->OverflowClip(); |
824 } | 837 } |
825 | 838 |
826 static FloatPoint PerspectiveOrigin(const LayoutBox& box) { | 839 static FloatPoint PerspectiveOrigin(const LayoutBox& box) { |
827 const ComputedStyle& style = box.StyleRef(); | 840 const ComputedStyle& style = box.StyleRef(); |
828 // Perspective origin has no effect without perspective. | 841 // Perspective origin has no effect without perspective. |
829 DCHECK(style.HasPerspective()); | 842 DCHECK(style.HasPerspective()); |
830 FloatSize border_box_size(box.Size()); | 843 FloatSize border_box_size(box.Size()); |
831 return FloatPoint( | 844 return FloatPoint( |
832 FloatValueForLength(style.PerspectiveOriginX(), border_box_size.Width()), | 845 FloatValueForLength(style.PerspectiveOriginX(), border_box_size.Width()), |
833 FloatValueForLength(style.PerspectiveOriginY(), | 846 FloatValueForLength(style.PerspectiveOriginY(), |
834 border_box_size.Height())); | 847 border_box_size.Height())); |
835 } | 848 } |
836 | 849 |
837 static bool NeedsPerspective(const LayoutObject& object) { | 850 static bool NeedsPerspective(const LayoutObject& object) { |
838 return object.IsBox() && object.StyleRef().HasPerspective(); | 851 return object.IsBox() && object.StyleRef().HasPerspective(); |
839 } | 852 } |
840 | 853 |
841 void PaintPropertyTreeBuilder::UpdatePerspective( | 854 void PaintPropertyTreeBuilder::UpdatePerspective( |
842 const LayoutObject& object, | 855 const LayoutObject& object, |
843 PaintPropertyTreeBuilderContext& context) { | 856 PaintPropertyTreeBuilderFragmentContext& context, |
844 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 857 bool& force_subtree_update) { |
| 858 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
845 if (NeedsPerspective(object)) { | 859 if (NeedsPerspective(object)) { |
846 const ComputedStyle& style = object.StyleRef(); | 860 const ComputedStyle& style = object.StyleRef(); |
847 // The perspective node must not flatten (else nothing will get | 861 // The perspective node must not flatten (else nothing will get |
848 // perspective), but it should still extend the rendering context as | 862 // perspective), but it should still extend the rendering context as |
849 // most transform nodes do. | 863 // most transform nodes do. |
850 TransformationMatrix matrix = | 864 TransformationMatrix matrix = |
851 TransformationMatrix().ApplyPerspective(style.Perspective()); | 865 TransformationMatrix().ApplyPerspective(style.Perspective()); |
852 FloatPoint3D origin = PerspectiveOrigin(ToLayoutBox(object)) + | 866 FloatPoint3D origin = PerspectiveOrigin(ToLayoutBox(object)) + |
853 ToLayoutSize(context.current.paint_offset); | 867 ToLayoutSize(context.current.paint_offset); |
854 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 868 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
855 context.force_subtree_update |= properties.UpdatePerspective( | 869 force_subtree_update |= properties.UpdatePerspective( |
856 context.current.transform, matrix, origin, | 870 context.current.transform, matrix, origin, |
857 context.current.should_flatten_inherited_transform, | 871 context.current.should_flatten_inherited_transform, |
858 context.current.rendering_context_id); | 872 context.current.rendering_context_id); |
859 } else { | 873 } else { |
860 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 874 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
861 context.force_subtree_update |= properties->ClearPerspective(); | 875 force_subtree_update |= properties->ClearPerspective(); |
862 } | 876 } |
863 } | 877 } |
864 | 878 |
865 const auto* properties = object.PaintProperties(); | 879 const auto* properties = object.PaintProperties(); |
866 if (properties && properties->Perspective()) { | 880 if (properties && properties->Perspective()) { |
867 context.current.transform = properties->Perspective(); | 881 context.current.transform = properties->Perspective(); |
868 context.current.should_flatten_inherited_transform = false; | 882 context.current.should_flatten_inherited_transform = false; |
869 } | 883 } |
870 } | 884 } |
871 | 885 |
872 static bool NeedsSVGLocalToBorderBoxTransform(const LayoutObject& object) { | 886 static bool NeedsSVGLocalToBorderBoxTransform(const LayoutObject& object) { |
873 return object.IsSVGRoot(); | 887 return object.IsSVGRoot(); |
874 } | 888 } |
875 | 889 |
876 void PaintPropertyTreeBuilder::UpdateSvgLocalToBorderBoxTransform( | 890 void PaintPropertyTreeBuilder::UpdateSvgLocalToBorderBoxTransform( |
877 const LayoutObject& object, | 891 const LayoutObject& object, |
878 PaintPropertyTreeBuilderContext& context) { | 892 PaintPropertyTreeBuilderFragmentContext& context, |
| 893 bool& force_subtree_update) { |
879 if (!object.IsSVGRoot()) | 894 if (!object.IsSVGRoot()) |
880 return; | 895 return; |
881 | 896 |
882 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 897 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
883 AffineTransform transform_to_border_box = | 898 AffineTransform transform_to_border_box = |
884 SVGRootPainter(ToLayoutSVGRoot(object)) | 899 SVGRootPainter(ToLayoutSVGRoot(object)) |
885 .TransformToPixelSnappedBorderBox(context.current.paint_offset); | 900 .TransformToPixelSnappedBorderBox(context.current.paint_offset); |
886 if (!transform_to_border_box.IsIdentity() && | 901 if (!transform_to_border_box.IsIdentity() && |
887 NeedsSVGLocalToBorderBoxTransform(object)) { | 902 NeedsSVGLocalToBorderBoxTransform(object)) { |
888 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 903 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
889 context.force_subtree_update |= | 904 force_subtree_update |= properties.UpdateSvgLocalToBorderBoxTransform( |
890 properties.UpdateSvgLocalToBorderBoxTransform( | 905 context.current.transform, transform_to_border_box, FloatPoint3D()); |
891 context.current.transform, transform_to_border_box, | |
892 FloatPoint3D()); | |
893 } else { | 906 } else { |
894 if (auto* properties = object.GetMutableForPainting().PaintProperties()) { | 907 if (auto* properties = object.GetMutableForPainting().PaintProperties()) { |
895 context.force_subtree_update |= | 908 force_subtree_update |= properties->ClearSvgLocalToBorderBoxTransform(); |
896 properties->ClearSvgLocalToBorderBoxTransform(); | |
897 } | 909 } |
898 } | 910 } |
899 } | 911 } |
900 | 912 |
901 const auto* properties = object.PaintProperties(); | 913 const auto* properties = object.PaintProperties(); |
902 if (properties && properties->SvgLocalToBorderBoxTransform()) { | 914 if (properties && properties->SvgLocalToBorderBoxTransform()) { |
903 context.current.transform = properties->SvgLocalToBorderBoxTransform(); | 915 context.current.transform = properties->SvgLocalToBorderBoxTransform(); |
904 context.current.should_flatten_inherited_transform = false; | 916 context.current.should_flatten_inherited_transform = false; |
905 context.current.rendering_context_id = 0; | 917 context.current.rendering_context_id = 0; |
906 } | 918 } |
(...skipping 21 matching lines...) Expand all Loading... |
928 auto* scrollable_area = box.GetScrollableArea(); | 940 auto* scrollable_area = box.GetScrollableArea(); |
929 IntSize scroll_offset = box.ScrolledContentOffset(); | 941 IntSize scroll_offset = box.ScrolledContentOffset(); |
930 if (!scroll_offset.IsZero() || scrollable_area->ScrollsOverflow()) | 942 if (!scroll_offset.IsZero() || scrollable_area->ScrollsOverflow()) |
931 return true; | 943 return true; |
932 } | 944 } |
933 return false; | 945 return false; |
934 } | 946 } |
935 | 947 |
936 void PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation( | 948 void PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation( |
937 const LayoutObject& object, | 949 const LayoutObject& object, |
938 PaintPropertyTreeBuilderContext& context) { | 950 PaintPropertyTreeBuilderFragmentContext& context, |
939 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 951 bool& force_subtree_update) { |
| 952 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
940 if (NeedsScrollTranslation(object)) { | 953 if (NeedsScrollTranslation(object)) { |
941 const LayoutBox& box = ToLayoutBox(object); | 954 const LayoutBox& box = ToLayoutBox(object); |
942 auto* scrollable_area = box.GetScrollableArea(); | 955 auto* scrollable_area = box.GetScrollableArea(); |
943 IntSize scroll_offset = box.ScrolledContentOffset(); | 956 IntSize scroll_offset = box.ScrolledContentOffset(); |
944 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 957 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
945 | 958 |
946 IntSize scroll_clip = scrollable_area->VisibleContentRect().Size(); | 959 IntSize scroll_clip = scrollable_area->VisibleContentRect().Size(); |
947 IntSize scroll_bounds = scrollable_area->ContentsSize(); | 960 IntSize scroll_bounds = scrollable_area->ContentsSize(); |
948 bool user_scrollable_horizontal = | 961 bool user_scrollable_horizontal = |
949 scrollable_area->UserInputScrollable(kHorizontalScrollbar); | 962 scrollable_area->UserInputScrollable(kHorizontalScrollbar); |
950 bool user_scrollable_vertical = | 963 bool user_scrollable_vertical = |
951 scrollable_area->UserInputScrollable(kVerticalScrollbar); | 964 scrollable_area->UserInputScrollable(kVerticalScrollbar); |
952 | 965 |
953 auto ancestor_reasons = | 966 auto ancestor_reasons = |
954 context.current.scroll->GetMainThreadScrollingReasons(); | 967 context.current.scroll->GetMainThreadScrollingReasons(); |
955 auto reasons = GetMainThreadScrollingReasons(object, ancestor_reasons); | 968 auto reasons = GetMainThreadScrollingReasons(object, ancestor_reasons); |
956 | 969 |
957 // Main thread scrolling reasons depend on their ancestor's reasons | 970 // Main thread scrolling reasons depend on their ancestor's reasons |
958 // so ensure the entire subtree is updated when reasons change. | 971 // so ensure the entire subtree is updated when reasons change. |
959 if (auto* existing_scroll_translation = properties.ScrollTranslation()) { | 972 if (auto* existing_scroll_translation = properties.ScrollTranslation()) { |
960 auto* existing_scroll_node = existing_scroll_translation->ScrollNode(); | 973 auto* existing_scroll_node = existing_scroll_translation->ScrollNode(); |
961 if (existing_scroll_node->GetMainThreadScrollingReasons() != reasons) | 974 if (existing_scroll_node->GetMainThreadScrollingReasons() != reasons) |
962 context.force_subtree_update = true; | 975 force_subtree_update = true; |
963 } | 976 } |
964 | 977 |
965 CompositorElementId compositor_element_id = | 978 CompositorElementId compositor_element_id = |
966 CreateDomNodeBasedCompositorElementId(object); | 979 CreateDomNodeBasedCompositorElementId(object); |
967 TransformationMatrix matrix = TransformationMatrix().Translate( | 980 TransformationMatrix matrix = TransformationMatrix().Translate( |
968 -scroll_offset.Width(), -scroll_offset.Height()); | 981 -scroll_offset.Width(), -scroll_offset.Height()); |
969 context.force_subtree_update |= properties.UpdateScrollTranslation( | 982 force_subtree_update |= properties.UpdateScrollTranslation( |
970 context.current.transform, matrix, FloatPoint3D(), | 983 context.current.transform, matrix, FloatPoint3D(), |
971 context.current.should_flatten_inherited_transform, | 984 context.current.should_flatten_inherited_transform, |
972 context.current.rendering_context_id, kCompositingReasonNone, | 985 context.current.rendering_context_id, kCompositingReasonNone, |
973 compositor_element_id, context.current.scroll, scroll_clip, | 986 compositor_element_id, context.current.scroll, scroll_clip, |
974 scroll_bounds, user_scrollable_horizontal, user_scrollable_vertical, | 987 scroll_bounds, user_scrollable_horizontal, user_scrollable_vertical, |
975 reasons, scrollable_area); | 988 reasons, scrollable_area); |
976 } else { | 989 } else { |
977 // Ensure pre-existing properties are cleared. | 990 // Ensure pre-existing properties are cleared. |
978 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 991 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
979 context.force_subtree_update |= properties->ClearScrollTranslation(); | 992 force_subtree_update |= properties->ClearScrollTranslation(); |
980 } | 993 } |
981 } | 994 } |
982 | 995 |
983 if (object.PaintProperties() && | 996 if (object.PaintProperties() && |
984 object.PaintProperties()->ScrollTranslation()) { | 997 object.PaintProperties()->ScrollTranslation()) { |
985 context.current.transform = object.PaintProperties()->ScrollTranslation(); | 998 context.current.transform = object.PaintProperties()->ScrollTranslation(); |
986 context.current.scroll = context.current.transform->ScrollNode(); | 999 context.current.scroll = context.current.transform->ScrollNode(); |
987 context.current.should_flatten_inherited_transform = false; | 1000 context.current.should_flatten_inherited_transform = false; |
988 } | 1001 } |
989 } | 1002 } |
990 | 1003 |
991 static bool NeedsCssClipFixedPosition(const LayoutObject& object) { | 1004 static bool NeedsCssClipFixedPosition(const LayoutObject& object) { |
992 return !object.IsLayoutView() && !object.CanContainFixedPositionObjects() && | 1005 return !object.IsLayoutView() && !object.CanContainFixedPositionObjects() && |
993 NeedsCssClip(object); | 1006 NeedsCssClip(object); |
994 } | 1007 } |
995 | 1008 |
996 void PaintPropertyTreeBuilder::UpdateOutOfFlowContext( | 1009 void PaintPropertyTreeBuilder::UpdateOutOfFlowContext( |
997 const LayoutObject& object, | 1010 const LayoutObject& object, |
998 PaintPropertyTreeBuilderContext& context) { | 1011 PaintPropertyTreeBuilderFragmentContext& context, |
| 1012 bool& force_subtree_update) { |
999 if (object.IsLayoutBlock()) | 1013 if (object.IsLayoutBlock()) |
1000 context.paint_offset_for_float = context.current.paint_offset; | 1014 context.paint_offset_for_float = context.current.paint_offset; |
1001 | 1015 |
1002 if (object.CanContainAbsolutePositionObjects()) { | 1016 if (object.CanContainAbsolutePositionObjects()) |
1003 context.absolute_position = context.current; | 1017 context.absolute_position = context.current; |
1004 context.container_for_absolute_position = &object; | |
1005 } | |
1006 | 1018 |
1007 if (object.IsLayoutView()) { | 1019 if (object.IsLayoutView()) { |
1008 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 1020 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
1009 const auto* initial_fixed_transform = context.fixed_position.transform; | 1021 const auto* initial_fixed_transform = context.fixed_position.transform; |
1010 const auto* initial_fixed_scroll = context.fixed_position.scroll; | 1022 const auto* initial_fixed_scroll = context.fixed_position.scroll; |
1011 | 1023 |
1012 context.fixed_position = context.current; | 1024 context.fixed_position = context.current; |
1013 | 1025 |
1014 // Fixed position transform and scroll nodes should not be affected. | 1026 // Fixed position transform and scroll nodes should not be affected. |
1015 context.fixed_position.transform = initial_fixed_transform; | 1027 context.fixed_position.transform = initial_fixed_transform; |
(...skipping 10 matching lines...) Expand all Loading... |
1026 // need to insert the clip here if we are not a containing block ancestor of | 1038 // need to insert the clip here if we are not a containing block ancestor of |
1027 // them. | 1039 // them. |
1028 auto& properties = *object.GetMutableForPainting().PaintProperties(); | 1040 auto& properties = *object.GetMutableForPainting().PaintProperties(); |
1029 auto* css_clip = properties.CssClip(); | 1041 auto* css_clip = properties.CssClip(); |
1030 | 1042 |
1031 // Before we actually create anything, check whether in-flow context and | 1043 // Before we actually create anything, check whether in-flow context and |
1032 // fixed-position context has exactly the same clip. Reuse if possible. | 1044 // fixed-position context has exactly the same clip. Reuse if possible. |
1033 if (context.fixed_position.clip == css_clip->Parent()) { | 1045 if (context.fixed_position.clip == css_clip->Parent()) { |
1034 context.fixed_position.clip = css_clip; | 1046 context.fixed_position.clip = css_clip; |
1035 } else { | 1047 } else { |
1036 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 1048 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
1037 context.force_subtree_update |= properties.UpdateCssClipFixedPosition( | 1049 force_subtree_update |= properties.UpdateCssClipFixedPosition( |
1038 context.fixed_position.clip, | 1050 context.fixed_position.clip, |
1039 const_cast<TransformPaintPropertyNode*>( | 1051 const_cast<TransformPaintPropertyNode*>( |
1040 css_clip->LocalTransformSpace()), | 1052 css_clip->LocalTransformSpace()), |
1041 css_clip->ClipRect()); | 1053 css_clip->ClipRect()); |
1042 } | 1054 } |
1043 if (properties.CssClipFixedPosition()) | 1055 if (properties.CssClipFixedPosition()) |
1044 context.fixed_position.clip = properties.CssClipFixedPosition(); | 1056 context.fixed_position.clip = properties.CssClipFixedPosition(); |
1045 return; | 1057 return; |
1046 } | 1058 } |
1047 } | 1059 } |
1048 | 1060 |
1049 if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) { | 1061 if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { |
1050 if (auto* properties = object.GetMutableForPainting().PaintProperties()) | 1062 if (auto* properties = object.GetMutableForPainting().PaintProperties()) |
1051 context.force_subtree_update |= properties->ClearCssClipFixedPosition(); | 1063 force_subtree_update |= properties->ClearCssClipFixedPosition(); |
1052 } | 1064 } |
1053 } | 1065 } |
1054 | 1066 |
1055 void PaintPropertyTreeBuilder::UpdatePaintOffset( | 1067 void PaintPropertyTreeBuilder::UpdatePaintOffset( |
1056 const LayoutBoxModelObject& object, | 1068 const LayoutBoxModelObject& object, |
1057 PaintPropertyTreeBuilderContext& context) { | 1069 PaintPropertyTreeBuilderFragmentContext& context, |
| 1070 const LayoutObject* container_for_absolute_position) { |
1058 if (object.IsFloating()) | 1071 if (object.IsFloating()) |
1059 context.current.paint_offset = context.paint_offset_for_float; | 1072 context.current.paint_offset = context.paint_offset_for_float; |
1060 | 1073 |
1061 // Multicolumn spanners are painted starting at the multicolumn container (but | 1074 // Multicolumn spanners are painted starting at the multicolumn container (but |
1062 // still inherit properties in layout-tree order) so reset the paint offset. | 1075 // still inherit properties in layout-tree order) so reset the paint offset. |
1063 if (object.IsColumnSpanAll()) | 1076 if (object.IsColumnSpanAll()) |
1064 context.current.paint_offset = object.Container()->PaintOffset(); | 1077 context.current.paint_offset = object.Container()->PaintOffset(); |
1065 | 1078 |
1066 switch (object.StyleRef().GetPosition()) { | 1079 switch (object.StyleRef().GetPosition()) { |
1067 case EPosition::kStatic: | 1080 case EPosition::kStatic: |
1068 break; | 1081 break; |
1069 case EPosition::kRelative: | 1082 case EPosition::kRelative: |
1070 context.current.paint_offset += object.OffsetForInFlowPosition(); | 1083 context.current.paint_offset += object.OffsetForInFlowPosition(); |
1071 break; | 1084 break; |
1072 case EPosition::kAbsolute: { | 1085 case EPosition::kAbsolute: { |
1073 DCHECK(context.container_for_absolute_position == object.Container()); | 1086 DCHECK(container_for_absolute_position == object.Container()); |
1074 context.current = context.absolute_position; | 1087 context.current = context.absolute_position; |
1075 | 1088 |
1076 // Absolutely positioned content in an inline should be positioned | 1089 // Absolutely positioned content in an inline should be positioned |
1077 // relative to the inline. | 1090 // relative to the inline. |
1078 const LayoutObject* container = context.container_for_absolute_position; | 1091 const LayoutObject* container = container_for_absolute_position; |
1079 if (container && container->IsInFlowPositioned() && | 1092 if (container && container->IsInFlowPositioned() && |
1080 container->IsLayoutInline()) { | 1093 container->IsLayoutInline()) { |
1081 DCHECK(object.IsBox()); | 1094 DCHECK(object.IsBox()); |
1082 context.current.paint_offset += | 1095 context.current.paint_offset += |
1083 ToLayoutInline(container)->OffsetForInFlowPositionedInline( | 1096 ToLayoutInline(container)->OffsetForInFlowPositionedInline( |
1084 ToLayoutBox(object)); | 1097 ToLayoutBox(object)); |
1085 } | 1098 } |
1086 break; | 1099 break; |
1087 } | 1100 } |
1088 case EPosition::kSticky: | 1101 case EPosition::kSticky: |
1089 context.current.paint_offset += object.OffsetForInFlowPosition(); | 1102 context.current.paint_offset += object.OffsetForInFlowPosition(); |
1090 break; | 1103 break; |
1091 case EPosition::kFixed: | 1104 case EPosition::kFixed: |
1092 context.current = context.fixed_position; | 1105 context.current = context.fixed_position; |
1093 break; | 1106 break; |
1094 default: | 1107 default: |
1095 ASSERT_NOT_REACHED(); | 1108 ASSERT_NOT_REACHED(); |
1096 } | 1109 } |
1097 | 1110 |
1098 if (object.IsBox()) { | 1111 if (object.IsBox()) { |
1099 // TODO(pdr): Several calls in this function walk back up the tree to | 1112 // TODO(pdr): Several calls in this function walk back up the tree to |
1100 // calculate containers (e.g., physicalLocation, offsetForInFlowPosition*). | 1113 // calculate containers (e.g., physicalLocation, offsetForInFlowPosition*). |
1101 // The containing block and other containers can be stored on | 1114 // The containing block and other containers can be stored on |
1102 // PaintPropertyTreeBuilderContext instead of recomputing them. | 1115 // PaintPropertyTreeBuilderFragmentContext instead of recomputing them. |
1103 context.current.paint_offset.MoveBy(ToLayoutBox(object).PhysicalLocation()); | 1116 context.current.paint_offset.MoveBy(ToLayoutBox(object).PhysicalLocation()); |
1104 // This is a weird quirk that table cells paint as children of table rows, | 1117 // This is a weird quirk that table cells paint as children of table rows, |
1105 // but their location have the row's location baked-in. | 1118 // but their location have the row's location baked-in. |
1106 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). | 1119 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). |
1107 if (object.IsTableCell()) { | 1120 if (object.IsTableCell()) { |
1108 LayoutObject* parent_row = object.Parent(); | 1121 LayoutObject* parent_row = object.Parent(); |
1109 DCHECK(parent_row && parent_row->IsTableRow()); | 1122 DCHECK(parent_row && parent_row->IsTableRow()); |
1110 context.current.paint_offset.MoveBy( | 1123 context.current.paint_offset.MoveBy( |
1111 -ToLayoutBox(parent_row)->PhysicalLocation()); | 1124 -ToLayoutBox(parent_row)->PhysicalLocation()); |
1112 } | 1125 } |
1113 } | 1126 } |
1114 } | 1127 } |
1115 | 1128 |
1116 void PaintPropertyTreeBuilder::UpdateForObjectLocationAndSize( | 1129 void PaintPropertyTreeBuilder::UpdateForObjectLocationAndSize( |
1117 const LayoutObject& object, | 1130 const LayoutObject& object, |
1118 PaintPropertyTreeBuilderContext& context) { | 1131 const LayoutObject* container_for_absolute_position, |
| 1132 bool& is_actually_needed, |
| 1133 PaintPropertyTreeBuilderFragmentContext& context, |
| 1134 bool& force_subtree_update) { |
1119 #if DCHECK_IS_ON() | 1135 #if DCHECK_IS_ON() |
1120 FindPaintOffsetNeedingUpdateScope check_scope(object, context); | 1136 FindPaintOffsetNeedingUpdateScope check_scope(object, is_actually_needed); |
1121 #endif | 1137 #endif |
1122 | 1138 |
1123 if (object.IsBoxModelObject()) { | 1139 if (object.IsBoxModelObject()) { |
1124 UpdatePaintOffset(ToLayoutBoxModelObject(object), context); | 1140 UpdatePaintOffset(ToLayoutBoxModelObject(object), context, |
1125 UpdatePaintOffsetTranslation(ToLayoutBoxModelObject(object), context); | 1141 container_for_absolute_position); |
| 1142 UpdatePaintOffsetTranslation(ToLayoutBoxModelObject(object), context, |
| 1143 force_subtree_update); |
1126 } | 1144 } |
1127 | 1145 |
1128 if (object.PaintOffset() != context.current.paint_offset) { | 1146 if (object.PaintOffset() != context.current.paint_offset) { |
1129 // Many paint properties depend on paint offset so we force an update of | 1147 // Many paint properties depend on paint offset so we force an update of |
1130 // the entire subtree on paint offset changes. | 1148 // the entire subtree on paint offset changes. |
1131 context.force_subtree_update = true; | 1149 force_subtree_update = true; |
1132 | 1150 |
1133 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 1151 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
1134 object.GetMutableForPainting().SetShouldDoFullPaintInvalidation( | 1152 object.GetMutableForPainting().SetShouldDoFullPaintInvalidation( |
1135 kPaintInvalidationLocationChange); | 1153 kPaintInvalidationLocationChange); |
1136 } | 1154 } |
1137 object.GetMutableForPainting().SetPaintOffset(context.current.paint_offset); | 1155 object.GetMutableForPainting().SetPaintOffset(context.current.paint_offset); |
1138 } | 1156 } |
1139 | 1157 |
1140 if (!object.IsBox()) | 1158 if (!object.IsBox()) |
1141 return; | 1159 return; |
(...skipping 17 matching lines...) Expand all Loading... |
1159 // transform-origin, and perspective-origin can depend on the size of the | 1177 // transform-origin, and perspective-origin can depend on the size of the |
1160 // frame rect, so force a property update if it changes. TODO(pdr): We | 1178 // frame rect, so force a property update if it changes. TODO(pdr): We |
1161 // only need to update properties if there are relative lengths. | 1179 // only need to update properties if there are relative lengths. |
1162 box.StyleRef().HasTransform() || box.StyleRef().HasPerspective() || | 1180 box.StyleRef().HasTransform() || box.StyleRef().HasPerspective() || |
1163 box_generates_property_nodes_for_mask_and_clip_path) | 1181 box_generates_property_nodes_for_mask_and_clip_path) |
1164 box.GetMutableForPainting().SetNeedsPaintPropertyUpdate(); | 1182 box.GetMutableForPainting().SetNeedsPaintPropertyUpdate(); |
1165 } | 1183 } |
1166 | 1184 |
1167 void PaintPropertyTreeBuilder::UpdatePaintProperties( | 1185 void PaintPropertyTreeBuilder::UpdatePaintProperties( |
1168 const LayoutObject& object, | 1186 const LayoutObject& object, |
1169 PaintPropertyTreeBuilderContext& context) { | 1187 PaintPropertyTreeBuilderContext& full_context) { |
1170 bool needs_paint_properties = | 1188 bool needs_paint_properties = |
1171 NeedsPaintOffsetTranslation(object) || NeedsTransform(object) || | 1189 NeedsPaintOffsetTranslation(object) || NeedsTransform(object) || |
1172 NeedsEffect(object) || NeedsTransformForNonRootSVG(object) || | 1190 NeedsEffect(object) || NeedsTransformForNonRootSVG(object) || |
1173 NeedsFilter(object) || NeedsCssClip(object) || | 1191 NeedsFilter(object) || NeedsCssClip(object) || |
1174 NeedsScrollbarPaintOffset(object) || NeedsOverflowScroll(object) || | 1192 NeedsScrollbarPaintOffset(object) || NeedsOverflowScroll(object) || |
1175 NeedsPerspective(object) || NeedsSVGLocalToBorderBoxTransform(object) || | 1193 NeedsPerspective(object) || NeedsSVGLocalToBorderBoxTransform(object) || |
1176 NeedsScrollTranslation(object) || NeedsCssClipFixedPosition(object); | 1194 NeedsScrollTranslation(object) || NeedsCssClipFixedPosition(object); |
1177 | 1195 |
1178 bool had_paint_properties = object.PaintProperties(); | 1196 bool had_paint_properties = object.PaintProperties(); |
1179 | 1197 |
1180 if (needs_paint_properties) { | 1198 if (needs_paint_properties) { |
1181 object.GetMutableForPainting().EnsurePaintProperties(); | 1199 object.GetMutableForPainting().EnsurePaintProperties(); |
1182 } else { | 1200 } else { |
1183 object.GetMutableForPainting().ClearPaintProperties(); | 1201 object.GetMutableForPainting().ClearPaintProperties(); |
1184 if (had_paint_properties) | 1202 if (had_paint_properties) |
1185 context.force_subtree_update = true; | 1203 full_context.force_subtree_update = true; |
1186 } | 1204 } |
1187 } | 1205 } |
1188 | 1206 |
1189 void PaintPropertyTreeBuilder::UpdatePropertiesForSelf( | 1207 void PaintPropertyTreeBuilder::UpdatePropertiesForSelf( |
1190 const LayoutObject& object, | 1208 const LayoutObject& object, |
1191 PaintPropertyTreeBuilderContext& context) { | 1209 PaintPropertyTreeBuilderContext& full_context) { |
| 1210 PaintPropertyTreeBuilderFragmentContext& context = full_context.fragments[0]; |
1192 if (object.IsSVGHiddenContainer()) { | 1211 if (object.IsSVGHiddenContainer()) { |
1193 // SVG resources are painted within one or more other locations in the | 1212 // SVG resources are painted within one or more other locations in the |
1194 // SVG during paint, and hence have their own independent paint property | 1213 // SVG during paint, and hence have their own independent paint property |
1195 // trees, paint offset, etc. | 1214 // trees, paint offset, etc. |
1196 context = PaintPropertyTreeBuilderContext(); | 1215 context = PaintPropertyTreeBuilderFragmentContext(); |
1197 } | 1216 } |
1198 | 1217 |
1199 UpdatePaintProperties(object, context); | 1218 UpdatePaintProperties(object, full_context); |
| 1219 |
| 1220 bool is_actually_needed = false; |
| 1221 #if DCHECK_IS_ON() |
| 1222 is_actually_needed = full_context.is_actually_needed; |
| 1223 #endif |
1200 | 1224 |
1201 // This is not in FindObjectPropertiesNeedingUpdateScope because paint offset | 1225 // This is not in FindObjectPropertiesNeedingUpdateScope because paint offset |
1202 // can change without needsPaintPropertyUpdate. | 1226 // can change without needsPaintPropertyUpdate. |
1203 UpdateForObjectLocationAndSize(object, context); | 1227 UpdateForObjectLocationAndSize( |
| 1228 object, full_context.container_for_absolute_position, is_actually_needed, |
| 1229 context, full_context.force_subtree_update); |
1204 | 1230 |
1205 #if DCHECK_IS_ON() | 1231 #if DCHECK_IS_ON() |
1206 FindObjectPropertiesNeedingUpdateScope check_needs_update_scope(object, | 1232 FindObjectPropertiesNeedingUpdateScope check_needs_update_scope( |
1207 context); | 1233 object, full_context.force_subtree_update); |
1208 #endif | 1234 #endif |
1209 | 1235 |
1210 if (object.IsBoxModelObject() || object.IsSVG()) { | 1236 if (object.IsBoxModelObject() || object.IsSVG()) { |
1211 UpdateTransform(object, context); | 1237 UpdateTransform(object, context, full_context.force_subtree_update); |
1212 UpdateCssClip(object, context); | 1238 UpdateCssClip(object, context, full_context.force_subtree_update); |
1213 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 1239 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
1214 UpdateEffect(object, context); | 1240 UpdateEffect(object, context, full_context.force_subtree_update); |
1215 UpdateFilter(object, context); | 1241 UpdateFilter(object, context, full_context.force_subtree_update); |
1216 } | 1242 } |
1217 UpdateLocalBorderBoxContext(object, context); | 1243 UpdateLocalBorderBoxContext(object, context, |
1218 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 1244 full_context.force_subtree_update); |
1219 UpdateScrollbarPaintOffset(object, context); | 1245 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 1246 UpdateScrollbarPaintOffset(object, context, |
| 1247 full_context.force_subtree_update); |
| 1248 } |
1220 } | 1249 } |
1221 } | 1250 } |
1222 | 1251 |
1223 void PaintPropertyTreeBuilder::UpdatePropertiesForChildren( | 1252 void PaintPropertyTreeBuilder::UpdatePropertiesForChildren( |
1224 const LayoutObject& object, | 1253 const LayoutObject& object, |
1225 PaintPropertyTreeBuilderContext& context) { | 1254 PaintPropertyTreeBuilderContext& context) { |
1226 #if DCHECK_IS_ON() | |
1227 FindObjectPropertiesNeedingUpdateScope check_needs_update_scope(object, | |
1228 context); | |
1229 #endif | |
1230 | |
1231 if (!object.IsBoxModelObject() && !object.IsSVG()) | 1255 if (!object.IsBoxModelObject() && !object.IsSVG()) |
1232 return; | 1256 return; |
1233 | 1257 |
1234 UpdateOverflowClip(object, context); | 1258 for (auto& fragment_context : context.fragments) { |
1235 UpdatePerspective(object, context); | 1259 #if DCHECK_IS_ON() |
1236 UpdateSvgLocalToBorderBoxTransform(object, context); | 1260 FindObjectPropertiesNeedingUpdateScope check_needs_update_scope( |
1237 UpdateScrollAndScrollTranslation(object, context); | 1261 object, context.force_subtree_update); |
1238 UpdateOutOfFlowContext(object, context); | 1262 #endif |
| 1263 UpdateOverflowClip(object, fragment_context, context.force_subtree_update); |
| 1264 UpdatePerspective(object, fragment_context, context.force_subtree_update); |
| 1265 UpdateSvgLocalToBorderBoxTransform(object, fragment_context, |
| 1266 context.force_subtree_update); |
| 1267 UpdateScrollAndScrollTranslation(object, fragment_context, |
| 1268 context.force_subtree_update); |
| 1269 UpdateOutOfFlowContext(object, fragment_context, |
| 1270 context.force_subtree_update); |
1239 | 1271 |
1240 context.force_subtree_update |= object.SubtreeNeedsPaintPropertyUpdate(); | 1272 context.force_subtree_update |= object.SubtreeNeedsPaintPropertyUpdate(); |
| 1273 } |
| 1274 |
| 1275 if (object.CanContainAbsolutePositionObjects()) |
| 1276 context.container_for_absolute_position = &object; |
1241 } | 1277 } |
1242 | 1278 |
1243 } // namespace blink | 1279 } // namespace blink |
OLD | NEW |