| 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 = DisplayItem::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, 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 | |
| 96 WTF::String ClipDisplayItem::asDebugString() const | |
| 97 { | |
| 98 return String::format("{%s, type: \"%s\", clipRect: [%d,%d,%d,%d]}", | |
| 99 rendererDebugString(renderer()).utf8().data(), typeAsDebugString(type())
.utf8().data(), | |
| 100 m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height())
; | |
| 101 } | |
| 102 #endif | |
| 103 | |
| 104 } // namespace blink | 41 } // namespace blink |
| OLD | NEW |