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/LayerClipRecorder.h" | 5 #include "core/paint/LayerClipRecorder.h" |
6 | 6 |
7 #include "core/layout/ClipRect.h" | 7 #include "core/layout/ClipRect.h" |
8 #include "core/layout/LayoutView.h" | 8 #include "core/layout/LayoutView.h" |
9 #include "core/paint/PaintLayer.h" | 9 #include "core/paint/PaintLayer.h" |
10 #include "platform/geometry/IntRect.h" | 10 #include "platform/geometry/IntRect.h" |
11 #include "platform/graphics/GraphicsContext.h" | 11 #include "platform/graphics/GraphicsContext.h" |
12 #include "platform/graphics/GraphicsLayer.h" | 12 #include "platform/graphics/GraphicsLayer.h" |
13 #include "platform/graphics/paint/ClipRecorder.h" | 13 #include "platform/graphics/paint/ClipRecorder.h" |
14 #include "platform/graphics/paint/PaintController.h" | 14 #include "platform/graphics/paint/PaintController.h" |
15 | 15 |
16 namespace blink { | 16 namespace blink { |
17 | 17 |
18 LayerClipRecorder::LayerClipRecorder(GraphicsContext& graphicsContext, | 18 LayerClipRecorder::LayerClipRecorder( |
19 const LayoutBoxModelObject& layoutObject, | 19 GraphicsContext& graphicsContext, |
20 DisplayItem::Type clipType, | 20 const LayoutBoxModelObject& layoutObject, |
21 const ClipRect& clipRect, | 21 DisplayItem::Type clipType, |
22 const PaintLayer* clipRoot, | 22 const ClipRect& clipRect, |
23 const LayoutPoint& fragmentOffset, | 23 const PaintLayerPaintingInfo* localPaintingInfo, |
24 PaintLayerFlags paintFlags, | 24 const LayoutPoint& fragmentOffset, |
25 BorderRadiusClippingRule rule) | 25 PaintLayerFlags paintFlags, |
| 26 BorderRadiusClippingRule rule) |
26 : m_graphicsContext(graphicsContext), | 27 : m_graphicsContext(graphicsContext), |
27 m_layoutObject(layoutObject), | 28 m_layoutObject(layoutObject), |
28 m_clipType(clipType) { | 29 m_clipType(clipType) { |
29 IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect()); | 30 IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect()); |
30 Vector<FloatRoundedRect> roundedRects; | 31 Vector<FloatRoundedRect> roundedRects; |
31 if (clipRoot && clipRect.hasRadius()) { | 32 if (localPaintingInfo && clipRect.hasRadius()) { |
32 collectRoundedRectClips(*layoutObject.layer(), clipRoot, graphicsContext, | 33 collectRoundedRectClips(*layoutObject.layer(), *localPaintingInfo, |
33 fragmentOffset, paintFlags, rule, roundedRects); | 34 graphicsContext, fragmentOffset, paintFlags, rule, |
| 35 roundedRects); |
34 } | 36 } |
35 | 37 |
36 m_graphicsContext.getPaintController().createAndAppend<ClipDisplayItem>( | 38 m_graphicsContext.getPaintController().createAndAppend<ClipDisplayItem>( |
37 layoutObject, m_clipType, snappedClipRect, roundedRects); | 39 layoutObject, m_clipType, snappedClipRect, roundedRects); |
38 } | 40 } |
39 | 41 |
40 static bool inContainingBlockChain(PaintLayer* startLayer, | 42 static bool inContainingBlockChain(PaintLayer* startLayer, |
41 PaintLayer* endLayer) { | 43 PaintLayer* endLayer) { |
42 if (startLayer == endLayer) | 44 if (startLayer == endLayer) |
43 return true; | 45 return true; |
44 | 46 |
45 LayoutView* view = startLayer->layoutObject()->view(); | 47 LayoutView* view = startLayer->layoutObject()->view(); |
46 for (const LayoutBlock* currentBlock = | 48 for (const LayoutBlock* currentBlock = |
47 startLayer->layoutObject()->containingBlock(); | 49 startLayer->layoutObject()->containingBlock(); |
48 currentBlock && currentBlock != view; | 50 currentBlock && currentBlock != view; |
49 currentBlock = currentBlock->containingBlock()) { | 51 currentBlock = currentBlock->containingBlock()) { |
50 if (currentBlock->layer() == endLayer) | 52 if (currentBlock->layer() == endLayer) |
51 return true; | 53 return true; |
52 } | 54 } |
53 | 55 |
54 return false; | 56 return false; |
55 } | 57 } |
56 | 58 |
57 void LayerClipRecorder::collectRoundedRectClips( | 59 void LayerClipRecorder::collectRoundedRectClips( |
58 PaintLayer& paintLayer, | 60 PaintLayer& paintLayer, |
59 const PaintLayer* clipRoot, | 61 const PaintLayerPaintingInfo& localPaintingInfo, |
60 GraphicsContext& context, | 62 GraphicsContext& context, |
61 const LayoutPoint& fragmentOffset, | 63 const LayoutPoint& fragmentOffset, |
62 PaintLayerFlags paintFlags, | 64 PaintLayerFlags paintFlags, |
63 BorderRadiusClippingRule rule, | 65 BorderRadiusClippingRule rule, |
64 Vector<FloatRoundedRect>& roundedRectClips) { | 66 Vector<FloatRoundedRect>& roundedRectClips) { |
65 // If the clip rect has been tainted by a border radius, then we have to walk | 67 // If the clip rect has been tainted by a border radius, then we have to walk |
66 // up our layer chain applying the clips from any layers with overflow. The | 68 // up our layer chain applying the clips from any layers with overflow. The |
67 // condition for being able to apply these clips is that the overflow object | 69 // condition for being able to apply these clips is that the overflow object |
68 // be in our containing block chain so we check that also. | 70 // be in our containing block chain so we check that also. |
69 for (PaintLayer* layer = rule == IncludeSelfForBorderRadius | 71 for (PaintLayer* layer = rule == IncludeSelfForBorderRadius |
70 ? &paintLayer | 72 ? &paintLayer |
71 : paintLayer.parent(); | 73 : paintLayer.parent(); |
72 layer; layer = layer->parent()) { | 74 layer; layer = layer->parent()) { |
73 // Composited scrolling layers handle border-radius clip in the compositor | 75 // Composited scrolling layers handle border-radius clip in the compositor |
74 // via a mask layer. We do not want to apply a border-radius clip to the | 76 // via a mask layer. We do not want to apply a border-radius clip to the |
75 // layer contents itself, because that would require re-rastering every | 77 // layer contents itself, because that would require re-rastering every |
76 // frame to update the clip. We only want to make sure that the mask layer | 78 // frame to update the clip. We only want to make sure that the mask layer |
77 // is properly clipped so that it can in turn clip the scrolled contents in | 79 // is properly clipped so that it can in turn clip the scrolled contents in |
78 // the compositor. | 80 // the compositor. |
79 if (layer->needsCompositedScrolling() && | 81 if (layer->needsCompositedScrolling() && |
80 !(paintFlags & PaintLayerPaintingChildClippingMaskPhase || | 82 !(paintFlags & PaintLayerPaintingChildClippingMaskPhase)) |
81 paintFlags & PaintLayerPaintingAncestorClippingMaskPhase)) | |
82 break; | 83 break; |
83 | 84 |
84 if (layer->layoutObject()->hasOverflowClip() && | 85 if (layer->layoutObject()->hasOverflowClip() && |
85 layer->layoutObject()->style()->hasBorderRadius() && | 86 layer->layoutObject()->style()->hasBorderRadius() && |
86 inContainingBlockChain(&paintLayer, layer)) { | 87 inContainingBlockChain(&paintLayer, layer)) { |
87 LayoutPoint delta(fragmentOffset); | 88 LayoutPoint delta(fragmentOffset); |
88 layer->convertToLayerCoords(clipRoot, delta); | 89 layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta); |
89 | 90 |
90 // The PaintLayer's size is pixel-snapped if it is a LayoutBox. We can't | 91 // The PaintLayer's size is pixel-snapped if it is a LayoutBox. We can't |
91 // use a pre-snapped border rect for clipping, since | 92 // use a pre-snapped border rect for clipping, since |
92 // getRoundedInnerBorderFor assumes it has not been snapped yet. | 93 // getRoundedInnerBorderFor assumes it has not been snapped yet. |
93 LayoutSize size(layer->layoutBox() | 94 LayoutSize size(layer->layoutBox() |
94 ? toLayoutBox(layer->layoutObject())->size() | 95 ? toLayoutBox(layer->layoutObject())->size() |
95 : LayoutSize(layer->size())); | 96 : LayoutSize(layer->size())); |
96 roundedRectClips.append( | 97 roundedRectClips.append( |
97 layer->layoutObject()->style()->getRoundedInnerBorderFor( | 98 layer->layoutObject()->style()->getRoundedInnerBorderFor( |
98 LayoutRect(delta, size))); | 99 LayoutRect(delta, size))); |
99 } | 100 } |
100 | 101 |
101 if (layer == clipRoot) | 102 if (layer == localPaintingInfo.rootLayer) |
102 break; | 103 break; |
103 } | 104 } |
104 } | 105 } |
105 | 106 |
106 LayerClipRecorder::~LayerClipRecorder() { | 107 LayerClipRecorder::~LayerClipRecorder() { |
107 m_graphicsContext.getPaintController().endItem<EndClipDisplayItem>( | 108 m_graphicsContext.getPaintController().endItem<EndClipDisplayItem>( |
108 m_layoutObject, DisplayItem::clipTypeToEndClipType(m_clipType)); | 109 m_layoutObject, DisplayItem::clipTypeToEndClipType(m_clipType)); |
109 } | 110 } |
110 | 111 |
111 } // namespace blink | 112 } // namespace blink |
OLD | NEW |