Diff
Modified: trunk/Source/WebCore/ChangeLog (235585 => 235586)
--- trunk/Source/WebCore/ChangeLog 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/ChangeLog 2018-09-02 03:04:24 UTC (rev 235586)
@@ -1,3 +1,88 @@
+2018-09-01 Simon Fraser <[email protected]>
+
+ Rename FilterEffectRenderer to CSSFilter
+ https://bugs.webkit.org/show_bug.cgi?id=189223
+
+ Reviewed by Sam Weinig.
+
+ Filter was subclassed by SVGFilter for SVG, and FilterEffectRenderer for CSS,
+ which was very confusing, especially when the code uses renderer() to get it.
+
+ Rename FilterEffectRenderer to CSSFilter, and access via filter().
+
+ Future cleanup will deal with FilterEffectRendererHelper.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSFilterImageValue.cpp:
+ (WebCore::CSSFilterImageValue::image):
+ * platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm:
+ * platform/graphics/filters/Filter.h:
+ (WebCore::Filter::isCSSFilter const):
+ * rendering/CSSFilter.cpp: Copied from Source/WebCore/rendering/FilterEffectRenderer.cpp.
+ (WebCore::endMatrixRow):
+ (WebCore::lastMatrixRow):
+ (WebCore::CSSFilter::create):
+ (WebCore::CSSFilter::CSSFilter):
+ (WebCore::m_sourceGraphic):
+ (WebCore::CSSFilter::inputContext):
+ (WebCore::CSSFilter::buildReferenceFilter):
+ (WebCore::CSSFilter::build):
+ (WebCore::CSSFilter::updateBackingStoreRect):
+ (WebCore::CSSFilter::allocateBackingStoreIfNeeded):
+ (WebCore::CSSFilter::clearIntermediateResults):
+ (WebCore::CSSFilter::apply):
+ (WebCore::CSSFilter::computeSourceImageRectForDirtyRect):
+ (WebCore::CSSFilter::output const):
+ (WebCore::CSSFilter::setSourceImageRect):
+ (WebCore::CSSFilter::setMaxEffectRects):
+ (WebCore::CSSFilter::outputRect const):
+ * rendering/CSSFilter.h: Copied from Source/WebCore/rendering/FilterEffectRenderer.h.
+ (isType):
+ * rendering/FilterEffectRenderer.cpp:
+ (WebCore::FilterEffectRendererHelper::prepareFilterEffect):
+ (WebCore::FilterEffectRendererHelper::filterContext const):
+ (WebCore::FilterEffectRendererHelper::beginFilterEffect):
+ (WebCore::FilterEffectRendererHelper::applyFilterEffect):
+ (WebCore::endMatrixRow): Deleted.
+ (WebCore::lastMatrixRow): Deleted.
+ (WebCore::FilterEffectRenderer::FilterEffectRenderer): Deleted.
+ (WebCore::m_sourceGraphic): Deleted.
+ (WebCore::FilterEffectRenderer::create): Deleted.
+ (WebCore::FilterEffectRenderer::inputContext): Deleted.
+ (WebCore::FilterEffectRenderer::buildReferenceFilter): Deleted.
+ (WebCore::FilterEffectRenderer::build): Deleted.
+ (WebCore::FilterEffectRenderer::updateBackingStoreRect): Deleted.
+ (WebCore::FilterEffectRenderer::allocateBackingStoreIfNeeded): Deleted.
+ (WebCore::FilterEffectRenderer::clearIntermediateResults): Deleted.
+ (WebCore::FilterEffectRenderer::apply): Deleted.
+ (WebCore::FilterEffectRenderer::computeSourceImageRectForDirtyRect): Deleted.
+ (WebCore::FilterEffectRenderer::output const): Deleted.
+ (WebCore::FilterEffectRenderer::setMaxEffectRects): Deleted.
+ (WebCore::FilterEffectRenderer::outputRect const): Deleted.
+ * rendering/FilterEffectRenderer.h:
+ (WebCore::FilterEffectRendererHelper::FilterEffectRendererHelper):
+ (WebCore::FilterEffectRenderer::setSourceImageRect): Deleted.
+ * rendering/RenderBlockFlow.cpp:
+ * rendering/RenderFrame.cpp:
+ * rendering/RenderImage.cpp:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::requiresFullLayerImageForFilters const):
+ (WebCore::RenderLayer::filter const):
+ (WebCore::RenderLayer::filterPainter const):
+ (WebCore::RenderLayer::setupFilters):
+ (WebCore::RenderLayer::calculateClipRects const):
+ (WebCore::RenderLayer::filterRenderer const): Deleted.
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ * rendering/RenderLayerFilterInfo.cpp:
+ (WebCore::RenderLayer::FilterInfo::setFilter):
+ (WebCore::RenderLayer::FilterInfo::updateReferenceFilterClients):
+ (WebCore::RenderLayer::FilterInfo::removeReferenceFilterClients):
+ (WebCore::RenderLayer::FilterInfo::setRenderer): Deleted.
+ * rendering/RenderLayerFilterInfo.h:
+ * rendering/updating/RenderTreeBuilderBlock.cpp:
+
2018-09-01 Darin Adler <[email protected]>
[CFNetwork] Update CFNetwork SPI use to use CFNetworkSPI.h more consistently
Modified: trunk/Source/WebCore/Sources.txt (235585 => 235586)
--- trunk/Source/WebCore/Sources.txt 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/Sources.txt 2018-09-02 03:04:24 UTC (rev 235586)
@@ -1837,6 +1837,7 @@
rendering/BidiRun.cpp
rendering/BorderEdge.cpp
rendering/BreakLines.cpp
+rendering/CSSFilter.cpp
rendering/ClipRect.cpp
rendering/CounterNode.cpp
rendering/EllipsisBox.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (235585 => 235586)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-02 03:04:24 UTC (rev 235586)
@@ -5609,6 +5609,8 @@
0F4966A71DB40C4300A274BB /* JSDOMPointInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPointInit.h; sourceTree = "<group>"; };
0F4966A81DB40C4300A274BB /* JSDOMPointReadOnly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMPointReadOnly.cpp; sourceTree = "<group>"; };
0F4966A91DB40C4300A274BB /* JSDOMPointReadOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPointReadOnly.h; sourceTree = "<group>"; };
+ 0F53FB81213B1BB800C40D34 /* CSSFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFilter.cpp; sourceTree = "<group>"; };
+ 0F53FB83213B1BB800C40D34 /* CSSFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFilter.h; sourceTree = "<group>"; };
0F54DCE31881051D003EEDBB /* TextAutoSizing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextAutoSizing.cpp; sourceTree = "<group>"; };
0F54DCE41881051D003EEDBB /* TextAutoSizing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextAutoSizing.h; sourceTree = "<group>"; };
0F54DD051881D5F5003EEDBB /* Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Touch.h; sourceTree = "<group>"; };
@@ -25737,6 +25739,8 @@
BCDD454D1236C95C009A7985 /* ColumnInfo.h */,
9392F14F0AD1862300691BD4 /* CounterNode.cpp */,
9392F14B0AD1861B00691BD4 /* CounterNode.h */,
+ 0F53FB81213B1BB800C40D34 /* CSSFilter.cpp */,
+ 0F53FB83213B1BB800C40D34 /* CSSFilter.h */,
A8CFF6CA0A1561CD000A4234 /* EllipsisBox.cpp */,
A8CFF6BD0A156118000A4234 /* EllipsisBox.h */,
31313F631443B35E006E2A90 /* FilterEffectRenderer.cpp */,
@@ -31412,6 +31416,7 @@
5CDD83641E4325A000621E92 /* LibWebRTCDataChannelHandler.cpp in Sources */,
417612AF1E3A994000C3D81D /* LibWebRTCMediaEndpoint.cpp in Sources */,
417612B11E3A994000C3D81D /* LibWebRTCPeerConnectionBackend.cpp in Sources */,
+ 41D28D0D2139E05800F4206F /* LibWebRTCStatsCollector.cpp in Sources */,
9759E93E14EF1CF80026A2DD /* LoadableTextTrack.cpp in Sources */,
445775EA2047303C008DCE5D /* LocalDefaultSystemAppearance.mm in Sources */,
FABE72FE1059C21100D999DD /* MathMLNames.cpp in Sources */,
@@ -31779,7 +31784,6 @@
DECA7E651F9EBD8300E3B661 /* UnifiedSource234.cpp in Sources */,
DECA7E661F9EBD8300E3B661 /* UnifiedSource235.cpp in Sources */,
DECA7E671F9EBD8300E3B661 /* UnifiedSource236.cpp in Sources */,
- 41D28D0D2139E05800F4206F /* LibWebRTCStatsCollector.cpp in Sources */,
DECA7E681F9EBD8300E3B661 /* UnifiedSource237.cpp in Sources */,
DECA7E691F9EBD8300E3B661 /* UnifiedSource238.cpp in Sources */,
DECA7E6A1F9EBD8300E3B661 /* UnifiedSource239.cpp in Sources */,
Modified: trunk/Source/WebCore/css/CSSFilterImageValue.cpp (235585 => 235586)
--- trunk/Source/WebCore/css/CSSFilterImageValue.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/css/CSSFilterImageValue.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -27,6 +27,7 @@
#include "config.h"
#include "CSSFilterImageValue.h"
+#include "CSSFilter.h"
#include "CachedImage.h"
#include "CachedResourceLoader.h"
#include "FilterEffectRenderer.h"
@@ -131,15 +132,15 @@
auto imageRect = FloatRect { { }, size };
texture->context().drawImage(*image, imageRect);
- auto filterRenderer = FilterEffectRenderer::create();
- filterRenderer->setSourceImage(WTFMove(texture));
- filterRenderer->setSourceImageRect(imageRect);
- filterRenderer->setFilterRegion(imageRect);
- if (!filterRenderer->build(*renderer, m_filterOperations, FilterFunction))
+ auto cssFilter = CSSFilter::create();
+ cssFilter->setSourceImage(WTFMove(texture));
+ cssFilter->setSourceImageRect(imageRect);
+ cssFilter->setFilterRegion(imageRect);
+ if (!cssFilter->build(*renderer, m_filterOperations, FilterConsumer::FilterFunction))
return &Image::nullImage();
- filterRenderer->apply();
+ cssFilter->apply();
- return filterRenderer->output()->copyImage();
+ return cssFilter->output()->copyImage();
}
void CSSFilterImageValue::filterImageChanged(const IntRect&)
Modified: trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm (235585 => 235586)
--- trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm 2018-09-02 03:04:24 UTC (rev 235586)
@@ -35,7 +35,7 @@
using namespace WebCore;
-// FIXME: Should share these values with FilterEffectRenderer::build() (https://bugs.webkit.org/show_bug.cgi?id=76008).
+// FIXME: Should share these values with CSSFilter::build() (https://bugs.webkit.org/show_bug.cgi?id=76008).
static const double sepiaFullConstants[3][3] = {
{ 0.393, 0.769, 0.189 },
{ 0.349, 0.686, 0.168 },
Modified: trunk/Source/WebCore/platform/graphics/filters/Filter.h (235585 => 235586)
--- trunk/Source/WebCore/platform/graphics/filters/Filter.h 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.h 2018-09-02 03:04:24 UTC (rev 235586)
@@ -48,6 +48,7 @@
void setRenderingMode(RenderingMode renderingMode) { m_renderingMode = renderingMode; }
virtual bool isSVGFilter() const { return false; }
+ virtual bool isCSSFilter() const { return false; }
virtual FloatSize scaledByFilterResolution(FloatSize size) const { return size * m_filterResolution; }
Copied: trunk/Source/WebCore/rendering/CSSFilter.cpp (from rev 235585, trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp) (0 => 235586)
--- trunk/Source/WebCore/rendering/CSSFilter.cpp (rev 0)
+++ trunk/Source/WebCore/rendering/CSSFilter.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CSSFilter.h"
+
+#include "CachedSVGDocument.h"
+#include "CachedSVGDocumentReference.h"
+#include "ElementIterator.h"
+#include "FEColorMatrix.h"
+#include "FEComponentTransfer.h"
+#include "FEDropShadow.h"
+#include "FEGaussianBlur.h"
+#include "FEMerge.h"
+#include "Logging.h"
+#include "RenderLayer.h"
+#include "SVGElement.h"
+#include "SVGFilterBuilder.h"
+#include "SVGFilterPrimitiveStandardAttributes.h"
+#include "SourceGraphic.h"
+#include <algorithm>
+#include <wtf/MathExtras.h>
+
+#if USE(DIRECT2D)
+#include <d2d1.h>
+#endif
+
+namespace WebCore {
+
+static inline void endMatrixRow(Vector<float>& parameters)
+{
+ parameters.append(0);
+ parameters.append(0);
+}
+
+static inline void lastMatrixRow(Vector<float>& parameters)
+{
+ parameters.append(0);
+ parameters.append(0);
+ parameters.append(0);
+ parameters.append(1);
+ parameters.append(0);
+}
+
+Ref<CSSFilter> CSSFilter::create()
+{
+ return adoptRef(*new CSSFilter);
+}
+
+CSSFilter::CSSFilter()
+ : Filter(FloatSize { 1, 1 })
+ , m_sourceGraphic(SourceGraphic::create(*this))
+{
+}
+
+CSSFilter::~CSSFilter() = default;
+
+GraphicsContext* CSSFilter::inputContext()
+{
+ return sourceImage() ? &sourceImage()->context() : nullptr;
+}
+
+RefPtr<FilterEffect> CSSFilter::buildReferenceFilter(RenderElement& renderer, FilterEffect& previousEffect, ReferenceFilterOperation& filterOperation)
+{
+ auto* cachedSVGDocumentReference = filterOperation.cachedSVGDocumentReference();
+ auto* cachedSVGDocument = cachedSVGDocumentReference ? cachedSVGDocumentReference->document() : nullptr;
+
+ // If we have an SVG document, this is an external reference. Otherwise
+ // we look up the referenced node in the current document.
+ Document* document;
+ if (!cachedSVGDocument)
+ document = &renderer.document();
+ else {
+ document = cachedSVGDocument->document();
+ if (!document)
+ return nullptr;
+ }
+
+ auto* filter = document->getElementById(filterOperation.fragment());
+ if (!filter) {
+ // Although we did not find the referenced filter, it might exist later in the document.
+ // FIXME: This skips anonymous RenderObjects. <https://webkit.org/b/131085>
+ if (auto* element = renderer.element())
+ document->accessSVGExtensions().addPendingResource(filterOperation.fragment(), element);
+ return nullptr;
+ }
+
+ RefPtr<FilterEffect> effect;
+
+ auto builder = std::make_unique<SVGFilterBuilder>(&previousEffect);
+
+ for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(*filter)) {
+ effect = effectElement.build(builder.get(), *this);
+ if (!effect)
+ continue;
+
+ effectElement.setStandardAttributes(effect.get());
+ if (effectElement.renderer())
+ effect->setOperatingColorSpace(effectElement.renderer()->style().svgStyle().colorInterpolationFilters() == ColorInterpolation::LinearRGB ? ColorSpaceLinearRGB : ColorSpaceSRGB);
+
+ builder->add(effectElement.result(), effect);
+ m_effects.append(*effect);
+ }
+ return effect;
+}
+
+bool CSSFilter::build(RenderElement& renderer, const FilterOperations& operations, FilterConsumer consumer)
+{
+ m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
+ m_hasFilterThatShouldBeRestrictedBySecurityOrigin = operations.hasFilterThatShouldBeRestrictedBySecurityOrigin();
+ if (m_hasFilterThatMovesPixels)
+ m_outsets = operations.outsets();
+
+ m_effects.clear();
+
+ RefPtr<FilterEffect> previousEffect = m_sourceGraphic.ptr();
+ for (auto& operation : operations.operations()) {
+ RefPtr<FilterEffect> effect;
+ auto& filterOperation = *operation;
+ switch (filterOperation.type()) {
+ case FilterOperation::REFERENCE: {
+ auto& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
+ effect = buildReferenceFilter(renderer, *previousEffect, referenceOperation);
+ referenceOperation.setFilterEffect(effect.copyRef());
+ break;
+ }
+ case FilterOperation::GRAYSCALE: {
+ auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
+ Vector<float> inputParameters;
+ double _oneMinusAmount_ = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0);
+
+ // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent
+ // for information on parameters.
+
+ inputParameters.append(narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
+ endMatrixRow(inputParameters);
+
+ inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
+ endMatrixRow(inputParameters);
+
+ inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount));
+ endMatrixRow(inputParameters);
+
+ lastMatrixRow(inputParameters);
+
+ effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
+ break;
+ }
+ case FilterOperation::SEPIA: {
+ auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
+ Vector<float> inputParameters;
+ double _oneMinusAmount_ = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0);
+
+ // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent
+ // for information on parameters.
+
+ inputParameters.append(narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount));
+ endMatrixRow(inputParameters);
+
+ inputParameters.append(narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount));
+ endMatrixRow(inputParameters);
+
+ inputParameters.append(narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount));
+ inputParameters.append(narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount));
+ endMatrixRow(inputParameters);
+
+ lastMatrixRow(inputParameters);
+
+ effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
+ break;
+ }
+ case FilterOperation::SATURATE: {
+ auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
+ Vector<float> inputParameters;
+ inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation.amount()));
+ effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_SATURATE, inputParameters);
+ break;
+ }
+ case FilterOperation::HUE_ROTATE: {
+ auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
+ Vector<float> inputParameters;
+ inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation.amount()));
+ effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters);
+ break;
+ }
+ case FilterOperation::INVERT: {
+ auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
+ ComponentTransferFunction transferFunction;
+ transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
+ Vector<float> transferParameters;
+ transferParameters.append(narrowPrecisionToFloat(componentTransferOperation.amount()));
+ transferParameters.append(narrowPrecisionToFloat(1 - componentTransferOperation.amount()));
+ transferFunction.tableValues = transferParameters;
+
+ ComponentTransferFunction nullFunction;
+ effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
+ break;
+ }
+ case FilterOperation::APPLE_INVERT_LIGHTNESS:
+ ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
+ break;
+ case FilterOperation::OPACITY: {
+ auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
+ ComponentTransferFunction transferFunction;
+ transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
+ Vector<float> transferParameters;
+ transferParameters.append(0);
+ transferParameters.append(narrowPrecisionToFloat(componentTransferOperation.amount()));
+ transferFunction.tableValues = transferParameters;
+
+ ComponentTransferFunction nullFunction;
+ effect = FEComponentTransfer::create(*this, nullFunction, nullFunction, nullFunction, transferFunction);
+ break;
+ }
+ case FilterOperation::BRIGHTNESS: {
+ auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
+ ComponentTransferFunction transferFunction;
+ transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
+ transferFunction.slope = narrowPrecisionToFloat(componentTransferOperation.amount());
+ transferFunction.intercept = 0;
+
+ ComponentTransferFunction nullFunction;
+ effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
+ break;
+ }
+ case FilterOperation::CONTRAST: {
+ auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
+ ComponentTransferFunction transferFunction;
+ transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
+ float amount = narrowPrecisionToFloat(componentTransferOperation.amount());
+ transferFunction.slope = amount;
+ transferFunction.intercept = -0.5 * amount + 0.5;
+
+ ComponentTransferFunction nullFunction;
+ effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
+ break;
+ }
+ case FilterOperation::BLUR: {
+ auto& blurOperation = downcast<BlurFilterOperation>(filterOperation);
+ float stdDeviation = floatValueForLength(blurOperation.stdDeviation(), 0);
+ effect = FEGaussianBlur::create(*this, stdDeviation, stdDeviation, consumer == FilterConsumer::FilterProperty ? EDGEMODE_NONE : EDGEMODE_DUPLICATE);
+ break;
+ }
+ case FilterOperation::DROP_SHADOW: {
+ auto& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation);
+ effect = FEDropShadow::create(*this, dropShadowOperation.stdDeviation(), dropShadowOperation.stdDeviation(),
+ dropShadowOperation.x(), dropShadowOperation.y(), dropShadowOperation.color(), 1);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (effect) {
+ // Unlike SVG Filters and CSSFilterImages, filter functions on the filter
+ // property applied here should not clip to their primitive subregions.
+ effect->setClipsToBounds(consumer == FilterConsumer::FilterFunction);
+ effect->setOperatingColorSpace(ColorSpaceSRGB);
+
+ if (filterOperation.type() != FilterOperation::REFERENCE) {
+ effect->inputEffects().append(WTFMove(previousEffect));
+ m_effects.append(*effect);
+ }
+ previousEffect = WTFMove(effect);
+ }
+ }
+
+ // If we didn't make any effects, tell our caller we are not valid.
+ if (m_effects.isEmpty())
+ return false;
+
+ setMaxEffectRects(m_sourceDrawingRegion);
+ return true;
+}
+
+bool CSSFilter::updateBackingStoreRect(const FloatRect& filterRect)
+{
+ if (filterRect.isEmpty() || ImageBuffer::sizeNeedsClamping(filterRect.size()))
+ return false;
+
+ if (filterRect == sourceImageRect())
+ return false;
+
+ setSourceImageRect(filterRect);
+ return true;
+}
+
+void CSSFilter::allocateBackingStoreIfNeeded(const GraphicsContext& targetContext)
+{
+ // At this point the effect chain has been built, and the
+ // source image sizes set. We just need to attach the graphic
+ // buffer if we have not yet done so.
+
+ if (m_graphicsBufferAttached)
+ return;
+
+ IntSize logicalSize { m_sourceDrawingRegion.size() };
+ if (!sourceImage() || sourceImage()->logicalSize() != logicalSize) {
+#if USE(DIRECT2D)
+ setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), &targetContext, filterScale()));
+#else
+ UNUSED_PARAM(targetContext);
+ setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), filterScale()));
+#endif
+ }
+ m_graphicsBufferAttached = true;
+}
+
+void CSSFilter::clearIntermediateResults()
+{
+ m_sourceGraphic->clearResult();
+ for (auto& effect : m_effects)
+ effect->clearResult();
+}
+
+void CSSFilter::apply()
+{
+ auto& effect = m_effects.last().get();
+ effect.apply();
+ effect.transformResultColorSpace(ColorSpaceSRGB);
+}
+
+LayoutRect CSSFilter::computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect)
+{
+ // The result of this function is the area in the "filterBoxRect" that needs to be repainted, so that we fully cover the "dirtyRect".
+ auto rectForRepaint = dirtyRect;
+ if (hasFilterThatMovesPixels()) {
+ // Note that the outsets are reversed here because we are going backwards -> we have the dirty rect and
+ // need to find out what is the rectangle that might influence the result inside that dirty rect.
+ rectForRepaint.move(-m_outsets.right(), -m_outsets.bottom());
+ rectForRepaint.expand(m_outsets.left() + m_outsets.right(), m_outsets.top() + m_outsets.bottom());
+ }
+ rectForRepaint.intersect(filterBoxRect);
+ return rectForRepaint;
+}
+
+ImageBuffer* CSSFilter::output() const
+{
+ return m_effects.last()->imageBufferResult();
+}
+
+void CSSFilter::setSourceImageRect(const FloatRect& sourceImageRect)
+{
+ m_sourceDrawingRegion = sourceImageRect;
+ setMaxEffectRects(sourceImageRect);
+ setFilterRegion(sourceImageRect);
+ m_graphicsBufferAttached = false;
+}
+
+
+void CSSFilter::setMaxEffectRects(const FloatRect& effectRect)
+{
+ for (auto& effect : m_effects)
+ effect->setMaxEffectRect(effectRect);
+}
+
+IntRect CSSFilter::outputRect() const
+{
+ auto& lastEffect = m_effects.last().get();
+ if (!lastEffect.hasResult())
+ return { };
+ return lastEffect.requestedRegionOfInputImageData(IntRect { m_filterRegion });
+}
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/rendering/CSSFilter.h (from rev 235585, trunk/Source/WebCore/rendering/FilterEffectRenderer.h) (0 => 235586)
--- trunk/Source/WebCore/rendering/CSSFilter.h (rev 0)
+++ trunk/Source/WebCore/rendering/CSSFilter.h 2018-09-02 03:04:24 UTC (rev 235586)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Filter.h"
+#include "IntRectExtent.h"
+#include "LayoutRect.h"
+#include <wtf/TypeCasts.h>
+
+namespace WebCore {
+
+class FilterEffect;
+class FilterOperations;
+class GraphicsContext;
+class ReferenceFilterOperation;
+class RenderElement;
+class SourceGraphic;
+
+enum class FilterConsumer { FilterProperty, FilterFunction };
+
+class CSSFilter final : public Filter {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ friend class FilterEffectRendererHelper;
+
+ static Ref<CSSFilter> create();
+
+ void setSourceImageRect(const FloatRect&);
+ void setFilterRegion(const FloatRect& filterRegion) { m_filterRegion = filterRegion; }
+
+ ImageBuffer* output() const;
+
+ bool build(RenderElement&, const FilterOperations&, FilterConsumer);
+ void clearIntermediateResults();
+ void apply();
+
+ bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
+ bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; }
+
+private:
+ CSSFilter();
+ virtual ~CSSFilter();
+
+ bool isCSSFilter() const final { return true; }
+
+ FloatRect sourceImageRect() const final { return m_sourceDrawingRegion; }
+ FloatRect filterRegion() const final { return m_filterRegion; }
+
+ RefPtr<FilterEffect> buildReferenceFilter(RenderElement&, FilterEffect& previousEffect, ReferenceFilterOperation&);
+
+ void setMaxEffectRects(const FloatRect&);
+
+ GraphicsContext* inputContext();
+
+ bool updateBackingStoreRect(const FloatRect& filterRect);
+ void allocateBackingStoreIfNeeded(const GraphicsContext&);
+
+ IntRect outputRect() const;
+
+ LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
+
+ FloatRect m_sourceDrawingRegion;
+ FloatRect m_filterRegion;
+
+ Vector<Ref<FilterEffect>> m_effects;
+ Ref<SourceGraphic> m_sourceGraphic;
+
+ IntRectExtent m_outsets;
+
+ bool m_graphicsBufferAttached { false };
+ bool m_hasFilterThatMovesPixels { false };
+ bool m_hasFilterThatShouldBeRestrictedBySecurityOrigin { false };
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::CSSFilter)
+ static bool isType(const WebCore::Filter& filter) { return filter.isCSSFilter(); }
+SPECIALIZE_TYPE_TRAITS_END()
Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -27,6 +27,7 @@
#include "config.h"
#include "FilterEffectRenderer.h"
+#include "CSSFilter.h"
#include "CachedSVGDocument.h"
#include "CachedSVGDocumentReference.h"
#include "ElementIterator.h"
@@ -50,349 +51,12 @@
namespace WebCore {
-static inline void endMatrixRow(Vector<float>& parameters)
-{
- parameters.append(0);
- parameters.append(0);
-}
-
-static inline void lastMatrixRow(Vector<float>& parameters)
-{
- parameters.append(0);
- parameters.append(0);
- parameters.append(0);
- parameters.append(1);
- parameters.append(0);
-}
-
-inline FilterEffectRenderer::FilterEffectRenderer()
- : Filter(FloatSize { 1, 1 })
- , m_sourceGraphic(SourceGraphic::create(*this))
-{
-}
-
-Ref<FilterEffectRenderer> FilterEffectRenderer::create()
-{
- return adoptRef(*new FilterEffectRenderer);
-}
-
-FilterEffectRenderer::~FilterEffectRenderer() = default;
-
-GraphicsContext* FilterEffectRenderer::inputContext()
-{
- return sourceImage() ? &sourceImage()->context() : nullptr;
-}
-
-RefPtr<FilterEffect> FilterEffectRenderer::buildReferenceFilter(RenderElement& renderer, FilterEffect& previousEffect, ReferenceFilterOperation& filterOperation)
-{
- auto* cachedSVGDocumentReference = filterOperation.cachedSVGDocumentReference();
- auto* cachedSVGDocument = cachedSVGDocumentReference ? cachedSVGDocumentReference->document() : nullptr;
-
- // If we have an SVG document, this is an external reference. Otherwise
- // we look up the referenced node in the current document.
- Document* document;
- if (!cachedSVGDocument)
- document = &renderer.document();
- else {
- document = cachedSVGDocument->document();
- if (!document)
- return nullptr;
- }
-
- auto* filter = document->getElementById(filterOperation.fragment());
- if (!filter) {
- // Although we did not find the referenced filter, it might exist later in the document.
- // FIXME: This skips anonymous RenderObjects. <https://webkit.org/b/131085>
- if (auto* element = renderer.element())
- document->accessSVGExtensions().addPendingResource(filterOperation.fragment(), element);
- return nullptr;
- }
-
- RefPtr<FilterEffect> effect;
-
- auto builder = std::make_unique<SVGFilterBuilder>(&previousEffect);
-
- for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(*filter)) {
- effect = effectElement.build(builder.get(), *this);
- if (!effect)
- continue;
-
- effectElement.setStandardAttributes(effect.get());
- if (effectElement.renderer())
- effect->setOperatingColorSpace(effectElement.renderer()->style().svgStyle().colorInterpolationFilters() == ColorInterpolation::LinearRGB ? ColorSpaceLinearRGB : ColorSpaceSRGB);
-
- builder->add(effectElement.result(), effect);
- m_effects.append(*effect);
- }
- return effect;
-}
-
-bool FilterEffectRenderer::build(RenderElement& renderer, const FilterOperations& operations, FilterConsumer consumer)
-{
- m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
- m_hasFilterThatShouldBeRestrictedBySecurityOrigin = operations.hasFilterThatShouldBeRestrictedBySecurityOrigin();
- if (m_hasFilterThatMovesPixels)
- m_outsets = operations.outsets();
-
- m_effects.clear();
-
- RefPtr<FilterEffect> previousEffect = m_sourceGraphic.ptr();
- for (auto& operation : operations.operations()) {
- RefPtr<FilterEffect> effect;
- auto& filterOperation = *operation;
- switch (filterOperation.type()) {
- case FilterOperation::REFERENCE: {
- auto& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
- effect = buildReferenceFilter(renderer, *previousEffect, referenceOperation);
- referenceOperation.setFilterEffect(effect.copyRef());
- break;
- }
- case FilterOperation::GRAYSCALE: {
- auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
- Vector<float> inputParameters;
- double _oneMinusAmount_ = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0);
-
- // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent
- // for information on parameters.
-
- inputParameters.append(narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
- endMatrixRow(inputParameters);
-
- inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
- endMatrixRow(inputParameters);
-
- inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount));
- endMatrixRow(inputParameters);
-
- lastMatrixRow(inputParameters);
-
- effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
- break;
- }
- case FilterOperation::SEPIA: {
- auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
- Vector<float> inputParameters;
- double _oneMinusAmount_ = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0);
-
- // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent
- // for information on parameters.
-
- inputParameters.append(narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount));
- endMatrixRow(inputParameters);
-
- inputParameters.append(narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount));
- endMatrixRow(inputParameters);
-
- inputParameters.append(narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount));
- inputParameters.append(narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount));
- endMatrixRow(inputParameters);
-
- lastMatrixRow(inputParameters);
-
- effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
- break;
- }
- case FilterOperation::SATURATE: {
- auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
- Vector<float> inputParameters;
- inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation.amount()));
- effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_SATURATE, inputParameters);
- break;
- }
- case FilterOperation::HUE_ROTATE: {
- auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
- Vector<float> inputParameters;
- inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation.amount()));
- effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters);
- break;
- }
- case FilterOperation::INVERT: {
- auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
- ComponentTransferFunction transferFunction;
- transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
- Vector<float> transferParameters;
- transferParameters.append(narrowPrecisionToFloat(componentTransferOperation.amount()));
- transferParameters.append(narrowPrecisionToFloat(1 - componentTransferOperation.amount()));
- transferFunction.tableValues = transferParameters;
-
- ComponentTransferFunction nullFunction;
- effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
- break;
- }
- case FilterOperation::APPLE_INVERT_LIGHTNESS:
- ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
- break;
- case FilterOperation::OPACITY: {
- auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
- ComponentTransferFunction transferFunction;
- transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
- Vector<float> transferParameters;
- transferParameters.append(0);
- transferParameters.append(narrowPrecisionToFloat(componentTransferOperation.amount()));
- transferFunction.tableValues = transferParameters;
-
- ComponentTransferFunction nullFunction;
- effect = FEComponentTransfer::create(*this, nullFunction, nullFunction, nullFunction, transferFunction);
- break;
- }
- case FilterOperation::BRIGHTNESS: {
- auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
- ComponentTransferFunction transferFunction;
- transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
- transferFunction.slope = narrowPrecisionToFloat(componentTransferOperation.amount());
- transferFunction.intercept = 0;
-
- ComponentTransferFunction nullFunction;
- effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
- break;
- }
- case FilterOperation::CONTRAST: {
- auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
- ComponentTransferFunction transferFunction;
- transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
- float amount = narrowPrecisionToFloat(componentTransferOperation.amount());
- transferFunction.slope = amount;
- transferFunction.intercept = -0.5 * amount + 0.5;
-
- ComponentTransferFunction nullFunction;
- effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
- break;
- }
- case FilterOperation::BLUR: {
- auto& blurOperation = downcast<BlurFilterOperation>(filterOperation);
- float stdDeviation = floatValueForLength(blurOperation.stdDeviation(), 0);
- effect = FEGaussianBlur::create(*this, stdDeviation, stdDeviation, consumer == FilterProperty ? EDGEMODE_NONE : EDGEMODE_DUPLICATE);
- break;
- }
- case FilterOperation::DROP_SHADOW: {
- auto& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation);
- effect = FEDropShadow::create(*this, dropShadowOperation.stdDeviation(), dropShadowOperation.stdDeviation(),
- dropShadowOperation.x(), dropShadowOperation.y(), dropShadowOperation.color(), 1);
- break;
- }
- default:
- break;
- }
-
- if (effect) {
- // Unlike SVG Filters and CSSFilterImages, filter functions on the filter
- // property applied here should not clip to their primitive subregions.
- effect->setClipsToBounds(consumer == FilterFunction);
- effect->setOperatingColorSpace(ColorSpaceSRGB);
-
- if (filterOperation.type() != FilterOperation::REFERENCE) {
- effect->inputEffects().append(WTFMove(previousEffect));
- m_effects.append(*effect);
- }
- previousEffect = WTFMove(effect);
- }
- }
-
- // If we didn't make any effects, tell our caller we are not valid.
- if (m_effects.isEmpty())
- return false;
-
- setMaxEffectRects(m_sourceDrawingRegion);
- return true;
-}
-
-bool FilterEffectRenderer::updateBackingStoreRect(const FloatRect& filterRect)
-{
- if (filterRect.isEmpty() || ImageBuffer::sizeNeedsClamping(filterRect.size()))
- return false;
-
- if (filterRect == sourceImageRect())
- return false;
-
- setSourceImageRect(filterRect);
- return true;
-}
-
-void FilterEffectRenderer::allocateBackingStoreIfNeeded(const GraphicsContext& targetContext)
-{
- // At this point the effect chain has been built, and the
- // source image sizes set. We just need to attach the graphic
- // buffer if we have not yet done so.
-
- if (m_graphicsBufferAttached)
- return;
-
- IntSize logicalSize { m_sourceDrawingRegion.size() };
- if (!sourceImage() || sourceImage()->logicalSize() != logicalSize) {
-#if USE(DIRECT2D)
- setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), &targetContext, filterScale()));
-#else
- UNUSED_PARAM(targetContext);
- setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), filterScale()));
-#endif
- }
- m_graphicsBufferAttached = true;
-}
-
-void FilterEffectRenderer::clearIntermediateResults()
-{
- m_sourceGraphic->clearResult();
- for (auto& effect : m_effects)
- effect->clearResult();
-}
-
-void FilterEffectRenderer::apply()
-{
- auto& effect = m_effects.last().get();
- effect.apply();
- effect.transformResultColorSpace(ColorSpaceSRGB);
-}
-
-LayoutRect FilterEffectRenderer::computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect)
-{
- // The result of this function is the area in the "filterBoxRect" that needs to be repainted, so that we fully cover the "dirtyRect".
- auto rectForRepaint = dirtyRect;
- if (hasFilterThatMovesPixels()) {
- // Note that the outsets are reversed here because we are going backwards -> we have the dirty rect and
- // need to find out what is the rectangle that might influence the result inside that dirty rect.
- rectForRepaint.move(-m_outsets.right(), -m_outsets.bottom());
- rectForRepaint.expand(m_outsets.left() + m_outsets.right(), m_outsets.top() + m_outsets.bottom());
- }
- rectForRepaint.intersect(filterBoxRect);
- return rectForRepaint;
-}
-
-ImageBuffer* FilterEffectRenderer::output() const
-{
- return m_effects.last()->imageBufferResult();
-}
-
-void FilterEffectRenderer::setMaxEffectRects(const FloatRect& effectRect)
-{
- for (auto& effect : m_effects)
- effect->setMaxEffectRect(effectRect);
-}
-
-IntRect FilterEffectRenderer::outputRect() const
-{
- auto& lastEffect = m_effects.last().get();
- if (!lastEffect.hasResult())
- return { };
- return lastEffect.requestedRegionOfInputImageData(IntRect { m_filterRegion });
-}
-
bool FilterEffectRendererHelper::prepareFilterEffect(RenderLayer& layer, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)
{
ASSERT(m_haveFilterEffect);
- ASSERT(layer.filterRenderer());
+ ASSERT(layer.filter());
- auto& filter = *layer.filterRenderer();
+ auto& filter = *layer.filter();
auto filterSourceRect = filter.computeSourceImageRectForDirtyRect(filterBoxRect, dirtyRect);
if (filterSourceRect.isEmpty()) {
@@ -424,15 +88,15 @@
{
if (!m_haveFilterEffect)
return nullptr;
- return m_renderLayer->filterRenderer()->inputContext();
+ return m_renderLayer->filter()->inputContext();
}
bool FilterEffectRendererHelper::beginFilterEffect()
{
ASSERT(m_renderLayer);
- ASSERT(m_renderLayer->filterRenderer());
+ ASSERT(m_renderLayer->filter());
- auto& filter = *m_renderLayer->filterRenderer();
+ auto& filter = *m_renderLayer->filter();
filter.allocateBackingStoreIfNeeded(m_targetContext);
// Paint into the context that represents the SourceGraphic of the filter.
auto* sourceGraphicsContext = filter.inputContext();
@@ -456,12 +120,12 @@
{
ASSERT(m_haveFilterEffect);
ASSERT(m_renderLayer);
- ASSERT(m_renderLayer->filterRenderer());
- ASSERT(m_renderLayer->filterRenderer()->inputContext());
+ ASSERT(m_renderLayer->filter());
+ ASSERT(m_renderLayer->filter()->inputContext());
LOG_WITH_STREAM(Filters, stream << "\nFilterEffectRendererHelper " << this << " applyFilterEffect");
- auto& filter = *m_renderLayer->filterRenderer();
+ auto& filter = *m_renderLayer->filter();
filter.inputContext()->restore();
filter.apply();
Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.h (235585 => 235586)
--- trunk/Source/WebCore/rendering/FilterEffectRenderer.h 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.h 2018-09-02 03:04:24 UTC (rev 235586)
@@ -25,27 +25,22 @@
#pragma once
-#include "Filter.h"
-#include "IntRectExtent.h"
#include "LayoutRect.h"
namespace WebCore {
class Document;
-class FilterEffect;
-class FilterOperations;
class GraphicsContext;
-class ReferenceFilterOperation;
-class RenderElement;
class RenderLayer;
-class SourceGraphic;
-enum FilterConsumer { FilterProperty, FilterFunction };
-
class FilterEffectRendererHelper {
WTF_MAKE_FAST_ALLOCATED;
public:
- FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext);
+ FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext)
+ : m_targetContext(targetContext)
+ , m_haveFilterEffect(haveFilterEffect)
+ {
+ }
bool haveFilterEffect() const { return m_haveFilterEffect; }
bool hasStartedFilterEffect() const { return m_startedFilterEffect; }
@@ -59,7 +54,7 @@
const LayoutRect& repaintRect() const { return m_repaintRect; }
private:
- RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the FilterEffectRenderer. FilterEffectRendererHelper should be weaned off it.
+ RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the CSSFilter. FilterEffectRendererHelper should be weaned off it.
LayoutPoint m_paintOffset;
LayoutRect m_repaintRect;
const GraphicsContext& m_targetContext;
@@ -67,71 +62,4 @@
bool m_startedFilterEffect { false };
};
-// This is used to render filters for the CSS filter: property, and the filter() image function.
-class FilterEffectRenderer final : public Filter {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- friend class FilterEffectRendererHelper;
-
- static Ref<FilterEffectRenderer> create();
-
- void setSourceImageRect(const FloatRect&);
- void setFilterRegion(const FloatRect& filterRegion) { m_filterRegion = filterRegion; }
-
- ImageBuffer* output() const;
-
- bool build(RenderElement&, const FilterOperations&, FilterConsumer);
- void clearIntermediateResults();
- void apply();
-
- bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
- bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; }
-
-private:
- FilterEffectRenderer();
- virtual ~FilterEffectRenderer();
-
- FloatRect sourceImageRect() const final { return m_sourceDrawingRegion; }
- FloatRect filterRegion() const final { return m_filterRegion; }
-
- RefPtr<FilterEffect> buildReferenceFilter(RenderElement&, FilterEffect& previousEffect, ReferenceFilterOperation&);
-
- void setMaxEffectRects(const FloatRect&);
-
- GraphicsContext* inputContext();
-
- bool updateBackingStoreRect(const FloatRect& filterRect);
- void allocateBackingStoreIfNeeded(const GraphicsContext&);
-
- IntRect outputRect() const;
-
- LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
-
- FloatRect m_sourceDrawingRegion;
- FloatRect m_filterRegion;
-
- Vector<Ref<FilterEffect>> m_effects;
- Ref<SourceGraphic> m_sourceGraphic;
-
- IntRectExtent m_outsets;
-
- bool m_graphicsBufferAttached { false };
- bool m_hasFilterThatMovesPixels { false };
- bool m_hasFilterThatShouldBeRestrictedBySecurityOrigin { false };
-};
-
-inline FilterEffectRendererHelper::FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext)
- : m_targetContext(targetContext)
- , m_haveFilterEffect(haveFilterEffect)
-{
-}
-
-inline void FilterEffectRenderer::setSourceImageRect(const FloatRect& sourceImageRect)
-{
- m_sourceDrawingRegion = sourceImageRect;
- setMaxEffectRects(sourceImageRect);
- setFilterRegion(sourceImageRect);
- m_graphicsBufferAttached = false;
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -35,6 +35,7 @@
#include "HitTestLocation.h"
#include "InlineTextBox.h"
#include "LayoutRepainter.h"
+#include "LayoutState.h"
#include "Logging.h"
#include "RenderCombineText.h"
#include "RenderFlexibleBox.h"
Modified: trunk/Source/WebCore/rendering/RenderFrame.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderFrame.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderFrame.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -26,6 +26,7 @@
#include "HTMLFrameElement.h"
#include "RenderFrameSet.h"
+#include <wtf/IsoMallocInlines.h>
namespace WebCore {
Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderImage.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -45,6 +45,7 @@
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "InlineElementBox.h"
+#include "LayoutState.h"
#include "Page.h"
#include "PaintInfo.h"
#include "RenderFragmentedFlow.h"
@@ -53,6 +54,7 @@
#include "RenderView.h"
#include "RuntimeEnabledFeatures.h"
#include "SVGImage.h"
+#include "Settings.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/StackStats.h>
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -46,6 +46,7 @@
#include "BoxShape.h"
#include "CSSAnimationController.h"
+#include "CSSFilter.h"
#include "CSSPropertyNames.h"
#include "Chrome.h"
#include "DebugPageOverlays.h"
@@ -461,14 +462,14 @@
{
if (!paintsWithFilters())
return false;
- auto* renderer = filterRenderer();
- return renderer && renderer->hasFilterThatMovesPixels();
+ auto* cssFilter = filter();
+ return cssFilter && cssFilter->hasFilterThatMovesPixels();
}
-FilterEffectRenderer* RenderLayer::filterRenderer() const
+CSSFilter* RenderLayer::filter() const
{
auto* filterInfo = FilterInfo::getIfExists(*this);
- return filterInfo ? filterInfo->renderer() : nullptr;
+ return filterInfo ? filterInfo->filter() : nullptr;
}
void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, OptionSet<UpdateLayerPositionsFlag> flags)
@@ -4207,7 +4208,7 @@
return { };
auto* info = FilterInfo::getIfExists(*this);
- if (!info || !info->renderer())
+ if (!info || !info->filter())
return { };
auto helper = std::make_unique<FilterEffectRendererHelper>(true, context);
@@ -4253,9 +4254,9 @@
// If the filter needs the full source image, we need to avoid using the clip rectangles.
// Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
// Note that we will still apply the clipping on the final rendering of the filter.
- paintingInfo.clipToDirtyRect = !filterInfo.renderer()->hasFilterThatMovesPixels();
+ paintingInfo.clipToDirtyRect = !filterInfo.filter()->hasFilterThatMovesPixels();
- paintingInfo.requireSecurityOriginAccessForWidgets = filterInfo.renderer()->hasFilterThatShouldBeRestrictedBySecurityOrigin();
+ paintingInfo.requireSecurityOriginAccessForWidgets = filterInfo.filter()->hasFilterThatShouldBeRestrictedBySecurityOrigin();
return WTFMove(painter.second);
}
@@ -6882,7 +6883,7 @@
// Don't delete the whole filter info here, because we might use it
// for loading SVG reference filter files.
if (FilterInfo* filterInfo = FilterInfo::getIfExists(*this))
- filterInfo->setRenderer(nullptr);
+ filterInfo->setFilter(nullptr);
// Early-return only if we *don't* have reference filters.
// For reference filters, we still want the FilterEffect graph built
@@ -6892,23 +6893,23 @@
}
FilterInfo& filterInfo = FilterInfo::get(*this);
- if (!filterInfo.renderer()) {
- RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
- filterRenderer->setFilterScale(page().deviceScaleFactor());
- filterRenderer->setRenderingMode(renderer().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated);
- filterInfo.setRenderer(WTFMove(filterRenderer));
+ if (!filterInfo.filter()) {
+ auto cssFilter = CSSFilter::create();
+ cssFilter->setFilterScale(page().deviceScaleFactor());
+ cssFilter->setRenderingMode(renderer().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated);
+ filterInfo.setFilter(WTFMove(cssFilter));
// We can optimize away code paths in other places if we know that there are no software filters.
renderer().view().setHasSoftwareFilters(true);
- } else if (filterInfo.renderer()->filterScale() != page().deviceScaleFactor()) {
- filterInfo.renderer()->setFilterScale(page().deviceScaleFactor());
- filterInfo.renderer()->clearIntermediateResults();
+ } else if (filterInfo.filter()->filterScale() != page().deviceScaleFactor()) {
+ filterInfo.filter()->setFilterScale(page().deviceScaleFactor());
+ filterInfo.filter()->clearIntermediateResults();
}
// If the filter fails to build, remove it from the layer. It will still attempt to
// go through regular processing (e.g. compositing), but never apply anything.
- if (!filterInfo.renderer()->build(renderer(), renderer().style().filter(), FilterProperty))
- filterInfo.setRenderer(nullptr);
+ if (!filterInfo.filter()->build(renderer(), renderer().style().filter(), FilterConsumer::FilterProperty))
+ filterInfo.setFilter(nullptr);
}
void RenderLayer::filterNeedsRepaint()
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2018-09-02 03:04:24 UTC (rev 235586)
@@ -60,9 +60,9 @@
namespace WebCore {
+class CSSFilter;
class ClipRects;
class ClipRectsCache;
-class FilterEffectRenderer;
class FilterEffectRendererHelper;
class FilterOperations;
class HitTestRequest;
@@ -679,7 +679,7 @@
bool paintsWithFilters() const;
bool requiresFullLayerImageForFilters() const;
- FilterEffectRenderer* filterRenderer() const;
+ CSSFilter* filter() const;
#if !ASSERT_DISABLED
bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -34,7 +34,6 @@
#include "CachedImage.h"
#include "Chrome.h"
#include "DocumentTimeline.h"
-#include "FilterEffectRenderer.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
Modified: trunk/Source/WebCore/rendering/RenderLayerFilterInfo.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderLayerFilterInfo.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderLayerFilterInfo.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -84,9 +84,9 @@
removeReferenceFilterClients();
}
-void RenderLayer::FilterInfo::setRenderer(RefPtr<FilterEffectRenderer>&& renderer)
+void RenderLayer::FilterInfo::setFilter(RefPtr<CSSFilter>&& filter)
{
- m_renderer = renderer;
+ m_filter = filter;
}
void RenderLayer::FilterInfo::notifyFinished(CachedResource&)
@@ -108,14 +108,14 @@
m_externalSVGReferences.append(cachedSVGDocument);
} else {
// Reference is internal; add layer as a client so we can trigger filter repaint on SVG attribute change.
- auto* filter = m_layer.renderer().document().getElementById(referenceOperation.fragment());
- if (!filter)
+ auto* filterElement = m_layer.renderer().document().getElementById(referenceOperation.fragment());
+ if (!filterElement)
continue;
- auto* renderer = filter->renderer();
+ auto* renderer = filterElement->renderer();
if (!is<RenderSVGResourceFilter>(renderer))
continue;
downcast<RenderSVGResourceFilter>(*renderer).addClientRenderLayer(&m_layer);
- m_internalSVGReferences.append(filter);
+ m_internalSVGReferences.append(filterElement);
}
}
}
@@ -124,10 +124,11 @@
{
for (auto& resourceHandle : m_externalSVGReferences)
resourceHandle->removeClient(*this);
+
m_externalSVGReferences.clear();
- for (auto& filter : m_internalSVGReferences) {
- if (auto* renderer = filter->renderer())
+ for (auto& filterElement : m_internalSVGReferences) {
+ if (auto* renderer = filterElement->renderer())
downcast<RenderSVGResourceContainer>(*renderer).removeClientRenderLayer(&m_layer);
}
m_internalSVGReferences.clear();
Modified: trunk/Source/WebCore/rendering/RenderLayerFilterInfo.h (235585 => 235586)
--- trunk/Source/WebCore/rendering/RenderLayerFilterInfo.h 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/RenderLayerFilterInfo.h 2018-09-02 03:04:24 UTC (rev 235586)
@@ -55,8 +55,8 @@
void expandDirtySourceRect(const LayoutRect& rect) { m_dirtySourceRect.unite(rect); }
void resetDirtySourceRect() { m_dirtySourceRect = LayoutRect(); }
- FilterEffectRenderer* renderer() const { return m_renderer.get(); }
- void setRenderer(RefPtr<FilterEffectRenderer>&&);
+ CSSFilter* filter() const { return m_filter.get(); }
+ void setFilter(RefPtr<CSSFilter>&&);
void updateReferenceFilterClients(const FilterOperations&);
void removeReferenceFilterClients();
@@ -68,7 +68,7 @@
RenderLayer& m_layer;
- RefPtr<FilterEffectRenderer> m_renderer;
+ RefPtr<CSSFilter> m_filter;
LayoutRect m_dirtySourceRect;
Vector<RefPtr<Element>> m_internalSVGReferences;
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp (235585 => 235586)
--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp 2018-09-02 02:54:58 UTC (rev 235585)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp 2018-09-02 03:04:24 UTC (rev 235586)
@@ -33,6 +33,7 @@
#include "RenderRuby.h"
#include "RenderRubyRun.h"
#include "RenderTextControl.h"
+#include "RenderTreeBuilderMultiColumn.h"
namespace WebCore {