| 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 "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/LayerPainter.h" | 6 #include "core/paint/LayerPainter.h" |
| 7 | 7 |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/page/Page.h" | 9 #include "core/page/Page.h" |
| 10 #include "core/rendering/ClipPathOperation.h" | 10 #include "core/rendering/ClipPathOperation.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 OwnPtr<ClipRecorder> clipRecorder; | 94 OwnPtr<ClipRecorder> clipRecorder; |
| 95 if (m_renderLayer.parent()) { | 95 if (m_renderLayer.parent()) { |
| 96 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlag
s & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, Ignore
OverlayScrollbarSize); | 96 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlag
s & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, Ignore
OverlayScrollbarSize); |
| 97 if (shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer())
== IgnoreOverflowClip) | 97 if (shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer())
== IgnoreOverflowClip) |
| 98 clipRectsContext.setIgnoreOverflowClip(); | 98 clipRectsContext.setIgnoreOverflowClip(); |
| 99 clipRect = m_renderLayer.clipper().backgroundClipRect(clipRectsConte
xt); | 99 clipRect = m_renderLayer.clipper().backgroundClipRect(clipRectsConte
xt); |
| 100 clipRect.intersect(paintingInfo.paintDirtyRect); | 100 clipRect.intersect(paintingInfo.paintDirtyRect); |
| 101 | 101 |
| 102 if (needsToClip(paintingInfo, clipRect)) { | 102 if (needsToClip(paintingInfo, clipRect)) { |
| 103 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(),
context, DisplayItem::ClipLayerParent, clipRect)); | 103 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(),
context, DisplayItem::ClipLayerParent, clipRect)); |
| 104 | 104 if (clipRect.hasRadius()) |
| 105 LayerPainter(*m_renderLayer.parent()).applyRoundedRectClips(pain
tingInfo, context, clipRect, paintFlags, *clipRecorder); | 105 LayerPainter(*m_renderLayer.parent()).applyRoundedRectClips(
paintingInfo, context, paintFlags, *clipRecorder); |
| 106 } | 106 } |
| 107 } | 107 } |
| 108 | 108 |
| 109 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); | 109 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); |
| 110 | 110 |
| 111 return; | 111 return; |
| 112 } | 112 } |
| 113 | 113 |
| 114 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); | 114 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); |
| 115 } | 115 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 beginTransparencyLayers(context, localPaintingInfo.rootLayer, pa
intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.
paintBehavior); | 288 beginTransparencyLayers(context, localPaintingInfo.rootLayer, pa
intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.
paintBehavior); |
| 289 } | 289 } |
| 290 | 290 |
| 291 // We'll handle clipping to the dirty rect before filter rasterizati
on. | 291 // We'll handle clipping to the dirty rect before filter rasterizati
on. |
| 292 // Filter processing will automatically expand the clip rect and the
offscreen to accommodate any filter outsets. | 292 // Filter processing will automatically expand the clip rect and the
offscreen to accommodate any filter outsets. |
| 293 // FIXME: It is incorrect to just clip to the damageRect here once m
ultiple fragments are involved. | 293 // FIXME: It is incorrect to just clip to the damageRect here once m
ultiple fragments are involved. |
| 294 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : la
yerFragments[0].backgroundRect; | 294 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : la
yerFragments[0].backgroundRect; |
| 295 | 295 |
| 296 if (needsToClip(localPaintingInfo, backgroundRect)) { | 296 if (needsToClip(localPaintingInfo, backgroundRect)) { |
| 297 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context
, DisplayItem::ClipLayerFilter, backgroundRect)); | 297 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context
, DisplayItem::ClipLayerFilter, backgroundRect)); |
| 298 applyRoundedRectClips(localPaintingInfo, context, backgroundRect
, paintFlags, *clipRecorder); | 298 if (backgroundRect.hasRadius()) |
| 299 applyRoundedRectClips(localPaintingInfo, context, paintFlags
, *clipRecorder); |
| 299 } | 300 } |
| 300 | 301 |
| 301 // Subsequent code should not clip to the dirty rect, since we've al
ready | 302 // Subsequent code should not clip to the dirty rect, since we've al
ready |
| 302 // done it above, and doing it later will defeat the outsets. | 303 // done it above, and doing it later will defeat the outsets. |
| 303 localPaintingInfo.clipToDirtyRect = false; | 304 localPaintingInfo.clipToDirtyRect = false; |
| 304 haveFilterEffect = m_renderLayer.filterRenderer()->beginFilterEffect
(context, rootRelativeBounds); | 305 haveFilterEffect = m_renderLayer.filterRenderer()->beginFilterEffect
(context, rootRelativeBounds); |
| 305 if (!haveFilterEffect) { | 306 if (!haveFilterEffect) { |
| 306 // If the the filter failed to start, undo the clip immediately | 307 // If the the filter failed to start, undo the clip immediately |
| 307 clipRecorder.clear(); | 308 clipRecorder.clear(); |
| 308 } | 309 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 } | 387 } |
| 387 | 388 |
| 388 return false; | 389 return false; |
| 389 } | 390 } |
| 390 | 391 |
| 391 bool LayerPainter::needsToClip(const LayerPaintingInfo& localPaintingInfo, const
ClipRect& clipRect) | 392 bool LayerPainter::needsToClip(const LayerPaintingInfo& localPaintingInfo, const
ClipRect& clipRect) |
| 392 { | 393 { |
| 393 return clipRect.rect() != localPaintingInfo.paintDirtyRect || clipRect.hasRa
dius(); | 394 return clipRect.rect() != localPaintingInfo.paintDirtyRect || clipRect.hasRa
dius(); |
| 394 } | 395 } |
| 395 | 396 |
| 396 void LayerPainter::applyRoundedRectClips(const LayerPaintingInfo& localPaintingI
nfo, GraphicsContext* context, const ClipRect& clipRect, | 397 void LayerPainter::applyRoundedRectClips(const LayerPaintingInfo& localPaintingI
nfo, GraphicsContext* context, PaintLayerFlags paintFlags, ClipRecorder& clipRec
order, BorderRadiusClippingRule rule) |
| 397 PaintLayerFlags paintFlags, ClipRecorder& clipRecorder, BorderRadiusClipping
Rule rule) | |
| 398 { | 398 { |
| 399 if (!clipRect.hasRadius()) | |
| 400 return; | |
| 401 | |
| 402 // If the clip rect has been tainted by a border radius, then we have to wal
k up our layer chain applying the clips from | 399 // If the clip rect has been tainted by a border radius, then we have to wal
k up our layer chain applying the clips from |
| 403 // any layers with overflow. The condition for being able to apply these cli
ps is that the overflow object be in our | 400 // any layers with overflow. The condition for being able to apply these cli
ps is that the overflow object be in our |
| 404 // containing block chain so we check that also. | 401 // containing block chain so we check that also. |
| 405 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? &m_renderLaye
r : m_renderLayer.parent(); layer; layer = layer->parent()) { | 402 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? &m_renderLaye
r : m_renderLayer.parent(); layer; layer = layer->parent()) { |
| 406 // Composited scrolling layers handle border-radius clip in the composit
or via a mask layer. We do not | 403 // Composited scrolling layers handle border-radius clip in the composit
or via a mask layer. We do not |
| 407 // want to apply a border-radius clip to the layer contents itself, beca
use that would require re-rastering | 404 // want to apply a border-radius clip to the layer contents itself, beca
use that would require re-rastering |
| 408 // every frame to update the clip. We only want to make sure that the ma
sk layer is properly clipped so | 405 // every frame to update the clip. We only want to make sure that the ma
sk layer is properly clipped so |
| 409 // that it can in turn clip the scrolled contents in the compositor. | 406 // that it can in turn clip the scrolled contents in the compositor. |
| 410 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPainti
ngChildClippingMaskPhase)) | 407 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPainti
ngChildClippingMaskPhase)) |
| 411 break; | 408 break; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 | 516 |
| 520 void LayerPainter::paintOverflowControlsForFragments(const LayerFragments& layer
Fragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
PaintLayerFlags paintFlags) | 517 void LayerPainter::paintOverflowControlsForFragments(const LayerFragments& layer
Fragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
PaintLayerFlags paintFlags) |
| 521 { | 518 { |
| 522 for (size_t i = 0; i < layerFragments.size(); ++i) { | 519 for (size_t i = 0; i < layerFragments.size(); ++i) { |
| 523 const LayerFragment& fragment = layerFragments.at(i); | 520 const LayerFragment& fragment = layerFragments.at(i); |
| 524 | 521 |
| 525 OwnPtr<ClipRecorder> clipRecorder; | 522 OwnPtr<ClipRecorder> clipRecorder; |
| 526 | 523 |
| 527 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) { | 524 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) { |
| 528 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, Di
splayItem::ClipLayerOverflowControls, fragment.backgroundRect)); | 525 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, Di
splayItem::ClipLayerOverflowControls, fragment.backgroundRect)); |
| 529 applyRoundedRectClips(localPaintingInfo, context, fragment.backgroun
dRect, paintFlags, *clipRecorder); | 526 if (fragment.backgroundRect.hasRadius()) |
| 527 applyRoundedRectClips(localPaintingInfo, context, paintFlags, *c
lipRecorder); |
| 530 } | 528 } |
| 531 if (RenderLayerScrollableArea* scrollableArea = m_renderLayer.scrollable
Area()) | 529 if (RenderLayerScrollableArea* scrollableArea = m_renderLayer.scrollable
Area()) |
| 532 scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoi
nt(fragment.layerBounds.location() - m_renderLayer.renderBoxLocation() + subPixe
lAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, m_renderLayer.comp
ositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); | 530 scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoi
nt(fragment.layerBounds.location() - m_renderLayer.renderBoxLocation() + subPixe
lAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, m_renderLayer.comp
ositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); |
| 533 } | 531 } |
| 534 } | 532 } |
| 535 | 533 |
| 536 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* rende
rer, RenderBox* ancestorColumnsRenderer) | 534 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* rende
rer, RenderBox* ancestorColumnsRenderer) |
| 537 { | 535 { |
| 538 RenderView* view = renderer->view(); | 536 RenderView* view = renderer->view(); |
| 539 RenderLayerModelObject* prevBlock = renderer; | 537 RenderLayerModelObject* prevBlock = renderer; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 clippingRule = DoNotIncludeSelfForBorderRadius; // Mask painting wil
l handle clipping to self. | 705 clippingRule = DoNotIncludeSelfForBorderRadius; // Mask painting wil
l handle clipping to self. |
| 708 break; | 706 break; |
| 709 case PaintPhaseClippingMask: | 707 case PaintPhaseClippingMask: |
| 710 clipType = DisplayItem::ClipLayerFragmentClippingMask; | 708 clipType = DisplayItem::ClipLayerFragmentClippingMask; |
| 711 break; | 709 break; |
| 712 default: | 710 default: |
| 713 ASSERT_NOT_REACHED(); | 711 ASSERT_NOT_REACHED(); |
| 714 } | 712 } |
| 715 | 713 |
| 716 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, clipTy
pe, clipRect)); | 714 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, clipTy
pe, clipRect)); |
| 717 applyRoundedRectClips(paintingInfo, context, clipRect, paintFlags, *clip
Recorder, clippingRule); | 715 if (clipRect.hasRadius()) |
| 716 applyRoundedRectClips(paintingInfo, context, paintFlags, *clipRecord
er, clippingRule); |
| 718 } | 717 } |
| 719 | 718 |
| 720 PaintInfo paintInfo(context, pixelSnappedIntRect(clipRect.rect()), phase, pa
intBehavior, paintingRootForRenderer, 0, paintingInfo.rootLayer->renderer()); | 719 PaintInfo paintInfo(context, pixelSnappedIntRect(clipRect.rect()), phase, pa
intBehavior, paintingRootForRenderer, 0, paintingInfo.rootLayer->renderer()); |
| 721 m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.loca
tion() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(painti
ngInfo.subPixelAccumulation, m_renderLayer.compositingState()))); | 720 m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.loca
tion() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(painti
ngInfo.subPixelAccumulation, m_renderLayer.compositingState()))); |
| 722 } | 721 } |
| 723 | 722 |
| 724 void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragme
nts, GraphicsContext* context, | 723 void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragme
nts, GraphicsContext* context, |
| 725 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L
ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, | 724 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L
ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
| 726 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) | 725 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) |
| 727 { | 726 { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 748 } | 747 } |
| 749 } | 748 } |
| 750 } | 749 } |
| 751 | 750 |
| 752 // Optimize clipping for the single fragment case. | 751 // Optimize clipping for the single fragment case. |
| 753 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size()
== 1 && !layerFragments[0].foregroundRect.isEmpty(); | 752 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size()
== 1 && !layerFragments[0].foregroundRect.isEmpty(); |
| 754 ClipState clipState = HasNotClipped; | 753 ClipState clipState = HasNotClipped; |
| 755 OwnPtr<ClipRecorder> clipRecorder; | 754 OwnPtr<ClipRecorder> clipRecorder; |
| 756 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { | 755 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { |
| 757 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, Displa
yItem::ClipLayerForeground, layerFragments[0].foregroundRect)); | 756 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, Displa
yItem::ClipLayerForeground, layerFragments[0].foregroundRect)); |
| 758 applyRoundedRectClips(localPaintingInfo, context, layerFragments[0].fore
groundRect, paintFlags, *clipRecorder); | 757 if (layerFragments[0].foregroundRect.hasRadius()) |
| 758 applyRoundedRectClips(localPaintingInfo, context, paintFlags, *clipR
ecorder); |
| 759 clipState = HasClipped; | 759 clipState = HasClipped; |
| 760 } | 760 } |
| 761 | 761 |
| 762 // We have to loop through every fragment multiple times, since we have to i
ssue paint invalidations in each specific phase in order for | 762 // We have to loop through every fragment multiple times, since we have to i
ssue paint invalidations in each specific phase in order for |
| 763 // interleaving of the fragments to work properly. | 763 // interleaving of the fragments to work properly. |
| 764 paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : P
aintPhaseChildBlockBackgrounds, layerFragments, | 764 paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : P
aintPhaseChildBlockBackgrounds, layerFragments, |
| 765 context, localPaintingInfo, paintBehavior, paintingRootForRenderer, pain
tFlags, clipState); | 765 context, localPaintingInfo, paintBehavior, paintingRootForRenderer, pain
tFlags, clipState); |
| 766 | 766 |
| 767 if (!selectionOnly) { | 767 if (!selectionOnly) { |
| 768 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, co
ntext, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags, cl
ipState); | 768 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, co
ntext, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags, cl
ipState); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 | 836 |
| 837 ClipRectsContext clipRectsContext(m_renderLayer.enclosingPaginationL
ayer(), (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : Paintin
gClipRects, IgnoreOverlayScrollbarSize); | 837 ClipRectsContext clipRectsContext(m_renderLayer.enclosingPaginationL
ayer(), (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : Paintin
gClipRects, IgnoreOverlayScrollbarSize); |
| 838 if (shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer())
== IgnoreOverflowClip) | 838 if (shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer())
== IgnoreOverflowClip) |
| 839 clipRectsContext.setIgnoreOverflowClip(); | 839 clipRectsContext.setIgnoreOverflowClip(); |
| 840 LayoutRect parentClipRect = m_renderLayer.clipper().backgroundClipRe
ct(clipRectsContext).rect(); | 840 LayoutRect parentClipRect = m_renderLayer.clipper().backgroundClipRe
ct(clipRectsContext).rect(); |
| 841 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPagination
LayerFromRoot); | 841 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPagination
LayerFromRoot); |
| 842 clipRect.intersect(parentClipRect); | 842 clipRect.intersect(parentClipRect); |
| 843 } | 843 } |
| 844 | 844 |
| 845 OwnPtr<ClipRecorder> clipRecorder; | 845 OwnPtr<ClipRecorder> clipRecorder; |
| 846 if (needsToClip(paintingInfo, clipRect)) { | 846 if (needsToClip(paintingInfo, clipRect)) |
| 847 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con
text, DisplayItem::ClipLayerFragmentParent, clipRect)); | 847 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con
text, DisplayItem::ClipLayerFragmentParent, clipRect)); |
| 848 // FIXME: why should we have to deal with rounded rect clips here at
all? | |
| 849 LayerPainter(*m_renderLayer.parent()).applyRoundedRectClips(painting
Info, context, clipRect, paintFlags, *clipRecorder); | |
| 850 } | |
| 851 | 848 |
| 852 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen
t.paginationOffset); | 849 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen
t.paginationOffset); |
| 853 } | 850 } |
| 854 } | 851 } |
| 855 | 852 |
| 856 } // namespace blink | 853 } // namespace blink |
| OLD | NEW |