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

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

Issue 2605333002: [SPInvalidation] Fix fixed-position printing (Closed)
Patch Set: - Created 3 years, 11 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 | « third_party/WebKit/Source/core/paint/PaintLayerPainter.h ('k') | 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 // 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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 // TODO(trchen): We haven't decided how to handle visual fragmentation with 415 // TODO(trchen): We haven't decided how to handle visual fragmentation with
416 // SPv2. Related thread 416 // SPv2. Related thread
417 // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuW Ff-mxM 417 // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuW Ff-mxM
418 if (fragmentPolicy == ForceSingleFragment || 418 if (fragmentPolicy == ForceSingleFragment ||
419 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 419 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
420 m_paintLayer.appendSingleFragmentIgnoringPagination( 420 m_paintLayer.appendSingleFragmentIgnoringPagination(
421 layerFragments, localPaintingInfo.rootLayer, 421 layerFragments, localPaintingInfo.rootLayer,
422 localPaintingInfo.paintDirtyRect, cacheSlot, 422 localPaintingInfo.paintDirtyRect, cacheSlot,
423 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, 423 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
424 localPaintingInfo.subPixelAccumulation); 424 localPaintingInfo.subPixelAccumulation);
425 } else if (!collectPaintFragmentsForPaginatedFixedPosition( 425 } else if (isFixedPositionObjectInPagedMedia()) {
426 paintingInfo, layerFragments)) { 426 PaintLayerFragments singleFragment;
427 m_paintLayer.appendSingleFragmentIgnoringPagination(
428 singleFragment, localPaintingInfo.rootLayer,
429 localPaintingInfo.paintDirtyRect, cacheSlot,
430 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
431 localPaintingInfo.subPixelAccumulation);
432 repeatFixedPositionObjectInPages(singleFragment[0], paintingInfo,
433 layerFragments);
434 } else {
427 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, 435 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer,
428 localPaintingInfo.paintDirtyRect, cacheSlot, 436 localPaintingInfo.paintDirtyRect, cacheSlot,
429 IgnoreOverlayScrollbarSize, 437 IgnoreOverlayScrollbarSize,
430 respectOverflowClip, &offsetFromRoot, 438 respectOverflowClip, &offsetFromRoot,
431 localPaintingInfo.subPixelAccumulation); 439 localPaintingInfo.subPixelAccumulation);
432 } 440 }
433 441
434 if (shouldPaintContent) { 442 if (shouldPaintContent) {
435 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar 443 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar
436 // optimization for slimming paint v2. 444 // optimization for slimming paint v2.
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 // fragment.layerBounds is set to the border box, not the bounding box, of 587 // fragment.layerBounds is set to the border box, not the bounding box, of
580 // the layer. 588 // the layer.
581 if (m_paintLayer.intersectsDamageRect(fragment.layerBounds, 589 if (m_paintLayer.intersectsDamageRect(fragment.layerBounds,
582 fragment.backgroundRect.rect(), 590 fragment.backgroundRect.rect(),
583 newOffsetFromRoot)) 591 newOffsetFromRoot))
584 return true; 592 return true;
585 } 593 }
586 return false; 594 return false;
587 } 595 }
588 596
589 bool PaintLayerPainter::collectPaintFragmentsForPaginatedFixedPosition( 597 inline bool PaintLayerPainter::isFixedPositionObjectInPagedMedia() {
598 LayoutObject* object = m_paintLayer.layoutObject();
599 LayoutView* view = object->view();
600 return object->styleRef().position() == FixedPosition &&
601 object->container() == view && view->pageLogicalHeight() &&
602 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed
603 // position objects in paged media with vertical writing modes.
604 view->isHorizontalWritingMode();
605 }
606
607 void PaintLayerPainter::repeatFixedPositionObjectInPages(
608 const PaintLayerFragment& singleFragmentIgnoredPagination,
590 const PaintLayerPaintingInfo& paintingInfo, 609 const PaintLayerPaintingInfo& paintingInfo,
591 PaintLayerFragments& layerFragments) { 610 PaintLayerFragments& layerFragments) {
592 LayoutObject* object = m_paintLayer.layoutObject(); 611 DCHECK(isFixedPositionObjectInPagedMedia());
593 LayoutView* view = object->view();
594 bool isFixedPosObjectInPagedMedia =
595 object->style()->position() == FixedPosition &&
596 object->container() == view && view->pageLogicalHeight();
597 612
598 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position 613 LayoutView* view = m_paintLayer.layoutObject()->view();
599 // objects in paged media with vertical writing modes.
600 if (!isFixedPosObjectInPagedMedia || !view->isHorizontalWritingMode())
601 return false;
602
603 // "For paged media, boxes with fixed positions are repeated on every page."
604 // https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioning
605 unsigned pages = 614 unsigned pages =
606 ceilf(view->documentRect().height() / view->pageLogicalHeight()); 615 ceilf(view->documentRect().height() / view->pageLogicalHeight());
607 LayoutPoint paginationOffset;
608 616
609 // The fixed position object is offset from the top of the page, so remove 617 // The fixed position object is offset from the top of the page, so remove
610 // any scroll offset. 618 // any scroll offset.
611 LayoutPoint offsetFromRoot; 619 LayoutPoint offsetFromRoot;
612 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); 620 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
613 paginationOffset -= offsetFromRoot - m_paintLayer.location(); 621 LayoutSize offsetAdjustment = m_paintLayer.location() - offsetFromRoot;
622 layerFragments.append(singleFragmentIgnoredPagination);
623 layerFragments[0].paginationOffset += offsetAdjustment;
624 layerFragments[0].layerBounds.move(offsetAdjustment);
614 625
615 for (unsigned i = 0; i < pages; i++) { 626 LayoutPoint pageOffset(LayoutUnit(), view->pageLogicalHeight());
616 PaintLayerFragment fragment; 627 for (unsigned i = 1; i < pages; i++) {
617 fragment.backgroundRect = paintingInfo.paintDirtyRect; 628 PaintLayerFragment fragment = layerFragments[i - 1];
618 fragment.paginationOffset = paginationOffset; 629 fragment.paginationOffset += pageOffset;
630 fragment.layerBounds.moveBy(pageOffset);
619 layerFragments.append(fragment); 631 layerFragments.append(fragment);
620 paginationOffset += LayoutPoint(LayoutUnit(), view->pageLogicalHeight());
621 } 632 }
622 return true;
623 } 633 }
624 634
625 PaintResult PaintLayerPainter::paintLayerWithTransform( 635 PaintResult PaintLayerPainter::paintLayerWithTransform(
626 GraphicsContext& context, 636 GraphicsContext& context,
627 const PaintLayerPaintingInfo& paintingInfo, 637 const PaintLayerPaintingInfo& paintingInfo,
628 PaintLayerFlags paintFlags) { 638 PaintLayerFlags paintFlags) {
629 TransformationMatrix layerTransform = 639 TransformationMatrix layerTransform =
630 m_paintLayer.renderableTransform(paintingInfo.getGlobalPaintFlags()); 640 m_paintLayer.renderableTransform(paintingInfo.getGlobalPaintFlags());
631 // If the transform can't be inverted, then don't paint anything. 641 // If the transform can't be inverted, then don't paint anything.
632 if (!layerTransform.isInvertible()) 642 if (!layerTransform.isInvertible())
633 return FullyPainted; 643 return FullyPainted;
634 644
635 // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer 645 // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer
636 // here. m_paintLayer may be the "root", and then we should avoid looking at 646 // here. m_paintLayer may be the "root", and then we should avoid looking at
637 // its parent. 647 // its parent.
638 PaintLayer* parentLayer = m_paintLayer.parent(); 648 PaintLayer* parentLayer = m_paintLayer.parent();
639 649
640 LayoutObject* object = m_paintLayer.layoutObject();
641 LayoutView* view = object->view();
642 bool isFixedPosObjectInPagedMedia =
643 object->style()->position() == FixedPosition &&
644 object->container() == view && view->pageLogicalHeight();
645 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); 650 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer();
646 PaintLayerFragments layerFragments; 651 PaintLayerFragments layerFragments;
647 if (!collectPaintFragmentsForPaginatedFixedPosition(paintingInfo, 652 bool isFixedPositionObjectInPagedMedia =
648 layerFragments)) { 653 this->isFixedPositionObjectInPagedMedia();
649 if (paginationLayer) { 654 if (!paginationLayer || isFixedPositionObjectInPagedMedia) {
650 // FIXME: This is a mess. Look closely at this code and the code in Layer 655 // We don't need to collect any fragments in the regular way here. We have
651 // and fix any issues in it & refactor to make it obvious from code 656 // already calculated a clip rectangle for the ancestry if it was needed,
652 // structure what it does and that it's correct. 657 // and clipping this layer is something that can be done further down the
653 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) 658 // path, when the transform has been applied.
654 ? UncachedClipRects 659 PaintLayerFragment fragment;
655 : PaintingClipRects; 660 fragment.backgroundRect = paintingInfo.paintDirtyRect;
656 ShouldRespectOverflowClipType respectOverflowClip = 661 if (isFixedPositionObjectInPagedMedia)
657 shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()); 662 repeatFixedPositionObjectInPages(fragment, paintingInfo, layerFragments);
658 // Calculate the transformed bounding box in the current coordinate space, 663 else
659 // to figure out which fragmentainers (e.g. columns) we need to visit.
660 LayoutRect transformedExtent = PaintLayer::transparencyClipBox(
661 &m_paintLayer, paginationLayer,
662 PaintLayer::PaintingTransparencyClipBox,
663 PaintLayer::RootOfTransparencyClipBox,
664 paintingInfo.subPixelAccumulation,
665 paintingInfo.getGlobalPaintFlags());
666 // FIXME: we don't check if paginationLayer is within
667 // paintingInfo.rootLayer
668 // here.
669 paginationLayer->collectFragments(
670 layerFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
671 cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, 0,
672 paintingInfo.subPixelAccumulation, &transformedExtent);
673 } else {
674 // We don't need to collect any fragments in the regular way here. We have
675 // already calculated a clip rectangle for the ancestry if it was needed,
676 // and clipping this layer is something that can be done further down the
677 // path, when the transform has been applied.
678 PaintLayerFragment fragment;
679 fragment.backgroundRect = paintingInfo.paintDirtyRect;
680 layerFragments.append(fragment); 664 layerFragments.append(fragment);
681 } 665 } else {
666 // FIXME: This is a mess. Look closely at this code and the code in Layer
667 // and fix any issues in it & refactor to make it obvious from code
668 // structure what it does and that it's correct.
669 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects)
670 ? UncachedClipRects
671 : PaintingClipRects;
672 ShouldRespectOverflowClipType respectOverflowClip =
673 shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject());
674 // Calculate the transformed bounding box in the current coordinate space,
675 // to figure out which fragmentainers (e.g. columns) we need to visit.
676 LayoutRect transformedExtent = PaintLayer::transparencyClipBox(
677 &m_paintLayer, paginationLayer, PaintLayer::PaintingTransparencyClipBox,
678 PaintLayer::RootOfTransparencyClipBox,
679 paintingInfo.subPixelAccumulation, paintingInfo.getGlobalPaintFlags());
680 // FIXME: we don't check if paginationLayer is within
681 // paintingInfo.rootLayer
682 // here.
683 paginationLayer->collectFragments(
684 layerFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
685 cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, nullptr,
686 paintingInfo.subPixelAccumulation, &transformedExtent);
682 } 687 }
683 688
684 Optional<DisplayItemCacheSkipper> cacheSkipper; 689 Optional<DisplayItemCacheSkipper> cacheSkipper;
685 if (layerFragments.size() > 1) 690 if (layerFragments.size() > 1)
686 cacheSkipper.emplace(context); 691 cacheSkipper.emplace(context);
687 692
688 ClipRect ancestorBackgroundClipRect; 693 ClipRect ancestorBackgroundClipRect;
689 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 694 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
690 if (parentLayer) { 695 if (parentLayer) {
691 // Calculate the clip rectangle that the ancestors establish. 696 // Calculate the clip rectangle that the ancestors establish.
692 ClipRectsContext clipRectsContext( 697 ClipRectsContext clipRectsContext(
693 paintingInfo.rootLayer, 698 paintingInfo.rootLayer,
694 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects 699 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects
695 : PaintingClipRects, 700 : PaintingClipRects,
696 IgnoreOverlayScrollbarSize); 701 IgnoreOverlayScrollbarSize);
697 if (shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()) == 702 if (shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()) ==
698 IgnoreOverflowClip) 703 IgnoreOverflowClip)
699 clipRectsContext.setIgnoreOverflowClip(); 704 clipRectsContext.setIgnoreOverflowClip();
700 ancestorBackgroundClipRect = 705 ancestorBackgroundClipRect =
701 m_paintLayer.clipper().backgroundClipRect(clipRectsContext); 706 m_paintLayer.clipper().backgroundClipRect(clipRectsContext);
702 } 707 }
703 } 708 }
704 709
705 PaintResult result = FullyPainted; 710 PaintResult result = FullyPainted;
706 for (const auto& fragment : layerFragments) { 711 for (const auto& fragment : layerFragments) {
707 Optional<LayerClipRecorder> clipRecorder; 712 Optional<LayerClipRecorder> clipRecorder;
708 if (parentLayer && !RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 713 if (parentLayer && !RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
709 ClipRect clipRectForFragment(ancestorBackgroundClipRect); 714 ClipRect clipRectForFragment(ancestorBackgroundClipRect);
710 // A fixed-position object is repeated on every page, but if it is clipped 715 // A fixed-position object is repeated on every page instead of paginated,
711 // by an ancestor layer then the repetitions are clipped out. 716 // so we should apply the original ancestor clip rect.
712 if (!isFixedPosObjectInPagedMedia) 717 if (!isFixedPositionObjectInPagedMedia)
713 clipRectForFragment.moveBy(fragment.paginationOffset); 718 clipRectForFragment.moveBy(fragment.paginationOffset);
714 clipRectForFragment.intersect(fragment.backgroundRect); 719 clipRectForFragment.intersect(fragment.backgroundRect);
715 if (clipRectForFragment.isEmpty()) 720 if (clipRectForFragment.isEmpty())
716 continue; 721 continue;
717 if (needsToClip(paintingInfo, clipRectForFragment)) { 722 if (needsToClip(paintingInfo, clipRectForFragment)) {
718 clipRecorder.emplace(context, *parentLayer->layoutObject(), 723 clipRecorder.emplace(context, *parentLayer->layoutObject(),
719 DisplayItem::kClipLayerParent, clipRectForFragment, 724 DisplayItem::kClipLayerParent, clipRectForFragment,
720 &paintingInfo, fragment.paginationOffset, 725 &paintingInfo, fragment.paginationOffset,
721 paintFlags); 726 paintFlags);
722 } 727 }
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 1124
1120 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, 1125 PaintLayerPaintingInfo paintingInfo(&m_paintLayer,
1121 LayoutRect(enclosingIntRect(damageRect)), 1126 LayoutRect(enclosingIntRect(damageRect)),
1122 paintFlags, LayoutSize()); 1127 paintFlags, LayoutSize());
1123 paint(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); 1128 paint(context, paintingInfo, PaintLayerPaintingOverlayScrollbars);
1124 1129
1125 m_paintLayer.setContainsDirtyOverlayScrollbars(false); 1130 m_paintLayer.setContainsDirtyOverlayScrollbars(false);
1126 } 1131 }
1127 1132
1128 } // namespace blink 1133 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/PaintLayerPainter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698