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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 paintLayer.previousScrollOffsetAccumulationForPainting()) { | 222 paintLayer.previousScrollOffsetAccumulationForPainting()) { |
223 needsRepaint = true; | 223 needsRepaint = true; |
224 shouldClearEmptyPaintPhaseFlags = true; | 224 shouldClearEmptyPaintPhaseFlags = true; |
225 } | 225 } |
226 paintLayer.setPreviousScrollOffsetAccumulationForPainting( | 226 paintLayer.setPreviousScrollOffsetAccumulationForPainting( |
227 paintingInfo.scrollOffsetAccumulation); | 227 paintingInfo.scrollOffsetAccumulation); |
228 | 228 |
229 return needsRepaint; | 229 return needsRepaint; |
230 } | 230 } |
231 | 231 |
| 232 LayoutPoint PaintLayerPainter::fragmentOffsetForAncestorClipMask( |
| 233 const LayoutPoint& originalFragmentOffset) { |
| 234 // The clipping container that will be used to define the clip and the |
| 235 // child layer with respect to which the fragment offset is defined share |
| 236 // a layer root. When the clip is recorded we will be using the clipping |
| 237 // container's layer's offset to the root to position the clip. Hence we |
| 238 // must convert the fragment offset into a corresponding offset in the |
| 239 // clipping container's layer coordinates. To do that, we find the |
| 240 // originalFragmentOffset's coordinate in the root layer, fragmentDelta. |
| 241 // We also find the offset of the clipping container's origin in the root |
| 242 // layer's coordinates, clippingDelta. clippingDelta - fragmentDelta gives |
| 243 // the fragment's position in the root layer. But we need the position in |
| 244 // the clipping layer coords, and we subtract clippingDelta to get that. The |
| 245 // resulting offset is -fragmentDelta. |
| 246 DCHECK_EQ(m_paintLayer.root(), |
| 247 m_paintLayer.clippingContainer()->enclosingLayer()->root()); |
| 248 LayoutPoint fragmentDelta(originalFragmentOffset); |
| 249 m_paintLayer.convertToLayerCoords(m_paintLayer.root(), fragmentDelta); |
| 250 return LayoutPoint(-fragmentDelta.x(), -fragmentDelta.y()); |
| 251 } |
| 252 |
232 PaintResult PaintLayerPainter::paintLayerContents( | 253 PaintResult PaintLayerPainter::paintLayerContents( |
233 GraphicsContext& context, | 254 GraphicsContext& context, |
234 const PaintLayerPaintingInfo& paintingInfoArg, | 255 const PaintLayerPaintingInfo& paintingInfoArg, |
235 PaintLayerFlags paintFlags, | 256 PaintLayerFlags paintFlags, |
236 FragmentPolicy fragmentPolicy) { | 257 FragmentPolicy fragmentPolicy) { |
237 Optional<ScopedPaintChunkProperties> scopedPaintChunkProperties; | 258 Optional<ScopedPaintChunkProperties> scopedPaintChunkProperties; |
238 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 259 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
239 RuntimeEnabledFeatures::rootLayerScrollingEnabled() && | 260 RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
240 m_paintLayer.layoutObject() && | 261 m_paintLayer.layoutObject() && |
241 m_paintLayer.layoutObject()->isLayoutView()) { | 262 m_paintLayer.layoutObject()->isLayoutView()) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 // These helpers output clip and compositing operations using a RAII pattern. | 367 // These helpers output clip and compositing operations using a RAII pattern. |
347 // Stack-allocated-varibles are destructed in the reverse order of | 368 // Stack-allocated-varibles are destructed in the reverse order of |
348 // construction, so they are nested properly. | 369 // construction, so they are nested properly. |
349 Optional<ClipPathClipper> clipPathClipper; | 370 Optional<ClipPathClipper> clipPathClipper; |
350 // 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 |
351 // composited-scrolling container. It must, however, still be applied to the | 372 // composited-scrolling container. It must, however, still be applied to the |
352 // mask layer, so that the compositor can properly mask the | 373 // mask layer, so that the compositor can properly mask the |
353 // scrolling contents and scrollbars. | 374 // scrolling contents and scrollbars. |
354 if (m_paintLayer.layoutObject()->hasClipPath() && | 375 if (m_paintLayer.layoutObject()->hasClipPath() && |
355 (!m_paintLayer.needsCompositedScrolling() || | 376 (!m_paintLayer.needsCompositedScrolling() || |
356 (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) { | 377 (paintFlags & (PaintLayerPaintingChildClippingMaskPhase | |
| 378 PaintLayerPaintingAncestorClippingMaskPhase)))) { |
357 paintingInfo.ancestorHasClipPathClipping = true; | 379 paintingInfo.ancestorHasClipPathClipping = true; |
358 | 380 |
359 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); | 381 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); |
360 // 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 |
361 // boundary. The reference box should be determined per-fragment, and hence | 383 // boundary. The reference box should be determined per-fragment, and hence |
362 // this ought to be performed after fragmentation. | 384 // this ought to be performed after fragmentation. |
363 if (m_paintLayer.enclosingPaginationLayer()) | 385 if (m_paintLayer.enclosingPaginationLayer()) |
364 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( | 386 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( |
365 paintingInfo.rootLayer, referenceBox); | 387 paintingInfo.rootLayer, referenceBox); |
366 else | 388 else |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 if (shouldPaintContent || shouldPaintSelfOutline || | 424 if (shouldPaintContent || shouldPaintSelfOutline || |
403 isPaintingOverlayScrollbars) { | 425 isPaintingOverlayScrollbars) { |
404 // Collect the fragments. This will compute the clip rectangles and paint | 426 // Collect the fragments. This will compute the clip rectangles and paint |
405 // offsets for each layer fragment. | 427 // offsets for each layer fragment. |
406 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) | 428 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) |
407 ? UncachedClipRects | 429 ? UncachedClipRects |
408 : PaintingClipRects; | 430 : PaintingClipRects; |
409 // 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 |
410 // SPv2. Related thread | 432 // SPv2. Related thread |
411 // 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 LayoutPoint clippersOffsetToRoot; |
| 443 paintLayerForFragmentsAndClip->convertToLayerCoords(m_paintLayer.root(), |
| 444 clippersOffsetToRoot); |
| 445 LayoutPoint thisOffsetToRoot; |
| 446 m_paintLayer.convertToLayerCoords(m_paintLayer.root(), thisOffsetToRoot); |
| 447 offsetFromRootForFragmentsAndClip = |
| 448 LayoutPoint(clippersOffsetToRoot.x() - thisOffsetToRoot.x(), |
| 449 clippersOffsetToRoot.y() - thisOffsetToRoot.y()); |
| 450 } |
| 451 |
412 if (fragmentPolicy == ForceSingleFragment || | 452 if (fragmentPolicy == ForceSingleFragment || |
413 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 453 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
414 m_paintLayer.appendSingleFragmentIgnoringPagination( | 454 paintLayerForFragmentsAndClip->appendSingleFragmentIgnoringPagination( |
415 layerFragments, localPaintingInfo.rootLayer, | 455 layerFragments, localPaintingInfo.rootLayer, |
416 localPaintingInfo.paintDirtyRect, cacheSlot, | 456 localPaintingInfo.paintDirtyRect, cacheSlot, |
417 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, | 457 IgnoreOverlayScrollbarSize, respectOverflowClip, |
| 458 &offsetFromRootForFragmentsAndClip, |
418 localPaintingInfo.subPixelAccumulation); | 459 localPaintingInfo.subPixelAccumulation); |
419 else | 460 } else { |
420 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, | 461 paintLayerForFragmentsAndClip->collectFragments( |
421 localPaintingInfo.paintDirtyRect, cacheSlot, | 462 layerFragments, localPaintingInfo.rootLayer, |
422 IgnoreOverlayScrollbarSize, | 463 localPaintingInfo.paintDirtyRect, cacheSlot, |
423 respectOverflowClip, &offsetFromRoot, | 464 IgnoreOverlayScrollbarSize, respectOverflowClip, |
424 localPaintingInfo.subPixelAccumulation); | 465 &offsetFromRootForFragmentsAndClip, |
| 466 localPaintingInfo.subPixelAccumulation); |
| 467 } |
| 468 |
| 469 // Reset the layerBounds because they were set using the clipper's layer |
| 470 if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) { |
| 471 for (auto& fragment : layerFragments) { |
| 472 fragment.layerBounds = |
| 473 LayoutRect(offsetFromRoot, LayoutSize(m_paintLayer.size())); |
| 474 } |
| 475 } |
425 | 476 |
426 if (shouldPaintContent) { | 477 if (shouldPaintContent) { |
427 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar | 478 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar |
428 // optimization for slimming paint v2. | 479 // optimization for slimming paint v2. |
429 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( | 480 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( |
430 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); | 481 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); |
431 if (!shouldPaintContent) | 482 if (!shouldPaintContent) |
432 result = MayBeClippedByPaintDirtyRect; | 483 result = MayBeClippedByPaintDirtyRect; |
433 } | 484 } |
434 } | 485 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 if (shouldPaintOverlayScrollbars) | 569 if (shouldPaintOverlayScrollbars) |
519 paintOverflowControlsForFragments(layerFragments, context, | 570 paintOverflowControlsForFragments(layerFragments, context, |
520 localPaintingInfo, paintFlags); | 571 localPaintingInfo, paintFlags); |
521 } // FilterPainter block | 572 } // FilterPainter block |
522 | 573 |
523 bool shouldPaintMask = | 574 bool shouldPaintMask = |
524 (paintFlags & PaintLayerPaintingCompositingMaskPhase) && | 575 (paintFlags & PaintLayerPaintingCompositingMaskPhase) && |
525 shouldPaintContent && m_paintLayer.layoutObject()->hasMask() && | 576 shouldPaintContent && m_paintLayer.layoutObject()->hasMask() && |
526 !selectionOnly; | 577 !selectionOnly; |
527 bool shouldPaintClippingMask = | 578 bool shouldPaintClippingMask = |
528 (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && | 579 (paintFlags & (PaintLayerPaintingChildClippingMaskPhase | |
| 580 PaintLayerPaintingAncestorClippingMaskPhase)) && |
529 shouldPaintContent && !selectionOnly; | 581 shouldPaintContent && !selectionOnly; |
530 | 582 |
531 if (shouldPaintMask) | 583 if (shouldPaintMask) |
532 paintMaskForFragments(layerFragments, context, localPaintingInfo, | 584 paintMaskForFragments(layerFragments, context, localPaintingInfo, |
533 paintFlags); | 585 paintFlags); |
534 if (shouldPaintClippingMask) { | 586 if (shouldPaintClippingMask) { |
535 // Paint the border radius mask for the fragments. | 587 // Paint the border radius mask for the fragments. |
536 paintChildClippingMaskForFragments(layerFragments, context, | 588 paintChildClippingMaskForFragments(layerFragments, context, |
537 localPaintingInfo, paintFlags); | 589 localPaintingInfo, paintFlags); |
538 } | 590 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // its parent. | 649 // its parent. |
598 PaintLayer* parentLayer = m_paintLayer.parent(); | 650 PaintLayer* parentLayer = m_paintLayer.parent(); |
599 | 651 |
600 LayoutObject* object = m_paintLayer.layoutObject(); | 652 LayoutObject* object = m_paintLayer.layoutObject(); |
601 LayoutView* view = object->view(); | 653 LayoutView* view = object->view(); |
602 bool isFixedPosObjectInPagedMedia = | 654 bool isFixedPosObjectInPagedMedia = |
603 object->style()->position() == FixedPosition && | 655 object->style()->position() == FixedPosition && |
604 object->container() == view && view->pageLogicalHeight(); | 656 object->container() == view && view->pageLogicalHeight(); |
605 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); | 657 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); |
606 PaintLayerFragments fragments; | 658 PaintLayerFragments fragments; |
| 659 |
607 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position | 660 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position |
608 // objects in paged media with vertical writing modes. | 661 // objects in paged media with vertical writing modes. |
609 if (isFixedPosObjectInPagedMedia && view->isHorizontalWritingMode()) { | 662 if (isFixedPosObjectInPagedMedia && view->isHorizontalWritingMode()) { |
610 // "For paged media, boxes with fixed positions are repeated on every page." | 663 // "For paged media, boxes with fixed positions are repeated on every page." |
611 // https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioni
ng | 664 // https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioni
ng |
612 unsigned pages = | 665 unsigned pages = |
613 ceilf(view->documentRect().height() / view->pageLogicalHeight()); | 666 ceilf(view->documentRect().height() / view->pageLogicalHeight()); |
614 LayoutPoint paginationOffset; | 667 LayoutPoint paginationOffset; |
615 | 668 |
616 // The fixed position object is offset from the top of the page, so remove | 669 // The fixed position object is offset from the top of the page, so remove |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 // handle clipping to self. | 934 // handle clipping to self. |
882 case PaintPhaseSelfOutlineOnly: | 935 case PaintPhaseSelfOutlineOnly: |
883 case PaintPhaseMask: // Mask painting will handle clipping to self. | 936 case PaintPhaseMask: // Mask painting will handle clipping to self. |
884 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; | 937 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; |
885 break; | 938 break; |
886 default: | 939 default: |
887 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; | 940 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; |
888 break; | 941 break; |
889 } | 942 } |
890 | 943 |
891 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, | 944 // When painting the clipping mask for a composited child, we pass |
892 clipRect, &paintingInfo, fragment.paginationOffset, | 945 // the clipping container object as the layoutObject to provide the clip. |
893 paintFlags, clippingRule); | 946 // The recorder assumes the fragment is positioned in that objects's |
| 947 // layer coordinates, so we also convert that. |
| 948 if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) { |
| 949 clipRecorder.emplace( |
| 950 context, *(toLayoutBoxModelObject(m_paintLayer.clippingContainer())), |
| 951 clipType, clipRect, &paintingInfo, |
| 952 fragmentOffsetForAncestorClipMask(fragment.paginationOffset), |
| 953 paintFlags, clippingRule); |
| 954 } else { |
| 955 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, |
| 956 clipRect, &paintingInfo, fragment.paginationOffset, |
| 957 paintFlags, clippingRule); |
| 958 } |
894 } | 959 } |
895 | 960 |
896 LayoutRect newCullRect(clipRect.rect()); | 961 LayoutRect newCullRect(clipRect.rect()); |
897 Optional<ScrollRecorder> scrollRecorder; | 962 Optional<ScrollRecorder> scrollRecorder; |
898 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); | 963 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); |
899 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 964 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
900 const auto* objectPaintProperties = | 965 const auto* objectPaintProperties = |
901 m_paintLayer.layoutObject()->paintProperties(); | 966 m_paintLayer.layoutObject()->paintProperties(); |
902 DCHECK(objectPaintProperties && | 967 DCHECK(objectPaintProperties && |
903 objectPaintProperties->localBorderBoxProperties()); | 968 objectPaintProperties->localBorderBoxProperties()); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 | 1167 |
1103 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, | 1168 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, |
1104 LayoutRect(enclosingIntRect(damageRect)), | 1169 LayoutRect(enclosingIntRect(damageRect)), |
1105 paintFlags, LayoutSize()); | 1170 paintFlags, LayoutSize()); |
1106 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 1171 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
1107 | 1172 |
1108 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 1173 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
1109 } | 1174 } |
1110 | 1175 |
1111 } // namespace blink | 1176 } // namespace blink |
OLD | NEW |