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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
367 // These helpers output clip and compositing operations using a RAII pattern. | 367 // These helpers output clip and compositing operations using a RAII pattern. |
368 // Stack-allocated-varibles are destructed in the reverse order of | 368 // Stack-allocated-varibles are destructed in the reverse order of |
369 // construction, so they are nested properly. | 369 // construction, so they are nested properly. |
370 Optional<ClipPathClipper> clipPathClipper; | 370 Optional<ClipPathClipper> clipPathClipper; |
371 // Clip-path, like border radius, must not be applied to the contents of a | 371 // Clip-path, like border radius, must not be applied to the contents of a |
372 // composited-scrolling container. It must, however, still be applied to the | 372 // composited-scrolling container. It must, however, still be applied to the |
373 // mask layer, so that the compositor can properly mask the | 373 // mask layer, so that the compositor can properly mask the |
374 // scrolling contents and scrollbars. | 374 // scrolling contents and scrollbars. |
375 if (m_paintLayer.layoutObject()->hasClipPath() && | 375 if (m_paintLayer.layoutObject()->hasClipPath() && |
376 (!m_paintLayer.needsCompositedScrolling() || | 376 (!m_paintLayer.needsCompositedScrolling() || |
377 (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) { | 377 (paintFlags & (PaintLayerPaintingChildClippingMaskPhase | |
378 PaintLayerPaintingAncestorClippingMaskPhase)))) { | |
378 paintingInfo.ancestorHasClipPathClipping = true; | 379 paintingInfo.ancestorHasClipPathClipping = true; |
379 | 380 |
380 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); | 381 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); |
381 // Note that this isn't going to work correctly if crossing a column | 382 // Note that this isn't going to work correctly if crossing a column |
382 // boundary. The reference box should be determined per-fragment, and hence | 383 // boundary. The reference box should be determined per-fragment, and hence |
383 // this ought to be performed after fragmentation. | 384 // this ought to be performed after fragmentation. |
384 if (m_paintLayer.enclosingPaginationLayer()) | 385 if (m_paintLayer.enclosingPaginationLayer()) |
385 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( | 386 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( |
386 paintingInfo.rootLayer, referenceBox); | 387 paintingInfo.rootLayer, referenceBox); |
387 else | 388 else |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 localPaintingInfo.subPixelAccumulation = subpixelAccumulation; | 421 localPaintingInfo.subPixelAccumulation = subpixelAccumulation; |
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; |
430 // TODO(trchen): We haven't decided how to handle visual fragmentation with | 431 // TODO(trchen): We haven't decided how to handle visual fragmentation with |
chrishtr
2016/12/02 19:21:47
This comment belongs down by line 446.
Stephen Chennney
2016/12/07 21:39:38
Done.
| |
431 // SPv2. Related thread | 432 // SPv2. Related thread |
432 // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuW Ff-mxM | 433 // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuW Ff-mxM |
434 PaintLayer* paintLayerForFragmentsAndClip = &m_paintLayer; | |
435 LayoutPoint offsetFromRootForFragmentsAndClip = offsetFromRoot; | |
436 if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) { | |
437 // Compute fragments and their clips with respect to the clipping | |
438 // container, and then convert them back to this layer's space. | |
439 // We need a new offset from root. | |
440 paintLayerForFragmentsAndClip = | |
441 m_paintLayer.clippingContainer()->enclosingLayer(); | |
442 paintLayerForFragmentsAndClip->convertToLayerCoords( | |
chrishtr
2016/12/02 19:21:47
You can't map from an ancestor to a descendant Pai
Stephen Chennney
2016/12/07 21:39:38
Done.
| |
443 m_paintLayer.root(), offsetFromRootForFragmentsAndClip); | |
444 } | |
445 | |
433 if (fragmentPolicy == ForceSingleFragment || | 446 if (fragmentPolicy == ForceSingleFragment || |
434 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 447 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
435 m_paintLayer.appendSingleFragmentIgnoringPagination( | 448 paintLayerForFragmentsAndClip->appendSingleFragmentIgnoringPagination( |
436 layerFragments, localPaintingInfo.rootLayer, | 449 layerFragments, localPaintingInfo.rootLayer, |
437 localPaintingInfo.paintDirtyRect, cacheSlot, | 450 localPaintingInfo.paintDirtyRect, cacheSlot, |
438 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, | 451 IgnoreOverlayScrollbarSize, respectOverflowClip, |
452 &offsetFromRootForFragmentsAndClip, | |
439 localPaintingInfo.subPixelAccumulation); | 453 localPaintingInfo.subPixelAccumulation); |
440 else | 454 } else { |
441 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, | 455 paintLayerForFragmentsAndClip->collectFragments( |
442 localPaintingInfo.paintDirtyRect, cacheSlot, | 456 layerFragments, localPaintingInfo.rootLayer, |
443 IgnoreOverlayScrollbarSize, | 457 localPaintingInfo.paintDirtyRect, cacheSlot, |
444 respectOverflowClip, &offsetFromRoot, | 458 IgnoreOverlayScrollbarSize, respectOverflowClip, |
445 localPaintingInfo.subPixelAccumulation); | 459 &offsetFromRootForFragmentsAndClip, |
460 localPaintingInfo.subPixelAccumulation); | |
461 } | |
446 | 462 |
447 if (shouldPaintContent) { | 463 if (shouldPaintContent) { |
448 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar | 464 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar |
449 // optimization for slimming paint v2. | 465 // optimization for slimming paint v2. |
450 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( | 466 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( |
451 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); | 467 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); |
452 if (!shouldPaintContent) | 468 if (!shouldPaintContent) |
453 result = MayBeClippedByPaintDirtyRect; | 469 result = MayBeClippedByPaintDirtyRect; |
454 } | 470 } |
455 } | 471 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
539 if (shouldPaintOverlayScrollbars) | 555 if (shouldPaintOverlayScrollbars) |
540 paintOverflowControlsForFragments(layerFragments, context, | 556 paintOverflowControlsForFragments(layerFragments, context, |
541 localPaintingInfo, paintFlags); | 557 localPaintingInfo, paintFlags); |
542 } // FilterPainter block | 558 } // FilterPainter block |
543 | 559 |
544 bool shouldPaintMask = | 560 bool shouldPaintMask = |
545 (paintFlags & PaintLayerPaintingCompositingMaskPhase) && | 561 (paintFlags & PaintLayerPaintingCompositingMaskPhase) && |
546 shouldPaintContent && m_paintLayer.layoutObject()->hasMask() && | 562 shouldPaintContent && m_paintLayer.layoutObject()->hasMask() && |
547 !selectionOnly; | 563 !selectionOnly; |
548 bool shouldPaintClippingMask = | 564 bool shouldPaintClippingMask = |
549 (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && | 565 (paintFlags & (PaintLayerPaintingChildClippingMaskPhase | |
566 PaintLayerPaintingAncestorClippingMaskPhase)) && | |
550 shouldPaintContent && !selectionOnly; | 567 shouldPaintContent && !selectionOnly; |
551 | 568 |
552 if (shouldPaintMask) | 569 if (shouldPaintMask) |
553 paintMaskForFragments(layerFragments, context, localPaintingInfo, | 570 paintMaskForFragments(layerFragments, context, localPaintingInfo, |
554 paintFlags); | 571 paintFlags); |
555 if (shouldPaintClippingMask) { | 572 if (shouldPaintClippingMask) { |
556 // Paint the border radius mask for the fragments. | 573 // Paint the border radius mask for the fragments. |
557 paintChildClippingMaskForFragments(layerFragments, context, | 574 paintChildClippingMaskForFragments(layerFragments, context, |
558 localPaintingInfo, paintFlags); | 575 localPaintingInfo, paintFlags); |
559 } | 576 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 // its parent. | 635 // its parent. |
619 PaintLayer* parentLayer = m_paintLayer.parent(); | 636 PaintLayer* parentLayer = m_paintLayer.parent(); |
620 | 637 |
621 LayoutObject* object = m_paintLayer.layoutObject(); | 638 LayoutObject* object = m_paintLayer.layoutObject(); |
622 LayoutView* view = object->view(); | 639 LayoutView* view = object->view(); |
623 bool isFixedPosObjectInPagedMedia = | 640 bool isFixedPosObjectInPagedMedia = |
624 object->style()->position() == FixedPosition && | 641 object->style()->position() == FixedPosition && |
625 object->container() == view && view->pageLogicalHeight(); | 642 object->container() == view && view->pageLogicalHeight(); |
626 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); | 643 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); |
627 PaintLayerFragments fragments; | 644 PaintLayerFragments fragments; |
645 | |
chrishtr
2016/12/02 19:21:47
Super nit: spurious.
Stephen Chennney
2016/12/07 21:39:38
Done.
| |
628 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position | 646 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position |
629 // objects in paged media with vertical writing modes. | 647 // objects in paged media with vertical writing modes. |
630 if (isFixedPosObjectInPagedMedia && view->isHorizontalWritingMode()) { | 648 if (isFixedPosObjectInPagedMedia && view->isHorizontalWritingMode()) { |
631 // "For paged media, boxes with fixed positions are repeated on every page." | 649 // "For paged media, boxes with fixed positions are repeated on every page." |
632 // https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioni ng | 650 // https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioni ng |
633 unsigned pages = | 651 unsigned pages = |
634 ceilf(view->documentRect().height() / view->pageLogicalHeight()); | 652 ceilf(view->documentRect().height() / view->pageLogicalHeight()); |
635 LayoutPoint paginationOffset; | 653 LayoutPoint paginationOffset; |
636 | 654 |
637 // The fixed position object is offset from the top of the page, so remove | 655 // The fixed position object is offset from the top of the page, so remove |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
874 | 892 |
875 // We pass IntPoint() as the paint offset here, because | 893 // We pass IntPoint() as the paint offset here, because |
876 // ScrollableArea::paintOverflowControls just ignores it and uses the | 894 // ScrollableArea::paintOverflowControls just ignores it and uses the |
877 // offset found in a previous pass. | 895 // offset found in a previous pass. |
878 CullRect snappedCullRect(pixelSnappedIntRect(cullRect)); | 896 CullRect snappedCullRect(pixelSnappedIntRect(cullRect)); |
879 ScrollableAreaPainter(*scrollableArea) | 897 ScrollableAreaPainter(*scrollableArea) |
880 .paintOverflowControls(context, IntPoint(), snappedCullRect, true); | 898 .paintOverflowControls(context, IntPoint(), snappedCullRect, true); |
881 } | 899 } |
882 } | 900 } |
883 | 901 |
902 void adjustPaintOffsetForAncestorClippingMask( | |
903 PaintLayer& layer, LayoutPoint& paintOffset) | |
904 { | |
905 // Adjust the paint offset to reflect the fact that the fragment is | |
906 // positioned for the clipping container object. | |
907 LayoutPoint clippersOffsetToRoot; | |
908 PaintLayer* paintLayerForMask = | |
909 layer.clippingContainer()->enclosingLayer(); | |
910 paintLayerForMask->convertToLayerCoords(layer.root(), | |
chrishtr
2016/12/02 19:21:47
This duplicates line 442 I think?
| |
911 clippersOffsetToRoot); | |
912 LayoutPoint paintersOffsetToRoot; | |
913 layer.convertToLayerCoords(layer.root(), paintersOffsetToRoot); | |
914 | |
915 paintOffset.move(paintersOffsetToRoot - clippersOffsetToRoot); | |
916 } | |
917 | |
884 void PaintLayerPainter::paintFragmentWithPhase( | 918 void PaintLayerPainter::paintFragmentWithPhase( |
885 PaintPhase phase, | 919 PaintPhase phase, |
886 const PaintLayerFragment& fragment, | 920 const PaintLayerFragment& fragment, |
887 GraphicsContext& context, | 921 GraphicsContext& context, |
888 const ClipRect& clipRect, | 922 const ClipRect& clipRect, |
889 const PaintLayerPaintingInfo& paintingInfo, | 923 const PaintLayerPaintingInfo& paintingInfo, |
890 PaintLayerFlags paintFlags, | 924 PaintLayerFlags paintFlags, |
891 ClipState clipState) { | 925 ClipState clipState) { |
892 DCHECK(m_paintLayer.isSelfPaintingLayer()); | 926 DCHECK(m_paintLayer.isSelfPaintingLayer()); |
893 | 927 |
894 Optional<LayerClipRecorder> clipRecorder; | 928 Optional<LayerClipRecorder> clipRecorder; |
895 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && | 929 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && |
896 needsToClip(paintingInfo, clipRect)) { | 930 needsToClip(paintingInfo, clipRect)) { |
897 DisplayItem::Type clipType = | 931 DisplayItem::Type clipType = |
898 DisplayItem::paintPhaseToClipLayerFragmentType(phase); | 932 DisplayItem::paintPhaseToClipLayerFragmentType(phase); |
899 LayerClipRecorder::BorderRadiusClippingRule clippingRule; | 933 LayerClipRecorder::BorderRadiusClippingRule clippingRule; |
900 switch (phase) { | 934 switch (phase) { |
901 case PaintPhaseSelfBlockBackgroundOnly: // Background painting will | 935 case PaintPhaseSelfBlockBackgroundOnly: // Background painting will |
902 // handle clipping to self. | 936 // handle clipping to self. |
903 case PaintPhaseSelfOutlineOnly: | 937 case PaintPhaseSelfOutlineOnly: |
904 case PaintPhaseMask: // Mask painting will handle clipping to self. | 938 case PaintPhaseMask: // Mask painting will handle clipping to self. |
905 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; | 939 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; |
906 break; | 940 break; |
907 default: | 941 default: |
908 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; | 942 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; |
909 break; | 943 break; |
910 } | 944 } |
911 | 945 |
912 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, | 946 // When painting the clipping mask for a composited child, we pass |
913 clipRect, &paintingInfo, fragment.paginationOffset, | 947 // the clipping container object as the layoutObject to provide the clip. |
914 paintFlags, clippingRule); | 948 // The recorder assumes the fragment is positioned in that objects's |
949 // layer coordinates, so we also convert that. | |
950 if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) { | |
951 clipRecorder.emplace( | |
952 context, *(toLayoutBoxModelObject(m_paintLayer.clippingContainer())), | |
chrishtr
2016/12/02 19:21:47
Might be easier to read if you make a local variab
| |
953 clipType, clipRect, &paintingInfo, | |
954 fragment.paginationOffset, | |
955 paintFlags, clippingRule); | |
956 } else { | |
957 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, | |
958 clipRect, &paintingInfo, fragment.paginationOffset, | |
959 paintFlags, clippingRule); | |
960 } | |
915 } | 961 } |
916 | 962 |
917 LayoutRect newCullRect(clipRect.rect()); | 963 LayoutRect newCullRect(clipRect.rect()); |
918 Optional<ScrollRecorder> scrollRecorder; | 964 Optional<ScrollRecorder> scrollRecorder; |
919 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); | 965 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); |
920 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 966 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
921 const auto* objectPaintProperties = | 967 const auto* objectPaintProperties = |
922 m_paintLayer.layoutObject()->paintProperties(); | 968 m_paintLayer.layoutObject()->paintProperties(); |
923 DCHECK(objectPaintProperties && | 969 DCHECK(objectPaintProperties && |
924 objectPaintProperties->localBorderBoxProperties()); | 970 objectPaintProperties->localBorderBoxProperties()); |
(...skipping 13 matching lines...) Expand all Loading... | |
938 | 984 |
939 newCullRect.move(paintingInfo.scrollOffsetAccumulation); | 985 newCullRect.move(paintingInfo.scrollOffsetAccumulation); |
940 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), phase, | 986 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), phase, |
941 paintingInfo.scrollOffsetAccumulation); | 987 paintingInfo.scrollOffsetAccumulation); |
942 } | 988 } |
943 } | 989 } |
944 PaintInfo paintInfo(context, pixelSnappedIntRect(newCullRect), phase, | 990 PaintInfo paintInfo(context, pixelSnappedIntRect(newCullRect), phase, |
945 paintingInfo.getGlobalPaintFlags(), paintFlags, | 991 paintingInfo.getGlobalPaintFlags(), paintFlags, |
946 paintingInfo.rootLayer->layoutObject()); | 992 paintingInfo.rootLayer->layoutObject()); |
947 | 993 |
994 if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) | |
995 adjustPaintOffsetForAncestorClippingMask(m_paintLayer, paintOffset); | |
996 | |
948 m_paintLayer.layoutObject()->paint(paintInfo, paintOffset); | 997 m_paintLayer.layoutObject()->paint(paintInfo, paintOffset); |
949 } | 998 } |
950 | 999 |
951 void PaintLayerPainter::paintBackgroundForFragments( | 1000 void PaintLayerPainter::paintBackgroundForFragments( |
952 const PaintLayerFragments& layerFragments, | 1001 const PaintLayerFragments& layerFragments, |
953 GraphicsContext& context, | 1002 GraphicsContext& context, |
954 const LayoutRect& transparencyPaintDirtyRect, | 1003 const LayoutRect& transparencyPaintDirtyRect, |
955 const PaintLayerPaintingInfo& localPaintingInfo, | 1004 const PaintLayerPaintingInfo& localPaintingInfo, |
956 PaintLayerFlags paintFlags) { | 1005 PaintLayerFlags paintFlags) { |
957 Optional<DisplayItemCacheSkipper> cacheSkipper; | 1006 Optional<DisplayItemCacheSkipper> cacheSkipper; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1123 | 1172 |
1124 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, | 1173 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, |
1125 LayoutRect(enclosingIntRect(damageRect)), | 1174 LayoutRect(enclosingIntRect(damageRect)), |
1126 paintFlags, LayoutSize()); | 1175 paintFlags, LayoutSize()); |
1127 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 1176 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
1128 | 1177 |
1129 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 1178 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
1130 } | 1179 } |
1131 | 1180 |
1132 } // namespace blink | 1181 } // namespace blink |
OLD | NEW |