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

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

Issue 2817053002: [blink] Refactor PaintLayerClipper::CalculateClipRects
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
6 * 6 *
7 * Other contributors: 7 * Other contributors:
8 * Robert O'Callahan <roc+@cs.cmu.edu> 8 * Robert O'Callahan <roc+@cs.cmu.edu>
9 * David Baron <dbaron@fas.harvard.edu> 9 * David Baron <dbaron@fas.harvard.edu>
10 * Christian Biesinger <cbiesinger@web.de> 10 * Christian Biesinger <cbiesinger@web.de>
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 46
47 #include "core/frame/FrameView.h" 47 #include "core/frame/FrameView.h"
48 #include "core/frame/Settings.h" 48 #include "core/frame/Settings.h"
49 #include "core/layout/LayoutView.h" 49 #include "core/layout/LayoutView.h"
50 #include "core/paint/ObjectPaintProperties.h" 50 #include "core/paint/ObjectPaintProperties.h"
51 #include "core/paint/PaintLayer.h" 51 #include "core/paint/PaintLayer.h"
52 #include "platform/graphics/paint/GeometryMapper.h" 52 #include "platform/graphics/paint/GeometryMapper.h"
53 53
54 namespace blink { 54 namespace blink {
55 55
56 static void AdjustClipRectsForChildren( 56 // Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdatePaintOffset.
57 const LayoutBoxModelObject& layout_object, 57 static void InheritAncestorClipByPosition(EPosition position,
58 ClipRects& clip_rects) { 58 ClipRects& clip_rects) {
59 EPosition position = layout_object.StyleRef().GetPosition(); 59 if (position == EPosition::kAbsolute) {
60 // A fixed object is essentially the root of its containing block hierarchy, 60 clip_rects.SetOverflowClipRect(clip_rects.PosClipRect());
61 // so when we encounter such an object, we reset our clip rects to the 61 } else if (position == EPosition::kFixed) {
62 // fixedClipRect.
63 if (position == EPosition::kFixed) {
64 clip_rects.SetPosClipRect(clip_rects.FixedClipRect());
65 clip_rects.SetOverflowClipRect(clip_rects.FixedClipRect()); 62 clip_rects.SetOverflowClipRect(clip_rects.FixedClipRect());
66 clip_rects.SetFixed(true); 63 clip_rects.SetFixed(true);
67 } else if (position == EPosition::kRelative) {
68 clip_rects.SetPosClipRect(clip_rects.OverflowClipRect());
69 } else if (position == EPosition::kAbsolute) {
70 clip_rects.SetOverflowClipRect(clip_rects.PosClipRect());
71 } 64 }
72 } 65 }
73 66
74 static void ApplyClipRects(const ClipRectsContext& context, 67 // Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdateCssClip.
75 const LayoutBoxModelObject& layout_object, 68 static void ApplyCssClip(const ClipRectsContext& context,
76 LayoutPoint offset, 69 const LayoutBoxModelObject& object,
77 ClipRects& clip_rects) { 70 LayoutPoint offset,
78 DCHECK(layout_object.IsBox()); 71 ClipRects& clip_rects) {
79 const LayoutBox& box = *ToLayoutBox(&layout_object); 72 if (!object.HasClip())
73 return;
80 74
81 DCHECK(box.ShouldClipOverflow() || box.HasClip()); 75 const LayoutBox& box = ToLayoutBox(object);
82 LayoutView* view = box.View(); 76 LayoutRect new_clip = box.ClipRect(offset);
83 DCHECK(view); 77 clip_rects.SetOverflowClipRect(
84 if (clip_rects.Fixed() && &context.root_layer->GetLayoutObject() == view) 78 Intersection(new_clip, clip_rects.OverflowClipRect()));
85 offset -= LayoutSize(view->GetFrameView()->GetScrollOffset()); 79 clip_rects.SetFixedClipRect(
80 Intersection(new_clip, clip_rects.FixedClipRect()));
81 // Skip SetPosClipRect because CSS clip requires non-static position,
82 // thus absolute position children always inherit in-flow clips.
83 }
86 84
87 if (box.ShouldClipOverflow()) { 85 // Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdateOverflowClip.
88 ClipRect new_overflow_clip = 86 static void ApplyOverflowClip(const ClipRectsContext& context,
89 box.OverflowClipRect(offset, context.overlay_scrollbar_clip_behavior); 87 const LayoutBoxModelObject& object,
90 new_overflow_clip.SetHasRadius(box.StyleRef().HasBorderRadius()); 88 LayoutPoint offset,
91 clip_rects.SetOverflowClipRect( 89 ClipRects& clip_rects) {
92 Intersection(new_overflow_clip, clip_rects.OverflowClipRect())); 90 if (!object.IsBox())
93 if (box.IsPositioned()) 91 return;
94 clip_rects.SetPosClipRect( 92 const LayoutBox& box = ToLayoutBox(object);
95 Intersection(new_overflow_clip, clip_rects.PosClipRect())); 93 if (!box.ShouldClipOverflow())
96 if (box.CanContainFixedPositionObjects()) 94 return;
97 clip_rects.SetFixedClipRect( 95
98 Intersection(new_overflow_clip, clip_rects.FixedClipRect())); 96 ClipRect new_overflow_clip =
99 if (box.StyleRef().ContainsPaint()) 97 box.OverflowClipRect(offset, context.overlay_scrollbar_clip_behavior);
100 clip_rects.SetPosClipRect( 98 new_overflow_clip.SetHasRadius(box.StyleRef().HasBorderRadius());
101 Intersection(new_overflow_clip, clip_rects.PosClipRect())); 99
102 } 100 clip_rects.SetOverflowClipRect(
103 if (box.HasClip()) { 101 Intersection(new_overflow_clip, clip_rects.OverflowClipRect()));
104 LayoutRect new_clip = box.ClipRect(offset); 102 }
105 clip_rects.SetPosClipRect(Intersection(new_clip, clip_rects.PosClipRect())); 103
106 clip_rects.SetOverflowClipRect( 104 // Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdateOutOfFlowContext.
107 Intersection(new_clip, clip_rects.OverflowClipRect())); 105 static void AdjustClipRectsForChildren(const LayoutBoxModelObject& object,
108 clip_rects.SetFixedClipRect( 106 ClipRects& clip_rects) {
109 Intersection(new_clip, clip_rects.FixedClipRect())); 107 if (object.CanContainAbsolutePositionObjects())
110 } 108 clip_rects.SetPosClipRect(clip_rects.OverflowClipRect());
109 if (object.CanContainFixedPositionObjects())
110 clip_rects.SetFixedClipRect(clip_rects.OverflowClipRect());
111 } 111 }
112 112
113 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer, 113 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer,
114 bool usegeometry_mapper) 114 bool use_geometry_mapper)
115 : layer_(layer), use_geometry_mapper_(usegeometry_mapper) {} 115 : layer_(layer), use_geometry_mapper_(use_geometry_mapper) {}
116 116
117 ClipRects* PaintLayerClipper::ClipRectsIfCached( 117 ClipRects* PaintLayerClipper::ClipRectsIfCached(
118 const ClipRectsContext& context) const { 118 const ClipRectsContext& context) const {
119 DCHECK(context.UsesCache()); 119 DCHECK(context.UsesCache());
120 if (!layer_.GetClipRectsCache()) 120 if (!layer_.GetClipRectsCache())
121 return nullptr; 121 return nullptr;
122 ClipRectsCache::Entry& entry = 122 ClipRectsCache::Entry& entry =
123 layer_.GetClipRectsCache()->Get(context.CacheSlot()); 123 layer_.GetClipRectsCache()->Get(context.CacheSlot());
124 // FIXME: We used to ASSERT that we always got a consistent root layer. 124 // FIXME: We used to ASSERT that we always got a consistent root layer.
125 // We should add a test that has an inconsistent root. See 125 // We should add a test that has an inconsistent root. See
126 // http://crbug.com/366118 for an example. 126 // http://crbug.com/366118 for an example.
127 if (context.root_layer != entry.root) 127 if (context.root_layer != entry.root)
128 return 0; 128 return nullptr;
129 #if DCHECK_IS_ON() 129 #if DCHECK_IS_ON()
130 DCHECK(entry.overlay_scrollbar_clip_behavior == 130 DCHECK(entry.overlay_scrollbar_clip_behavior ==
131 context.overlay_scrollbar_clip_behavior); 131 context.overlay_scrollbar_clip_behavior);
132 #endif 132 #endif
133 return entry.clip_rects.Get(); 133 return entry.clip_rects.Get();
134 } 134 }
135 135
136 ClipRects& PaintLayerClipper::StoreClipRectsInCache( 136 ClipRects& PaintLayerClipper::StoreClipRectsInCache(
137 const ClipRectsContext& context, 137 const ClipRectsContext& context,
138 ClipRects* parent_clip_rects, 138 ClipRects* parent_clip_rects,
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 void PaintLayerClipper::CalculateClipRects(const ClipRectsContext& context, 364 void PaintLayerClipper::CalculateClipRects(const ClipRectsContext& context,
365 ClipRects& clip_rects) const { 365 ClipRects& clip_rects) const {
366 const LayoutBoxModelObject& layout_object = layer_.GetLayoutObject(); 366 const LayoutBoxModelObject& layout_object = layer_.GetLayoutObject();
367 if (!layer_.Parent() && 367 if (!layer_.Parent() &&
368 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { 368 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
369 // The root layer's clip rect is always infinite. 369 // The root layer's clip rect is always infinite.
370 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect())); 370 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
371 return; 371 return;
372 } 372 }
373 373
374 bool is_clipping_root = &layer_ == context.root_layer; 374 if (!ShouldRespectOverflowClip(context)) {
375 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
376 return;
377 }
375 378
376 // For transformed layers, the root layer was shifted to be us, so there is no 379 // For transformed layers, the root layer was shifted to be us, so there is no
377 // need to examine the parent. We want to cache clip rects with us as the 380 // need to examine the parent. We want to cache clip rects with us as the
378 // root. 381 // root.
379 PaintLayer* parent_layer = !is_clipping_root ? layer_.Parent() : nullptr; 382 bool is_clipping_root = &layer_ == context.root_layer;
380 // Ensure that our parent's clip has been calculated so that we can examine 383 if (!is_clipping_root && layer_.Parent()) {
381 // the values. 384 PaintLayerClipper(*layer_.Parent(), use_geometry_mapper_)
382 if (parent_layer) {
383 PaintLayerClipper(*parent_layer, use_geometry_mapper_)
384 .GetOrCalculateClipRects(context, clip_rects); 385 .GetOrCalculateClipRects(context, clip_rects);
386 InheritAncestorClipByPosition(layout_object.StyleRef().GetPosition(),
387 clip_rects);
385 } else { 388 } else {
386 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect())); 389 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
387 } 390 }
388 391
389 AdjustClipRectsForChildren(layout_object, clip_rects); 392 // Computing paint offset is expensive, skip the computation if the object
390 393 // is known to have no clip. This check is redundant otherwise.
391 if (ShouldClipOverflow(context) || layout_object.HasClip()) { 394 if (layout_object.HasClip() ||
395 (layout_object.IsBox() &&
396 ToLayoutBox(layout_object).ShouldClipOverflow())) {
392 // This offset cannot use convertToLayerCoords, because sometimes our 397 // This offset cannot use convertToLayerCoords, because sometimes our
393 // rootLayer may be across some transformed layer boundary, for example, in 398 // rootLayer may be across some transformed layer boundary, for example, in
394 // the PaintLayerCompositor overlapMap, where clipRects are needed in view 399 // the PaintLayerCompositor overlapMap, where clipRects are needed in view
395 // space. 400 // space.
396 ApplyClipRects(context, layout_object, 401 LayoutPoint paint_offset(layout_object.LocalToAncestorPoint(
397 LayoutPoint(layout_object.LocalToAncestorPoint( 402 FloatPoint(), &context.root_layer->GetLayoutObject()));
398 FloatPoint(), &context.root_layer->GetLayoutObject())), 403 LayoutView* view = layout_object.View();
399 clip_rects); 404 DCHECK(view);
405 if (clip_rects.Fixed() && &context.root_layer->GetLayoutObject() == view)
406 paint_offset -= LayoutSize(view->GetFrameView()->GetScrollOffset());
407
408 ApplyCssClip(context, layout_object, paint_offset, clip_rects);
409 ApplyOverflowClip(context, layout_object, paint_offset, clip_rects);
400 } 410 }
411 AdjustClipRectsForChildren(layout_object, clip_rects);
401 } 412 }
402 413
403 static ClipRect BackgroundClipRectForPosition(const ClipRects& parent_rects, 414 static ClipRect BackgroundClipRectForPosition(const ClipRects& parent_rects,
404 EPosition position) { 415 EPosition position) {
405 if (position == EPosition::kFixed) 416 if (position == EPosition::kFixed)
406 return parent_rects.FixedClipRect(); 417 return parent_rects.FixedClipRect();
407 418
408 if (position == EPosition::kAbsolute) 419 if (position == EPosition::kAbsolute)
409 return parent_rects.PosClipRect(); 420 return parent_rects.PosClipRect();
410 421
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 DCHECK(!use_geometry_mapper_); 643 DCHECK(!use_geometry_mapper_);
633 ClipRectsContext context(root_layer, kPaintingClipRects, 644 ClipRectsContext context(root_layer, kPaintingClipRects,
634 kIgnorePlatformOverlayScrollbarSize, 645 kIgnorePlatformOverlayScrollbarSize,
635 subpixel_accumulation); 646 subpixel_accumulation);
636 if (respect_overflow_clip == kIgnoreOverflowClip) 647 if (respect_overflow_clip == kIgnoreOverflowClip)
637 context.SetIgnoreOverflowClip(); 648 context.SetIgnoreOverflowClip();
638 return GetClipRects(context); 649 return GetClipRects(context);
639 } 650 }
640 651
641 } // namespace blink 652 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698