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/ClipRecorder.h" | 6 #include "core/paint/ClipRecorder.h" |
7 | 7 |
8 #include "core/rendering/ClipRect.h" | 8 #include "core/paint/ViewDisplayList.h" |
9 #include "core/rendering/RenderLayer.h" | 9 #include "core/rendering/PaintInfo.h" |
| 10 #include "core/rendering/RenderLayerModelObject.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/graphics/GraphicsContext.h" | |
14 | 13 |
15 namespace blink { | 14 namespace blink { |
16 | 15 |
17 void ClipDisplayItem::replay(GraphicsContext* context) | 16 ClipRecorder::ClipRecorder(RenderLayerModelObject& canvas, const PaintInfo& pain
tInfo, const LayoutRect& clipRect) |
| 17 : m_clipRect(clipRect) |
| 18 , m_paintInfo(paintInfo) |
| 19 , m_canvas(canvas) |
18 { | 20 { |
19 context->save(); | 21 DisplayItem::Type type = paintPhaseToClipType(paintInfo.phase); |
20 context->clip(m_clipRect); | 22 OwnPtr<ClipDisplayItem> clipDisplayItem = adoptPtr(new ClipDisplayItem(&m_ca
nvas, type, pixelSnappedIntRect(clipRect))); |
21 for (RoundedRect roundedRect : m_roundedRectClips) | |
22 context->clipRoundedRect(roundedRect); | |
23 } | |
24 | 23 |
25 void EndClipDisplayItem::replay(GraphicsContext* context) | 24 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) |
26 { | 25 m_canvas.view()->viewDisplayList().add(clipDisplayItem.release()); |
27 context->restore(); | 26 else |
28 } | 27 clipDisplayItem->replay(paintInfo.context); |
29 | |
30 ClipRecorder::ClipRecorder(const RenderLayerModelObject* renderer, GraphicsConte
xt* graphicsContext, DisplayItem::Type clipType, const ClipRect& clipRect, | |
31 const LayerPaintingInfo* localPaintingInfo, const LayoutPoint& fragmentOffse
t, PaintLayerFlags paintFlags, BorderRadiusClippingRule rule) | |
32 : m_graphicsContext(graphicsContext) | |
33 , m_renderer(renderer) | |
34 { | |
35 IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect()); | |
36 OwnPtr<ClipDisplayItem> clipDisplayItem = adoptPtr(new ClipDisplayItem(rende
rer, clipType, snappedClipRect)); | |
37 if (localPaintingInfo && clipRect.hasRadius()) | |
38 collectRoundedRectClips(*renderer->layer(), *localPaintingInfo, graphics
Context, fragmentOffset, paintFlags, rule, clipDisplayItem->roundedRectClips()); | |
39 if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) { | |
40 clipDisplayItem->replay(graphicsContext); | |
41 } else { | |
42 m_renderer->view()->viewDisplayList().add(clipDisplayItem.release()); | |
43 } | |
44 } | |
45 | |
46 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye
r) | |
47 { | |
48 if (startLayer == endLayer) | |
49 return true; | |
50 | |
51 RenderView* view = startLayer->renderer()->view(); | |
52 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock();
currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlo
ck()) { | |
53 if (currentBlock->layer() == endLayer) | |
54 return true; | |
55 } | |
56 | |
57 return false; | |
58 } | |
59 | |
60 void ClipRecorder::collectRoundedRectClips(RenderLayer& renderLayer, const Layer
PaintingInfo& localPaintingInfo, GraphicsContext* context, const LayoutPoint& fr
agmentOffset, PaintLayerFlags paintFlags, | |
61 BorderRadiusClippingRule rule, Vector<RoundedRect>& roundedRectClips) | |
62 { | |
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 // 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 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 // 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 // that it can in turn clip the scrolled contents in the compositor. | |
71 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPainti
ngChildClippingMaskPhase)) | |
72 break; | |
73 | |
74 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->
hasBorderRadius() && inContainingBlockChain(&renderLayer, layer)) { | |
75 LayoutPoint delta(fragmentOffset); | |
76 layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta); | |
77 roundedRectClips.append(layer->renderer()->style()->getRoundedInnerB
orderFor(LayoutRect(delta, LayoutSize(layer->size())))); | |
78 } | |
79 | |
80 if (layer == localPaintingInfo.rootLayer) | |
81 break; | |
82 } | |
83 } | 28 } |
84 | 29 |
85 ClipRecorder::~ClipRecorder() | 30 ClipRecorder::~ClipRecorder() |
86 { | 31 { |
| 32 OwnPtr<EndClipDisplayItem> endClipDisplayItem = adoptPtr(new EndClipDisplayI
tem(&m_canvas)); |
| 33 |
87 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { | 34 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
88 OwnPtr<EndClipDisplayItem> endClip = adoptPtr(new EndClipDisplayItem(m_r
enderer)); | 35 m_canvas.view()->viewDisplayList().add(endClipDisplayItem.release()); |
89 m_renderer->view()->viewDisplayList().add(endClip.release()); | |
90 } else { | 36 } else { |
91 m_graphicsContext->restore(); | 37 endClipDisplayItem->replay(m_paintInfo.context); |
92 } | 38 } |
93 } | 39 } |
94 | 40 |
95 #ifndef NDEBUG | 41 DisplayItem::Type ClipRecorder::paintPhaseToClipType(PaintPhase paintPhase) |
96 WTF::String ClipDisplayItem::asDebugString() const | |
97 { | 42 { |
98 return String::format("{%s, type: \"%s\", clipRect: [%d,%d,%d,%d]}", | 43 switch (paintPhase) { |
99 rendererDebugString(renderer()).utf8().data(), typeAsDebugString(type())
.utf8().data(), | 44 case PaintPhaseChildBlockBackgrounds: |
100 m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height())
; | 45 return DisplayItem::ClipBoxChildBlockBackgrounds; |
| 46 break; |
| 47 case PaintPhaseFloat: |
| 48 return DisplayItem::ClipBoxFloat; |
| 49 break; |
| 50 case PaintPhaseForeground: |
| 51 return DisplayItem::ClipBoxChildBlockBackgrounds; |
| 52 break; |
| 53 case PaintPhaseChildOutlines: |
| 54 return DisplayItem::ClipBoxChildOutlines; |
| 55 break; |
| 56 case PaintPhaseSelection: |
| 57 return DisplayItem::ClipBoxSelection; |
| 58 break; |
| 59 case PaintPhaseCollapsedTableBorders: |
| 60 return DisplayItem::ClipBoxCollapsedTableBorders; |
| 61 break; |
| 62 case PaintPhaseTextClip: |
| 63 return DisplayItem::ClipBoxTextClip; |
| 64 break; |
| 65 case PaintPhaseClippingMask: |
| 66 return DisplayItem::ClipBoxClippingMask; |
| 67 break; |
| 68 case PaintPhaseChildBlockBackground: |
| 69 case PaintPhaseOutline: |
| 70 case PaintPhaseBlockBackground: |
| 71 case PaintPhaseSelfOutline: |
| 72 case PaintPhaseMask: |
| 73 ASSERT_NOT_REACHED(); |
| 74 } |
| 75 // This should never happen. |
| 76 return DisplayItem::ClipBoxForeground; |
101 } | 77 } |
102 #endif | |
103 | 78 |
104 } // namespace blink | 79 } // namespace blink |
OLD | NEW |