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/LayerClipRecorder.h" |
| 7 |
6 #include "core/paint/ClipRecorder.h" | 8 #include "core/paint/ClipRecorder.h" |
7 | |
8 #include "core/rendering/ClipRect.h" | 9 #include "core/rendering/ClipRect.h" |
9 #include "core/rendering/RenderLayer.h" | 10 #include "core/rendering/RenderLayer.h" |
10 #include "core/rendering/RenderView.h" | 11 #include "core/rendering/RenderView.h" |
11 #include "platform/RuntimeEnabledFeatures.h" | 12 #include "platform/RuntimeEnabledFeatures.h" |
12 #include "platform/geometry/IntRect.h" | 13 #include "platform/geometry/IntRect.h" |
13 #include "platform/graphics/GraphicsContext.h" | 14 #include "platform/graphics/GraphicsContext.h" |
14 | 15 |
15 namespace blink { | 16 namespace blink { |
16 | 17 |
17 void ClipDisplayItem::replay(GraphicsContext* context) | 18 void ClipDisplayItem::replay(GraphicsContext* context) |
18 { | 19 { |
19 context->save(); | 20 context->save(); |
20 context->clip(m_clipRect); | 21 context->clip(m_clipRect); |
21 for (RoundedRect roundedRect : m_roundedRectClips) | 22 for (RoundedRect roundedRect : m_roundedRectClips) |
22 context->clipRoundedRect(roundedRect); | 23 context->clipRoundedRect(roundedRect); |
23 } | 24 } |
24 | 25 |
25 void EndClipDisplayItem::replay(GraphicsContext* context) | 26 void EndClipDisplayItem::replay(GraphicsContext* context) |
26 { | 27 { |
27 context->restore(); | 28 context->restore(); |
28 } | 29 } |
29 | 30 |
30 ClipRecorder::ClipRecorder(const RenderLayerModelObject* renderer, GraphicsConte
xt* graphicsContext, DisplayItem::Type clipType, const ClipRect& clipRect, | 31 LayerClipRecorder::LayerClipRecorder(const RenderLayerModelObject* renderer, Gra
phicsContext* graphicsContext, DisplayItem::Type clipType, const ClipRect& clipR
ect, |
31 const LayerPaintingInfo* localPaintingInfo, const LayoutPoint& fragmentOffse
t, PaintLayerFlags paintFlags, BorderRadiusClippingRule rule) | 32 const LayerPaintingInfo* localPaintingInfo, const LayoutPoint& fragmentOffse
t, PaintLayerFlags paintFlags, BorderRadiusClippingRule rule) |
32 : m_graphicsContext(graphicsContext) | 33 : m_graphicsContext(graphicsContext) |
33 , m_renderer(renderer) | 34 , m_renderer(renderer) |
34 { | 35 { |
35 IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect()); | 36 IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect()); |
36 OwnPtr<ClipDisplayItem> clipDisplayItem = adoptPtr(new ClipDisplayItem(rende
rer, clipType, snappedClipRect)); | 37 OwnPtr<ClipDisplayItem> clipDisplayItem = adoptPtr(new ClipDisplayItem(rende
rer, clipType, snappedClipRect)); |
37 if (localPaintingInfo && clipRect.hasRadius()) | 38 if (localPaintingInfo && clipRect.hasRadius()) |
38 collectRoundedRectClips(*renderer->layer(), *localPaintingInfo, graphics
Context, fragmentOffset, paintFlags, rule, clipDisplayItem->roundedRectClips()); | 39 collectRoundedRectClips(*renderer->layer(), *localPaintingInfo, graphics
Context, fragmentOffset, paintFlags, rule, clipDisplayItem->roundedRectClips()); |
39 if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) { | 40 if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
40 clipDisplayItem->replay(graphicsContext); | 41 clipDisplayItem->replay(graphicsContext); |
41 } else { | 42 } else { |
42 m_renderer->view()->viewDisplayList().add(clipDisplayItem.release()); | 43 m_renderer->view()->viewDisplayList().add(clipDisplayItem.release()); |
43 } | 44 } |
44 } | 45 } |
45 | 46 |
46 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye
r) | 47 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye
r) |
47 { | 48 { |
48 if (startLayer == endLayer) | 49 if (startLayer == endLayer) |
49 return true; | 50 return true; |
50 | 51 |
51 RenderView* view = startLayer->renderer()->view(); | 52 RenderView* view = startLayer->renderer()->view(); |
52 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock();
currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlo
ck()) { | 53 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock();
currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlo
ck()) { |
53 if (currentBlock->layer() == endLayer) | 54 if (currentBlock->layer() == endLayer) |
54 return true; | 55 return true; |
55 } | 56 } |
56 | 57 |
57 return false; | 58 return false; |
58 } | 59 } |
59 | 60 |
60 void ClipRecorder::collectRoundedRectClips(RenderLayer& renderLayer, const Layer
PaintingInfo& localPaintingInfo, GraphicsContext* context, const LayoutPoint& fr
agmentOffset, PaintLayerFlags paintFlags, | 61 void LayerClipRecorder::collectRoundedRectClips(RenderLayer& renderLayer, const
LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const LayoutPoin
t& fragmentOffset, PaintLayerFlags paintFlags, |
61 BorderRadiusClippingRule rule, Vector<RoundedRect>& roundedRectClips) | 62 BorderRadiusClippingRule rule, Vector<RoundedRect>& roundedRectClips) |
62 { | 63 { |
63 // 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 | 64 // 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 |
64 // any layers with overflow. The condition for being able to apply these cli
ps is that the overflow object be in our | 65 // any layers with overflow. The condition for being able to apply these cli
ps is that the overflow object be in our |
65 // containing block chain so we check that also. | 66 // containing block chain so we check that also. |
66 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? &renderLayer
: renderLayer.parent(); layer; layer = layer->parent()) { | 67 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? &renderLayer
: renderLayer.parent(); layer; layer = layer->parent()) { |
67 // Composited scrolling layers handle border-radius clip in the composit
or via a mask layer. We do not | 68 // Composited scrolling layers handle border-radius clip in the composit
or via a mask layer. We do not |
68 // want to apply a border-radius clip to the layer contents itself, beca
use that would require re-rastering | 69 // want to apply a border-radius clip to the layer contents itself, beca
use that would require re-rastering |
69 // every frame to update the clip. We only want to make sure that the ma
sk layer is properly clipped so | 70 // every frame to update the clip. We only want to make sure that the ma
sk layer is properly clipped so |
70 // that it can in turn clip the scrolled contents in the compositor. | 71 // that it can in turn clip the scrolled contents in the compositor. |
71 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPainti
ngChildClippingMaskPhase)) | 72 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPainti
ngChildClippingMaskPhase)) |
72 break; | 73 break; |
73 | 74 |
74 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->
hasBorderRadius() && inContainingBlockChain(&renderLayer, layer)) { | 75 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->
hasBorderRadius() && inContainingBlockChain(&renderLayer, layer)) { |
75 LayoutPoint delta(fragmentOffset); | 76 LayoutPoint delta(fragmentOffset); |
76 layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta); | 77 layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta); |
77 roundedRectClips.append(layer->renderer()->style()->getRoundedInnerB
orderFor(LayoutRect(delta, LayoutSize(layer->size())))); | 78 roundedRectClips.append(layer->renderer()->style()->getRoundedInnerB
orderFor(LayoutRect(delta, LayoutSize(layer->size())))); |
78 } | 79 } |
79 | 80 |
80 if (layer == localPaintingInfo.rootLayer) | 81 if (layer == localPaintingInfo.rootLayer) |
81 break; | 82 break; |
82 } | 83 } |
83 } | 84 } |
84 | 85 |
85 ClipRecorder::~ClipRecorder() | 86 LayerClipRecorder::~LayerClipRecorder() |
86 { | 87 { |
87 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { | 88 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
88 OwnPtr<EndClipDisplayItem> endClip = adoptPtr(new EndClipDisplayItem(m_r
enderer)); | 89 OwnPtr<EndClipDisplayItem> endClip = adoptPtr(new EndClipDisplayItem(m_r
enderer)); |
89 m_renderer->view()->viewDisplayList().add(endClip.release()); | 90 m_renderer->view()->viewDisplayList().add(endClip.release()); |
90 } else { | 91 } else { |
91 m_graphicsContext->restore(); | 92 m_graphicsContext->restore(); |
92 } | 93 } |
93 } | 94 } |
94 | 95 |
95 #ifndef NDEBUG | 96 #ifndef NDEBUG |
96 WTF::String ClipDisplayItem::asDebugString() const | 97 WTF::String ClipDisplayItem::asDebugString() const |
97 { | 98 { |
98 return String::format("{%s, type: \"%s\", clipRect: [%d,%d,%d,%d]}", | 99 return String::format("{%s, type: \"%s\", clipRect: [%d,%d,%d,%d]}", |
99 rendererDebugString(renderer()).utf8().data(), typeAsDebugString(type())
.utf8().data(), | 100 rendererDebugString(renderer()).utf8().data(), typeAsDebugString(type())
.utf8().data(), |
100 m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height())
; | 101 m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height())
; |
101 } | 102 } |
102 #endif | 103 #endif |
103 | 104 |
104 } // namespace blink | 105 } // namespace blink |
OLD | NEW |