| Index: Source/core/paint/ClipRecorder.cpp
|
| diff --git a/Source/core/paint/ClipRecorder.cpp b/Source/core/paint/ClipRecorder.cpp
|
| index 7aa6bead920b2b5d5acf85c33507207e5bbbc2e7..5c2e696bd3bd547ed5b772bfc43cce85e125acee 100644
|
| --- a/Source/core/paint/ClipRecorder.cpp
|
| +++ b/Source/core/paint/ClipRecorder.cpp
|
| @@ -5,75 +5,100 @@
|
| #include "config.h"
|
| #include "core/paint/ClipRecorder.h"
|
|
|
| -#include "core/paint/ViewDisplayList.h"
|
| -#include "core/rendering/PaintInfo.h"
|
| -#include "core/rendering/RenderLayerModelObject.h"
|
| +#include "core/rendering/ClipRect.h"
|
| +#include "core/rendering/RenderLayer.h"
|
| #include "core/rendering/RenderView.h"
|
| #include "platform/RuntimeEnabledFeatures.h"
|
| +#include "platform/geometry/IntRect.h"
|
| +#include "platform/graphics/GraphicsContext.h"
|
|
|
| namespace blink {
|
|
|
| -ClipRecorder::ClipRecorder(RenderLayerModelObject& canvas, const PaintInfo& paintInfo, const LayoutRect& clipRect)
|
| - : m_clipRect(clipRect)
|
| - , m_paintInfo(paintInfo)
|
| - , m_canvas(canvas)
|
| +void ClipDisplayItem::replay(GraphicsContext* context)
|
| {
|
| - DisplayItem::Type type = paintPhaseToClipType(paintInfo.phase);
|
| - OwnPtr<ClipDisplayItem> clipDisplayItem = adoptPtr(new ClipDisplayItem(&m_canvas, type, pixelSnappedIntRect(clipRect)));
|
| + context->save();
|
| + context->clip(m_clipRect);
|
| + for (RoundedRect roundedRect : m_roundedRectClips)
|
| + context->clipRoundedRect(roundedRect);
|
| +}
|
|
|
| - if (RuntimeEnabledFeatures::slimmingPaintEnabled())
|
| - m_canvas.view()->viewDisplayList().add(clipDisplayItem.release());
|
| - else
|
| - clipDisplayItem->replay(paintInfo.context);
|
| +void EndClipDisplayItem::replay(GraphicsContext* context)
|
| +{
|
| + context->restore();
|
| +}
|
| +
|
| +ClipRecorder::ClipRecorder(const RenderLayerModelObject* renderer, GraphicsContext* graphicsContext, DisplayItem::Type clipType, const ClipRect& clipRect,
|
| + const LayerPaintingInfo* localPaintingInfo, const LayoutPoint& fragmentOffset, PaintLayerFlags paintFlags, BorderRadiusClippingRule rule)
|
| + : m_graphicsContext(graphicsContext)
|
| + , m_renderer(renderer)
|
| +{
|
| + IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect());
|
| + OwnPtr<ClipDisplayItem> clipDisplayItem = adoptPtr(new ClipDisplayItem(renderer, clipType, snappedClipRect));
|
| + if (localPaintingInfo && clipRect.hasRadius())
|
| + collectRoundedRectClips(*renderer->layer(), *localPaintingInfo, graphicsContext, fragmentOffset, paintFlags, rule, clipDisplayItem->roundedRectClips());
|
| + if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) {
|
| + clipDisplayItem->replay(graphicsContext);
|
| + } else {
|
| + m_renderer->view()->viewDisplayList().add(clipDisplayItem.release());
|
| + }
|
| +}
|
| +
|
| +static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
|
| +{
|
| + if (startLayer == endLayer)
|
| + return true;
|
| +
|
| + RenderView* view = startLayer->renderer()->view();
|
| + for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) {
|
| + if (currentBlock->layer() == endLayer)
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +void ClipRecorder::collectRoundedRectClips(RenderLayer& renderLayer, const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const LayoutPoint& fragmentOffset, PaintLayerFlags paintFlags,
|
| + BorderRadiusClippingRule rule, Vector<RoundedRect>& roundedRectClips)
|
| +{
|
| + // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
|
| + // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
|
| + // containing block chain so we check that also.
|
| + for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? &renderLayer : renderLayer.parent(); layer; layer = layer->parent()) {
|
| + // Composited scrolling layers handle border-radius clip in the compositor via a mask layer. We do not
|
| + // want to apply a border-radius clip to the layer contents itself, because that would require re-rastering
|
| + // every frame to update the clip. We only want to make sure that the mask layer is properly clipped so
|
| + // that it can in turn clip the scrolled contents in the compositor.
|
| + if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
|
| + break;
|
| +
|
| + if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(&renderLayer, layer)) {
|
| + LayoutPoint delta(fragmentOffset);
|
| + layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
|
| + roundedRectClips.append(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, LayoutSize(layer->size()))));
|
| + }
|
| +
|
| + if (layer == localPaintingInfo.rootLayer)
|
| + break;
|
| + }
|
| }
|
|
|
| ClipRecorder::~ClipRecorder()
|
| {
|
| - OwnPtr<EndClipDisplayItem> endClipDisplayItem = adoptPtr(new EndClipDisplayItem(&m_canvas));
|
| -
|
| if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
|
| - m_canvas.view()->viewDisplayList().add(endClipDisplayItem.release());
|
| + OwnPtr<EndClipDisplayItem> endClip = adoptPtr(new EndClipDisplayItem(m_renderer));
|
| + m_renderer->view()->viewDisplayList().add(endClip.release());
|
| } else {
|
| - endClipDisplayItem->replay(m_paintInfo.context);
|
| + m_graphicsContext->restore();
|
| }
|
| }
|
|
|
| -DisplayItem::Type ClipRecorder::paintPhaseToClipType(PaintPhase paintPhase)
|
| +#ifndef NDEBUG
|
| +WTF::String ClipDisplayItem::asDebugString() const
|
| {
|
| - switch (paintPhase) {
|
| - case PaintPhaseChildBlockBackgrounds:
|
| - return DisplayItem::ClipBoxChildBlockBackgrounds;
|
| - break;
|
| - case PaintPhaseFloat:
|
| - return DisplayItem::ClipBoxFloat;
|
| - break;
|
| - case PaintPhaseForeground:
|
| - return DisplayItem::ClipBoxChildBlockBackgrounds;
|
| - break;
|
| - case PaintPhaseChildOutlines:
|
| - return DisplayItem::ClipBoxChildOutlines;
|
| - break;
|
| - case PaintPhaseSelection:
|
| - return DisplayItem::ClipBoxSelection;
|
| - break;
|
| - case PaintPhaseCollapsedTableBorders:
|
| - return DisplayItem::ClipBoxCollapsedTableBorders;
|
| - break;
|
| - case PaintPhaseTextClip:
|
| - return DisplayItem::ClipBoxTextClip;
|
| - break;
|
| - case PaintPhaseClippingMask:
|
| - return DisplayItem::ClipBoxClippingMask;
|
| - break;
|
| - case PaintPhaseChildBlockBackground:
|
| - case PaintPhaseOutline:
|
| - case PaintPhaseBlockBackground:
|
| - case PaintPhaseSelfOutline:
|
| - case PaintPhaseMask:
|
| - ASSERT_NOT_REACHED();
|
| - }
|
| - // This should never happen.
|
| - return DisplayItem::ClipBoxForeground;
|
| + return String::format("{%s, type: \"%s\", clipRect: [%d,%d,%d,%d]}",
|
| + rendererDebugString(renderer()).utf8().data(), typeAsDebugString(type()).utf8().data(),
|
| + m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height());
|
| }
|
| +#endif
|
|
|
| } // namespace blink
|
|
|