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

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

Issue 2849603004: Introduce PaintPropertyTreeBuilderFragmentContext and use it throughout. (Closed)
Patch Set: none Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/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
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
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
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
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
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
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
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 15 matching lines...) Expand all
1157 box.HasClip() || 1175 box.HasClip() ||
1158 // Relative lengths (e.g., percentage values) in transform, perspective, 1176 // Relative lengths (e.g., percentage values) in transform, perspective,
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::CollectFragments(
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 CollectFragments(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698