| 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/LayoutInline.h" | 8 #include "core/layout/LayoutInline.h" |
| 9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
| 10 #include "core/paint/ClipPathClipper.h" | 10 #include "core/paint/ClipPathClipper.h" |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 | 143 |
| 144 // When in FOUC-avoidance mode, don't cache any subsequences, to avoid havin
g | 144 // When in FOUC-avoidance mode, don't cache any subsequences, to avoid havin
g |
| 145 // to invalidate all of them when leaving this mode. There is an early-out i
n BlockPainter::paintContents that may result | 145 // to invalidate all of them when leaving this mode. There is an early-out i
n BlockPainter::paintContents that may result |
| 146 // in nothing getting painted in thos mode, in addition to early-out logic i
n PaintLayerPainter. | 146 // in nothing getting painted in thos mode, in addition to early-out logic i
n PaintLayerPainter. |
| 147 if (paintLayer.layoutObject()->document().didLayoutWithPendingStylesheets()) | 147 if (paintLayer.layoutObject()->document().didLayoutWithPendingStylesheets()) |
| 148 return false; | 148 return false; |
| 149 | 149 |
| 150 return true; | 150 return true; |
| 151 } | 151 } |
| 152 | 152 |
| 153 static bool shouldRepaintSubsequence(PaintLayer& paintLayer, const PaintLayerPai
ntingInfo& paintingInfo, ShouldRespectOverflowClipType respectOverflowClip, cons
t LayoutSize& subpixelAccumulation) | 153 static bool shouldRepaintSubsequence(PaintLayer& paintLayer, const PaintLayerPai
ntingInfo& paintingInfo, ShouldRespectOverflowClipType respectOverflowClip, cons
t LayoutSize& subpixelAccumulation, bool& shouldClearEmptyPaintPhaseFlags) |
| 154 { | 154 { |
| 155 bool needsRepaint = false; | 155 bool needsRepaint = false; |
| 156 | 156 |
| 157 // We should set shouldResetEmptyPaintPhaseFlags if some previously unpainte
d objects may begin |
| 158 // to be painted, causing a previously empty paint phase to become non-empty
. |
| 159 |
| 157 // Repaint subsequence if the layer is marked for needing repaint. | 160 // Repaint subsequence if the layer is marked for needing repaint. |
| 161 // We don't set needsResetEmptyPaintPhase here, but clear the empty paint ph
ase flags |
| 162 // in PaintLayer::setNeedsPaintPhaseXXX(), to ensure that we won't clear |
| 163 // previousPaintPhaseXXXEmpty flags when unrelated things changed which won'
t |
| 164 // cause the paint phases to become non-empty. |
| 158 if (paintLayer.needsRepaint()) | 165 if (paintLayer.needsRepaint()) |
| 159 needsRepaint = true; | 166 needsRepaint = true; |
| 160 | 167 |
| 161 // Repaint if layer's clip changes. | 168 // Repaint if layer's clip changes. |
| 162 ClipRects& clipRects = paintLayer.clipper().paintingClipRects(paintingInfo.r
ootLayer, respectOverflowClip, subpixelAccumulation); | 169 ClipRects& clipRects = paintLayer.clipper().paintingClipRects(paintingInfo.r
ootLayer, respectOverflowClip, subpixelAccumulation); |
| 163 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); | 170 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); |
| 164 if (!needsRepaint && &clipRects != previousClipRects && (!previousClipRects
|| clipRects != *previousClipRects)) | 171 if (&clipRects != previousClipRects && (!previousClipRects || clipRects != *
previousClipRects)) { |
| 165 needsRepaint = true; | 172 needsRepaint = true; |
| 173 shouldClearEmptyPaintPhaseFlags = true; |
| 174 } |
| 166 paintLayer.setPreviousPaintingClipRects(clipRects); | 175 paintLayer.setPreviousPaintingClipRects(clipRects); |
| 167 | 176 |
| 168 // Repaint if previously the layer might be clipped by paintDirtyRect and pa
intDirtyRect changes. | 177 // Repaint if previously the layer might be clipped by paintDirtyRect and pa
intDirtyRect changes. |
| 169 if (!needsRepaint && paintLayer.previousPaintResult() == PaintLayerPainter::
MayBeClippedByPaintDirtyRect && paintLayer.previousPaintDirtyRect() != paintingI
nfo.paintDirtyRect) | 178 if (paintLayer.previousPaintResult() == PaintLayerPainter::MayBeClippedByPai
ntDirtyRect && paintLayer.previousPaintDirtyRect() != paintingInfo.paintDirtyRec
t) { |
| 170 needsRepaint = true; | 179 needsRepaint = true; |
| 180 shouldClearEmptyPaintPhaseFlags = true; |
| 181 } |
| 171 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); | 182 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); |
| 172 | 183 |
| 173 // Repaint if scroll offset accumulation changes. | 184 // Repaint if scroll offset accumulation changes. |
| 174 if (!needsRepaint && paintingInfo.scrollOffsetAccumulation != paintLayer.pre
viousScrollOffsetAccumulationForPainting()) | 185 if (paintingInfo.scrollOffsetAccumulation != paintLayer.previousScrollOffset
AccumulationForPainting()) { |
| 175 needsRepaint = true; | 186 needsRepaint = true; |
| 187 shouldClearEmptyPaintPhaseFlags = true; |
| 188 } |
| 176 paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfo.scrol
lOffsetAccumulation); | 189 paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfo.scrol
lOffsetAccumulation); |
| 177 | 190 |
| 178 return needsRepaint; | 191 return needsRepaint; |
| 179 } | 192 } |
| 180 | 193 |
| 181 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
text& context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags pa
intFlags, FragmentPolicy fragmentPolicy) | 194 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
text& context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags pa
intFlags, FragmentPolicy fragmentPolicy) |
| 182 { | 195 { |
| 183 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay
erDescendant()); | 196 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay
erDescendant()); |
| 184 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); | 197 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); |
| 185 | 198 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 209 if (m_paintLayer.layoutObject()->view()->frame() && m_paintLayer.layoutObjec
t()->view()->frame()->shouldThrottleRendering()) | 222 if (m_paintLayer.layoutObject()->view()->frame() && m_paintLayer.layoutObjec
t()->view()->frame()->shouldThrottleRendering()) |
| 210 return result; | 223 return result; |
| 211 | 224 |
| 212 // Ensure our lists are up to date. | 225 // Ensure our lists are up to date. |
| 213 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); | 226 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); |
| 214 | 227 |
| 215 LayoutSize subpixelAccumulation = m_paintLayer.compositingState() == PaintsI
ntoOwnBacking ? m_paintLayer.subpixelAccumulation() : paintingInfoArg.subPixelAc
cumulation; | 228 LayoutSize subpixelAccumulation = m_paintLayer.compositingState() == PaintsI
ntoOwnBacking ? m_paintLayer.subpixelAccumulation() : paintingInfoArg.subPixelAc
cumulation; |
| 216 ShouldRespectOverflowClipType respectOverflowClip = shouldRespectOverflowCli
p(paintFlags, m_paintLayer.layoutObject()); | 229 ShouldRespectOverflowClipType respectOverflowClip = shouldRespectOverflowCli
p(paintFlags, m_paintLayer.layoutObject()); |
| 217 | 230 |
| 218 Optional<SubsequenceRecorder> subsequenceRecorder; | 231 Optional<SubsequenceRecorder> subsequenceRecorder; |
| 232 bool shouldClearEmptyPaintPhaseFlags = false; |
| 219 if (shouldCreateSubsequence(m_paintLayer, context, paintingInfoArg, paintFla
gs)) { | 233 if (shouldCreateSubsequence(m_paintLayer, context, paintingInfoArg, paintFla
gs)) { |
| 220 if (!shouldRepaintSubsequence(m_paintLayer, paintingInfoArg, respectOver
flowClip, subpixelAccumulation) | 234 if (!shouldRepaintSubsequence(m_paintLayer, paintingInfoArg, respectOver
flowClip, subpixelAccumulation, shouldClearEmptyPaintPhaseFlags) |
| 221 && SubsequenceRecorder::useCachedSubsequenceIfPossible(context, m_pa
intLayer)) | 235 && SubsequenceRecorder::useCachedSubsequenceIfPossible(context, m_pa
intLayer)) |
| 222 return result; | 236 return result; |
| 223 subsequenceRecorder.emplace(context, m_paintLayer); | 237 subsequenceRecorder.emplace(context, m_paintLayer); |
| 238 } else { |
| 239 shouldClearEmptyPaintPhaseFlags = true; |
| 240 } |
| 241 |
| 242 if (shouldClearEmptyPaintPhaseFlags) { |
| 243 m_paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); |
| 244 m_paintLayer.setPreviousPaintPhaseFloatEmpty(false); |
| 245 m_paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false)
; |
| 224 } | 246 } |
| 225 | 247 |
| 226 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; | 248 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; |
| 227 | 249 |
| 228 LayoutPoint offsetFromRoot; | 250 LayoutPoint offsetFromRoot; |
| 229 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); | 251 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); |
| 230 offsetFromRoot.move(subpixelAccumulation); | 252 offsetFromRoot.move(subpixelAccumulation); |
| 231 | 253 |
| 232 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); | 254 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); |
| 233 if (!paintingInfo.paintDirtyRect.contains(bounds)) | 255 if (!paintingInfo.paintDirtyRect.contains(bounds)) |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { | 701 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { |
| 680 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), DisplayItem:
:kClipLayerForeground, layerFragments[0].foregroundRect, &localPaintingInfo, lay
erFragments[0].paginationOffset, paintFlags); | 702 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), DisplayItem:
:kClipLayerForeground, layerFragments[0].foregroundRect, &localPaintingInfo, lay
erFragments[0].paginationOffset, paintFlags); |
| 681 clipState = HasClipped; | 703 clipState = HasClipped; |
| 682 } | 704 } |
| 683 | 705 |
| 684 // We have to loop through every fragment multiple times, since we have to i
ssue paint invalidations in each specific phase in order for | 706 // We have to loop through every fragment multiple times, since we have to i
ssue paint invalidations in each specific phase in order for |
| 685 // interleaving of the fragments to work properly. | 707 // interleaving of the fragments to work properly. |
| 686 if (selectionOnly) { | 708 if (selectionOnly) { |
| 687 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments
, context, localPaintingInfo, paintFlags, clipState); | 709 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments
, context, localPaintingInfo, paintFlags, clipState); |
| 688 } else { | 710 } else { |
| 689 if (m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) | 711 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnable
d() || m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) { |
| 712 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); |
| 690 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantBlockBackgr
oundsOnly, layerFragments, context, localPaintingInfo, paintFlags, clipState); | 713 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantBlockBackgr
oundsOnly, layerFragments, context, localPaintingInfo, paintFlags, clipState); |
| 691 if (m_paintLayer.needsPaintPhaseFloat()) | 714 // Don't set the empty flag if we are not painting the whole backgro
und. |
| 715 if (!(paintFlags & PaintLayerPaintingSkipRootBackground)) { |
| 716 bool phaseIsEmpty = context.getPaintController().newDisplayItemL
ist().size() == sizeBefore; |
| 717 DCHECK(phaseIsEmpty || m_paintLayer.needsPaintPhaseDescendantBlo
ckBackgrounds()); |
| 718 m_paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpt
y(phaseIsEmpty); |
| 719 } |
| 720 } |
| 721 |
| 722 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnable
d() || m_paintLayer.needsPaintPhaseFloat()) { |
| 723 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); |
| 692 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments
, context, localPaintingInfo, paintFlags, clipState); | 724 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments
, context, localPaintingInfo, paintFlags, clipState); |
| 725 bool phaseIsEmpty = context.getPaintController().newDisplayItemList(
).size() == sizeBefore; |
| 726 DCHECK(phaseIsEmpty || m_paintLayer.needsPaintPhaseFloat()); |
| 727 m_paintLayer.setPreviousPaintPhaseFloatEmpty(phaseIsEmpty); |
| 728 } |
| 729 |
| 693 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragment
s, context, localPaintingInfo, paintFlags, clipState); | 730 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragment
s, context, localPaintingInfo, paintFlags, clipState); |
| 694 if (m_paintLayer.needsPaintPhaseDescendantOutlines()) | 731 |
| 732 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnable
d() || m_paintLayer.needsPaintPhaseDescendantOutlines()) { |
| 733 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); |
| 695 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantOutlinesOnl
y, layerFragments, context, localPaintingInfo, paintFlags, clipState); | 734 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantOutlinesOnl
y, layerFragments, context, localPaintingInfo, paintFlags, clipState); |
| 735 bool phaseIsEmpty = context.getPaintController().newDisplayItemList(
).size() == sizeBefore; |
| 736 DCHECK(phaseIsEmpty || m_paintLayer.needsPaintPhaseDescendantOutline
s()); |
| 737 m_paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(phaseIsEmp
ty); |
| 738 } |
| 696 } | 739 } |
| 697 } | 740 } |
| 698 | 741 |
| 699 void PaintLayerPainter::paintForegroundForFragmentsWithPhase(PaintPhase phase, | 742 void PaintLayerPainter::paintForegroundForFragmentsWithPhase(PaintPhase phase, |
| 700 const PaintLayerFragments& layerFragments, GraphicsContext& context, | 743 const PaintLayerFragments& layerFragments, GraphicsContext& context, |
| 701 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags,
ClipState clipState) | 744 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags,
ClipState clipState) |
| 702 { | 745 { |
| 703 Optional<DisplayItemCacheSkipper> cacheSkipper; | 746 Optional<DisplayItemCacheSkipper> cacheSkipper; |
| 704 if (layerFragments.size() > 1) | 747 if (layerFragments.size() > 1) |
| 705 cacheSkipper.emplace(context); | 748 cacheSkipper.emplace(context); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 793 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
| 751 return; | 794 return; |
| 752 | 795 |
| 753 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); | 796 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); |
| 754 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 797 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
| 755 | 798 |
| 756 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 799 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
| 757 } | 800 } |
| 758 | 801 |
| 759 } // namespace blink | 802 } // namespace blink |
| OLD | NEW |