Skip to content

Commit

Permalink
Cherry-pick b686ba4. rdar://problem/109673458
Browse files Browse the repository at this point in the history
    [GPU Process] [Filters] Cache the SVGFilter applying results in RemoteResourceCache
    https://bugs.webkit.org/show_bug.cgi?id=232845
    rdar://85426641

    Reviewed by Simon Fraser.

    This allows caching the results of applying an SVGFilter to a source ImageBuffer
    in GPU Process. We should be able to use the cached result if the Filter was not
    changed. We should be also able to clear some of the result FilterImages if a
    FilterEffect was changed.

    * Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp:
    (WebCore::RenderSVGResourceFilter::applyResource):
    * Source/WebCore/svg/graphics/filters/SVGFilter.cpp:
    (WebCore::SVGFilter::mergeEffects):
    * Source/WebCore/svg/graphics/filters/SVGFilter.h:
    * Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
    (WebKit::RemoteDisplayListRecorder::drawFilteredImageBufferInternal):
    (WebKit::RemoteDisplayListRecorder::drawFilteredImageBuffer):
    * Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h:
    * Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
    (WebKit::RemoteDisplayListRecorderProxy::recordDrawFilteredImageBuffer):

    Canonical link: https://commits.webkit.org/264087@main

Identifier: 263769.53@safari-7616.1.14.11-branch
  • Loading branch information
shallawa authored and Dan Robson committed May 22, 2023
1 parent b8409a7 commit d37854b
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
auto preferredFilterModes = renderer.page().preferredFilterRenderingModes();

// Create the SVGFilter object.
filterData->filter = SVGFilter::create(filterElement(), preferredFilterModes, filterScale, filterRegion, targetBoundingBox, *context);
filterData->filter = SVGFilter::create(filterElement(), preferredFilterModes, filterScale, filterRegion, targetBoundingBox, *context, RenderingResourceIdentifier::generate());
if (!filterData->filter) {
m_rendererFilterDataMap.remove(&renderer);
return false;
Expand Down
13 changes: 13 additions & 0 deletions Source/WebCore/svg/graphics/filters/SVGFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,19 @@ void SVGFilter::clearEffectResult(FilterEffect& effect)
m_results->clearEffectResult(effect);
}

void SVGFilter::mergeEffects(const FilterEffectVector& effects)
{
ASSERT(m_effects.size() == effects.size());

for (unsigned index = 0; index < m_effects.size(); ++index) {
if (m_effects[index].get() == effects[index].get())
continue;

clearEffectResult(m_effects[index]);
m_effects[index] = effects[index];
}
}

RefPtr<FilterImage> SVGFilter::apply(const Filter&, FilterImage& sourceImage, FilterResults& results)
{
return apply(&sourceImage, results);
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/svg/graphics/filters/SVGFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class SVGFilter final : public Filter {

WEBCORE_EXPORT FilterResults& ensureResults(const FilterResultsCreator&);
void clearEffectResult(FilterEffect&);
WEBCORE_EXPORT void mergeEffects(const FilterEffectVector&);

RefPtr<FilterImage> apply(FilterImage* sourceImage, FilterResults&) final;
FilterStyleVector createFilterStyles(const FilterStyle& sourceStyle) const final;
Expand Down
35 changes: 31 additions & 4 deletions Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <WebCore/BitmapImage.h>
#include <WebCore/FEImage.h>
#include <WebCore/FilterResults.h>
#include <WebCore/SVGFilter.h>

#if USE(SYSTEM_PREVIEW)
#include <WebCore/ARKitBadgeSystemImage.h>
Expand Down Expand Up @@ -234,7 +235,7 @@ void RemoteDisplayListRecorder::resetClip()
handleItem(DisplayList::ResetClip());
}

void RemoteDisplayListRecorder::drawFilteredImageBuffer(std::optional<RenderingResourceIdentifier> sourceImageIdentifier, const FloatRect& sourceImageRect, Ref<Filter> filter)
void RemoteDisplayListRecorder::drawFilteredImageBufferInternal(std::optional<RenderingResourceIdentifier> sourceImageIdentifier, const FloatRect& sourceImageRect, Filter& filter, FilterResults& results)
{
RefPtr<ImageBuffer> sourceImage;

Expand All @@ -246,7 +247,7 @@ void RemoteDisplayListRecorder::drawFilteredImageBuffer(std::optional<RenderingR
}
}

for (auto& effect : filter->effectsOfType(FilterEffect::Type::FEImage)) {
for (auto& effect : filter.effectsOfType(FilterEffect::Type::FEImage)) {
auto& feImage = downcast<FEImage>(effect.get());

auto sourceImage = resourceCache().cachedSourceImage({ feImage.sourceImage().imageIdentifier(), m_webProcessIdentifier });
Expand All @@ -258,8 +259,34 @@ void RemoteDisplayListRecorder::drawFilteredImageBuffer(std::optional<RenderingR
feImage.setImageSource(WTFMove(*sourceImage));
}

FilterResults results(makeUnique<ImageBufferShareableAllocator>(m_renderingBackend->resourceOwner()));
handleItem(DisplayList::DrawFilteredImageBuffer(sourceImageIdentifier, sourceImageRect, WTFMove(filter)), sourceImage.get(), results);
handleItem(DisplayList::DrawFilteredImageBuffer(sourceImageIdentifier, sourceImageRect, filter), sourceImage.get(), results);
}

void RemoteDisplayListRecorder::drawFilteredImageBuffer(std::optional<RenderingResourceIdentifier> sourceImageIdentifier, const FloatRect& sourceImageRect, Ref<Filter> filter)
{
auto* svgFilter = dynamicDowncast<SVGFilter>(filter.get());

if (!svgFilter || !svgFilter->hasValidRenderingResourceIdentifier()) {
FilterResults results(makeUnique<ImageBufferShareableAllocator>(m_renderingBackend->resourceOwner()));
drawFilteredImageBufferInternal(sourceImageIdentifier, sourceImageRect, filter, results);
return;
}

RefPtr cachedFilter = resourceCache().cachedFilter({ filter->renderingResourceIdentifier(), m_webProcessIdentifier });
auto* cachedSVGFilter = dynamicDowncast<SVGFilter>(cachedFilter.get());
if (!cachedSVGFilter) {
ASSERT_NOT_REACHED();
return;
}

cachedSVGFilter->mergeEffects(svgFilter->effects());

auto& results = cachedSVGFilter->ensureResults([&]() {
auto allocator = makeUnique<ImageBufferShareableAllocator>(m_renderingBackend->resourceOwner());
return makeUnique<FilterResults>(WTFMove(allocator));
});

drawFilteredImageBufferInternal(sourceImageIdentifier, sourceImageRect, *cachedSVGFilter, results);
}

void RemoteDisplayListRecorder::drawGlyphs(DisplayList::DrawGlyphs&& item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class RemoteDisplayListRecorder : public IPC::StreamMessageReceiver, public CanM
void clipToImageBufferWithQualifiedIdentifier(QualifiedRenderingResourceIdentifier, const WebCore::FloatRect& destinationRect);
void drawGlyphsWithQualifiedIdentifier(WebCore::DisplayList::DrawGlyphs&&, QualifiedRenderingResourceIdentifier fontIdentifier);
void drawDecomposedGlyphsWithQualifiedIdentifiers(QualifiedRenderingResourceIdentifier fontIdentifier, QualifiedRenderingResourceIdentifier decomposedGlyphsIdentifier);
void drawFilteredImageBufferInternal(std::optional<WebCore::RenderingResourceIdentifier> sourceImageIdentifier, const WebCore::FloatRect& sourceImageRect, WebCore::Filter&, WebCore::FilterResults&);
void drawImageBufferWithQualifiedIdentifier(QualifiedRenderingResourceIdentifier imageBufferIdentifier, const WebCore::FloatRect& destinationRect, const WebCore::FloatRect& srcRect, const WebCore::ImagePaintingOptions&);
void drawNativeImageWithQualifiedIdentifier(QualifiedRenderingResourceIdentifier imageIdentifier, const WebCore::FloatSize& imageSize, const WebCore::FloatRect& destRect, const WebCore::FloatRect& srcRect, const WebCore::ImagePaintingOptions&);
void drawPatternWithQualifiedIdentifier(QualifiedRenderingResourceIdentifier imageIdentifier, const WebCore::FloatRect& destRect, const WebCore::FloatRect& tileRect, const WebCore::AffineTransform&, const WebCore::FloatPoint&, const WebCore::FloatSize& spacing, const WebCore::ImagePaintingOptions&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <WebCore/ImageBuffer.h>
#include <WebCore/MediaPlayer.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/SVGFilter.h>
#include <wtf/MathExtras.h>
#include <wtf/text/TextStream.h>

Expand Down Expand Up @@ -195,6 +196,11 @@ void RemoteDisplayListRecorderProxy::recordDrawFilteredImageBuffer(ImageBuffer*
std::optional<RenderingResourceIdentifier> identifier;
if (sourceImage)
identifier = sourceImage->renderingResourceIdentifier();

auto* svgFilter = dynamicDowncast<SVGFilter>(filter);
if (svgFilter && svgFilter->hasValidRenderingResourceIdentifier())
recordResourceUse(filter);

send(Messages::RemoteDisplayListRecorder::DrawFilteredImageBuffer(WTFMove(identifier), sourceImageRect, filter));
}

Expand Down

0 comments on commit d37854b

Please sign in to comment.