Commit 97944c93 authored by chrishtr@chromium.org's avatar chrishtr@chromium.org

Factor painting code for filters out of FilterEffectRenderer into FilterPainter.

BUG=412088

Review URL: https://codereview.chromium.org/713823005

git-svn-id: svn://svn.chromium.org/blink/trunk@185163 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent eb603446
...@@ -1518,6 +1518,8 @@ ...@@ -1518,6 +1518,8 @@
'paint/EllipsisBoxPainter.h', 'paint/EllipsisBoxPainter.h',
'paint/FileUploadControlPainter.cpp', 'paint/FileUploadControlPainter.cpp',
'paint/FileUploadControlPainter.h', 'paint/FileUploadControlPainter.h',
'paint/FilterPainter.cpp',
'paint/FilterPainter.h',
'paint/FramePainter.cpp', 'paint/FramePainter.cpp',
'paint/FramePainter.h', 'paint/FramePainter.h',
'paint/GridPainter.cpp', 'paint/GridPainter.cpp',
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/paint/FilterPainter.h"
#include "core/paint/LayerPainter.h"
#include "core/rendering/FilterEffectRenderer.h"
#include "core/rendering/RenderLayer.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/filters/FilterEffect.h"
#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
namespace blink {
FilterPainter::FilterPainter(RenderLayer& renderLayer, GraphicsContext* context, const FloatRect& filterBoxRect, const ClipRect& clipRect, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
: m_filterInProgress(false)
, m_context(context)
{
SkiaImageFilterBuilder builder(context);
RefPtr<FilterEffect> lastEffect = renderLayer.filterRenderer()->lastEffect();
lastEffect->determineFilterPrimitiveSubregion(MapRectForward);
RefPtr<ImageFilter> imageFilter = builder.build(lastEffect.get(), ColorSpaceDeviceRGB);
if (!imageFilter)
return;
if (clipRect.rect() != paintingInfo.paintDirtyRect || clipRect.hasRadius()) {
m_clipRecorder = adoptPtr(new ClipRecorder(&renderLayer, context, DisplayItem::ClipLayerFilter, clipRect));
if (clipRect.hasRadius())
LayerPainter::applyRoundedRectClips(renderLayer, paintingInfo, context, paintFlags, *m_clipRecorder);
}
context->save();
FloatRect boundaries = mapImageFilterRect(imageFilter.get(), filterBoxRect);
context->translate(filterBoxRect.x(), filterBoxRect.y());
boundaries.move(-filterBoxRect.x(), -filterBoxRect.y());
context->beginLayer(1, CompositeSourceOver, &boundaries, ColorFilterNone, imageFilter.get());
context->translate(-filterBoxRect.x(), -filterBoxRect.y());
m_filterInProgress = true;
}
FilterPainter::~FilterPainter()
{
if (m_filterInProgress) {
m_context->endLayer();
m_context->restore();
}
}
} // namespace blink
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FilterPainter_h
#define FilterPainter_h
#include "core/rendering/LayerPaintingInfo.h"
#include "wtf/OwnPtr.h"
namespace blink {
class ClipRecorder;
class ClipRect;
class FloatRect;
class GraphicsContext;
class RenderLayer;
class FilterPainter {
public:
FilterPainter(RenderLayer&, GraphicsContext*, const FloatRect& filterBoxRect, const ClipRect&, const LayerPaintingInfo&, PaintLayerFlags paintFlags);
~FilterPainter();
private:
bool m_filterInProgress;
GraphicsContext* m_context;
OwnPtr<ClipRecorder> m_clipRecorder;
};
} // namespace blink
#endif // FilterPainter_h
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "core/frame/Settings.h" #include "core/frame/Settings.h"
#include "core/page/Page.h" #include "core/page/Page.h"
#include "core/paint/FilterPainter.h"
#include "core/rendering/ClipPathOperation.h" #include "core/rendering/ClipPathOperation.h"
#include "core/rendering/FilterEffectRenderer.h" #include "core/rendering/FilterEffectRenderer.h"
#include "core/rendering/PaintInfo.h" #include "core/rendering/PaintInfo.h"
...@@ -102,7 +103,7 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo& ...@@ -102,7 +103,7 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
if (needsToClip(paintingInfo, clipRect)) { if (needsToClip(paintingInfo, clipRect)) {
clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), context, DisplayItem::ClipLayerParent, clipRect)); clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), context, DisplayItem::ClipLayerParent, clipRect));
if (clipRect.hasRadius()) if (clipRect.hasRadius())
LayerPainter(*m_renderLayer.parent()).applyRoundedRectClips(paintingInfo, context, paintFlags, *clipRecorder); applyRoundedRectClips(*m_renderLayer.parent(), paintingInfo, context, paintFlags, *clipRecorder);
} }
} }
...@@ -253,7 +254,6 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint ...@@ -253,7 +254,6 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint
beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
LayerPaintingInfo localPaintingInfo(paintingInfo); LayerPaintingInfo localPaintingInfo(paintingInfo);
bool haveFilterEffect = m_renderLayer.filterRenderer() && m_renderLayer.paintsWithFilters();
LayerFragments layerFragments; LayerFragments layerFragments;
if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
...@@ -274,9 +274,9 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint ...@@ -274,9 +274,9 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint
if (localPaintingInfo.paintingRoot && !m_renderLayer.renderer()->isDescendantOf(localPaintingInfo.paintingRoot)) if (localPaintingInfo.paintingRoot && !m_renderLayer.renderer()->isDescendantOf(localPaintingInfo.paintingRoot))
paintingRootForRenderer = localPaintingInfo.paintingRoot; paintingRootForRenderer = localPaintingInfo.paintingRoot;
{ // Begin block for the lifetime of any filter clip. { // Begin block for the lifetime of any filter.
OwnPtr<ClipRecorder> clipRecorder; OwnPtr<FilterPainter> filterPainter;
if (haveFilterEffect) { if (m_renderLayer.filterRenderer() && m_renderLayer.paintsWithFilters()) {
ASSERT(m_renderLayer.filterInfo()); ASSERT(m_renderLayer.filterInfo());
if (!rootRelativeBoundsComputed) if (!rootRelativeBoundsComputed)
...@@ -293,20 +293,10 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint ...@@ -293,20 +293,10 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint
// FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved. // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect; ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
if (needsToClip(localPaintingInfo, backgroundRect)) {
clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, DisplayItem::ClipLayerFilter, backgroundRect));
if (backgroundRect.hasRadius())
applyRoundedRectClips(localPaintingInfo, context, paintFlags, *clipRecorder);
}
// Subsequent code should not clip to the dirty rect, since we've already // Subsequent code should not clip to the dirty rect, since we've already
// done it above, and doing it later will defeat the outsets. // done it above, and doing it later will defeat the outsets.
localPaintingInfo.clipToDirtyRect = false; localPaintingInfo.clipToDirtyRect = false;
haveFilterEffect = m_renderLayer.filterRenderer()->beginFilterEffect(context, rootRelativeBounds); filterPainter = adoptPtr(new FilterPainter(m_renderLayer, context, rootRelativeBounds, backgroundRect, localPaintingInfo, paintFlags));
if (!haveFilterEffect) {
// If the the filter failed to start, undo the clip immediately
clipRecorder.clear();
}
} }
ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText)); ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText));
...@@ -344,13 +334,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint ...@@ -344,13 +334,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint
if (shouldPaintOverlayScrollbars) if (shouldPaintOverlayScrollbars)
paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags); paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags);
} // Filter painter block
if (haveFilterEffect) {
// Apply the correct clipping (ie. overflow: hidden).
// FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
m_renderLayer.filterRenderer()->endFilterEffect(context);
}
} // Filter clip block
bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && m_renderLayer.renderer()->hasMask() && !selectionOnly; bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && m_renderLayer.renderer()->hasMask() && !selectionOnly;
bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly; bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly;
...@@ -394,12 +378,13 @@ bool LayerPainter::needsToClip(const LayerPaintingInfo& localPaintingInfo, const ...@@ -394,12 +378,13 @@ bool LayerPainter::needsToClip(const LayerPaintingInfo& localPaintingInfo, const
return clipRect.rect() != localPaintingInfo.paintDirtyRect || clipRect.hasRadius(); return clipRect.rect() != localPaintingInfo.paintDirtyRect || clipRect.hasRadius();
} }
void LayerPainter::applyRoundedRectClips(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, PaintLayerFlags paintFlags, ClipRecorder& clipRecorder, BorderRadiusClippingRule rule) void LayerPainter::applyRoundedRectClips(RenderLayer& renderLayer, const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context,
PaintLayerFlags paintFlags, ClipRecorder& clipRecorder, BorderRadiusClippingRule rule)
{ {
// If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from // 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 // 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. // containing block chain so we check that also.
for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? &m_renderLayer : m_renderLayer.parent(); layer; layer = layer->parent()) { 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 // 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 // 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 // every frame to update the clip. We only want to make sure that the mask layer is properly clipped so
...@@ -407,7 +392,7 @@ void LayerPainter::applyRoundedRectClips(const LayerPaintingInfo& localPaintingI ...@@ -407,7 +392,7 @@ void LayerPainter::applyRoundedRectClips(const LayerPaintingInfo& localPaintingI
if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase)) if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
break; break;
if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(&m_renderLayer, layer)) { if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(&renderLayer, layer)) {
LayoutPoint delta; LayoutPoint delta;
layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta); layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
clipRecorder.addRoundedRectClip(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size()))); clipRecorder.addRoundedRectClip(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
...@@ -523,7 +508,7 @@ void LayerPainter::paintOverflowControlsForFragments(const LayerFragments& layer ...@@ -523,7 +508,7 @@ void LayerPainter::paintOverflowControlsForFragments(const LayerFragments& layer
if (needsToClip(localPaintingInfo, fragment.backgroundRect)) { if (needsToClip(localPaintingInfo, fragment.backgroundRect)) {
clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, DisplayItem::ClipLayerOverflowControls, fragment.backgroundRect)); clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, DisplayItem::ClipLayerOverflowControls, fragment.backgroundRect));
if (fragment.backgroundRect.hasRadius()) if (fragment.backgroundRect.hasRadius())
applyRoundedRectClips(localPaintingInfo, context, paintFlags, *clipRecorder); applyRoundedRectClips(m_renderLayer, localPaintingInfo, context, paintFlags, *clipRecorder);
} }
if (RenderLayerScrollableArea* scrollableArea = m_renderLayer.scrollableArea()) if (RenderLayerScrollableArea* scrollableArea = m_renderLayer.scrollableArea())
scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, m_renderLayer.compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, m_renderLayer.compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
...@@ -712,7 +697,7 @@ void LayerPainter::paintFragmentWithPhase(PaintPhase phase, const LayerFragment& ...@@ -712,7 +697,7 @@ void LayerPainter::paintFragmentWithPhase(PaintPhase phase, const LayerFragment&
clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, clipType, clipRect)); clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, clipType, clipRect));
if (clipRect.hasRadius()) if (clipRect.hasRadius())
applyRoundedRectClips(paintingInfo, context, paintFlags, *clipRecorder, clippingRule); applyRoundedRectClips(m_renderLayer, paintingInfo, context, paintFlags, *clipRecorder, clippingRule);
} }
PaintInfo paintInfo(context, pixelSnappedIntRect(clipRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, paintingInfo.rootLayer->renderer()); PaintInfo paintInfo(context, pixelSnappedIntRect(clipRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, paintingInfo.rootLayer->renderer());
...@@ -754,7 +739,7 @@ void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragme ...@@ -754,7 +739,7 @@ void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragme
if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) { if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) {
clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, DisplayItem::ClipLayerForeground, layerFragments[0].foregroundRect)); clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, DisplayItem::ClipLayerForeground, layerFragments[0].foregroundRect));
if (layerFragments[0].foregroundRect.hasRadius()) if (layerFragments[0].foregroundRect.hasRadius())
applyRoundedRectClips(localPaintingInfo, context, paintFlags, *clipRecorder); applyRoundedRectClips(m_renderLayer, localPaintingInfo, context, paintFlags, *clipRecorder);
clipState = HasClipped; clipState = HasClipped;
} }
......
...@@ -29,6 +29,9 @@ public: ...@@ -29,6 +29,9 @@ public:
void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior, RenderObject* paintingRoot = 0); void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior, RenderObject* paintingRoot = 0);
enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius };
static void applyRoundedRectClips(RenderLayer&, const LayerPaintingInfo&, GraphicsContext*, PaintLayerFlags, ClipRecorder&, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
private: private:
enum ClipState { HasNotClipped, HasClipped }; enum ClipState { HasNotClipped, HasClipped };
...@@ -53,9 +56,6 @@ private: ...@@ -53,9 +56,6 @@ private:
void paintTransformedLayerIntoFragments(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); void paintTransformedLayerIntoFragments(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior); void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior);
enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius };
void applyRoundedRectClips(const LayerPaintingInfo&, GraphicsContext*, PaintLayerFlags, ClipRecorder&, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
static bool needsToClip(const LayerPaintingInfo& localPaintingInfo, const ClipRect&); static bool needsToClip(const LayerPaintingInfo& localPaintingInfo, const ClipRect&);
// Returns whether this layer should be painted during sofware painting (i.e., not via calls from CompositedLayerMapping to draw into composited // Returns whether this layer should be painted during sofware painting (i.e., not via calls from CompositedLayerMapping to draw into composited
......
...@@ -39,14 +39,12 @@ ...@@ -39,14 +39,12 @@
#include "platform/FloatConversion.h" #include "platform/FloatConversion.h"
#include "platform/LengthFunctions.h" #include "platform/LengthFunctions.h"
#include "platform/graphics/ColorSpace.h" #include "platform/graphics/ColorSpace.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/ImageFilter.h" #include "platform/graphics/ImageFilter.h"
#include "platform/graphics/UnacceleratedImageBufferSurface.h" #include "platform/graphics/UnacceleratedImageBufferSurface.h"
#include "platform/graphics/filters/FEColorMatrix.h" #include "platform/graphics/filters/FEColorMatrix.h"
#include "platform/graphics/filters/FEComponentTransfer.h" #include "platform/graphics/filters/FEComponentTransfer.h"
#include "platform/graphics/filters/FEDropShadow.h" #include "platform/graphics/filters/FEDropShadow.h"
#include "platform/graphics/filters/FEGaussianBlur.h" #include "platform/graphics/filters/FEGaussianBlur.h"
#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
#include "platform/graphics/filters/SourceGraphic.h" #include "platform/graphics/filters/SourceGraphic.h"
#include "wtf/MathExtras.h" #include "wtf/MathExtras.h"
#include <algorithm> #include <algorithm>
...@@ -254,27 +252,6 @@ void FilterEffectRenderer::clearIntermediateResults() ...@@ -254,27 +252,6 @@ void FilterEffectRenderer::clearIntermediateResults()
m_lastEffect->clearResultsRecursive(); m_lastEffect->clearResultsRecursive();
} }
bool FilterEffectRenderer::beginFilterEffect(GraphicsContext* context, const FloatRect& filterBoxRect)
{
SkiaImageFilterBuilder builder(context);
m_lastEffect->determineFilterPrimitiveSubregion(MapRectForward);
RefPtr<ImageFilter> imageFilter = builder.build(m_lastEffect.get(), ColorSpaceDeviceRGB);
if (!imageFilter)
return false;
context->save();
FloatRect boundaries = mapImageFilterRect(imageFilter.get(), filterBoxRect);
context->translate(filterBoxRect.x(), filterBoxRect.y());
boundaries.move(-filterBoxRect.x(), -filterBoxRect.y());
context->beginLayer(1, CompositeSourceOver, &boundaries, ColorFilterNone, imageFilter.get());
context->translate(-filterBoxRect.x(), -filterBoxRect.y());
return true;
}
void FilterEffectRenderer::endFilterEffect(GraphicsContext* context)
{
context->endLayer();
context->restore();
}
} // namespace blink } // namespace blink
...@@ -51,8 +51,6 @@ public: ...@@ -51,8 +51,6 @@ public:
} }
bool build(RenderObject* renderer, const FilterOperations&); bool build(RenderObject* renderer, const FilterOperations&);
bool beginFilterEffect(GraphicsContext*, const FloatRect& filterBoxRect);
void endFilterEffect(GraphicsContext*);
void clearIntermediateResults(); void clearIntermediateResults();
PassRefPtr<FilterEffect> lastEffect() const PassRefPtr<FilterEffect> lastEffect() const
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment