Diff
Modified: trunk/LayoutTests/ChangeLog (286525 => 286526)
--- trunk/LayoutTests/ChangeLog 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/LayoutTests/ChangeLog 2021-12-04 06:12:25 UTC (rev 286526)
@@ -1,3 +1,14 @@
+2021-12-03 Said Abou-Hallawa <[email protected]>
+
+ [GPU Process] (REGRESSION r285597): Fix SVGFilter clamping calculation
+ https://bugs.webkit.org/show_bug.cgi?id=233843
+
+ Reviewed by Simon Fraser.
+
+ Unskip two layout tests which were skipped in r285597.
+
+ * TestExpectations:
+
2021-12-03 Lauro Moura <[email protected]>
[GLIB] Gardening some consistent timeouts
Modified: trunk/LayoutTests/TestExpectations (286525 => 286526)
--- trunk/LayoutTests/TestExpectations 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/LayoutTests/TestExpectations 2021-12-04 06:12:25 UTC (rev 286526)
@@ -5174,10 +5174,8 @@
webkit.org/b/232705 fast/filter-image/filter-image-blur.html [ Skip ]
webkit.org/b/232705 fast/filter-image/filter-image-svg.html [ Skip ]
webkit.org/b/232705 fast/filter-image/filter-image.html [ Skip ]
-webkit.org/b/232705 imported/blink/svg/filters/filter-huge-clamping.svg [ Skip ]
webkit.org/b/232705 imported/mozilla/svg/dynamic-filter-contents-01a.svg [ Skip ]
webkit.org/b/232705 imported/mozilla/svg/filters/feComposite-2.svg [ Skip ]
webkit.org/b/232705 imported/mozilla/svg/filters/feSpecularLighting-1.svg [ Skip ]
webkit.org/b/232705 svg/custom/resources-css-scaled.html [ Skip ]
webkit.org/b/232705 svg/filters/feLighting-clipped.svg [ Skip ]
-webkit.org/b/232705 svg/filters/big-sized-off-viewport-filter.svg [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (286525 => 286526)
--- trunk/Source/WebCore/ChangeLog 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/ChangeLog 2021-12-04 06:12:25 UTC (rev 286526)
@@ -1,3 +1,60 @@
+2021-12-03 Said Abou-Hallawa <[email protected]>
+
+ [GPU Process] (REGRESSION r285597): Fix SVGFilter clamping calculation
+ https://bugs.webkit.org/show_bug.cgi?id=233843
+
+ Reviewed by Simon Fraser.
+
+ In this patch:
+
+ 1. lastEffect() is made virtual function of Filter and it's already
+ implemented as non-virtual function in both CSSFilter and SVGFilter.
+
+ 2. The clamping calculations for SVGFilter and CSSFilter are merged in
+ one function called Filter::clampFilterRegionIfNeeded(). This merge
+ makes the new function is the only caller to FilterEffect::maxEffectRect().
+
+ 3. Remove FilterEffect::maxEffectRect() . It can be calculated by clipping
+ the FilterEffect::filterPrimitiveSubregion() to filterRegion() and then
+ scaling the result by filterScale().
+
+ 4. In RenderSVGResourceFilter::applyResource() we need to pass the non-
+ scaled drawingRegion to ImageBuffer::sizeNeedsClamping() because this
+ function starts by scaling the argument 'size' by the argument 'scale'.
+ So we were doubling the scaling by passing 'absoluteDrawingRegion'
+
+ 5. SVGRenderingContext::createImageBuffer() needs to use ImageBuffer::
+ sizeNeedsClamping() instead of using ImageBuffer::clampedSize(). The
+ former function clamps the size to the MaxClampedArea. But the later
+ function shrinks the size to { MaxClampedLength, MaxClampedLength }.
+ When calling createImageBuffer() from RenderSVGResourceFilter::
+ applyResource() we do not expect any further clamping. But if we pass
+ a size with a side greater than MaxClampedLength to clampedSize(),
+ it will be clamped even if the area is less than MaxClampedArea. And
+ for filters we clamp to the area.
+
+ * platform/graphics/filters/Filter.cpp:
+ (WebCore::Filter::clampFilterRegionIfNeeded):
+ * platform/graphics/filters/Filter.h:
+ * platform/graphics/filters/FilterEffect.cpp:
+ (WebCore::FilterEffect::determineFilterPrimitiveSubregion):
+ (WebCore::FilterEffect::apply):
+ * platform/graphics/filters/FilterEffect.h:
+ (WebCore::FilterEffect::maxEffectRect const): Deleted.
+ (WebCore::FilterEffect::setMaxEffectRect): Deleted.
+ * rendering/CSSFilter.cpp:
+ (WebCore::CSSFilter::lastEffect const):
+ (WebCore::CSSFilter::lastEffect): Deleted.
+ (WebCore::CSSFilter::determineFilterPrimitiveSubregion): Deleted.
+ * rendering/CSSFilter.h:
+ * rendering/RenderLayerFilters.cpp:
+ (WebCore::RenderLayerFilters::beginFilterEffect):
+ * rendering/svg/RenderSVGResourceFilter.cpp:
+ (WebCore::RenderSVGResourceFilter::applyResource):
+ * rendering/svg/SVGRenderingContext.cpp:
+ (WebCore::SVGRenderingContext::createImageBuffer):
+ * svg/graphics/filters/SVGFilter.h:
+
2021-12-03 Chris Dumez <[email protected]>
Add BroadcastChannel, COOP, COEP and Web Locks to features.json
Modified: trunk/Source/WebCore/platform/graphics/filters/Filter.cpp (286525 => 286526)
--- trunk/Source/WebCore/platform/graphics/filters/Filter.cpp 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.cpp 2021-12-04 06:12:25 UTC (rev 286526)
@@ -26,7 +26,9 @@
#include "config.h"
#include "Filter.h"
+#include "FilterEffect.h"
#include "FilterImage.h"
+#include "ImageBuffer.h"
namespace WebCore {
@@ -76,6 +78,26 @@
return m_clipOperation == ClipOperation::Intersect ? intersection(imageRect, maxEffectRect) : unionRect(imageRect, maxEffectRect);
}
+bool Filter::clampFilterRegionIfNeeded()
+{
+ auto lastEffect = this->lastEffect();
+ lastEffect->determineFilterPrimitiveSubregion(*this);
+
+ auto maxEffectRect = this->maxEffectRect(lastEffect->filterPrimitiveSubregion());
+ auto scaledMaxEffectRect = scaledByFilterScale(maxEffectRect);
+
+ FloatSize clampingScale(1, 1);
+ if (!ImageBuffer::sizeNeedsClamping(scaledMaxEffectRect.size(), clampingScale))
+ return false;
+
+ m_filterScale = m_filterScale * clampingScale;
+
+ // At least one FilterEffect has a too big image size,
+ // recalculate the effect sizes with new scale factors.
+ lastEffect->determineFilterPrimitiveSubregion(*this);
+ return true;
+}
+
RefPtr<FilterImage> Filter::apply(ImageBuffer* sourceImage)
{
setSourceImage(sourceImage);
Modified: trunk/Source/WebCore/platform/graphics/filters/Filter.h (286525 => 286526)
--- trunk/Source/WebCore/platform/graphics/filters/Filter.h 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.h 2021-12-04 06:12:25 UTC (rev 286526)
@@ -67,6 +67,10 @@
FloatRect maxEffectRect(const FloatRect& primitiveSubregion) const;
FloatRect clipToMaxEffectRect(const FloatRect& imageRect, const FloatRect& primitiveSubregion) const;
+ virtual RefPtr<FilterEffect> lastEffect() const = 0;
+
+ bool clampFilterRegionIfNeeded();
+
virtual RefPtr<FilterImage> apply() = 0;
WEBCORE_EXPORT RefPtr<FilterImage> apply(ImageBuffer* sourceImage);
Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (286525 => 286526)
--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp 2021-12-04 06:12:25 UTC (rev 286526)
@@ -70,13 +70,7 @@
primitiveSubregion.setHeight(*height);
}
- // Clip every filter effect to the filter region.
- auto absoluteMaxEffectRect = filter.maxEffectRect(primitiveSubregion);
- absoluteMaxEffectRect.scale(filter.filterScale());
-
setFilterPrimitiveSubregion(primitiveSubregion);
- setMaxEffectRect(absoluteMaxEffectRect);
-
return primitiveSubregion;
}
@@ -127,7 +121,7 @@
<< "FilterEffect " << filterName() << " " << this << " apply():"
<< "\n filterPrimitiveSubregion " << m_filterPrimitiveSubregion
<< "\n absolutePaintRect " << absoluteImageRect
- << "\n maxEffectRect " << m_maxEffectRect
+ << "\n maxEffectRect " << filter.scaledByFilterScale(filter.maxEffectRect(m_filterPrimitiveSubregion))
<< "\n filter scale " << filter.filterScale());
return applier->apply(filter, inputFilterImages, *m_filterImage);
Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h (286525 => 286526)
--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h 2021-12-04 06:12:25 UTC (rev 286526)
@@ -56,9 +56,6 @@
// Recurses on inputs.
FloatRect determineFilterPrimitiveSubregion(const Filter&);
- FloatRect maxEffectRect() const { return m_maxEffectRect; }
- void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; }
-
bool apply(const Filter&) override;
// Correct any invalid pixels, if necessary, in the result of a filter operation.
@@ -96,10 +93,6 @@
RefPtr<FilterImage> m_filterImage;
- // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space.
- // The absolute paint rect should never be bigger than m_maxEffectRect.
- FloatRect m_maxEffectRect;
-
// The subregion of a filter primitive according to the SVG Filter specification in local coordinates.
// This is SVG specific and needs to move to RenderSVGResourceFilterPrimitive.
FloatRect m_filterPrimitiveSubregion;
Modified: trunk/Source/WebCore/rendering/CSSFilter.cpp (286525 => 286526)
--- trunk/Source/WebCore/rendering/CSSFilter.cpp 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/rendering/CSSFilter.cpp 2021-12-04 06:12:25 UTC (rev 286526)
@@ -31,7 +31,6 @@
#include "FEComponentTransfer.h"
#include "FEDropShadow.h"
#include "FEGaussianBlur.h"
-#include "FEMerge.h"
#include "FilterOperations.h"
#include "GraphicsContext.h"
#include "LengthFunctions.h"
@@ -43,10 +42,6 @@
#include "SVGFilterElement.h"
#include "SourceGraphic.h"
-#if USE(DIRECT2D)
-#include <d2d1.h>
-#endif
-
namespace WebCore {
RefPtr<CSSFilter> CSSFilter::create(const FilterOperations& operations, RenderingMode renderingMode, float scaleFactor, ClipOperation clipOperation)
@@ -336,7 +331,7 @@
return true;
}
-RefPtr<FilterEffect> CSSFilter::lastEffect()
+RefPtr<FilterEffect> CSSFilter::lastEffect() const
{
if (m_functions.isEmpty())
return nullptr;
@@ -363,19 +358,6 @@
}
#endif
-void CSSFilter::determineFilterPrimitiveSubregion()
-{
- auto effect = lastEffect();
- effect->determineFilterPrimitiveSubregion(*this);
- FloatRect subRegion = effect->maxEffectRect();
- // At least one FilterEffect has a too big image size, recalculate the effect sizes with new scale factors.
- FloatSize filterScale { 1, 1 };
- if (ImageBuffer::sizeNeedsClamping(subRegion.size(), filterScale)) {
- setFilterScale(filterScale);
- effect->determineFilterPrimitiveSubregion(*this);
- }
-}
-
void CSSFilter::clearIntermediateResults()
{
for (auto& function : m_functions)
Modified: trunk/Source/WebCore/rendering/CSSFilter.h (286525 => 286526)
--- trunk/Source/WebCore/rendering/CSSFilter.h 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/rendering/CSSFilter.h 2021-12-04 06:12:25 UTC (rev 286526)
@@ -46,16 +46,15 @@
void setSourceImageRect(const FloatRect&);
bool buildFilterFunctions(RenderElement&, const FilterOperations&);
- void determineFilterPrimitiveSubregion();
bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; }
- RefPtr<FilterEffect> lastEffect();
- IntOutsets outsets() const override;
+ RefPtr<FilterEffect> lastEffect() const final;
+ IntOutsets outsets() const final;
void clearIntermediateResults();
- RefPtr<FilterImage> apply() override;
+ RefPtr<FilterImage> apply() final;
bool updateBackingStoreRect(const FloatRect& filterRect);
@@ -65,7 +64,7 @@
CSSFilter(RenderingMode, float scaleFactor, ClipOperation, bool hasFilterThatMovesPixels, bool hasFilterThatShouldBeRestrictedBySecurityOrigin);
#if USE(CORE_IMAGE)
- bool supportsCoreImageRendering() const override;
+ bool supportsCoreImageRendering() const final;
#endif
bool m_hasFilterThatMovesPixels { false };
Modified: trunk/Source/WebCore/rendering/RenderLayerFilters.cpp (286525 => 286526)
--- trunk/Source/WebCore/rendering/RenderLayerFilters.cpp 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/rendering/RenderLayerFilters.cpp 2021-12-04 06:12:25 UTC (rev 286526)
@@ -180,7 +180,7 @@
m_paintOffset = filterSourceRect.location();
resetDirtySourceRect();
- filter.determineFilterPrimitiveSubregion();
+ filter.clampFilterRegionIfNeeded();
if (hasUpdatedBackingStore)
allocateBackingStore(destinationContext);
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (286525 => 286526)
--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp 2021-12-04 06:12:25 UTC (rev 286526)
@@ -122,9 +122,7 @@
filterData->drawingRegion.intersect(filterData->boundaries);
// Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
- FloatRect absoluteDrawingRegion = filterData->drawingRegion;
- absoluteDrawingRegion.scale(filterScale);
- ImageBuffer::sizeNeedsClamping(absoluteDrawingRegion.size(), filterScale);
+ ImageBuffer::sizeNeedsClamping(filterData->drawingRegion.size(), filterScale);
// Set the rendering mode from the page's settings.
auto renderingMode = renderer.settings().acceleratedFiltersEnabled() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
@@ -137,21 +135,9 @@
return false;
}
- auto lastEffect = filterData->builder->lastEffect();
- ASSERT(lastEffect);
-
- LOG_WITH_STREAM(Filters, stream << "RenderSVGResourceFilter::applyResource\n" << *filterData->builder->lastEffect());
-
- lastEffect->determineFilterPrimitiveSubregion(*filterData->filter);
- FloatRect subRegion = lastEffect->maxEffectRect();
-
- // At least one FilterEffect has a too big image size,
- // recalculate the effect sizes with new scale factors.
- if (ImageBuffer::sizeNeedsClamping(subRegion.size(), filterScale)) {
- filterData->filter->setFilterScale(filterScale);
- lastEffect->determineFilterPrimitiveSubregion(*filterData->filter);
- }
-
+ if (filterData->filter->clampFilterRegionIfNeeded())
+ filterScale = filterData->filter->filterScale();
+
// If the drawingRegion is empty, we have something like <g filter=".."/>.
// Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
if (filterData->drawingRegion.isEmpty()) {
Modified: trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp (286525 => 286526)
--- trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp 2021-12-04 06:12:25 UTC (rev 286526)
@@ -235,8 +235,10 @@
if (paintRect.isEmpty())
return nullptr;
- FloatSize scale;
- FloatSize clampedSize = ImageBuffer::clampedSize(paintRect.size(), scale);
+ FloatSize scale(1, 1);
+ FloatSize clampedSize = paintRect.size();
+ if (ImageBuffer::sizeNeedsClamping(clampedSize, scale))
+ clampedSize = clampedSize * scale;
#if USE(DIRECT2D)
auto imageBuffer = ImageBuffer::create(clampedSize, renderingMode, context, 1, colorSpace, PixelFormat::BGRA8);
Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h (286525 => 286526)
--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h 2021-12-04 03:30:03 UTC (rev 286525)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h 2021-12-04 06:12:25 UTC (rev 286526)
@@ -42,9 +42,9 @@
FloatRect targetBoundingBox() const { return m_targetBoundingBox; }
- RefPtr<FilterEffect> lastEffect() const { return !m_expression.isEmpty() ? m_expression.last() : nullptr; }
+ RefPtr<FilterEffect> lastEffect() const final { return !m_expression.isEmpty() ? m_expression.last() : nullptr; }
- RefPtr<FilterImage> apply() override;
+ RefPtr<FilterImage> apply() final;
private:
SVGFilter(RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, ClipOperation, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits);
@@ -54,14 +54,14 @@
void setEffectGeometryMap(FilterEffectGeometryMap&& effectGeometryMap) { m_effectGeometryMap = WTFMove(effectGeometryMap); }
#if USE(CORE_IMAGE)
- bool supportsCoreImageRendering() const override;
+ bool supportsCoreImageRendering() const final;
#endif
- std::optional<FilterEffectGeometry> effectGeometry(FilterEffect&) const override;
+ std::optional<FilterEffectGeometry> effectGeometry(FilterEffect&) const final;
FloatSize resolvedSize(const FloatSize&) const final;
- bool apply(const Filter&) override;
- IntOutsets outsets() const override;
- void clearResult() override;
+ bool apply(const Filter&) final;
+ IntOutsets outsets() const final;
+ void clearResult() final;
FloatRect m_targetBoundingBox;
SVGUnitTypes::SVGUnitType m_primitiveUnits;