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 |