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