| 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/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/layout/ClipPathOperation.h" | 9 #include "core/layout/ClipPathOperation.h" |
| 10 #include "core/layout/LayoutBlock.h" | 10 #include "core/layout/LayoutBlock.h" |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 if (!paintLayer.stackingNode()->isStackingContext()) | 205 if (!paintLayer.stackingNode()->isStackingContext()) |
| 206 return false; | 206 return false; |
| 207 | 207 |
| 208 // The layer doesn't have children. Subsequence caching is not worth because
normally the actual painting will be cheap. | 208 // The layer doesn't have children. Subsequence caching is not worth because
normally the actual painting will be cheap. |
| 209 if (!PaintLayerStackingNodeIterator(*paintLayer.stackingNode(), AllChildren)
.next()) | 209 if (!PaintLayerStackingNodeIterator(*paintLayer.stackingNode(), AllChildren)
.next()) |
| 210 return false; | 210 return false; |
| 211 | 211 |
| 212 return true; | 212 return true; |
| 213 } | 213 } |
| 214 | 214 |
| 215 static bool shouldRepaintSubsequence(PaintLayer& paintLayer, const PaintLayerPai
ntingInfo& paintingInfo, ShouldRespectOverflowClipType respectOverflowClip, cons
t LayoutSize& subpixelAccumulation, bool& shouldClearEmptyPaintPhaseFlags) | 215 static bool shouldRepaintSubsequence(PaintLayer& paintLayer, const PaintLayerPai
ntingInfo& paintingInfo, ShouldRespectOverflowClipType respectOverflowClip, cons
t LayoutSize& subpixelAccumulation) |
| 216 { | 216 { |
| 217 bool needsRepaint = false; | 217 bool needsRepaint = false; |
| 218 | 218 |
| 219 // We should set shouldResetEmptyPaintPhaseFlags if some previously unpainte
d objects may begin | |
| 220 // to be painted, causing a previously empty paint phase to become non-empty
. | |
| 221 | |
| 222 // Repaint subsequence if the layer is marked for needing repaint. | 219 // Repaint subsequence if the layer is marked for needing repaint. |
| 223 // We don't set needsResetEmptyPaintPhase here, but clear the empty paint ph
ase flags | |
| 224 // in PaintLayer::setNeedsPaintPhaseXXX(), to ensure that we won't clear | |
| 225 // previousPaintPhaseXXXEmpty flags when unrelated things changed which won'
t | |
| 226 // cause the paint phases to become non-empty. | |
| 227 if (paintLayer.needsRepaint()) | 220 if (paintLayer.needsRepaint()) |
| 228 needsRepaint = true; | 221 needsRepaint = true; |
| 229 | 222 |
| 230 // Repaint if layer's clip changes. | 223 // Repaint if layer's clip changes. |
| 231 ClipRects& clipRects = paintLayer.clipper().paintingClipRects(paintingInfo.r
ootLayer, respectOverflowClip, subpixelAccumulation); | 224 ClipRects& clipRects = paintLayer.clipper().paintingClipRects(paintingInfo.r
ootLayer, respectOverflowClip, subpixelAccumulation); |
| 232 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); | 225 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); |
| 233 if (&clipRects != previousClipRects && (!previousClipRects || clipRects != *
previousClipRects)) { | 226 if (!needsRepaint && &clipRects != previousClipRects && (!previousClipRects
|| clipRects != *previousClipRects)) |
| 234 needsRepaint = true; | 227 needsRepaint = true; |
| 235 shouldClearEmptyPaintPhaseFlags = true; | |
| 236 } | |
| 237 paintLayer.setPreviousPaintingClipRects(clipRects); | 228 paintLayer.setPreviousPaintingClipRects(clipRects); |
| 238 | 229 |
| 239 // Repaint if previously the layer might be clipped by paintDirtyRect and pa
intDirtyRect changes. | 230 // Repaint if previously the layer might be clipped by paintDirtyRect and pa
intDirtyRect changes. |
| 240 if (paintLayer.previousPaintResult() == PaintLayerPainter::MayBeClippedByPai
ntDirtyRect && paintLayer.previousPaintDirtyRect() != paintingInfo.paintDirtyRec
t) { | 231 if (!needsRepaint && paintLayer.previousPaintResult() == PaintLayerPainter::
MayBeClippedByPaintDirtyRect && paintLayer.previousPaintDirtyRect() != paintingI
nfo.paintDirtyRect) |
| 241 needsRepaint = true; | 232 needsRepaint = true; |
| 242 shouldClearEmptyPaintPhaseFlags = true; | |
| 243 } | |
| 244 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); | 233 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); |
| 245 | 234 |
| 246 // Repaint if scroll offset accumulation changes. | 235 // Repaint if scroll offset accumulation changes. |
| 247 if (paintingInfo.scrollOffsetAccumulation != paintLayer.previousScrollOffset
AccumulationForPainting()) { | 236 if (!needsRepaint && paintingInfo.scrollOffsetAccumulation != paintLayer.pre
viousScrollOffsetAccumulationForPainting()) |
| 248 needsRepaint = true; | 237 needsRepaint = true; |
| 249 shouldClearEmptyPaintPhaseFlags = true; | |
| 250 } | |
| 251 paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfo.scrol
lOffsetAccumulation); | 238 paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfo.scrol
lOffsetAccumulation); |
| 252 | 239 |
| 253 return needsRepaint; | 240 return needsRepaint; |
| 254 } | 241 } |
| 255 | 242 |
| 256 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
text& context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags pa
intFlags, FragmentPolicy fragmentPolicy) | 243 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
text& context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags pa
intFlags, FragmentPolicy fragmentPolicy) |
| 257 { | 244 { |
| 258 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay
erDescendant()); | 245 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay
erDescendant()); |
| 259 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); | 246 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); |
| 260 | 247 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 284 if (m_paintLayer.layoutObject()->isLayoutView() && toLayoutView(m_paintLayer
.layoutObject())->frameView()->shouldThrottleRendering()) | 271 if (m_paintLayer.layoutObject()->isLayoutView() && toLayoutView(m_paintLayer
.layoutObject())->frameView()->shouldThrottleRendering()) |
| 285 return result; | 272 return result; |
| 286 | 273 |
| 287 // Ensure our lists are up-to-date. | 274 // Ensure our lists are up-to-date. |
| 288 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); | 275 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); |
| 289 | 276 |
| 290 LayoutSize subpixelAccumulation = m_paintLayer.compositingState() == PaintsI
ntoOwnBacking ? m_paintLayer.subpixelAccumulation() : paintingInfoArg.subPixelAc
cumulation; | 277 LayoutSize subpixelAccumulation = m_paintLayer.compositingState() == PaintsI
ntoOwnBacking ? m_paintLayer.subpixelAccumulation() : paintingInfoArg.subPixelAc
cumulation; |
| 291 ShouldRespectOverflowClipType respectOverflowClip = shouldRespectOverflowCli
p(paintFlags, m_paintLayer.layoutObject()); | 278 ShouldRespectOverflowClipType respectOverflowClip = shouldRespectOverflowCli
p(paintFlags, m_paintLayer.layoutObject()); |
| 292 | 279 |
| 293 Optional<SubsequenceRecorder> subsequenceRecorder; | 280 Optional<SubsequenceRecorder> subsequenceRecorder; |
| 294 bool shouldClearEmptyPaintPhaseFlags = false; | |
| 295 if (shouldCreateSubsequence(m_paintLayer, context, paintingInfoArg, paintFla
gs)) { | 281 if (shouldCreateSubsequence(m_paintLayer, context, paintingInfoArg, paintFla
gs)) { |
| 296 if (!shouldRepaintSubsequence(m_paintLayer, paintingInfoArg, respectOver
flowClip, subpixelAccumulation, shouldClearEmptyPaintPhaseFlags) | 282 if (!shouldRepaintSubsequence(m_paintLayer, paintingInfoArg, respectOver
flowClip, subpixelAccumulation) |
| 297 && SubsequenceRecorder::useCachedSubsequenceIfPossible(context, m_pa
intLayer)) | 283 && SubsequenceRecorder::useCachedSubsequenceIfPossible(context, m_pa
intLayer)) |
| 298 return result; | 284 return result; |
| 299 subsequenceRecorder.emplace(context, m_paintLayer); | 285 subsequenceRecorder.emplace(context, m_paintLayer); |
| 300 } else { | |
| 301 shouldClearEmptyPaintPhaseFlags = true; | |
| 302 } | |
| 303 | |
| 304 if (shouldClearEmptyPaintPhaseFlags) { | |
| 305 m_paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); | |
| 306 m_paintLayer.setPreviousPaintPhaseFloatEmpty(false); | |
| 307 m_paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false)
; | |
| 308 } | 286 } |
| 309 | 287 |
| 310 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; | 288 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; |
| 311 | 289 |
| 312 LayoutPoint offsetFromRoot; | 290 LayoutPoint offsetFromRoot; |
| 313 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); | 291 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); |
| 314 offsetFromRoot.move(subpixelAccumulation); | 292 offsetFromRoot.move(subpixelAccumulation); |
| 315 | 293 |
| 316 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); | 294 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); |
| 317 if (!paintingInfo.paintDirtyRect.contains(bounds)) | 295 if (!paintingInfo.paintDirtyRect.contains(bounds)) |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { | 692 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { |
| 715 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), DisplayItem:
:ClipLayerForeground, layerFragments[0].foregroundRect, &localPaintingInfo, laye
rFragments[0].paginationOffset, paintFlags); | 693 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), DisplayItem:
:ClipLayerForeground, layerFragments[0].foregroundRect, &localPaintingInfo, laye
rFragments[0].paginationOffset, paintFlags); |
| 716 clipState = HasClipped; | 694 clipState = HasClipped; |
| 717 } | 695 } |
| 718 | 696 |
| 719 // We have to loop through every fragment multiple times, since we have to i
ssue paint invalidations in each specific phase in order for | 697 // We have to loop through every fragment multiple times, since we have to i
ssue paint invalidations in each specific phase in order for |
| 720 // interleaving of the fragments to work properly. | 698 // interleaving of the fragments to work properly. |
| 721 if (selectionOnly) { | 699 if (selectionOnly) { |
| 722 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments
, context, localPaintingInfo, paintFlags, clipState); | 700 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments
, context, localPaintingInfo, paintFlags, clipState); |
| 723 } else { | 701 } else { |
| 724 if (m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) { | 702 if (m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) |
| 725 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); | |
| 726 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantBlockBackgr
oundsOnly, layerFragments, context, localPaintingInfo, paintFlags, clipState); | 703 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantBlockBackgr
oundsOnly, layerFragments, context, localPaintingInfo, paintFlags, clipState); |
| 727 m_paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(co
ntext.getPaintController().newDisplayItemList().size() == sizeBefore); | 704 if (m_paintLayer.needsPaintPhaseFloat()) |
| 728 } | |
| 729 if (m_paintLayer.needsPaintPhaseFloat()) { | |
| 730 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); | |
| 731 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments
, context, localPaintingInfo, paintFlags, clipState); | 705 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments
, context, localPaintingInfo, paintFlags, clipState); |
| 732 m_paintLayer.setPreviousPaintPhaseFloatEmpty(context.getPaintControl
ler().newDisplayItemList().size() == sizeBefore); | |
| 733 } | |
| 734 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragment
s, context, localPaintingInfo, paintFlags, clipState); | 706 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragment
s, context, localPaintingInfo, paintFlags, clipState); |
| 735 if (m_paintLayer.needsPaintPhaseDescendantOutlines()) { | 707 if (m_paintLayer.needsPaintPhaseDescendantOutlines()) |
| 736 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); | |
| 737 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantOutlinesOnl
y, layerFragments, context, localPaintingInfo, paintFlags, clipState); | 708 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantOutlinesOnl
y, layerFragments, context, localPaintingInfo, paintFlags, clipState); |
| 738 m_paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(context.ge
tPaintController().newDisplayItemList().size() == sizeBefore); | |
| 739 } | |
| 740 } | 709 } |
| 741 } | 710 } |
| 742 | 711 |
| 743 void PaintLayerPainter::paintForegroundForFragmentsWithPhase(PaintPhase phase, | 712 void PaintLayerPainter::paintForegroundForFragmentsWithPhase(PaintPhase phase, |
| 744 const PaintLayerFragments& layerFragments, GraphicsContext& context, | 713 const PaintLayerFragments& layerFragments, GraphicsContext& context, |
| 745 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags,
ClipState clipState) | 714 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags,
ClipState clipState) |
| 746 { | 715 { |
| 747 bool needsScope = layerFragments.size() > 1; | 716 bool needsScope = layerFragments.size() > 1; |
| 748 for (auto& fragment : layerFragments) { | 717 for (auto& fragment : layerFragments) { |
| 749 if (!fragment.foregroundRect.isEmpty()) { | 718 if (!fragment.foregroundRect.isEmpty()) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 767 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
| 799 return; | 768 return; |
| 800 | 769 |
| 801 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); | 770 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); |
| 802 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 771 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
| 803 | 772 |
| 804 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 773 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
| 805 } | 774 } |
| 806 | 775 |
| 807 } // namespace blink | 776 } // namespace blink |
| OLD | NEW |