| 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) | 215 static bool shouldRepaintSubsequence(PaintLayer& paintLayer, const PaintLayerPai
ntingInfo& paintingInfo, ShouldRespectOverflowClipType respectOverflowClip, cons
t LayoutSize& subpixelAccumulation, bool& shouldClearEmptyPaintPhaseFlags) |
| 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 |
| 219 // Repaint subsequence if the layer is marked for needing repaint. | 222 // 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. |
| 220 if (paintLayer.needsRepaint()) | 227 if (paintLayer.needsRepaint()) |
| 221 needsRepaint = true; | 228 needsRepaint = true; |
| 222 | 229 |
| 223 // Repaint if layer's clip changes. | 230 // Repaint if layer's clip changes. |
| 224 ClipRects& clipRects = paintLayer.clipper().paintingClipRects(paintingInfo.r
ootLayer, respectOverflowClip, subpixelAccumulation); | 231 ClipRects& clipRects = paintLayer.clipper().paintingClipRects(paintingInfo.r
ootLayer, respectOverflowClip, subpixelAccumulation); |
| 225 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); | 232 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); |
| 226 if (!needsRepaint && &clipRects != previousClipRects && (!previousClipRects
|| clipRects != *previousClipRects)) | 233 if (&clipRects != previousClipRects && (!previousClipRects || clipRects != *
previousClipRects)) { |
| 227 needsRepaint = true; | 234 needsRepaint = true; |
| 235 shouldClearEmptyPaintPhaseFlags = true; |
| 236 } |
| 228 paintLayer.setPreviousPaintingClipRects(clipRects); | 237 paintLayer.setPreviousPaintingClipRects(clipRects); |
| 229 | 238 |
| 230 // Repaint if previously the layer might be clipped by paintDirtyRect and pa
intDirtyRect changes. | 239 // Repaint if previously the layer might be clipped by paintDirtyRect and pa
intDirtyRect changes. |
| 231 if (!needsRepaint && paintLayer.previousPaintResult() == PaintLayerPainter::
MayBeClippedByPaintDirtyRect && paintLayer.previousPaintDirtyRect() != paintingI
nfo.paintDirtyRect) | 240 if (paintLayer.previousPaintResult() == PaintLayerPainter::MayBeClippedByPai
ntDirtyRect && paintLayer.previousPaintDirtyRect() != paintingInfo.paintDirtyRec
t) { |
| 232 needsRepaint = true; | 241 needsRepaint = true; |
| 242 shouldClearEmptyPaintPhaseFlags = true; |
| 243 } |
| 233 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); | 244 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); |
| 234 | 245 |
| 235 // Repaint if scroll offset accumulation changes. | 246 // Repaint if scroll offset accumulation changes. |
| 236 if (!needsRepaint && paintingInfo.scrollOffsetAccumulation != paintLayer.pre
viousScrollOffsetAccumulationForPainting()) | 247 if (paintingInfo.scrollOffsetAccumulation != paintLayer.previousScrollOffset
AccumulationForPainting()) { |
| 237 needsRepaint = true; | 248 needsRepaint = true; |
| 249 shouldClearEmptyPaintPhaseFlags = true; |
| 250 } |
| 238 paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfo.scrol
lOffsetAccumulation); | 251 paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfo.scrol
lOffsetAccumulation); |
| 239 | 252 |
| 240 return needsRepaint; | 253 return needsRepaint; |
| 241 } | 254 } |
| 242 | 255 |
| 243 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
text& context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags pa
intFlags, FragmentPolicy fragmentPolicy) | 256 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
text& context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags pa
intFlags, FragmentPolicy fragmentPolicy) |
| 244 { | 257 { |
| 245 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay
erDescendant()); | 258 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay
erDescendant()); |
| 246 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); | 259 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); |
| 247 | 260 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 271 if (m_paintLayer.layoutObject()->isLayoutView() && toLayoutView(m_paintLayer
.layoutObject())->frameView()->shouldThrottleRendering()) | 284 if (m_paintLayer.layoutObject()->isLayoutView() && toLayoutView(m_paintLayer
.layoutObject())->frameView()->shouldThrottleRendering()) |
| 272 return result; | 285 return result; |
| 273 | 286 |
| 274 // Ensure our lists are up-to-date. | 287 // Ensure our lists are up-to-date. |
| 275 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); | 288 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); |
| 276 | 289 |
| 277 LayoutSize subpixelAccumulation = m_paintLayer.compositingState() == PaintsI
ntoOwnBacking ? m_paintLayer.subpixelAccumulation() : paintingInfoArg.subPixelAc
cumulation; | 290 LayoutSize subpixelAccumulation = m_paintLayer.compositingState() == PaintsI
ntoOwnBacking ? m_paintLayer.subpixelAccumulation() : paintingInfoArg.subPixelAc
cumulation; |
| 278 ShouldRespectOverflowClipType respectOverflowClip = shouldRespectOverflowCli
p(paintFlags, m_paintLayer.layoutObject()); | 291 ShouldRespectOverflowClipType respectOverflowClip = shouldRespectOverflowCli
p(paintFlags, m_paintLayer.layoutObject()); |
| 279 | 292 |
| 280 Optional<SubsequenceRecorder> subsequenceRecorder; | 293 Optional<SubsequenceRecorder> subsequenceRecorder; |
| 294 bool shouldClearEmptyPaintPhaseFlags = false; |
| 281 if (shouldCreateSubsequence(m_paintLayer, context, paintingInfoArg, paintFla
gs)) { | 295 if (shouldCreateSubsequence(m_paintLayer, context, paintingInfoArg, paintFla
gs)) { |
| 282 if (!shouldRepaintSubsequence(m_paintLayer, paintingInfoArg, respectOver
flowClip, subpixelAccumulation) | 296 if (!shouldRepaintSubsequence(m_paintLayer, paintingInfoArg, respectOver
flowClip, subpixelAccumulation, shouldClearEmptyPaintPhaseFlags) |
| 283 && SubsequenceRecorder::useCachedSubsequenceIfPossible(context, m_pa
intLayer)) | 297 && SubsequenceRecorder::useCachedSubsequenceIfPossible(context, m_pa
intLayer)) |
| 284 return result; | 298 return result; |
| 285 subsequenceRecorder.emplace(context, m_paintLayer); | 299 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)
; |
| 286 } | 308 } |
| 287 | 309 |
| 288 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; | 310 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; |
| 289 | 311 |
| 290 LayoutPoint offsetFromRoot; | 312 LayoutPoint offsetFromRoot; |
| 291 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); | 313 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); |
| 292 offsetFromRoot.move(subpixelAccumulation); | 314 offsetFromRoot.move(subpixelAccumulation); |
| 293 | 315 |
| 294 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); | 316 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); |
| 295 if (!paintingInfo.paintDirtyRect.contains(bounds)) | 317 if (!paintingInfo.paintDirtyRect.contains(bounds)) |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { | 714 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { |
| 693 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), DisplayItem:
:ClipLayerForeground, layerFragments[0].foregroundRect, &localPaintingInfo, laye
rFragments[0].paginationOffset, paintFlags); | 715 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), DisplayItem:
:ClipLayerForeground, layerFragments[0].foregroundRect, &localPaintingInfo, laye
rFragments[0].paginationOffset, paintFlags); |
| 694 clipState = HasClipped; | 716 clipState = HasClipped; |
| 695 } | 717 } |
| 696 | 718 |
| 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 | 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 |
| 698 // interleaving of the fragments to work properly. | 720 // interleaving of the fragments to work properly. |
| 699 if (selectionOnly) { | 721 if (selectionOnly) { |
| 700 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments
, context, localPaintingInfo, paintFlags, clipState); | 722 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments
, context, localPaintingInfo, paintFlags, clipState); |
| 701 } else { | 723 } else { |
| 702 if (m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) | 724 if (m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) { |
| 725 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); |
| 703 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantBlockBackgr
oundsOnly, layerFragments, context, localPaintingInfo, paintFlags, clipState); | 726 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantBlockBackgr
oundsOnly, layerFragments, context, localPaintingInfo, paintFlags, clipState); |
| 704 if (m_paintLayer.needsPaintPhaseFloat()) | 727 m_paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(co
ntext.getPaintController().newDisplayItemList().size() == sizeBefore); |
| 728 } |
| 729 if (m_paintLayer.needsPaintPhaseFloat()) { |
| 730 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); |
| 705 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments
, context, localPaintingInfo, paintFlags, clipState); | 731 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments
, context, localPaintingInfo, paintFlags, clipState); |
| 732 m_paintLayer.setPreviousPaintPhaseFloatEmpty(context.getPaintControl
ler().newDisplayItemList().size() == sizeBefore); |
| 733 } |
| 706 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragment
s, context, localPaintingInfo, paintFlags, clipState); | 734 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragment
s, context, localPaintingInfo, paintFlags, clipState); |
| 707 if (m_paintLayer.needsPaintPhaseDescendantOutlines()) | 735 if (m_paintLayer.needsPaintPhaseDescendantOutlines()) { |
| 736 size_t sizeBefore = context.getPaintController().newDisplayItemList(
).size(); |
| 708 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantOutlinesOnl
y, layerFragments, context, localPaintingInfo, paintFlags, clipState); | 737 paintForegroundForFragmentsWithPhase(PaintPhaseDescendantOutlinesOnl
y, layerFragments, context, localPaintingInfo, paintFlags, clipState); |
| 738 m_paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(context.ge
tPaintController().newDisplayItemList().size() == sizeBefore); |
| 739 } |
| 709 } | 740 } |
| 710 } | 741 } |
| 711 | 742 |
| 712 void PaintLayerPainter::paintForegroundForFragmentsWithPhase(PaintPhase phase, | 743 void PaintLayerPainter::paintForegroundForFragmentsWithPhase(PaintPhase phase, |
| 713 const PaintLayerFragments& layerFragments, GraphicsContext& context, | 744 const PaintLayerFragments& layerFragments, GraphicsContext& context, |
| 714 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags,
ClipState clipState) | 745 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags,
ClipState clipState) |
| 715 { | 746 { |
| 716 bool needsScope = layerFragments.size() > 1; | 747 bool needsScope = layerFragments.size() > 1; |
| 717 for (auto& fragment : layerFragments) { | 748 for (auto& fragment : layerFragments) { |
| 718 if (!fragment.foregroundRect.isEmpty()) { | 749 if (!fragment.foregroundRect.isEmpty()) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 798 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
| 768 return; | 799 return; |
| 769 | 800 |
| 770 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); | 801 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); |
| 771 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 802 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
| 772 | 803 |
| 773 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 804 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
| 774 } | 805 } |
| 775 | 806 |
| 776 } // namespace blink | 807 } // namespace blink |
| OLD | NEW |