[GPU Process] Implement FilterEffect CoreImage appliers
https://bugs.webkit.org/show_bug.cgi?id=232831

Reviewed by Cameron McCormack.

This will allow applying the CoreImage filters through FilterEffect::apply().
It will also allow passing FilterImages to the FilterEffect CoreImage
appliers. This will require adding a CIImage as a possible result to
FilterImage.

If the CoreImage filters are enabled, the Filter will check if all the
FilterEffects supports CoreImage rendering. And if one if them does not
support it, the renderingMode will be switched to Unaccelerated.

* Sources.txt:
* SourcesCocoa.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/coreimage/FEColorMatrixCoreImageApplier.h: Copied from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp.
* platform/graphics/coreimage/FEColorMatrixCoreImageApplier.mm: Added.
(WebCore::FEColorMatrixCoreImageApplier::FEColorMatrixCoreImageApplier):
(WebCore::FEColorMatrixCoreImageApplier::supportsCoreImageRendering):
(WebCore::FEColorMatrixCoreImageApplier::apply const):
* platform/graphics/coreimage/FEComponentTransferCoreImageApplier.h: Renamed from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.h.
* platform/graphics/coreimage/FEComponentTransferCoreImageApplier.mm: Added.
(WebCore::FEComponentTransferCoreImageApplier::FEComponentTransferCoreImageApplier):
(WebCore::FEComponentTransferCoreImageApplier::supportsCoreImageRendering):
(WebCore::FEComponentTransferCoreImageApplier::apply const):
* platform/graphics/coreimage/FilterEffectRendererCoreImage.h: Removed.
* platform/graphics/coreimage/FilterEffectRendererCoreImage.mm: Removed.
* platform/graphics/coreimage/FilterImageCoreImage.mm: Added.
(WebCore::sharedCIContext):
(WebCore::FilterImage::setCIImage):
(WebCore::FilterImage::imageBufferFromCIImage):
* platform/graphics/coreimage/SourceGraphicCoreImageApplier.h: Copied from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp.
* platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm: Renamed from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp.
(WebCore::SourceGraphicCoreImageApplier::apply const):
* platform/graphics/cv/CVUtilities.mm:
* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrix::supportsCoreImageRendering const):
(WebCore::FEColorMatrix::createApplier const):
* platform/graphics/filters/FEColorMatrix.h:
* platform/graphics/filters/FEComponentTransfer.cpp:
(WebCore::FEComponentTransfer::supportsCoreImageRendering const):
(WebCore::FEComponentTransfer::createApplier const):
* platform/graphics/filters/FEComponentTransfer.h:
* platform/graphics/filters/Filter.h:
(WebCore::Filter::Filter):
(): Deleted.
* platform/graphics/filters/FilterFunction.h:
(WebCore::FilterFunction::supportsCoreImageRendering const):
* platform/graphics/filters/FilterImage.cpp:
(WebCore::FilterImage::imageBuffer):
(WebCore::FilterImage::imageBufferFromPixelBuffer):
* platform/graphics/filters/FilterImage.h:
(WebCore::FilterImage::ciImage const):
* platform/graphics/filters/SourceGraphic.cpp:
(WebCore::SourceGraphic::createApplier const):
* platform/graphics/filters/SourceGraphic.h:
* platform/mac/ScrollingEffectsController.mm:
* rendering/CSSFilter.cpp:
(WebCore::CSSFilter::create):
(WebCore::CSSFilter::CSSFilter):
(WebCore::createSVGFilter):
(WebCore::CSSFilter::buildFilterFunctions):
(WebCore::CSSFilter::allocateBackingStoreIfNeeded):
(WebCore::CSSFilter::supportsCoreImageRendering const):
(WebCore::CSSFilter::apply):
(WebCore::CSSFilter::output):
(WebCore::CSSFilter::outputRect):
* rendering/CSSFilter.h:
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::applyResource):
* rendering/svg/SVGRenderTreeAsText.cpp:
(WebCore::writeSVGResourceContainer):
* svg/graphics/filters/SVGFilter.cpp:
(WebCore::SVGFilter::create):
(WebCore::SVGFilter::SVGFilter):
(WebCore::SVGFilter::supportsCoreImageRendering const):
* svg/graphics/filters/SVGFilter.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@286193 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 9428b05..0b26677 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,85 @@
+2021-11-27  Said Abou-Hallawa  <said@apple.com>
+
+        [GPU Process] Implement FilterEffect CoreImage appliers
+        https://bugs.webkit.org/show_bug.cgi?id=232831
+
+        Reviewed by Cameron McCormack.
+
+        This will allow applying the CoreImage filters through FilterEffect::apply().
+        It will also allow passing FilterImages to the FilterEffect CoreImage
+        appliers. This will require adding a CIImage as a possible result to
+        FilterImage.
+
+        If the CoreImage filters are enabled, the Filter will check if all the 
+        FilterEffects supports CoreImage rendering. And if one if them does not
+        support it, the renderingMode will be switched to Unaccelerated.
+
+        * Sources.txt:
+        * SourcesCocoa.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/coreimage/FEColorMatrixCoreImageApplier.h: Copied from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp.
+        * platform/graphics/coreimage/FEColorMatrixCoreImageApplier.mm: Added.
+        (WebCore::FEColorMatrixCoreImageApplier::FEColorMatrixCoreImageApplier):
+        (WebCore::FEColorMatrixCoreImageApplier::supportsCoreImageRendering):
+        (WebCore::FEColorMatrixCoreImageApplier::apply const):
+        * platform/graphics/coreimage/FEComponentTransferCoreImageApplier.h: Renamed from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.h.
+        * platform/graphics/coreimage/FEComponentTransferCoreImageApplier.mm: Added.
+        (WebCore::FEComponentTransferCoreImageApplier::FEComponentTransferCoreImageApplier):
+        (WebCore::FEComponentTransferCoreImageApplier::supportsCoreImageRendering):
+        (WebCore::FEComponentTransferCoreImageApplier::apply const):
+        * platform/graphics/coreimage/FilterEffectRendererCoreImage.h: Removed.
+        * platform/graphics/coreimage/FilterEffectRendererCoreImage.mm: Removed.
+        * platform/graphics/coreimage/FilterImageCoreImage.mm: Added.
+        (WebCore::sharedCIContext):
+        (WebCore::FilterImage::setCIImage):
+        (WebCore::FilterImage::imageBufferFromCIImage):
+        * platform/graphics/coreimage/SourceGraphicCoreImageApplier.h: Copied from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp.
+        * platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm: Renamed from Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp.
+        (WebCore::SourceGraphicCoreImageApplier::apply const):
+        * platform/graphics/cv/CVUtilities.mm:
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrix::supportsCoreImageRendering const):
+        (WebCore::FEColorMatrix::createApplier const):
+        * platform/graphics/filters/FEColorMatrix.h:
+        * platform/graphics/filters/FEComponentTransfer.cpp:
+        (WebCore::FEComponentTransfer::supportsCoreImageRendering const):
+        (WebCore::FEComponentTransfer::createApplier const):
+        * platform/graphics/filters/FEComponentTransfer.h:
+        * platform/graphics/filters/Filter.h:
+        (WebCore::Filter::Filter):
+        (): Deleted.
+        * platform/graphics/filters/FilterFunction.h:
+        (WebCore::FilterFunction::supportsCoreImageRendering const):
+        * platform/graphics/filters/FilterImage.cpp:
+        (WebCore::FilterImage::imageBuffer):
+        (WebCore::FilterImage::imageBufferFromPixelBuffer):
+        * platform/graphics/filters/FilterImage.h:
+        (WebCore::FilterImage::ciImage const):
+        * platform/graphics/filters/SourceGraphic.cpp:
+        (WebCore::SourceGraphic::createApplier const):
+        * platform/graphics/filters/SourceGraphic.h:
+        * platform/mac/ScrollingEffectsController.mm:
+        * rendering/CSSFilter.cpp:
+        (WebCore::CSSFilter::create):
+        (WebCore::CSSFilter::CSSFilter):
+        (WebCore::createSVGFilter):
+        (WebCore::CSSFilter::buildFilterFunctions):
+        (WebCore::CSSFilter::allocateBackingStoreIfNeeded):
+        (WebCore::CSSFilter::supportsCoreImageRendering const):
+        (WebCore::CSSFilter::apply):
+        (WebCore::CSSFilter::output):
+        (WebCore::CSSFilter::outputRect):
+        * rendering/CSSFilter.h:
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::applyResource):
+        * rendering/svg/SVGRenderTreeAsText.cpp:
+        (WebCore::writeSVGResourceContainer):
+        * svg/graphics/filters/SVGFilter.cpp:
+        (WebCore::SVGFilter::create):
+        (WebCore::SVGFilter::SVGFilter):
+        (WebCore::SVGFilter::supportsCoreImageRendering const):
+        * svg/graphics/filters/SVGFilter.h:
+
 2021-11-27  Sam Weinig  <weinig@apple.com>
 
         [CSS Color 4] Add support for oklab() and oklch() colors
diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt
index b6ec144..114ad10 100644
--- a/Source/WebCore/Sources.txt
+++ b/Source/WebCore/Sources.txt
@@ -2101,7 +2101,6 @@
 platform/graphics/filters/FETile.cpp
 platform/graphics/filters/FETurbulence.cpp
 platform/graphics/filters/FilterEffect.cpp
-platform/graphics/filters/FilterEffectRenderer.cpp
 platform/graphics/filters/FilterFunction.cpp
 platform/graphics/filters/FilterImage.cpp
 platform/graphics/filters/FilterOperation.cpp
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
index d2d1b56..2d03124 100644
--- a/Source/WebCore/SourcesCocoa.txt
+++ b/Source/WebCore/SourcesCocoa.txt
@@ -402,7 +402,10 @@
 platform/graphics/cv/ImageTransferSessionVT.mm
 platform/graphics/cv/PixelBufferConformerCV.cpp
 platform/graphics/cv/GraphicsContextGLCVANGLE.cpp
-platform/graphics/coreimage/FilterEffectRendererCoreImage.mm
+platform/graphics/coreimage/FEColorMatrixCoreImageApplier.mm
+platform/graphics/coreimage/FEComponentTransferCoreImageApplier.mm
+platform/graphics/coreimage/FilterImageCoreImage.mm
+platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm
 platform/graphics/gpu/cocoa/GPUPrewarmingMetal.mm
 platform/graphics/ios/DisplayRefreshMonitorIOS.mm
 platform/graphics/ios/IconIOS.mm
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 7354eba..3c4174ef 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -488,7 +488,6 @@
 		1A494EDF0A123F4C00FDAFC1 /* JSDocumentFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A494EDD0A123F4C00FDAFC1 /* JSDocumentFragment.h */; };
 		1A4A2DF00A1B852A00C807F8 /* JSHTMLAnchorElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4A2DEC0A1B852A00C807F8 /* JSHTMLAnchorElement.h */; };
 		1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4A954C0B4EDCCB002D8C3C /* SharedBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		51FA2EDF27506FDE0011C15D /* SharedBufferChunkReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FA2ED6274F78370011C15D /* SharedBufferChunkReader.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1A4DA4221CDD3A8300F4473C /* LinkIconCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4DA4201CDD3A8300F4473C /* LinkIconCollector.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1A569D120D7E2B82007C3983 /* objc_class.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CE30D7E2B82007C3983 /* objc_class.h */; };
 		1A569D130D7E2B82007C3983 /* objc_class.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CE40D7E2B82007C3983 /* objc_class.mm */; };
@@ -769,8 +768,6 @@
 		2AEF6FDD26E7ECCF00326D02 /* CSSNumericType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AEF6FCE26E71F2D00326D02 /* CSSNumericType.h */; };
 		2B365C841525119E0091D27B /* RenderSVGEllipse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B4235A015250F6000DBBCD8 /* RenderSVGEllipse.h */; };
 		2BE8E2C712A589EC00FAD550 /* HTMLMetaCharsetParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BE8E2C612A589EC00FAD550 /* HTMLMetaCharsetParser.h */; };
-		2C85653424C0F73C00A37673 /* FilterEffectRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C85653324C0F73C00A37673 /* FilterEffectRenderer.h */; };
-		2CAA4A3A24BE18B7009DEE70 /* FilterEffectRendererCoreImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CAA4A3924BE18B7009DEE70 /* FilterEffectRendererCoreImage.h */; };
 		2D0621441DA639B600A7FB26 /* WebKitMediaKeyMessageEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D0621421DA6398800A7FB26 /* WebKitMediaKeyMessageEvent.cpp */; };
 		2D0621451DA639BA00A7FB26 /* WebKitMediaKeyMessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D0621431DA6398800A7FB26 /* WebKitMediaKeyMessageEvent.h */; };
 		2D06214D1DA63A8B00A7FB26 /* WebKitMediaKeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D0621491DA63A7900A7FB26 /* WebKitMediaKeys.cpp */; };
@@ -1689,6 +1686,7 @@
 		51F798F01BE880E7008AE491 /* IDBIndexInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F798EC1BE880D3008AE491 /* IDBIndexInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		51F886C01F32923100C193EF /* JSNavigatorServiceWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F886BF1F32920700C193EF /* JSNavigatorServiceWorker.h */; };
 		51FA2D78152132B300C1BA0B /* DOMWindowExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 517FBA18151AA71B00B57959 /* DOMWindowExtension.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		51FA2EDF27506FDE0011C15D /* SharedBufferChunkReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FA2ED6274F78370011C15D /* SharedBufferChunkReader.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		51FB5504113E3E9100821176 /* JSCloseEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FB5502113E3E9100821176 /* JSCloseEvent.h */; };
 		51FB67DC1AE6B82F00D06C5A /* ContentExtensionStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FB67DA1AE6B5E400D06C5A /* ContentExtensionStyleSheet.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5273CC77256103CF00850007 /* PlatformXRCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 5273CC75256103CF00850007 /* PlatformXRCocoa.h */; };
@@ -7659,10 +7657,6 @@
 		2B4235A015250F6000DBBCD8 /* RenderSVGEllipse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGEllipse.h; sourceTree = "<group>"; };
 		2BE8E2C612A589EC00FAD550 /* HTMLMetaCharsetParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLMetaCharsetParser.h; sourceTree = "<group>"; };
 		2BE8E2C812A58A0100FAD550 /* HTMLMetaCharsetParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLMetaCharsetParser.cpp; sourceTree = "<group>"; };
-		2C85653324C0F73C00A37673 /* FilterEffectRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FilterEffectRenderer.h; sourceTree = "<group>"; };
-		2C85653824C10B0B00A37673 /* FilterEffectRenderer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FilterEffectRenderer.cpp; sourceTree = "<group>"; };
-		2CAA4A3724BE18A1009DEE70 /* FilterEffectRendererCoreImage.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FilterEffectRendererCoreImage.mm; sourceTree = "<group>"; };
-		2CAA4A3924BE18B7009DEE70 /* FilterEffectRendererCoreImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FilterEffectRendererCoreImage.h; sourceTree = "<group>"; };
 		2D0621421DA6398800A7FB26 /* WebKitMediaKeyMessageEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitMediaKeyMessageEvent.cpp; sourceTree = "<group>"; };
 		2D0621431DA6398800A7FB26 /* WebKitMediaKeyMessageEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitMediaKeyMessageEvent.h; sourceTree = "<group>"; };
 		2D0621471DA63A7900A7FB26 /* WebKitMediaKeyNeededEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitMediaKeyNeededEvent.cpp; sourceTree = "<group>"; };
@@ -10935,6 +10929,13 @@
 		72B4EF74274E233300293C2F /* FEBlendSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEBlendSoftwareApplier.h; sourceTree = "<group>"; };
 		72B4EF75274E233400293C2F /* FEBlendSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEBlendSoftwareApplier.cpp; sourceTree = "<group>"; };
 		72B4EF7C274EE37F00293C2F /* FilterImageVector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FilterImageVector.h; sourceTree = "<group>"; };
+		72B8B0142751084D00F752AA /* SourceGraphicCoreImageApplier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SourceGraphicCoreImageApplier.mm; sourceTree = "<group>"; };
+		72B8B0162751086A00F752AA /* SourceGraphicCoreImageApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceGraphicCoreImageApplier.h; sourceTree = "<group>"; };
+		72B8B01B2751B6BC00F752AA /* FEComponentTransferCoreImageApplier.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FEComponentTransferCoreImageApplier.mm; sourceTree = "<group>"; };
+		72B8B01D2751B82B00F752AA /* FEComponentTransferCoreImageApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEComponentTransferCoreImageApplier.h; sourceTree = "<group>"; };
+		72B8B01E2751B91000F752AA /* FEColorMatrixCoreImageApplier.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FEColorMatrixCoreImageApplier.mm; sourceTree = "<group>"; };
+		72B8B01F2751B92800F752AA /* FEColorMatrixCoreImageApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEColorMatrixCoreImageApplier.h; sourceTree = "<group>"; };
+		72B8B0202751C4B700F752AA /* FilterImageCoreImage.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FilterImageCoreImage.mm; sourceTree = "<group>"; };
 		72BAC3A423E17327008D741C /* ImageBufferBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferBackend.cpp; sourceTree = "<group>"; };
 		72BAC3A523E17328008D741C /* ImageBufferBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferBackend.h; sourceTree = "<group>"; };
 		72BAC3A623E17328008D741C /* PlatformImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformImageBuffer.h; sourceTree = "<group>"; };
@@ -20214,8 +20215,13 @@
 		2CE1189824C2402C003770E9 /* coreimage */ = {
 			isa = PBXGroup;
 			children = (
-				2CAA4A3924BE18B7009DEE70 /* FilterEffectRendererCoreImage.h */,
-				2CAA4A3724BE18A1009DEE70 /* FilterEffectRendererCoreImage.mm */,
+				72B8B01F2751B92800F752AA /* FEColorMatrixCoreImageApplier.h */,
+				72B8B01E2751B91000F752AA /* FEColorMatrixCoreImageApplier.mm */,
+				72B8B01D2751B82B00F752AA /* FEComponentTransferCoreImageApplier.h */,
+				72B8B01B2751B6BC00F752AA /* FEComponentTransferCoreImageApplier.mm */,
+				72B8B0202751C4B700F752AA /* FilterImageCoreImage.mm */,
+				72B8B0162751086A00F752AA /* SourceGraphicCoreImageApplier.h */,
+				72B8B0142751084D00F752AA /* SourceGraphicCoreImageApplier.mm */,
 			);
 			path = coreimage;
 			sourceTree = "<group>";
@@ -26026,8 +26032,6 @@
 				08C925170FCC7C4A00480DEC /* FilterEffect.cpp */,
 				08C925180FCC7C4A00480DEC /* FilterEffect.h */,
 				72A13A9F274C5CC700E2A88E /* FilterEffectApplier.h */,
-				2C85653824C10B0B00A37673 /* FilterEffectRenderer.cpp */,
-				2C85653324C0F73C00A37673 /* FilterEffectRenderer.h */,
 				7214B9B7274458FA003BE6DF /* FilterEffectVector.h */,
 				7262D757272A174100C56A09 /* FilterFunction.cpp */,
 				7262D756272A174100C56A09 /* FilterFunction.h */,
@@ -33566,8 +33570,6 @@
 				712BE4831FE865DD002031CC /* FillMode.h in Headers */,
 				845E72F80FD261EE00A87D79 /* Filter.h in Headers */,
 				08C9251A0FCC7C4A00480DEC /* FilterEffect.h in Headers */,
-				2C85653424C0F73C00A37673 /* FilterEffectRenderer.h in Headers */,
-				2CAA4A3A24BE18B7009DEE70 /* FilterEffectRendererCoreImage.h in Headers */,
 				49ECEB6E1499790D00CDD3A4 /* FilterOperation.h in Headers */,
 				49ECEB701499790D00CDD3A4 /* FilterOperations.h in Headers */,
 				372C00D9129619F8005C9575 /* FindOptions.h in Headers */,
diff --git a/Source/WebCore/platform/graphics/coreimage/FEColorMatrixCoreImageApplier.h b/Source/WebCore/platform/graphics/coreimage/FEColorMatrixCoreImageApplier.h
new file mode 100644
index 0000000..402e6eb
--- /dev/null
+++ b/Source/WebCore/platform/graphics/coreimage/FEColorMatrixCoreImageApplier.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020-2021 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
+
+#import "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEColorMatrix;
+
+class FEColorMatrixCoreImageApplier : public FilterEffectConcreteApplier<FEColorMatrix> {
+    WTF_MAKE_FAST_ALLOCATED;
+    using Base = FilterEffectConcreteApplier<FEColorMatrix>;
+
+public:
+    FEColorMatrixCoreImageApplier(const FEColorMatrix&);
+
+    static bool supportsCoreImageRendering(const FEColorMatrix&);
+
+    bool apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) const override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/coreimage/FEColorMatrixCoreImageApplier.mm b/Source/WebCore/platform/graphics/coreimage/FEColorMatrixCoreImageApplier.mm
new file mode 100644
index 0000000..7acd409
--- /dev/null
+++ b/Source/WebCore/platform/graphics/coreimage/FEColorMatrixCoreImageApplier.mm
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020-2021 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.
+ */
+
+#import "config.h"
+#import "FEColorMatrixCoreImageApplier.h"
+
+#if USE(CORE_IMAGE)
+
+#import "FEColorMatrix.h"
+#import "FilterImage.h"
+#import <CoreImage/CIContext.h>
+#import <CoreImage/CIFilter.h>
+#import <CoreImage/CoreImage.h>
+
+namespace WebCore {
+
+FEColorMatrixCoreImageApplier::FEColorMatrixCoreImageApplier(const FEColorMatrix& effect)
+    : Base(effect)
+{
+    // FIXME: Implement the rest of FEColorMatrix types
+    ASSERT(supportsCoreImageRendering(effect));
+}
+
+bool FEColorMatrixCoreImageApplier::supportsCoreImageRendering(const FEColorMatrix& effect)
+{
+    return effect.type() == FECOLORMATRIX_TYPE_SATURATE
+        || effect.type() == FECOLORMATRIX_TYPE_HUEROTATE
+        || effect.type() == FECOLORMATRIX_TYPE_MATRIX;
+}
+
+bool FEColorMatrixCoreImageApplier::apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) const
+{
+    ASSERT(inputs.size() == 1);
+    auto& input = inputs[0].get();
+
+    auto inputImage = input.ciImage();
+    if (!inputImage)
+        return false;
+
+    auto values = FEColorMatrix::normalizedFloats(m_effect.values());
+    float components[9];
+
+    switch (m_effect.type()) {
+    case FECOLORMATRIX_TYPE_SATURATE:
+        FEColorMatrix::calculateSaturateComponents(components, values[0]);
+        break;
+
+    case FECOLORMATRIX_TYPE_HUEROTATE:
+        FEColorMatrix::calculateHueRotateComponents(components, values[0]);
+        break;
+
+    case FECOLORMATRIX_TYPE_MATRIX:
+        break;
+
+    case FECOLORMATRIX_TYPE_UNKNOWN:
+    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: // FIXME: Add Luminance to Alpha Implementation
+        return nullptr;
+    }
+
+    auto *colorMatrixFilter = [CIFilter filterWithName:@"CIColorMatrix"];
+    [colorMatrixFilter setValue:inputImage.get() forKey:kCIInputImageKey];
+
+    switch (m_effect.type()) {
+    case FECOLORMATRIX_TYPE_SATURATE:
+    case FECOLORMATRIX_TYPE_HUEROTATE:
+        [colorMatrixFilter setValue:[CIVector vectorWithX:components[0] Y:components[1] Z:components[2] W:0] forKey:@"inputRVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:components[3] Y:components[4] Z:components[5] W:0] forKey:@"inputGVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:components[6] Y:components[7] Z:components[8] W:0] forKey:@"inputBVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:0             Y:0             Z:0             W:1] forKey:@"inputAVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:0             Y:0             Z:0             W:0] forKey:@"inputBiasVector"];
+        break;
+
+    case FECOLORMATRIX_TYPE_MATRIX:
+        [colorMatrixFilter setValue:[CIVector vectorWithX:values[0]  Y:values[1]  Z:values[2]  W:values[3]]  forKey:@"inputRVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:values[5]  Y:values[6]  Z:values[7]  W:values[8]]  forKey:@"inputGVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:values[10] Y:values[11] Z:values[12] W:values[13]] forKey:@"inputBVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:values[15] Y:values[16] Z:values[17] W:values[18]] forKey:@"inputAVector"];
+        [colorMatrixFilter setValue:[CIVector vectorWithX:values[4]  Y:values[9]  Z:values[14] W:values[19]] forKey:@"inputBiasVector"];
+        break;
+
+    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
+    case FECOLORMATRIX_TYPE_UNKNOWN:
+        return nullptr;
+    }
+
+    result.setCIImage(colorMatrixFilter.outputImage);
+    return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(CORE_IMAGE)
diff --git a/Source/WebCore/platform/graphics/coreimage/FEComponentTransferCoreImageApplier.h b/Source/WebCore/platform/graphics/coreimage/FEComponentTransferCoreImageApplier.h
new file mode 100644
index 0000000..99c746f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/coreimage/FEComponentTransferCoreImageApplier.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020-2021 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
+
+#import "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEComponentTransfer;
+
+class FEComponentTransferCoreImageApplier : public FilterEffectConcreteApplier<FEComponentTransfer> {
+    WTF_MAKE_FAST_ALLOCATED;
+    using Base = FilterEffectConcreteApplier<FEComponentTransfer>;
+
+public:
+    FEComponentTransferCoreImageApplier(const FEComponentTransfer&);
+
+    static bool supportsCoreImageRendering(const FEComponentTransfer&);
+
+    bool apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) const override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/coreimage/FEComponentTransferCoreImageApplier.mm b/Source/WebCore/platform/graphics/coreimage/FEComponentTransferCoreImageApplier.mm
new file mode 100644
index 0000000..eb04e20
--- /dev/null
+++ b/Source/WebCore/platform/graphics/coreimage/FEComponentTransferCoreImageApplier.mm
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020-2021 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.
+ */
+
+#import "config.h"
+#import "FEComponentTransferCoreImageApplier.h"
+
+#if USE(CORE_IMAGE)
+
+#import "FEComponentTransfer.h"
+
+namespace WebCore {
+
+FEComponentTransferCoreImageApplier::FEComponentTransferCoreImageApplier(const FEComponentTransfer& effect)
+    : Base(effect)
+{
+    // FIXME: Implement the rest of FEComponentTransfer functions
+    ASSERT(supportsCoreImageRendering(effect));
+}
+
+bool FEComponentTransferCoreImageApplier::supportsCoreImageRendering(const FEComponentTransfer& effect)
+{
+    auto isNullOrLinear = [] (const ComponentTransferFunction& function) {
+        return function.type == FECOMPONENTTRANSFER_TYPE_UNKNOWN
+            || function.type == FECOMPONENTTRANSFER_TYPE_LINEAR;
+    };
+
+    return isNullOrLinear(effect.redFunction())
+        && isNullOrLinear(effect.greenFunction())
+        && isNullOrLinear(effect.blueFunction())
+        && isNullOrLinear(effect.alphaFunction());
+}
+
+bool FEComponentTransferCoreImageApplier::apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) const
+{
+    ASSERT(inputs.size() == 1);
+    auto& input = inputs[0].get();
+
+    auto inputImage = input.ciImage();
+    if (!inputImage)
+        return false;
+
+    auto componentTransferFilter = [CIFilter filterWithName:@"CIColorPolynomial"];
+    [componentTransferFilter setValue:inputImage.get() forKey:kCIInputImageKey];
+
+    auto setCoefficients = [&] (NSString *key, const ComponentTransferFunction& function) {
+        if (function.type == FECOMPONENTTRANSFER_TYPE_LINEAR)
+            [componentTransferFilter setValue:[CIVector vectorWithX:function.intercept Y:function.slope Z:0 W:0] forKey:key];
+    };
+
+    setCoefficients(@"inputRedCoefficients", m_effect.redFunction());
+    setCoefficients(@"inputGreenCoefficients", m_effect.greenFunction());
+    setCoefficients(@"inputBlueCoefficients", m_effect.blueFunction());
+    setCoefficients(@"inputAlphaCoefficients", m_effect.alphaFunction());
+
+    result.setCIImage(componentTransferFilter.outputImage);
+    return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(CORE_IMAGE)
diff --git a/Source/WebCore/platform/graphics/coreimage/FilterEffectRendererCoreImage.h b/Source/WebCore/platform/graphics/coreimage/FilterEffectRendererCoreImage.h
deleted file mode 100644
index e7bc853..0000000
--- a/Source/WebCore/platform/graphics/coreimage/FilterEffectRendererCoreImage.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-* Copyright (C) 2020 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
-
-#if USE(CORE_IMAGE)
-
-#import "FilterEffectRenderer.h"
-#import "PlatformImageBuffer.h"
-#import <wtf/Vector.h>
-
-OBJC_CLASS CIImage;
-OBJC_CLASS CIFilter;
-OBJC_CLASS CIContext;
-
-namespace WebCore {
-
-class FEColorMatrix;
-class FEComponentTransfer;
-class SourceGraphic;
-
-class FilterEffectRendererCoreImage : public FilterEffectRenderer {
-    WTF_MAKE_FAST_ALLOCATED;
-    
-public:
-    static std::unique_ptr<FilterEffectRendererCoreImage> tryCreate(FilterEffect&);
-    RetainPtr<CIContext> sharedCIContext();
-    void applyEffects(const Filter&, FilterEffect&) final;
-    bool hasResult() const final { return m_outputImage; }
-    ImageBuffer* output() const final;
-    FloatRect destRect(const FilterEffect&) const final;
-    void clearResult() final;
-    FilterEffectRendererCoreImage();
-    
-private:
-    RetainPtr<CIImage> connectCIFilters(const Filter&, FilterEffect&);
-    void renderToImageBuffer(FilterEffect&) final;
-    static bool supportsCoreImageRendering(FilterEffect&);
-    static bool canRenderUsingCIFilters(FilterEffect&);
-    
-    RetainPtr<CIImage> imageForSourceGraphic(const Filter&);
-    RetainPtr<CIImage> imageForFEColorMatrix(const FEColorMatrix&, const Vector<RetainPtr<CIImage>>&);
-    RetainPtr<CIImage> imageForFEComponentTransfer(const FEComponentTransfer&, Vector<RetainPtr<CIImage>>&);
-    
-    RefPtr<IOSurfaceImageBuffer> m_outputImageBuffer;
-    RetainPtr<CIImage> m_outputImage;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/platform/graphics/coreimage/FilterEffectRendererCoreImage.mm b/Source/WebCore/platform/graphics/coreimage/FilterEffectRendererCoreImage.mm
deleted file mode 100644
index 49615fd..0000000
--- a/Source/WebCore/platform/graphics/coreimage/FilterEffectRendererCoreImage.mm
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
-* Copyright (C) 2020-2021 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.
-*/
-
-#import "config.h"
-#import "FilterEffectRendererCoreImage.h"
-
-#if USE(CORE_IMAGE)
-
-#import "FEColorMatrix.h"
-#import "FEComponentTransfer.h"
-#import "Filter.h"
-#import "FilterEffect.h"
-#import "FilterOperation.h"
-#import "FloatConversion.h"
-#import "GraphicsContextCG.h"
-#import "ImageBuffer.h"
-#import "Logging.h"
-#import "SourceGraphic.h"
-#import <CoreImage/CIContext.h>
-#import <CoreImage/CIFilter.h>
-#import <CoreImage/CoreImage.h>
-#import <wtf/NeverDestroyed.h>
-#import <wtf/cocoa/TypeCastsCocoa.h>
-
-namespace WebCore {
-
-std::unique_ptr<FilterEffectRendererCoreImage> FilterEffectRendererCoreImage::tryCreate(FilterEffect& lastEffect)
-{
-    if (canRenderUsingCIFilters(lastEffect))
-        return makeUnique<FilterEffectRendererCoreImage>();
-    return nullptr;
-}
-
-RetainPtr<CIContext> FilterEffectRendererCoreImage::sharedCIContext()
-{
-    static NeverDestroyed<RetainPtr<CIContext>> ciContext = [CIContext contextWithOptions:@{ kCIContextWorkingColorSpace: bridge_id_cast(adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB))).get() }];
-    return ciContext;
-}
-
-static bool isNullOrLinearComponentTransferFunction(const FEComponentTransfer& effect)
-{
-    auto isNullOrLinear = [] (const ComponentTransferFunction& function) {
-        return function.type == FECOMPONENTTRANSFER_TYPE_UNKNOWN
-            || function.type == FECOMPONENTTRANSFER_TYPE_LINEAR;
-    };
-    return isNullOrLinear(effect.redFunction()) && isNullOrLinear(effect.greenFunction())
-        && isNullOrLinear(effect.blueFunction()) && isNullOrLinear(effect.alphaFunction());
-}
-
-bool FilterEffectRendererCoreImage::supportsCoreImageRendering(FilterEffect& effect)
-{
-    // FIXME: change return value to true once they are implemented
-    switch (effect.filterType()) {
-    case FilterEffect::Type::SourceGraphic:
-        return true;
-            
-    case FilterEffect::Type::FEColorMatrix: {
-        switch (downcast<FEColorMatrix>(effect).type()) {
-        case FECOLORMATRIX_TYPE_UNKNOWN:
-        case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
-            return false;
-        case FECOLORMATRIX_TYPE_MATRIX:
-        case FECOLORMATRIX_TYPE_SATURATE:
-        case FECOLORMATRIX_TYPE_HUEROTATE:
-            return true;
-        }
-    }
-
-    case FilterEffect::Type::FEComponentTransfer:
-        return isNullOrLinearComponentTransferFunction(downcast<FEComponentTransfer>(effect));
-
-    default:
-        return false;
-    }
-    return false;
-}
-
-void FilterEffectRendererCoreImage::applyEffects(const Filter& filter, FilterEffect& lastEffect)
-{
-    m_outputImage = connectCIFilters(filter, lastEffect);
-    if (!m_outputImage)
-        return;
-    renderToImageBuffer(lastEffect);
-}
-
-RetainPtr<CIImage> FilterEffectRendererCoreImage::connectCIFilters(const Filter& filter, FilterEffect& effect)
-{
-    Vector<RetainPtr<CIImage>> inputImages;
-    
-    for (auto in : effect.inputEffects()) {
-        auto inputImage = connectCIFilters(filter, *in);
-        if (!inputImage)
-            return nullptr;
-        inputImages.append(inputImage);
-    }
-    effect.determineAbsolutePaintRect(filter);
-    
-    if (effect.absolutePaintRect().isEmpty() || ImageBuffer::sizeNeedsClamping(effect.absolutePaintRect().size()))
-        return nullptr;
-    
-    switch (effect.filterType()) {
-    case FilterEffect::Type::SourceGraphic:
-        return imageForSourceGraphic(filter);
-    case FilterEffect::Type::FEColorMatrix:
-        return imageForFEColorMatrix(downcast<FEColorMatrix>(effect), inputImages);
-    case FilterEffect::Type::FEComponentTransfer:
-        return imageForFEComponentTransfer(downcast<FEComponentTransfer>(effect), inputImages);
-
-    default:
-        return nullptr;
-    }
-    return nullptr;
-}
-
-RetainPtr<CIImage> FilterEffectRendererCoreImage::imageForSourceGraphic(const Filter& filter)
-{
-    ImageBuffer* sourceImage = filter.sourceImage();
-    if (!sourceImage)
-        return nullptr;
-    
-    if (is<IOSurfaceImageBuffer>(*sourceImage))
-        return [CIImage imageWithIOSurface:downcast<IOSurfaceImageBuffer>(*sourceImage).surface().surface()];
-    
-    return [CIImage imageWithCGImage:sourceImage->copyNativeImage()->platformImage().get()];
-}
-
-RetainPtr<CIImage> FilterEffectRendererCoreImage::imageForFEColorMatrix(const FEColorMatrix& effect, const Vector<RetainPtr<CIImage>>& inputImages)
-{
-    auto inputImage = inputImages.at(0);
-
-    auto values = FEColorMatrix::normalizedFloats(effect.values());
-    float components[9];
-    
-    switch (effect.type()) {
-    case FECOLORMATRIX_TYPE_SATURATE:
-        FEColorMatrix::calculateSaturateComponents(components, values[0]);
-        break;
-    
-    case FECOLORMATRIX_TYPE_HUEROTATE:
-        FEColorMatrix::calculateHueRotateComponents(components, values[0]);
-        break;
-    
-    case FECOLORMATRIX_TYPE_MATRIX:
-        break;
-        
-    case FECOLORMATRIX_TYPE_UNKNOWN:
-    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: // FIXME: Add Luminance to Alpha Implementation
-        return nullptr;
-    }
-    
-    auto *colorMatrixFilter = [CIFilter filterWithName:@"CIColorMatrix"];
-    [colorMatrixFilter setValue:inputImage.get() forKey:kCIInputImageKey];
-    
-    switch (effect.type()) {
-    case FECOLORMATRIX_TYPE_SATURATE:
-    case FECOLORMATRIX_TYPE_HUEROTATE: {
-        [colorMatrixFilter setValue:[CIVector vectorWithX:components[0] Y:components[1] Z:components[2] W:0] forKey:@"inputRVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:components[3] Y:components[4] Z:components[5] W:0] forKey:@"inputGVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:components[6] Y:components[7] Z:components[8] W:0] forKey:@"inputBVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:0             Y:0             Z:0             W:1] forKey:@"inputAVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:0             Y:0             Z:0             W:0] forKey:@"inputBiasVector"];
-        break;
-    }
-    case FECOLORMATRIX_TYPE_MATRIX: {
-        [colorMatrixFilter setValue:[CIVector vectorWithX:values[0]  Y:values[1]  Z:values[2]  W:values[3]]  forKey:@"inputRVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:values[5]  Y:values[6]  Z:values[7]  W:values[8]]  forKey:@"inputGVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:values[10] Y:values[11] Z:values[12] W:values[13]] forKey:@"inputBVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:values[15] Y:values[16] Z:values[17] W:values[18]] forKey:@"inputAVector"];
-        [colorMatrixFilter setValue:[CIVector vectorWithX:values[4]  Y:values[9]  Z:values[14] W:values[19]] forKey:@"inputBiasVector"];
-        break;
-    }
-    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
-    case FECOLORMATRIX_TYPE_UNKNOWN:
-        return nullptr;
-    }
-    return colorMatrixFilter.outputImage;
-}
-
-RetainPtr<CIImage> FilterEffectRendererCoreImage::imageForFEComponentTransfer(const FEComponentTransfer& effect, Vector<RetainPtr<CIImage>>& inputImages)
-{
-    // FIXME: Implement the rest of FEComponentTransfer functions
-    ASSERT(isNullOrLinearComponentTransferFunction(effect));
-
-    auto inputImage = inputImages.at(0);
-    auto filter = [CIFilter filterWithName:@"CIColorPolynomial"];
-    
-    [filter setValue:inputImage.get() forKey:kCIInputImageKey];
-    
-    auto setCoefficients = [&] (NSString *key, const ComponentTransferFunction& function) {
-        if (function.type == FECOMPONENTTRANSFER_TYPE_LINEAR)
-            [filter setValue:[CIVector vectorWithX:function.intercept Y:function.slope Z:0 W:0] forKey:key];
-    };
-    setCoefficients(@"inputRedCoefficients", effect.redFunction());
-    setCoefficients(@"inputGreenCoefficients", effect.greenFunction());
-    setCoefficients(@"inputBlueCoefficients", effect.blueFunction());
-    setCoefficients(@"inputAlphaCoefficients", effect.alphaFunction());
-    
-    return filter.outputImage;
-}
-
-bool FilterEffectRendererCoreImage::canRenderUsingCIFilters(FilterEffect& effect)
-{
-    if (!supportsCoreImageRendering(effect))
-        return false;
-    
-    for (auto in : effect.inputEffects()) {
-        if (!supportsCoreImageRendering(*in) || !canRenderUsingCIFilters(*in))
-            return false;
-    }
-    return true;
-}
-
-ImageBuffer* FilterEffectRendererCoreImage::output() const
-{
-    LOG_WITH_STREAM(Filters, stream << "Rendering " << this << " using CoreImage\n");
-    return m_outputImageBuffer.get();
-}
-    
-void FilterEffectRendererCoreImage::renderToImageBuffer(FilterEffect& lastEffect)
-{
-    FloatSize clampedSize = ImageBuffer::clampedSize(lastEffect.absolutePaintRect().size());
-    m_outputImageBuffer = IOSurfaceImageBuffer::create(clampedSize, 1, lastEffect.resultColorSpace(), PixelFormat::BGRA8);
-    if (!m_outputImageBuffer) {
-        clearResult();
-        return;
-    }
-
-    [sharedCIContext().get() render: m_outputImage.get() toIOSurface: m_outputImageBuffer->surface().surface() bounds:destRect(lastEffect) colorSpace:lastEffect.resultColorSpace().platformColorSpace()];
-}
-    
-FloatRect FilterEffectRendererCoreImage::destRect(const FilterEffect& lastEffect) const
-{
-    IntSize destSize = lastEffect.absolutePaintRect().size();
-    FloatRect destRect = FloatRect(FloatPoint(), destSize);
-    return destRect;
-}
-
-void FilterEffectRendererCoreImage::clearResult()
-{
-    m_outputImageBuffer = nullptr;
-    m_outputImage = nullptr;
-}
-
-FilterEffectRendererCoreImage::FilterEffectRendererCoreImage()
-    : FilterEffectRenderer()
-{
-}
-    
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/platform/graphics/coreimage/FilterImageCoreImage.mm b/Source/WebCore/platform/graphics/coreimage/FilterImageCoreImage.mm
new file mode 100644
index 0000000..06510d9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/coreimage/FilterImageCoreImage.mm
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#import "config.h"
+#import "FilterImage.h"
+
+#if USE(CORE_IMAGE)
+
+#import "PlatformImageBuffer.h"
+#import <CoreImage/CIContext.h>
+#import <CoreImage/CoreImage.h>
+#import <wtf/NeverDestroyed.h>
+#import <wtf/cocoa/TypeCastsCocoa.h>
+
+namespace WebCore {
+
+static RetainPtr<CIContext> sharedCIContext()
+{
+    static NeverDestroyed<RetainPtr<CIContext>> ciContext = [CIContext contextWithOptions:@{ kCIContextWorkingColorSpace: bridge_id_cast(adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB))).get() }];
+    return ciContext;
+}
+
+void FilterImage::setCIImage(RetainPtr<CIImage>&& ciImage)
+{
+    ASSERT(ciImage);
+    m_ciImage = WTFMove(ciImage);
+}
+
+ImageBuffer* FilterImage::imageBufferFromCIImage()
+{
+    ASSERT(m_ciImage);
+
+    if (m_imageBuffer)
+        return m_imageBuffer.get();
+
+    m_imageBuffer = IOSurfaceImageBuffer::create(m_absoluteImageRect.size(), 1, m_colorSpace, PixelFormat::BGRA8);
+    if (!m_imageBuffer)
+        return nullptr;
+
+    auto destRect = FloatRect { FloatPoint(), m_absoluteImageRect.size() };
+    [sharedCIContext().get() render: m_ciImage.get() toIOSurface: downcast<IOSurfaceImageBuffer>(*m_imageBuffer).surface().surface() bounds:destRect colorSpace:m_colorSpace.platformColorSpace()];
+
+    return m_imageBuffer.get();
+}
+
+} // namespace WebCore
+
+#endif // USE(CORE_IMAGE)
diff --git a/Source/WebCore/platform/graphics/coreimage/SourceGraphicCoreImageApplier.h b/Source/WebCore/platform/graphics/coreimage/SourceGraphicCoreImageApplier.h
new file mode 100644
index 0000000..508f648
--- /dev/null
+++ b/Source/WebCore/platform/graphics/coreimage/SourceGraphicCoreImageApplier.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020-2021 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
+
+#import "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class SourceGraphic;
+
+class SourceGraphicCoreImageApplier : public FilterEffectConcreteApplier<SourceGraphic> {
+    WTF_MAKE_FAST_ALLOCATED;
+    using Base = FilterEffectConcreteApplier<SourceGraphic>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) const override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm b/Source/WebCore/platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm
new file mode 100644
index 0000000..8909070
--- /dev/null
+++ b/Source/WebCore/platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020-2021 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.
+ */
+
+#import "config.h"
+#import "SourceGraphicCoreImageApplier.h"
+
+#if USE(CORE_IMAGE)
+
+#import "Filter.h"
+#import "FilterImage.h"
+#import "PlatformImageBuffer.h"
+
+namespace WebCore {
+
+bool SourceGraphicCoreImageApplier::apply(const Filter& filter, const FilterImageVector&, FilterImage& result) const
+{
+    auto sourceImage = filter.sourceImage();
+    if (!sourceImage)
+        return false;
+
+    RetainPtr<CIImage> image;
+    if (is<IOSurfaceImageBuffer>(*sourceImage))
+        image = [CIImage imageWithIOSurface:downcast<IOSurfaceImageBuffer>(*sourceImage).surface().surface()];
+    else
+        image = [CIImage imageWithCGImage:sourceImage->copyNativeImage()->platformImage().get()];
+
+    if (!image)
+        return false;
+
+    result.setCIImage(WTFMove(image));
+    return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(CORE_IMAGE)
diff --git a/Source/WebCore/platform/graphics/cv/CVUtilities.mm b/Source/WebCore/platform/graphics/cv/CVUtilities.mm
index 4072704..acf96fd 100644
--- a/Source/WebCore/platform/graphics/cv/CVUtilities.mm
+++ b/Source/WebCore/platform/graphics/cv/CVUtilities.mm
@@ -26,6 +26,7 @@
 #import "config.h"
 #import "CVUtilities.h"
 
+#import "ColorSpaceCG.h"
 #import <wtf/StdLibExtras.h>
 #import "CoreVideoSoftLink.h"
 
diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index 630599f..201913a 100644
--- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -28,6 +28,10 @@
 #include "Filter.h"
 #include <wtf/text/TextStream.h>
 
+#if USE(CORE_IMAGE)
+#include "FEColorMatrixCoreImageApplier.h"
+#endif
+
 namespace WebCore {
 
 Ref<FEColorMatrix> FEColorMatrix::create(ColorMatrixType type, Vector<float>&& values)
@@ -94,6 +98,13 @@
     return normalizedValues;
 }
 
+#if USE(CORE_IMAGE)
+bool FEColorMatrix::supportsCoreImageRendering() const
+{
+    return FEColorMatrixCoreImageApplier::supportsCoreImageRendering(*this);
+}
+#endif
+
 bool FEColorMatrix::resultIsAlphaImage() const
 {
     return m_type == FECOLORMATRIX_TYPE_LUMINANCETOALPHA;
@@ -102,9 +113,8 @@
 std::unique_ptr<FilterEffectApplier> FEColorMatrix::createApplier(const Filter& filter) const
 {
 #if USE(CORE_IMAGE)
-    // FIXME: return FEColorMatrixCoreImageApplier.
     if (filter.renderingMode() == RenderingMode::Accelerated)
-        return nullptr;
+        return FilterEffectApplier::create<FEColorMatrixCoreImageApplier>(*this);
 #endif
     return FilterEffectApplier::create<FEColorMatrixSoftwareApplier>(*this);
 }
diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
index 04f57f1..3d0704e 100644
--- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
+++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
@@ -52,6 +52,10 @@
 private:
     FEColorMatrix(ColorMatrixType, Vector<float>&&);
 
+#if USE(CORE_IMAGE)
+    bool supportsCoreImageRendering() const override;
+#endif
+    
     bool resultIsAlphaImage() const override;
 
     std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override;
diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index eafa6b3..823e3da 100644
--- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -29,6 +29,10 @@
 #include "Filter.h"
 #include <wtf/text/TextStream.h>
 
+#if USE(CORE_IMAGE)
+#include "FEComponentTransferCoreImageApplier.h"
+#endif
+
 namespace WebCore {
 
 Ref<FEComponentTransfer> FEComponentTransfer::create(const ComponentTransferFunction& redFunction, const ComponentTransferFunction& greenFunction, const ComponentTransferFunction& blueFunction, const ComponentTransferFunction& alphaFunction)
@@ -45,12 +49,18 @@
 {
 }
 
+#if USE(CORE_IMAGE)
+bool FEComponentTransfer::supportsCoreImageRendering() const
+{
+    return FEComponentTransferCoreImageApplier::supportsCoreImageRendering(*this);
+}
+#endif
+
 std::unique_ptr<FilterEffectApplier> FEComponentTransfer::createApplier(const Filter& filter) const
 {
 #if USE(CORE_IMAGE)
-    // FIXME: return FEComponentTransferCoreImageApplier.
     if (filter.renderingMode() == RenderingMode::Accelerated)
-        return nullptr;
+        return FilterEffectApplier::create<FEComponentTransferCoreImageApplier>(*this);
 #endif
     return FilterEffectApplier::create<FEComponentTransferSoftwareApplier>(*this);
 }
diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
index 59c97b6..ccaf459 100644
--- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
+++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
@@ -62,6 +62,10 @@
 private:
     FEComponentTransfer(const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc, const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc);
 
+#if USE(CORE_IMAGE)
+    bool supportsCoreImageRendering() const override;
+#endif
+
     std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override;
 
     WTF::TextStream& externalRepresentation(WTF::TextStream&, RepresentationType) const override;
diff --git a/Source/WebCore/platform/graphics/filters/Filter.h b/Source/WebCore/platform/graphics/filters/Filter.h
index 884e788..2b06bfb 100644
--- a/Source/WebCore/platform/graphics/filters/Filter.h
+++ b/Source/WebCore/platform/graphics/filters/Filter.h
@@ -54,14 +54,16 @@
     void setRenderingMode(RenderingMode renderingMode) { m_renderingMode = renderingMode; }
 
 protected:
-    Filter(Filter::Type filterType, const FloatSize& filterScale)
+    Filter(Filter::Type filterType, RenderingMode renderingMode, const FloatSize& filterScale)
         : FilterFunction(filterType)
+        , m_renderingMode(renderingMode)
         , m_filterScale(filterScale)
     {
     }
 
-    Filter(Filter::Type filterType, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion)
+    Filter(Filter::Type filterType, RenderingMode renderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion)
         : FilterFunction(filterType)
+        , m_renderingMode(renderingMode)
         , m_filterScale(filterScale)
         , m_sourceImageRect(sourceImageRect)
         , m_filterRegion(filterRegion)
@@ -69,12 +71,13 @@
     }
 
 private:
+    RenderingMode m_renderingMode;
+
     FloatSize m_filterScale;
     FloatRect m_sourceImageRect;
     FloatRect m_filterRegion;
 
     RefPtr<ImageBuffer> m_sourceImage;
-    RenderingMode m_renderingMode { RenderingMode::Unaccelerated };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp b/Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp
deleted file mode 100644
index 9da855c..0000000
--- a/Source/WebCore/platform/graphics/filters/FilterEffectRenderer.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* Copyright (C) 2020 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.
-*/
-
-#include "config.h"
-#include "FilterEffectRenderer.h"
-
-#if USE(CORE_IMAGE)
-#include "FilterEffectRendererCoreImage.h"
-#endif
-
-namespace WebCore {
-
-std::unique_ptr<FilterEffectRenderer> FilterEffectRenderer::tryCreate(bool acceleratedFilterRenderingEnabled, FilterEffect& lastEffect)
-{
-#if USE(CORE_IMAGE)
-    if (acceleratedFilterRenderingEnabled)
-        return FilterEffectRendererCoreImage::tryCreate(lastEffect);
-#else
-    UNUSED_PARAM(acceleratedFilterRenderingEnabled);
-    UNUSED_PARAM(lastEffect);
-#endif
-    return nullptr;
-}
-
-
-} // namspace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffectRenderer.h b/Source/WebCore/platform/graphics/filters/FilterEffectRenderer.h
deleted file mode 100644
index 59cf7df..0000000
--- a/Source/WebCore/platform/graphics/filters/FilterEffectRenderer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-* Copyright (C) 2020 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 "FilterEffect.h"
-#include "ImageBuffer.h"
-#include "Settings.h"
-
-namespace WebCore {
-
-class FilterEffectRenderer {
-    WTF_MAKE_FAST_ALLOCATED;
-    
-public:
-    static std::unique_ptr<FilterEffectRenderer> tryCreate(bool, FilterEffect&);
-    virtual void applyEffects(const Filter&, FilterEffect&) = 0;
-    virtual bool hasResult() const = 0;
-    virtual ImageBuffer* output() const = 0;
-    virtual FloatRect destRect(const FilterEffect&) const = 0;
-    virtual void clearResult() = 0;
-    
-    virtual ~FilterEffectRenderer() = default;
-    
-protected:
-    FilterEffectRenderer() = default;
-    virtual void renderToImageBuffer(FilterEffect&) = 0;
-};
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/FilterFunction.h b/Source/WebCore/platform/graphics/filters/FilterFunction.h
index ab4a705..d29a3a6 100644
--- a/Source/WebCore/platform/graphics/filters/FilterFunction.h
+++ b/Source/WebCore/platform/graphics/filters/FilterFunction.h
@@ -84,6 +84,10 @@
     static AtomString sourceGraphicName() { return filterName(Type::SourceGraphic); }
     AtomString filterName() const { return filterName(m_filterType); }
 
+#if USE(CORE_IMAGE)
+    virtual bool supportsCoreImageRendering() const { return false; }
+#endif
+
     virtual bool apply(const Filter&) { return false; }
     virtual IntOutsets outsets() const { return { }; }
     virtual void clearResult() { }
diff --git a/Source/WebCore/platform/graphics/filters/FilterImage.cpp b/Source/WebCore/platform/graphics/filters/FilterImage.cpp
index 055dd85..3a4fe90 100644
--- a/Source/WebCore/platform/graphics/filters/FilterImage.cpp
+++ b/Source/WebCore/platform/graphics/filters/FilterImage.cpp
@@ -65,6 +65,15 @@
 
 ImageBuffer* FilterImage::imageBuffer()
 {
+#if USE(CORE_IMAGE)
+    if (m_ciImage)
+        return imageBufferFromCIImage();
+#endif
+    return imageBufferFromPixelBuffer();
+}
+
+ImageBuffer* FilterImage::imageBufferFromPixelBuffer()
+{
     if (m_imageBuffer)
         return m_imageBuffer.get();
 
diff --git a/Source/WebCore/platform/graphics/filters/FilterImage.h b/Source/WebCore/platform/graphics/filters/FilterImage.h
index 10c39d9..235a3e8 100644
--- a/Source/WebCore/platform/graphics/filters/FilterImage.h
+++ b/Source/WebCore/platform/graphics/filters/FilterImage.h
@@ -31,6 +31,10 @@
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
+#if USE(CORE_IMAGE)
+OBJC_CLASS CIImage;
+#endif
+
 namespace WebCore {
 
 class Filter;
@@ -61,11 +65,22 @@
     void correctPremultipliedPixelBuffer();
     void transformToColorSpace(const DestinationColorSpace&);
 
+#if USE(CORE_IMAGE)
+    RetainPtr<CIImage> ciImage() const { return m_ciImage; }
+    void setCIImage(RetainPtr<CIImage>&&);
+#endif
+
 private:
     FilterImage(const FloatRect& primitiveSubregion, const IntRect& absoluteImageRect, bool isAlphaImage, RenderingMode, const DestinationColorSpace&);
 
     std::optional<PixelBuffer>& pixelBufferSlot(AlphaPremultiplication);
 
+    ImageBuffer* imageBufferFromPixelBuffer();
+
+#if USE(CORE_IMAGE)
+    ImageBuffer* imageBufferFromCIImage();
+#endif
+
     bool requiresPixelBufferColorSpaceConversion(std::optional<DestinationColorSpace>) const;
 
     FloatRect m_primitiveSubregion;
@@ -78,6 +93,10 @@
     RefPtr<ImageBuffer> m_imageBuffer;
     std::optional<PixelBuffer> m_unpremultipliedPixelBuffer;
     std::optional<PixelBuffer> m_premultipliedPixelBuffer;
+
+#if USE(CORE_IMAGE)
+    RetainPtr<CIImage> m_ciImage;
+#endif
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp
index f7b16e6..a8e7166 100644
--- a/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp
+++ b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp
@@ -25,6 +25,10 @@
 #include "SourceGraphicSoftwareApplier.h"
 #include <wtf/text/TextStream.h>
 
+#if USE(CORE_IMAGE)
+#include "SourceGraphicCoreImageApplier.h"
+#endif
+
 namespace WebCore {
 
 Ref<SourceGraphic> SourceGraphic::create()
@@ -48,7 +52,7 @@
 #if USE(CORE_IMAGE)
     // FIXME: return SourceGraphicCoreImageApplier.
     if (filter.renderingMode() == RenderingMode::Accelerated)
-        return nullptr;
+        return FilterEffectApplier::create<SourceGraphicCoreImageApplier>(*this);
 #endif
     return FilterEffectApplier::create<SourceGraphicSoftwareApplier>(*this);
 }
diff --git a/Source/WebCore/platform/graphics/filters/SourceGraphic.h b/Source/WebCore/platform/graphics/filters/SourceGraphic.h
index e42be6c..03748a1 100644
--- a/Source/WebCore/platform/graphics/filters/SourceGraphic.h
+++ b/Source/WebCore/platform/graphics/filters/SourceGraphic.h
@@ -34,6 +34,10 @@
 private:
     SourceGraphic();
 
+#if USE(CORE_IMAGE)
+    bool supportsCoreImageRendering() const override { return true; }
+#endif
+
     void determineAbsolutePaintRect(const Filter&) override;
 
     std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override;
diff --git a/Source/WebCore/platform/mac/ScrollingEffectsController.mm b/Source/WebCore/platform/mac/ScrollingEffectsController.mm
index 1360059..a93ddd3 100644
--- a/Source/WebCore/platform/mac/ScrollingEffectsController.mm
+++ b/Source/WebCore/platform/mac/ScrollingEffectsController.mm
@@ -30,6 +30,7 @@
 #import "PlatformWheelEvent.h"
 #import "ScrollAnimationRubberBand.h"
 #import "ScrollExtents.h"
+#import "ScrollableArea.h"
 #import "WheelEventDeltaFilter.h"
 #import <pal/spi/mac/NSScrollViewSPI.h>
 #import <sys/sysctl.h>
diff --git a/Source/WebCore/rendering/CSSFilter.cpp b/Source/WebCore/rendering/CSSFilter.cpp
index 0ac6899..17a93d3 100644
--- a/Source/WebCore/rendering/CSSFilter.cpp
+++ b/Source/WebCore/rendering/CSSFilter.cpp
@@ -32,7 +32,6 @@
 #include "FEDropShadow.h"
 #include "FEGaussianBlur.h"
 #include "FEMerge.h"
-#include "FilterEffectRenderer.h"
 #include "FilterOperations.h"
 #include "GraphicsContext.h"
 #include "LengthFunctions.h"
@@ -55,14 +54,11 @@
     bool hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
     bool hasFilterThatShouldBeRestrictedBySecurityOrigin = operations.hasFilterThatShouldBeRestrictedBySecurityOrigin();
 
-    auto filter = adoptRef(*new CSSFilter(hasFilterThatMovesPixels, hasFilterThatShouldBeRestrictedBySecurityOrigin, scaleFactor));
-
-    filter->setRenderingMode(renderingMode);
-    return filter;
+    return adoptRef(*new CSSFilter(renderingMode, scaleFactor, hasFilterThatMovesPixels, hasFilterThatShouldBeRestrictedBySecurityOrigin));
 }
 
-CSSFilter::CSSFilter(bool hasFilterThatMovesPixels, bool hasFilterThatShouldBeRestrictedBySecurityOrigin, float scaleFactor)
-    : Filter(Filter::Type::CSSFilter, FloatSize { scaleFactor, scaleFactor })
+CSSFilter::CSSFilter(RenderingMode renderingMode, float scaleFactor, bool hasFilterThatMovesPixels, bool hasFilterThatShouldBeRestrictedBySecurityOrigin)
+    : Filter(Filter::Type::CSSFilter, renderingMode, FloatSize { scaleFactor, scaleFactor })
     , m_hasFilterThatMovesPixels(hasFilterThatMovesPixels)
     , m_hasFilterThatShouldBeRestrictedBySecurityOrigin(hasFilterThatShouldBeRestrictedBySecurityOrigin)
 {
@@ -225,7 +221,7 @@
     }
 
     SVGFilterBuilder builder;
-    return SVGFilter::create(*filterElement, builder, filter.filterScale(), filter.sourceImageRect(), filter.filterRegion(), previousEffect);
+    return SVGFilter::create(*filterElement, builder, filter.renderingMode(), filter.filterScale(), filter.sourceImageRect(), filter.filterRegion(), previousEffect);
 }
 
 static void setupLastEffectProperties(FilterEffect& effect, FilterConsumer consumer)
@@ -329,9 +325,10 @@
     m_functions.shrinkToFit();
 
 #if USE(CORE_IMAGE)
-    if (!m_filterRenderer)
-        m_filterRenderer = FilterEffectRenderer::tryCreate(renderer.settings().coreImageAcceleratedFilterRenderEnabled(), *lastEffect());
+    if (!supportsCoreImageRendering())
+        setRenderingMode(RenderingMode::Unaccelerated);
 #endif
+
     return true;
 }
 
@@ -367,8 +364,7 @@
         setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), &targetContext, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8));
 #else
         UNUSED_PARAM(targetContext);
-        RenderingMode mode = m_filterRenderer ? RenderingMode::Accelerated : renderingMode();
-        setSourceImage(ImageBuffer::create(logicalSize, mode, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8));
+        setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8));
 #endif
         if (auto context = inputContext())
             context->scale(filterScale());
@@ -389,6 +385,21 @@
     return downcast<FilterEffect>(function.ptr());
 }
 
+#if USE(CORE_IMAGE)
+bool CSSFilter::supportsCoreImageRendering() const
+{
+    if (renderingMode() == RenderingMode::Unaccelerated)
+        return false;
+
+    for (auto& function : m_functions) {
+        if (!function->supportsCoreImageRendering())
+            return false;
+    }
+
+    return true;
+}
+#endif
+
 void CSSFilter::determineFilterPrimitiveSubregion()
 {
     auto effect = lastEffect();
@@ -410,21 +421,12 @@
 
 bool CSSFilter::apply()
 {
-    auto effect = lastEffect();
-    if (m_filterRenderer) {
-        m_filterRenderer->applyEffects(*this, *effect);
-        if (m_filterRenderer->hasResult()) {
-            effect->transformResultColorSpace(DestinationColorSpace::SRGB());
-            return true;
-        }
-    }
-
     for (auto& function : m_functions) {
         if (!function->apply(*this))
             return false;
     }
 
-    effect->transformResultColorSpace(DestinationColorSpace::SRGB());
+    lastEffect()->transformResultColorSpace(DestinationColorSpace::SRGB());
     return true;
 }
 
@@ -440,9 +442,6 @@
 
 ImageBuffer* CSSFilter::output()
 {
-    if (m_filterRenderer && m_filterRenderer->hasResult())
-        return m_filterRenderer->output();
-
     if (auto result = lastEffect()->filterImage())
         return result->imageBuffer();
 
@@ -471,8 +470,8 @@
 {
     auto effect = lastEffect();
 
-    if (effect->hasResult() || (m_filterRenderer && m_filterRenderer->hasResult()))
-        return effect->absolutePaintRect() - IntPoint(filterRegion().location());
+    if (auto result = effect->filterImage())
+        return result->absoluteImageRect() - IntPoint(filterRegion().location());
 
     return { };
 }
diff --git a/Source/WebCore/rendering/CSSFilter.h b/Source/WebCore/rendering/CSSFilter.h
index c340871..0eba47d 100644
--- a/Source/WebCore/rendering/CSSFilter.h
+++ b/Source/WebCore/rendering/CSSFilter.h
@@ -33,7 +33,6 @@
 namespace WebCore {
 
 class FilterEffect;
-class FilterEffectRenderer;
 class FilterOperations;
 class GraphicsContext;
 class ReferenceFilterOperation;
@@ -71,7 +70,11 @@
     LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
 
 private:
-    CSSFilter(bool hasFilterThatMovesPixels, bool hasFilterThatShouldBeRestrictedBySecurityOrigin, float scaleFactor);
+    CSSFilter(RenderingMode, float scaleFactor, bool hasFilterThatMovesPixels, bool hasFilterThatShouldBeRestrictedBySecurityOrigin);
+
+#if USE(CORE_IMAGE)
+    bool supportsCoreImageRendering() const override;
+#endif
 
     bool m_graphicsBufferAttached { false };
     bool m_hasFilterThatMovesPixels { false };
@@ -80,8 +83,6 @@
     Vector<Ref<FilterFunction>> m_functions;
 
     mutable IntOutsets m_outsets;
-
-    std::unique_ptr<FilterEffectRenderer> m_filterRenderer;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
index 934fc83..82cceb4 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
@@ -126,9 +126,12 @@
     absoluteDrawingRegion.scale(filterScale);
     ImageBuffer::sizeNeedsClamping(absoluteDrawingRegion.size(), filterScale);
 
+    // Set the rendering mode from the page's settings.
+    auto renderingMode = renderer.settings().acceleratedFiltersEnabled() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
+
     // Create the SVGFilter object.
     filterData->builder = makeUnique<SVGFilterBuilder>();
-    filterData->filter = SVGFilter::create(filterElement(), *filterData->builder, filterScale, absoluteDrawingRegion, filterData->boundaries, targetBoundingBox);
+    filterData->filter = SVGFilter::create(filterElement(), *filterData->builder, renderingMode, filterScale, absoluteDrawingRegion, filterData->boundaries, targetBoundingBox);
     if (!filterData->filter) {
         m_rendererFilterDataMap.remove(&renderer);
         return false;
@@ -160,22 +163,18 @@
     // Change the coordinate transformation applied to the filtered element to reflect the resolution of the filter.
     AffineTransform effectiveTransform = AffineTransform(filterScale.width(), 0, 0, filterScale.height(), 0, 0);
 
-    auto renderingMode = renderer.settings().acceleratedFiltersEnabled() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
 #if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
     auto colorSpace = DestinationColorSpace::LinearSRGB();
 #else
     auto colorSpace = DestinationColorSpace::SRGB();
 #endif
-    auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, colorSpace, renderingMode, context);
+    auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, colorSpace, filterData->filter->renderingMode(), context);
     if (!sourceGraphic) {
         ASSERT(m_rendererFilterDataMap.contains(&renderer));
         filterData->savedContext = context;
         return false;
     }
     
-    // Set the rendering mode from the page's settings.
-    filterData->filter->setRenderingMode(renderingMode);
-
     GraphicsContext& sourceGraphicContext = sourceGraphic->context();
   
     filterData->sourceGraphicBuffer = WTFMove(sourceGraphic);
diff --git a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
index c5b7106..4966a0a 100644
--- a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
@@ -431,7 +431,7 @@
         FloatRect dummyRect;
         FloatSize dummyScale(1, 1);
         SVGFilterBuilder builder;
-        auto dummyFilter = SVGFilter::create(filter.filterElement(), builder, dummyScale, dummyRect, dummyRect, dummyRect);
+        auto dummyFilter = SVGFilter::create(filter.filterElement(), builder, RenderingMode::Unaccelerated, dummyScale, dummyRect, dummyRect, dummyRect);
         if (dummyFilter) {
             TextStream::IndentScope indentScope(ts);
 
diff --git a/Source/WebCore/svg/graphics/filters/SVGFilter.cpp b/Source/WebCore/svg/graphics/filters/SVGFilter.cpp
index df73749..8727096 100644
--- a/Source/WebCore/svg/graphics/filters/SVGFilter.cpp
+++ b/Source/WebCore/svg/graphics/filters/SVGFilter.cpp
@@ -28,21 +28,21 @@
 
 namespace WebCore {
 
-RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, FilterEffect& previousEffect)
+RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, RenderingMode renderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, FilterEffect& previousEffect)
 {
-    return create(filterElement, builder, filterScale, sourceImageRect, filterRegion, filterRegion, &previousEffect);
+    return create(filterElement, builder, renderingMode, filterScale, sourceImageRect, filterRegion, filterRegion, &previousEffect);
 }
 
-RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox)
+RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, RenderingMode renderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox)
 {
-    return create(filterElement, builder, filterScale, sourceImageRect, filterRegion, targetBoundingBox, nullptr);
+    return create(filterElement, builder, renderingMode, filterScale, sourceImageRect, filterRegion, targetBoundingBox, nullptr);
 }
 
-RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect)
+RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, RenderingMode renderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect)
 {
     bool primitiveBoundingBoxMode = filterElement.primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
 
-    auto filter = adoptRef(*new SVGFilter(filterScale, sourceImageRect, filterRegion, targetBoundingBox, primitiveBoundingBoxMode));
+    auto filter = adoptRef(*new SVGFilter(renderingMode, filterScale, sourceImageRect, filterRegion, targetBoundingBox, primitiveBoundingBoxMode));
 
     if (!previousEffect)
         builder.setupBuiltinEffects(SourceGraphic::create());
@@ -62,11 +62,17 @@
 
     ASSERT(!expression.isEmpty());
     filter->setExpression(WTFMove(expression));
+    
+#if USE(CORE_IMAGE)
+    if (!filter->supportsCoreImageRendering())
+        filter->setRenderingMode(RenderingMode::Unaccelerated);
+#endif
+
     return filter;
 }
 
-SVGFilter::SVGFilter(const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, bool effectBBoxMode)
-    : Filter(Filter::Type::SVGFilter, filterScale, sourceImageRect, filterRegion)
+SVGFilter::SVGFilter(RenderingMode renderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, bool effectBBoxMode)
+    : Filter(Filter::Type::SVGFilter, renderingMode, filterScale, sourceImageRect, filterRegion)
     , m_targetBoundingBox(targetBoundingBox)
     , m_effectBBoxMode(effectBBoxMode)
 {
@@ -80,6 +86,22 @@
     return Filter::scaledByFilterScale(size);
 }
 
+#if USE(CORE_IMAGE)
+bool SVGFilter::supportsCoreImageRendering() const
+{
+    if (renderingMode() == RenderingMode::Unaccelerated)
+        return false;
+
+    ASSERT(!m_expression.isEmpty());
+    for (auto& effect : m_expression) {
+        if (!effect->supportsCoreImageRendering())
+            return false;
+    }
+
+    return true;
+}
+#endif
+
 bool SVGFilter::apply(const Filter& filter)
 {
     setSourceImage({ filter.sourceImage() });
diff --git a/Source/WebCore/svg/graphics/filters/SVGFilter.h b/Source/WebCore/svg/graphics/filters/SVGFilter.h
index 896fbb2..49b5553 100644
--- a/Source/WebCore/svg/graphics/filters/SVGFilter.h
+++ b/Source/WebCore/svg/graphics/filters/SVGFilter.h
@@ -33,9 +33,9 @@
 
 class SVGFilter final : public Filter {
 public:
-    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, FilterEffect& previousEffect);
-    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox);
-    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect);
+    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, FilterEffect& previousEffect);
+    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox);
+    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect);
 
     FloatSize scaledByFilterScale(FloatSize) const final;
 
@@ -46,7 +46,11 @@
     RefPtr<FilterEffect> lastEffect() const { return !m_expression.isEmpty() ? m_expression.last() : nullptr; }
 
 private:
-    SVGFilter(const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode);
+    SVGFilter(RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode);
+
+#if USE(CORE_IMAGE)
+    bool supportsCoreImageRendering() const override;
+#endif
 
     bool apply(const Filter&) override;
     IntOutsets outsets() const override;