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

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

Issue 2856373002: [blink] Unify PaintLayerClipper behavior with kIgnoreOverflowClip (Closed)
Patch Set: 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 /* 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 bool HasOverflowClip(
57 const PaintLayer& layer) {
58 if (!layer.GetLayoutObject().IsBox())
59 return false;
60 const LayoutBox& box = ToLayoutBox(layer.GetLayoutObject());
61 return box.ShouldClipOverflow();
62 }
63
64 bool ClipRectsContext::ShouldRespectRootLayerClip() const {
65 if (respect_overflow_clip == kIgnoreOverflowClip)
66 return false;
67
68 if (root_layer->IsRootLayer() &&
69 respect_overflow_clip_for_viewport == kIgnoreOverflowClip)
70 return false;
71
72 return true;
73 }
74
56 static void AdjustClipRectsForChildren( 75 static void AdjustClipRectsForChildren(
57 const LayoutBoxModelObject& layout_object, 76 const LayoutBoxModelObject& layout_object,
58 ClipRects& clip_rects) { 77 ClipRects& clip_rects) {
59 EPosition position = layout_object.StyleRef().GetPosition(); 78 EPosition position = layout_object.StyleRef().GetPosition();
60 // A fixed object is essentially the root of its containing block hierarchy, 79 // A fixed object is essentially the root of its containing block hierarchy,
61 // so when we encounter such an object, we reset our clip rects to the 80 // so when we encounter such an object, we reset our clip rects to the
62 // fixedClipRect. 81 // fixedClipRect.
63 if (position == EPosition::kFixed) { 82 if (position == EPosition::kFixed) {
64 clip_rects.SetPosClipRect(clip_rects.FixedClipRect()); 83 clip_rects.SetPosClipRect(clip_rects.FixedClipRect());
65 clip_rects.SetOverflowClipRect(clip_rects.FixedClipRect()); 84 clip_rects.SetOverflowClipRect(clip_rects.FixedClipRect());
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 const LayoutBoxModelObject& layout_object = layer_.GetLayoutObject(); 398 const LayoutBoxModelObject& layout_object = layer_.GetLayoutObject();
380 if (!layer_.Parent() && 399 if (!layer_.Parent() &&
381 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { 400 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
382 // The root layer's clip rect is always infinite. 401 // The root layer's clip rect is always infinite.
383 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect())); 402 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
384 return; 403 return;
385 } 404 }
386 405
387 bool is_clipping_root = &layer_ == context.root_layer; 406 bool is_clipping_root = &layer_ == context.root_layer;
388 407
408 if (is_clipping_root && !context.ShouldRespectRootLayerClip()) {
409 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
410 if (layout_object.StyleRef().GetPosition() == EPosition::kFixed)
411 clip_rects.SetFixed(true);
412 return;
413 }
414
389 // For transformed layers, the root layer was shifted to be us, so there is no 415 // For transformed layers, the root layer was shifted to be us, so there is no
390 // need to examine the parent. We want to cache clip rects with us as the 416 // need to examine the parent. We want to cache clip rects with us as the
391 // root. 417 // root.
392 PaintLayer* parent_layer = !is_clipping_root ? layer_.Parent() : nullptr; 418 PaintLayer* parent_layer = !is_clipping_root ? layer_.Parent() : nullptr;
393 // Ensure that our parent's clip has been calculated so that we can examine 419 // Ensure that our parent's clip has been calculated so that we can examine
394 // the values. 420 // the values.
395 if (parent_layer) { 421 if (parent_layer) {
396 PaintLayerClipper(*parent_layer, use_geometry_mapper_) 422 PaintLayerClipper(*parent_layer, use_geometry_mapper_)
397 .GetOrCalculateClipRects(context, clip_rects); 423 .GetOrCalculateClipRects(context, clip_rects);
398 } else { 424 } else {
399 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect())); 425 clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
400 } 426 }
401 427
402 AdjustClipRectsForChildren(layout_object, clip_rects); 428 AdjustClipRectsForChildren(layout_object, clip_rects);
403 429
404 if (ShouldClipOverflow(context) || layout_object.HasClip()) { 430 // Computing paint offset is expensive, skip the computation if the object
431 // is known to have no clip. This check is redundant otherwise.
432 if (HasOverflowClip(layer_) || layout_object.HasClip()) {
405 // This offset cannot use convertToLayerCoords, because sometimes our 433 // This offset cannot use convertToLayerCoords, because sometimes our
406 // rootLayer may be across some transformed layer boundary, for example, in 434 // rootLayer may be across some transformed layer boundary, for example, in
407 // the PaintLayerCompositor overlapMap, where clipRects are needed in view 435 // the PaintLayerCompositor overlapMap, where clipRects are needed in view
408 // space. 436 // space.
409 ApplyClipRects(context, layout_object, 437 ApplyClipRects(context, layout_object,
410 LayoutPoint(layout_object.LocalToAncestorPoint( 438 LayoutPoint(layout_object.LocalToAncestorPoint(
411 FloatPoint(), &context.root_layer->GetLayoutObject())), 439 FloatPoint(), &context.root_layer->GetLayoutObject())),
412 clip_rects); 440 clip_rects);
413 } 441 }
414 } 442 }
415 443
416 static ClipRect BackgroundClipRectForPosition(const ClipRects& parent_rects, 444 static ClipRect BackgroundClipRectForPosition(const ClipRects& parent_rects,
417 EPosition position) { 445 EPosition position) {
418 if (position == EPosition::kFixed) 446 if (position == EPosition::kFixed)
419 return parent_rects.FixedClipRect(); 447 return parent_rects.FixedClipRect();
420 448
421 if (position == EPosition::kAbsolute) 449 if (position == EPosition::kAbsolute)
422 return parent_rects.PosClipRect(); 450 return parent_rects.PosClipRect();
423 451
424 return parent_rects.OverflowClipRect(); 452 return parent_rects.OverflowClipRect();
425 } 453 }
426 454
427 void PaintLayerClipper::CalculateBackgroundClipRectWithGeometryMapper( 455 void PaintLayerClipper::CalculateBackgroundClipRectWithGeometryMapper(
428 const ClipRectsContext& context, 456 const ClipRectsContext& context,
429 ClipRect& output) const { 457 ClipRect& output) const {
430 DCHECK(use_geometry_mapper_); 458 DCHECK(use_geometry_mapper_);
459
460 bool is_clipping_root = &layer_ == context.root_layer;
461 if (is_clipping_root && !context.ShouldRespectRootLayerClip()) {
462 output.SetRect(FloatClipRect());
463 return;
464 }
465
431 PropertyTreeState source_property_tree_state(nullptr, nullptr, nullptr); 466 PropertyTreeState source_property_tree_state(nullptr, nullptr, nullptr);
432 PropertyTreeState destination_property_tree_state(nullptr, nullptr, nullptr); 467 PropertyTreeState destination_property_tree_state(nullptr, nullptr, nullptr);
433 InitializeCommonClipRectState(context, source_property_tree_state, 468 InitializeCommonClipRectState(context, source_property_tree_state,
434 destination_property_tree_state); 469 destination_property_tree_state);
435 470
436 if (&layer_ != context.root_layer) {
437 auto* ancestor_properties =
438 context.root_layer->GetLayoutObject().PaintProperties();
439 const auto* ancestor_overflow_clip =
440 ancestor_properties ? ancestor_properties->OverflowClip() : nullptr;
441 // Set the clip of |destinationPropertyTreeState| to be inside the
442 // ancestor's overflow clip, so that that clip is not applied.
443 if (context.respect_overflow_clip == kIgnoreOverflowClip &&
444 ancestor_overflow_clip)
445 destination_property_tree_state.SetClip(ancestor_overflow_clip);
446 }
447
448 // The background rect applies all clips *above* m_layer, but not the overflow 471 // The background rect applies all clips *above* m_layer, but not the overflow
449 // clip of m_layer. It also applies a clip to the total painting bounds 472 // clip of m_layer. It also applies a clip to the total painting bounds
450 // of m_layer, because nothing in m_layer or its children within the clip can 473 // of m_layer, because nothing in m_layer or its children within the clip can
451 // paint outside of those bounds. 474 // paint outside of those bounds.
452 // The total painting bounds includes any visual overflow (such as shadow) and 475 // The total painting bounds includes any visual overflow (such as shadow) and
453 // filter bounds. 476 // filter bounds.
454 // 477 //
455 // TODO(chrishtr): sourceToDestinationVisualRect and 478 // TODO(chrishtr): sourceToDestinationVisualRect and
456 // sourceToDestinationClipRect may not compute tight results in the presence 479 // sourceToDestinationClipRect may not compute tight results in the presence
457 // of transforms. Tight results are required for most use cases of these 480 // of transforms. Tight results are required for most use cases of these
458 // rects, so we should add methods to GeometryMapper that guarantee there 481 // rects, so we should add methods to GeometryMapper that guarantee there
459 // are tight results, or else signal an error. 482 // are tight results, or else signal an error.
460 if (ShouldClipOverflow(context)) { 483 if (HasOverflowClip(layer_)) {
461 FloatClipRect clip_rect((FloatRect(LocalVisualRect()))); 484 FloatClipRect clip_rect((FloatRect(LocalVisualRect())));
462 clip_rect.MoveBy(FloatPoint(layer_.GetLayoutObject().PaintOffset())); 485 clip_rect.MoveBy(FloatPoint(layer_.GetLayoutObject().PaintOffset()));
463 GeometryMapper::SourceToDestinationVisualRect( 486 GeometryMapper::SourceToDestinationVisualRect(
464 source_property_tree_state, destination_property_tree_state, clip_rect); 487 source_property_tree_state, destination_property_tree_state, clip_rect);
465 output.SetRect(clip_rect); 488 output.SetRect(clip_rect);
466 } else { 489 } else {
467 const FloatClipRect& clipped_rect_in_root_layer_space = 490 const FloatClipRect& clipped_rect_in_root_layer_space =
468 GeometryMapper::SourceToDestinationClipRect( 491 GeometryMapper::SourceToDestinationClipRect(
469 source_property_tree_state, destination_property_tree_state); 492 source_property_tree_state, destination_property_tree_state);
470 output.SetRect(clipped_rect_in_root_layer_space); 493 output.SetRect(clipped_rect_in_root_layer_space);
471 } 494 }
472 495
473 output.MoveBy(-context.root_layer->GetLayoutObject().PaintOffset()); 496 output.MoveBy(-context.root_layer->GetLayoutObject().PaintOffset());
474 } 497 }
475 498
476 void PaintLayerClipper::InitializeCommonClipRectState( 499 void PaintLayerClipper::InitializeCommonClipRectState(
477 const ClipRectsContext& context, 500 const ClipRectsContext& context,
478 PropertyTreeState& source_property_tree_state, 501 PropertyTreeState& source_property_tree_state,
479 PropertyTreeState& destination_property_tree_state) const { 502 PropertyTreeState& destination_property_tree_state) const {
480 DCHECK(use_geometry_mapper_); 503 DCHECK(use_geometry_mapper_);
504
481 DCHECK(layer_.GetLayoutObject().LocalBorderBoxProperties()); 505 DCHECK(layer_.GetLayoutObject().LocalBorderBoxProperties());
482
483 source_property_tree_state = 506 source_property_tree_state =
484 *layer_.GetLayoutObject().LocalBorderBoxProperties(); 507 *layer_.GetLayoutObject().LocalBorderBoxProperties();
508
485 DCHECK(context.root_layer->GetLayoutObject().LocalBorderBoxProperties()); 509 DCHECK(context.root_layer->GetLayoutObject().LocalBorderBoxProperties());
486 destination_property_tree_state = 510 destination_property_tree_state =
487 *context.root_layer->GetLayoutObject().LocalBorderBoxProperties(); 511 *context.root_layer->GetLayoutObject().LocalBorderBoxProperties();
488 512
489 auto* ancestor_properties = 513 auto* ancestor_properties =
490 context.root_layer->GetLayoutObject().PaintProperties(); 514 context.root_layer->GetLayoutObject().PaintProperties();
491 const auto* ancestor_css_clip = 515 if (!ancestor_properties)
492 ancestor_properties ? ancestor_properties->CssClip() : nullptr; 516 return;
493 // CSS clip of the root is always applied. 517
494 if (ancestor_css_clip) { 518 if (context.ShouldRespectRootLayerClip()) {
495 DCHECK(destination_property_tree_state.Clip() == 519 const auto* ancestor_css_clip = ancestor_properties->CssClip();
496 ancestor_properties->CssClip()); 520 if (ancestor_css_clip) {
497 destination_property_tree_state.SetClip(ancestor_css_clip->Parent()); 521 DCHECK_EQ(destination_property_tree_state.Clip(),
522 ancestor_css_clip);
523 destination_property_tree_state.SetClip(ancestor_css_clip->Parent());
524 }
525 } else {
526 const auto* ancestor_overflow_clip = ancestor_properties->OverflowClip();
527 if (ancestor_overflow_clip) {
528 DCHECK_EQ(destination_property_tree_state.Clip(),
529 ancestor_overflow_clip->Parent());
530 destination_property_tree_state.SetClip(ancestor_overflow_clip);
531 }
498 } 532 }
499 } 533 }
500 534
501 LayoutRect PaintLayerClipper::LocalVisualRect() const { 535 LayoutRect PaintLayerClipper::LocalVisualRect() const {
502 const LayoutObject& layout_object = layer_.GetLayoutObject(); 536 const LayoutObject& layout_object = layer_.GetLayoutObject();
503 // The LayoutView is special since its overflow clipping rect may be larger 537 // The LayoutView is special since its overflow clipping rect may be larger
504 // than its box rect (crbug.com/492871). 538 // than its box rect (crbug.com/492871).
505 LayoutRect layer_bounds_with_visual_overflow = 539 LayoutRect layer_bounds_with_visual_overflow =
506 layout_object.IsLayoutView() 540 layout_object.IsLayoutView()
507 ? ToLayoutView(layout_object).ViewRect() 541 ? ToLayoutView(layout_object).ViewRect()
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 DCHECK(!use_geometry_mapper_); 599 DCHECK(!use_geometry_mapper_);
566 600
567 if (context.UsesCache()) 601 if (context.UsesCache())
568 clip_rects = GetClipRects(context); 602 clip_rects = GetClipRects(context);
569 else 603 else
570 CalculateClipRects(context, clip_rects); 604 CalculateClipRects(context, clip_rects);
571 } 605 }
572 606
573 bool PaintLayerClipper::ShouldClipOverflow( 607 bool PaintLayerClipper::ShouldClipOverflow(
574 const ClipRectsContext& context) const { 608 const ClipRectsContext& context) const {
575 if (!layer_.GetLayoutObject().IsBox()) 609 if (&layer_ == context.root_layer && !context.ShouldRespectRootLayerClip())
576 return false; 610 return false;
577 const LayoutBox& box = ToLayoutBox(layer_.GetLayoutObject()); 611 return HasOverflowClip(layer_);
578
579 if (!ShouldRespectOverflowClip(context))
580 return false;
581
582 return box.ShouldClipOverflow();
583 }
584
585 bool PaintLayerClipper::ShouldRespectOverflowClip(
586 const ClipRectsContext& context) const {
587 if (&layer_ != context.root_layer)
588 return true;
589
590 if (context.respect_overflow_clip == kIgnoreOverflowClip)
591 return false;
592
593 if (layer_.IsRootLayer() &&
594 context.respect_overflow_clip_for_viewport == kIgnoreOverflowClip)
595 return false;
596
597 return true;
598 } 612 }
599 613
600 ClipRects& PaintLayerClipper::PaintingClipRects( 614 ClipRects& PaintLayerClipper::PaintingClipRects(
601 const PaintLayer* root_layer, 615 const PaintLayer* root_layer,
602 ShouldRespectOverflowClipType respect_overflow_clip, 616 ShouldRespectOverflowClipType respect_overflow_clip,
603 const LayoutSize& subpixel_accumulation) const { 617 const LayoutSize& subpixel_accumulation) const {
604 DCHECK(!use_geometry_mapper_); 618 DCHECK(!use_geometry_mapper_);
605 ClipRectsContext context(root_layer, kPaintingClipRects, 619 ClipRectsContext context(root_layer, kPaintingClipRects,
606 kIgnorePlatformOverlayScrollbarSize, 620 kIgnorePlatformOverlayScrollbarSize,
607 subpixel_accumulation); 621 subpixel_accumulation);
608 if (respect_overflow_clip == kIgnoreOverflowClip) 622 if (respect_overflow_clip == kIgnoreOverflowClip)
609 context.SetIgnoreOverflowClip(); 623 context.SetIgnoreOverflowClip();
610 return GetClipRects(context); 624 return GetClipRects(context);
611 } 625 }
612 626
613 } // namespace blink 627 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698