OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/PaintLayerPainter.h" | 5 #include "core/paint/PaintLayerPainter.h" |
6 | 6 |
7 #include "core/frame/LocalFrame.h" | 7 #include "core/frame/LocalFrame.h" |
8 #include "core/layout/LayoutView.h" | 8 #include "core/layout/LayoutView.h" |
9 #include "core/paint/ClipPathClipper.h" | 9 #include "core/paint/ClipPathClipper.h" |
10 #include "core/paint/FilterPainter.h" | 10 #include "core/paint/FilterPainter.h" |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 // These helpers output clip and compositing operations using a RAII pattern. | 364 // These helpers output clip and compositing operations using a RAII pattern. |
365 // Stack-allocated-varibles are destructed in the reverse order of | 365 // Stack-allocated-varibles are destructed in the reverse order of |
366 // construction, so they are nested properly. | 366 // construction, so they are nested properly. |
367 Optional<ClipPathClipper> clipPathClipper; | 367 Optional<ClipPathClipper> clipPathClipper; |
368 // Clip-path, like border radius, must not be applied to the contents of a | 368 // Clip-path, like border radius, must not be applied to the contents of a |
369 // composited-scrolling container. It must, however, still be applied to the | 369 // composited-scrolling container. It must, however, still be applied to the |
370 // mask layer, so that the compositor can properly mask the | 370 // mask layer, so that the compositor can properly mask the |
371 // scrolling contents and scrollbars. | 371 // scrolling contents and scrollbars. |
372 if (m_paintLayer.layoutObject()->hasClipPath() && | 372 if (m_paintLayer.layoutObject()->hasClipPath() && |
373 (!m_paintLayer.needsCompositedScrolling() || | 373 (!m_paintLayer.needsCompositedScrolling() || |
374 (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) { | 374 (paintFlags & (PaintLayerPaintingChildClippingMaskPhase | |
| 375 PaintLayerPaintingAncestorClippingMaskPhase)))) { |
375 paintingInfo.ancestorHasClipPathClipping = true; | 376 paintingInfo.ancestorHasClipPathClipping = true; |
376 | 377 |
377 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); | 378 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); |
378 // Note that this isn't going to work correctly if crossing a column | 379 // Note that this isn't going to work correctly if crossing a column |
379 // boundary. The reference box should be determined per-fragment, and hence | 380 // boundary. The reference box should be determined per-fragment, and hence |
380 // this ought to be performed after fragmentation. | 381 // this ought to be performed after fragmentation. |
381 if (m_paintLayer.enclosingPaginationLayer()) | 382 if (m_paintLayer.enclosingPaginationLayer()) |
382 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( | 383 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( |
383 paintingInfo.rootLayer, referenceBox); | 384 paintingInfo.rootLayer, referenceBox); |
384 else | 385 else |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 isSelfPaintingLayer && !isPaintingOverlayScrollbars; | 421 isSelfPaintingLayer && !isPaintingOverlayScrollbars; |
421 | 422 |
422 PaintLayerFragments layerFragments; | 423 PaintLayerFragments layerFragments; |
423 if (shouldPaintContent || shouldPaintSelfOutline || | 424 if (shouldPaintContent || shouldPaintSelfOutline || |
424 isPaintingOverlayScrollbars) { | 425 isPaintingOverlayScrollbars) { |
425 // Collect the fragments. This will compute the clip rectangles and paint | 426 // Collect the fragments. This will compute the clip rectangles and paint |
426 // offsets for each layer fragment. | 427 // offsets for each layer fragment. |
427 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) | 428 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) |
428 ? UncachedClipRects | 429 ? UncachedClipRects |
429 : PaintingClipRects; | 430 : PaintingClipRects; |
| 431 LayoutPoint offsetToClipper; |
| 432 PaintLayer* paintLayerForFragments = &m_paintLayer; |
| 433 if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) { |
| 434 // Compute fragments and their clips with respect to the clipping |
| 435 // container. The paint rect is in this layer's space, so convert it |
| 436 // to the clipper's layer's space. The rootLayer is also changed to |
| 437 // the clipper's layer to simplify coordinate system adjustments. |
| 438 // The change to rootLayer must persist to correctly record the clips. |
| 439 paintLayerForFragments = |
| 440 m_paintLayer.clippingContainer()->enclosingLayer(); |
| 441 localPaintingInfo.rootLayer = paintLayerForFragments; |
| 442 m_paintLayer.convertToLayerCoords(localPaintingInfo.rootLayer, |
| 443 offsetToClipper); |
| 444 localPaintingInfo.paintDirtyRect.moveBy(offsetToClipper); |
| 445 } |
| 446 |
430 // TODO(trchen): We haven't decided how to handle visual fragmentation with | 447 // TODO(trchen): We haven't decided how to handle visual fragmentation with |
431 // SPv2. Related thread | 448 // SPv2. Related thread |
432 // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuW
Ff-mxM | 449 // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuW
Ff-mxM |
433 if (fragmentPolicy == ForceSingleFragment || | 450 if (fragmentPolicy == ForceSingleFragment || |
434 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 451 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
435 m_paintLayer.appendSingleFragmentIgnoringPagination( | 452 paintLayerForFragments->appendSingleFragmentIgnoringPagination( |
436 layerFragments, localPaintingInfo.rootLayer, | 453 layerFragments, localPaintingInfo.rootLayer, |
437 localPaintingInfo.paintDirtyRect, cacheSlot, | 454 localPaintingInfo.paintDirtyRect, cacheSlot, |
438 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, | 455 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, |
439 localPaintingInfo.subPixelAccumulation); | 456 localPaintingInfo.subPixelAccumulation); |
440 else | 457 } else { |
441 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, | 458 paintLayerForFragments->collectFragments( |
442 localPaintingInfo.paintDirtyRect, cacheSlot, | 459 layerFragments, localPaintingInfo.rootLayer, |
443 IgnoreOverlayScrollbarSize, | 460 localPaintingInfo.paintDirtyRect, cacheSlot, |
444 respectOverflowClip, &offsetFromRoot, | 461 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, |
445 localPaintingInfo.subPixelAccumulation); | 462 localPaintingInfo.subPixelAccumulation); |
| 463 } |
| 464 |
| 465 if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) { |
| 466 // Fragment offsets have been computed in the clipping container's |
| 467 // layer's coordinate system, but for the rest of painting we need |
| 468 // them in the layer coordinate. So move them and the foreground rect |
| 469 // that is also in the clipper's space. |
| 470 LayoutSize negativeOffset(-offsetToClipper.x(), -offsetToClipper.y()); |
| 471 for (auto& fragment : layerFragments) { |
| 472 fragment.foregroundRect.move(negativeOffset); |
| 473 fragment.paginationOffset.move(negativeOffset); |
| 474 } |
| 475 } |
446 | 476 |
447 if (shouldPaintContent) { | 477 if (shouldPaintContent) { |
448 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar | 478 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar |
449 // optimization for slimming paint v2. | 479 // optimization for slimming paint v2. |
450 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( | 480 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( |
451 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); | 481 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); |
452 if (!shouldPaintContent) | 482 if (!shouldPaintContent) |
453 result = MayBeClippedByPaintDirtyRect; | 483 result = MayBeClippedByPaintDirtyRect; |
454 } | 484 } |
455 } | 485 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 if (shouldPaintOverlayScrollbars) | 569 if (shouldPaintOverlayScrollbars) |
540 paintOverflowControlsForFragments(layerFragments, context, | 570 paintOverflowControlsForFragments(layerFragments, context, |
541 localPaintingInfo, paintFlags); | 571 localPaintingInfo, paintFlags); |
542 } // FilterPainter block | 572 } // FilterPainter block |
543 | 573 |
544 bool shouldPaintMask = | 574 bool shouldPaintMask = |
545 (paintFlags & PaintLayerPaintingCompositingMaskPhase) && | 575 (paintFlags & PaintLayerPaintingCompositingMaskPhase) && |
546 shouldPaintContent && m_paintLayer.layoutObject()->hasMask() && | 576 shouldPaintContent && m_paintLayer.layoutObject()->hasMask() && |
547 !selectionOnly; | 577 !selectionOnly; |
548 bool shouldPaintClippingMask = | 578 bool shouldPaintClippingMask = |
549 (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && | 579 (paintFlags & (PaintLayerPaintingChildClippingMaskPhase | |
| 580 PaintLayerPaintingAncestorClippingMaskPhase)) && |
550 shouldPaintContent && !selectionOnly; | 581 shouldPaintContent && !selectionOnly; |
551 | 582 |
552 if (shouldPaintMask) | 583 if (shouldPaintMask) |
553 paintMaskForFragments(layerFragments, context, localPaintingInfo, | 584 paintMaskForFragments(layerFragments, context, localPaintingInfo, |
554 paintFlags); | 585 paintFlags); |
555 if (shouldPaintClippingMask) { | 586 if (shouldPaintClippingMask) { |
556 // Paint the border radius mask for the fragments. | 587 // Paint the border radius mask for the fragments. |
557 paintChildClippingMaskForFragments(layerFragments, context, | 588 paintChildClippingMaskForFragments(layerFragments, context, |
558 localPaintingInfo, paintFlags); | 589 localPaintingInfo, paintFlags); |
559 } | 590 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 if (needsToClip(paintingInfo, clipRectForFragment)) { | 745 if (needsToClip(paintingInfo, clipRectForFragment)) { |
715 if (m_paintLayer.layoutObject()->isPositioned() && | 746 if (m_paintLayer.layoutObject()->isPositioned() && |
716 clipRectForFragment.isClippedByClipCss()) | 747 clipRectForFragment.isClippedByClipCss()) |
717 UseCounter::count(m_paintLayer.layoutObject()->document(), | 748 UseCounter::count(m_paintLayer.layoutObject()->document(), |
718 UseCounter::ClipCssOfPositionedElement); | 749 UseCounter::ClipCssOfPositionedElement); |
719 if (m_paintLayer.layoutObject()->isFixedPositioned()) | 750 if (m_paintLayer.layoutObject()->isFixedPositioned()) |
720 UseCounter::count(m_paintLayer.layoutObject()->document(), | 751 UseCounter::count(m_paintLayer.layoutObject()->document(), |
721 UseCounter::ClipCssOfFixedPositionElement); | 752 UseCounter::ClipCssOfFixedPositionElement); |
722 clipRecorder.emplace(context, *parentLayer->layoutObject(), | 753 clipRecorder.emplace(context, *parentLayer->layoutObject(), |
723 DisplayItem::kClipLayerParent, clipRectForFragment, | 754 DisplayItem::kClipLayerParent, clipRectForFragment, |
724 &paintingInfo, fragment.paginationOffset, | 755 paintingInfo.rootLayer, fragment.paginationOffset, |
725 paintFlags); | 756 paintFlags); |
726 } | 757 } |
727 } | 758 } |
728 if (paintFragmentByApplyingTransform(context, paintingInfo, paintFlags, | 759 if (paintFragmentByApplyingTransform(context, paintingInfo, paintFlags, |
729 fragment.paginationOffset) == | 760 fragment.paginationOffset) == |
730 MayBeClippedByPaintDirtyRect) | 761 MayBeClippedByPaintDirtyRect) |
731 result = MayBeClippedByPaintDirtyRect; | 762 result = MayBeClippedByPaintDirtyRect; |
732 } | 763 } |
733 return result; | 764 return result; |
734 } | 765 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 | 883 |
853 for (auto& fragment : layerFragments) { | 884 for (auto& fragment : layerFragments) { |
854 // We need to apply the same clips and transforms that | 885 // We need to apply the same clips and transforms that |
855 // paintFragmentWithPhase would have. | 886 // paintFragmentWithPhase would have. |
856 LayoutRect cullRect = fragment.backgroundRect.rect(); | 887 LayoutRect cullRect = fragment.backgroundRect.rect(); |
857 | 888 |
858 Optional<LayerClipRecorder> clipRecorder; | 889 Optional<LayerClipRecorder> clipRecorder; |
859 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) { | 890 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) { |
860 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), | 891 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), |
861 DisplayItem::kClipLayerOverflowControls, | 892 DisplayItem::kClipLayerOverflowControls, |
862 fragment.backgroundRect, &localPaintingInfo, | 893 fragment.backgroundRect, localPaintingInfo.rootLayer, |
863 fragment.paginationOffset, paintFlags); | 894 fragment.paginationOffset, paintFlags); |
864 } | 895 } |
865 | 896 |
866 Optional<ScrollRecorder> scrollRecorder; | 897 Optional<ScrollRecorder> scrollRecorder; |
867 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 898 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
868 !localPaintingInfo.scrollOffsetAccumulation.isZero()) { | 899 !localPaintingInfo.scrollOffsetAccumulation.isZero()) { |
869 cullRect.move(localPaintingInfo.scrollOffsetAccumulation); | 900 cullRect.move(localPaintingInfo.scrollOffsetAccumulation); |
870 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), | 901 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), |
871 DisplayItem::kScrollOverflowControls, | 902 DisplayItem::kScrollOverflowControls, |
872 localPaintingInfo.scrollOffsetAccumulation); | 903 localPaintingInfo.scrollOffsetAccumulation); |
(...skipping 29 matching lines...) Expand all Loading... |
902 // handle clipping to self. | 933 // handle clipping to self. |
903 case PaintPhaseSelfOutlineOnly: | 934 case PaintPhaseSelfOutlineOnly: |
904 case PaintPhaseMask: // Mask painting will handle clipping to self. | 935 case PaintPhaseMask: // Mask painting will handle clipping to self. |
905 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; | 936 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; |
906 break; | 937 break; |
907 default: | 938 default: |
908 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; | 939 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; |
909 break; | 940 break; |
910 } | 941 } |
911 | 942 |
| 943 // TODO(schenney): Nested border-radius clips are not applied to composited |
| 944 // children, probably due to an incorrect clipRoot. |
| 945 // https://bugs.chromium.org/p/chromium/issues/detail?id=672561 |
912 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, | 946 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, |
913 clipRect, &paintingInfo, fragment.paginationOffset, | 947 clipRect, paintingInfo.rootLayer, |
914 paintFlags, clippingRule); | 948 fragment.paginationOffset, paintFlags, clippingRule); |
915 } | 949 } |
916 | 950 |
917 LayoutRect newCullRect(clipRect.rect()); | 951 LayoutRect newCullRect(clipRect.rect()); |
918 Optional<ScrollRecorder> scrollRecorder; | 952 Optional<ScrollRecorder> scrollRecorder; |
919 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); | 953 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); |
920 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 954 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
921 const auto* objectPaintProperties = | 955 const auto* objectPaintProperties = |
922 m_paintLayer.layoutObject()->paintProperties(); | 956 m_paintLayer.layoutObject()->paintProperties(); |
923 DCHECK(objectPaintProperties && | 957 DCHECK(objectPaintProperties && |
924 objectPaintProperties->localBorderBoxProperties()); | 958 objectPaintProperties->localBorderBoxProperties()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 // Optimize clipping for the single fragment case. | 1010 // Optimize clipping for the single fragment case. |
977 bool shouldClip = localPaintingInfo.clipToDirtyRect && | 1011 bool shouldClip = localPaintingInfo.clipToDirtyRect && |
978 layerFragments.size() == 1 && | 1012 layerFragments.size() == 1 && |
979 !layerFragments[0].foregroundRect.isEmpty(); | 1013 !layerFragments[0].foregroundRect.isEmpty(); |
980 ClipState clipState = HasNotClipped; | 1014 ClipState clipState = HasNotClipped; |
981 Optional<LayerClipRecorder> clipRecorder; | 1015 Optional<LayerClipRecorder> clipRecorder; |
982 if (shouldClip && | 1016 if (shouldClip && |
983 needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) { | 1017 needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) { |
984 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), | 1018 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), |
985 DisplayItem::kClipLayerForeground, | 1019 DisplayItem::kClipLayerForeground, |
986 layerFragments[0].foregroundRect, &localPaintingInfo, | 1020 layerFragments[0].foregroundRect, |
| 1021 localPaintingInfo.rootLayer, |
987 layerFragments[0].paginationOffset, paintFlags); | 1022 layerFragments[0].paginationOffset, paintFlags); |
988 clipState = HasClipped; | 1023 clipState = HasClipped; |
989 } | 1024 } |
990 | 1025 |
991 // We have to loop through every fragment multiple times, since we have to | 1026 // We have to loop through every fragment multiple times, since we have to |
992 // issue paint invalidations in each specific phase in order for interleaving | 1027 // issue paint invalidations in each specific phase in order for interleaving |
993 // of the fragments to work properly. | 1028 // of the fragments to work properly. |
994 if (selectionOnly) { | 1029 if (selectionOnly) { |
995 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments, | 1030 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments, |
996 context, localPaintingInfo, paintFlags, | 1031 context, localPaintingInfo, paintFlags, |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 | 1158 |
1124 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, | 1159 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, |
1125 LayoutRect(enclosingIntRect(damageRect)), | 1160 LayoutRect(enclosingIntRect(damageRect)), |
1126 paintFlags, LayoutSize()); | 1161 paintFlags, LayoutSize()); |
1127 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 1162 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
1128 | 1163 |
1129 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 1164 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
1130 } | 1165 } |
1131 | 1166 |
1132 } // namespace blink | 1167 } // namespace blink |
OLD | NEW |