<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[286152] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/286152">286152</a></dd>
<dt>Author</dt> <dd>said@apple.com</dd>
<dt>Date</dt> <dd>2021-11-24 11:41:26 -0800 (Wed, 24 Nov 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GPU Process] Move the software FilterEffectAppliers to separate files
https://bugs.webkit.org/show_bug.cgi?id=232833
rdar://85424225

Reviewed by Simon Fraser.

This patch moves the the software FilterEffectAppliers to separate source
and header files. There is no change in the appliers code.

But EdgeModeType and MorphologyOperatorType have to changed to be enum
classes so they can be forwarded declared in the appliers' header files.

* CMakeLists.txt:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/filters/FEBlend.cpp:
(WebCore::FEBlendSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEBlend.h:
* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrixSoftwareApplier::FEColorMatrixSoftwareApplier): Deleted.
(WebCore::FEColorMatrixSoftwareApplier::matrix const): Deleted.
(WebCore::FEColorMatrixSoftwareApplier::saturateAndHueRotate const): Deleted.
(WebCore::FEColorMatrixSoftwareApplier::luminance const): Deleted.
(WebCore::FEColorMatrixSoftwareApplier::applyPlatformAccelerated const): Deleted.
(WebCore::FEColorMatrixSoftwareApplier::applyPlatformUnaccelerated const): Deleted.
(WebCore::FEColorMatrixSoftwareApplier::applyPlatform const): Deleted.
(WebCore::FEColorMatrixSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEColorMatrix.h:
* platform/graphics/filters/FEComponentTransfer.cpp:
(WebCore::FEComponentTransferSoftwareApplier::computeIdentityTable): Deleted.
(WebCore::FEComponentTransferSoftwareApplier::computeTabularTable): Deleted.
(WebCore::FEComponentTransferSoftwareApplier::computeDiscreteTable): Deleted.
(WebCore::FEComponentTransferSoftwareApplier::computeLinearTable): Deleted.
(WebCore::FEComponentTransferSoftwareApplier::computeGammaTable): Deleted.
(WebCore::FEComponentTransferSoftwareApplier::computeLookupTable): Deleted.
(WebCore::FEComponentTransferSoftwareApplier::applyPlatform const): Deleted.
(WebCore::FEComponentTransferSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEComponentTransfer.h:
* platform/graphics/filters/FEComposite.cpp:
(WebCore::FECompositeSoftwareApplier::clampByte): Deleted.
(WebCore::FECompositeSoftwareApplier::computeArithmeticPixels): Deleted.
(WebCore::FECompositeSoftwareApplier::computeArithmeticPixelsUnclamped): Deleted.
(WebCore::FECompositeSoftwareApplier::applyPlatformArithmetic): Deleted.
(WebCore::FECompositeSoftwareApplier::applyArithmetic): Deleted.
(WebCore::FECompositeSoftwareApplier::applyNonArithmetic): Deleted.
(WebCore::FECompositeSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEComposite.h:
* platform/graphics/filters/FEConvolveMatrix.cpp:
(WebCore::operator<<):
(WebCore::FEConvolveMatrixSoftwareApplier::clampRGBAValue): Deleted.
(WebCore::FEConvolveMatrixSoftwareApplier::setDestinationPixels): Deleted.
(WebCore::FEConvolveMatrixSoftwareApplier::getPixelValue): Deleted.
(WebCore::FEConvolveMatrixSoftwareApplier::setInteriorPixels): Deleted.
(WebCore::FEConvolveMatrixSoftwareApplier::setOuterPixels): Deleted.
(WebCore::FEConvolveMatrixSoftwareApplier::applyPlatform const): Deleted.
(WebCore::FEConvolveMatrixSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEConvolveMatrix.h:
* platform/graphics/filters/FEDiffuseLighting.cpp:
* platform/graphics/filters/FEDiffuseLighting.h:
* platform/graphics/filters/FEDisplacementMap.cpp:
(WebCore::FEDisplacementMapSoftwareApplier::byteOffsetOfPixel): Deleted.
(WebCore::FEDisplacementMapSoftwareApplier::xChannelIndex const): Deleted.
(WebCore::FEDisplacementMapSoftwareApplier::yChannelIndex const): Deleted.
(WebCore::FEDisplacementMapSoftwareApplier::FEDisplacementMapSoftwareApplier): Deleted.
(WebCore::FEDisplacementMapSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEDisplacementMap.h:
* platform/graphics/filters/FEDropShadow.cpp:
(WebCore::FEDropShadowSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEDropShadow.h:
* platform/graphics/filters/FEFlood.cpp:
(WebCore::FEFloodSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEFlood.h:
* platform/graphics/filters/FEGaussianBlur.cpp:
(WebCore::FEGaussianBlur::determineAbsolutePaintRect):
(WebCore::FEGaussianBlurSoftwareApplier::kernelPosition): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurAlphaOnly): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::boxBlur): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurAccelerated): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurUnaccelerated): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurGeneric): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurWorker): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::applyPlatform): Deleted.
(WebCore::FEGaussianBlurSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEGaussianBlur.h:
* platform/graphics/filters/FELighting.cpp:
(): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::topLeft const): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::left const): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::bottomLeft const): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::top const): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::center const): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::bottom const): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::setTop): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::setCenter): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::setBottom): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::setTopRight): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::setRight): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::setBottomRight): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::shiftRow): Deleted.
(WebCore::FELightingSoftwareApplier::AlphaWindow::shift): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::topLeftNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::topRowNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::topRightNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::leftColumnNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::interiorNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::rightColumnNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::bottomLeftNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::bottomRowNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::LightingData::bottomRightNormal const): Deleted.
(WebCore::FELightingSoftwareApplier::setPixelInternal): Deleted.
(WebCore::FELightingSoftwareApplier::setPixel): Deleted.
(WebCore::FELightingSoftwareApplier::applyPlatformGenericPaint): Deleted.
(WebCore::FELightingSoftwareApplier::applyPlatformGenericWorker): Deleted.
(WebCore::FELightingSoftwareApplier::applyPlatformGeneric): Deleted.
(WebCore::FELightingSoftwareApplier::applyPlatform): Deleted.
(WebCore::FELightingSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FELighting.h:
* platform/graphics/filters/FEMerge.cpp:
(WebCore::FEMergeSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEMerge.h:
* platform/graphics/filters/FEMorphology.cpp:
(WebCore::operator<<):
(WebCore::FEMorphologySoftwareApplier::pixelArrayIndex): Deleted.
(WebCore::FEMorphologySoftwareApplier::makePixelValueFromColorComponents): Deleted.
(WebCore::FEMorphologySoftwareApplier::makeColorComponentsfromPixelValue): Deleted.
(WebCore::FEMorphologySoftwareApplier::minOrMax): Deleted.
(WebCore::FEMorphologySoftwareApplier::columnExtremum): Deleted.
(WebCore::FEMorphologySoftwareApplier::kernelExtremum): Deleted.
(WebCore::FEMorphologySoftwareApplier::applyPlatformGeneric): Deleted.
(WebCore::FEMorphologySoftwareApplier::applyPlatformWorker): Deleted.
(WebCore::FEMorphologySoftwareApplier::applyPlatform): Deleted.
(WebCore::FEMorphologySoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEMorphology.h:
(): Deleted.
* platform/graphics/filters/FEOffset.cpp:
(WebCore::FEOffsetSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FEOffset.h:
* platform/graphics/filters/FESpecularLighting.cpp:
* platform/graphics/filters/FESpecularLighting.h:
* platform/graphics/filters/FETile.cpp:
(WebCore::FETileSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FETile.h:
* platform/graphics/filters/FETurbulence.cpp:
(WebCore::FETurbulence::setStitchTiles):
(WebCore::FETurbulenceSoftwareApplier::PaintingData::random): Deleted.
(): Deleted.
(WebCore::FETurbulenceSoftwareApplier::smoothCurve): Deleted.
(WebCore::FETurbulenceSoftwareApplier::linearInterpolation): Deleted.
(WebCore::FETurbulenceSoftwareApplier::initPaintingData): Deleted.
(WebCore::FETurbulenceSoftwareApplier::computeStitching): Deleted.
(WebCore::FETurbulenceSoftwareApplier::noise2D): Deleted.
(WebCore::FETurbulenceSoftwareApplier::toIntBasedColorComponents): Deleted.
(WebCore::FETurbulenceSoftwareApplier::calculateTurbulenceValueForPoint): Deleted.
(WebCore::FETurbulenceSoftwareApplier::applyPlatformGeneric): Deleted.
(WebCore::FETurbulenceSoftwareApplier::applyPlatformWorker): Deleted.
(WebCore::FETurbulenceSoftwareApplier::applyPlatform): Deleted.
(WebCore::FETurbulenceSoftwareApplier::apply): Deleted.
* platform/graphics/filters/FETurbulence.h:
* platform/graphics/filters/FilterEffectApplier.h:
* platform/graphics/filters/SourceAlpha.cpp:
(WebCore::SourceAlphaSoftwareApplier::apply): Deleted.
* platform/graphics/filters/SourceAlpha.h:
* platform/graphics/filters/SourceGraphic.cpp:
(WebCore::SourceGraphicSoftwareApplier::apply): Deleted.
* platform/graphics/filters/SourceGraphic.h:
* platform/graphics/filters/software/FEBlendSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEBlend.cpp.
(WebCore::FEBlendSoftwareApplier::apply):
* platform/graphics/filters/software/FEBlendSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
* platform/graphics/filters/software/FEColorMatrixSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp.
(WebCore::FEColorMatrixSoftwareApplier::FEColorMatrixSoftwareApplier):
(WebCore::FEColorMatrixSoftwareApplier::matrix const):
(WebCore::FEColorMatrixSoftwareApplier::saturateAndHueRotate const):
(WebCore::FEColorMatrixSoftwareApplier::luminance const):
(WebCore::FEColorMatrixSoftwareApplier::applyPlatformAccelerated const):
(WebCore::FEColorMatrixSoftwareApplier::applyPlatformUnaccelerated const):
(WebCore::FEColorMatrixSoftwareApplier::applyPlatform const):
(WebCore::FEColorMatrixSoftwareApplier::apply):
* platform/graphics/filters/software/FEColorMatrixSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEOffset.h.
* platform/graphics/filters/software/FEComponentTransferSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp.
(WebCore::FEComponentTransferSoftwareApplier::computeIdentityTable):
(WebCore::FEComponentTransferSoftwareApplier::computeTabularTable):
(WebCore::FEComponentTransferSoftwareApplier::computeDiscreteTable):
(WebCore::FEComponentTransferSoftwareApplier::computeLinearTable):
(WebCore::FEComponentTransferSoftwareApplier::computeGammaTable):
(WebCore::FEComponentTransferSoftwareApplier::computeLookupTable):
(WebCore::FEComponentTransferSoftwareApplier::applyPlatform const):
(WebCore::FEComponentTransferSoftwareApplier::apply):
* platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEOffset.h.
* platform/graphics/filters/software/FECompositeSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEComposite.cpp.
(WebCore::FECompositeSoftwareApplier::clampByte):
(WebCore::FECompositeSoftwareApplier::computeArithmeticPixels):
(WebCore::FECompositeSoftwareApplier::computeArithmeticPixelsUnclamped):
(WebCore::FECompositeSoftwareApplier::applyPlatformArithmetic):
(WebCore::FECompositeSoftwareApplier::applyArithmetic):
(WebCore::FECompositeSoftwareApplier::applyNonArithmetic):
(WebCore::FECompositeSoftwareApplier::apply):
* platform/graphics/filters/software/FECompositeSoftwareApplier.h: Added.
* platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp.
(WebCore::FEConvolveMatrixSoftwareApplier::clampRGBAValue):
(WebCore::FEConvolveMatrixSoftwareApplier::setDestinationPixels):
(WebCore::FEConvolveMatrixSoftwareApplier::getPixelValue):
(WebCore::FEConvolveMatrixSoftwareApplier::setInteriorPixels):
(WebCore::FEConvolveMatrixSoftwareApplier::setOuterPixels):
(WebCore::FEConvolveMatrixSoftwareApplier::applyPlatform const):
(WebCore::FEConvolveMatrixSoftwareApplier::apply):
* platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.h: Added.
* platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp.
(WebCore::FEDisplacementMapSoftwareApplier::FEDisplacementMapSoftwareApplier):
(WebCore::FEDisplacementMapSoftwareApplier::xChannelIndex const):
(WebCore::FEDisplacementMapSoftwareApplier::yChannelIndex const):
(WebCore::FEDisplacementMapSoftwareApplier::apply):
* platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEOffset.h.
(WebCore::FEDisplacementMapSoftwareApplier::byteOffsetOfPixel):
* platform/graphics/filters/software/FEDropShadowSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEDropShadow.cpp.
(WebCore::FEDropShadowSoftwareApplier::apply):
* platform/graphics/filters/software/FEDropShadowSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
* platform/graphics/filters/software/FEFloodSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
(WebCore::FEFloodSoftwareApplier::apply):
* platform/graphics/filters/software/FEFloodSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
* platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp.
(WebCore::FEGaussianBlurSoftwareApplier::kernelPosition):
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurAlphaOnly):
(WebCore::FEGaussianBlurSoftwareApplier::boxBlur):
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurAccelerated):
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurUnaccelerated):
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurGeneric):
(WebCore::FEGaussianBlurSoftwareApplier::boxBlurWorker):
(WebCore::FEGaussianBlurSoftwareApplier::applyPlatform):
(WebCore::FEGaussianBlurSoftwareApplier::apply):
* platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.h: Added.
* platform/graphics/filters/software/FELightingSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FELighting.cpp.
(WebCore::FELightingSoftwareApplier::LightingData::topLeftNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::topRowNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::topRightNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::leftColumnNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::interiorNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::rightColumnNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::bottomLeftNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::bottomRowNormal const):
(WebCore::FELightingSoftwareApplier::LightingData::bottomRightNormal const):
(WebCore::FELightingSoftwareApplier::setPixelInternal):
(WebCore::FELightingSoftwareApplier::setPixel):
(WebCore::FELightingSoftwareApplier::applyPlatformGenericPaint):
(WebCore::FELightingSoftwareApplier::applyPlatformGenericWorker):
(WebCore::FELightingSoftwareApplier::applyPlatformGeneric):
(WebCore::FELightingSoftwareApplier::applyPlatform):
(WebCore::FELightingSoftwareApplier::apply):
* platform/graphics/filters/software/FELightingSoftwareApplier.h: Added.
(WebCore::FELightingSoftwareApplier::AlphaWindow::topLeft const):
(WebCore::FELightingSoftwareApplier::AlphaWindow::left const):
(WebCore::FELightingSoftwareApplier::AlphaWindow::bottomLeft const):
(WebCore::FELightingSoftwareApplier::AlphaWindow::top const):
(WebCore::FELightingSoftwareApplier::AlphaWindow::center const):
(WebCore::FELightingSoftwareApplier::AlphaWindow::bottom const):
(WebCore::FELightingSoftwareApplier::AlphaWindow::setTop):
(WebCore::FELightingSoftwareApplier::AlphaWindow::setCenter):
(WebCore::FELightingSoftwareApplier::AlphaWindow::setBottom):
(WebCore::FELightingSoftwareApplier::AlphaWindow::setTopRight):
(WebCore::FELightingSoftwareApplier::AlphaWindow::setRight):
(WebCore::FELightingSoftwareApplier::AlphaWindow::setBottomRight):
(WebCore::FELightingSoftwareApplier::AlphaWindow::shiftRow):
(WebCore::FELightingSoftwareApplier::AlphaWindow::shift):
* platform/graphics/filters/software/FEMergeSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEMerge.cpp.
(WebCore::FEMergeSoftwareApplier::apply):
* platform/graphics/filters/software/FEMergeSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
* platform/graphics/filters/software/FEMorphologySoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEMorphology.cpp.
(WebCore::FEMorphologySoftwareApplier::minOrMax):
(WebCore::FEMorphologySoftwareApplier::columnExtremum):
(WebCore::FEMorphologySoftwareApplier::kernelExtremum):
(WebCore::FEMorphologySoftwareApplier::applyPlatformGeneric):
(WebCore::FEMorphologySoftwareApplier::applyPlatformWorker):
(WebCore::FEMorphologySoftwareApplier::applyPlatform):
(WebCore::FEMorphologySoftwareApplier::apply):
* platform/graphics/filters/software/FEMorphologySoftwareApplier.h: Added.
(WebCore::FEMorphologySoftwareApplier::pixelArrayIndex):
(WebCore::FEMorphologySoftwareApplier::makePixelValueFromColorComponents):
(WebCore::FEMorphologySoftwareApplier::makeColorComponentsfromPixelValue):
* platform/graphics/filters/software/FEOffsetSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEOffset.cpp.
(WebCore::FEOffsetSoftwareApplier::apply):
* platform/graphics/filters/software/FEOffsetSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
* platform/graphics/filters/software/FETileSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FETile.cpp.
(WebCore::FETileSoftwareApplier::apply):
* platform/graphics/filters/software/FETileSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
* platform/graphics/filters/software/FETurbulenceSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FETurbulence.cpp.
(WebCore::FETurbulenceSoftwareApplier::initPaintingData):
(WebCore::FETurbulenceSoftwareApplier::computeStitching):
(WebCore::FETurbulenceSoftwareApplier::noise2D):
(WebCore::FETurbulenceSoftwareApplier::toIntBasedColorComponents):
(WebCore::FETurbulenceSoftwareApplier::calculateTurbulenceValueForPoint):
(WebCore::FETurbulenceSoftwareApplier::applyPlatformGeneric):
(WebCore::FETurbulenceSoftwareApplier::applyPlatformWorker):
(WebCore::FETurbulenceSoftwareApplier::applyPlatform):
(WebCore::FETurbulenceSoftwareApplier::apply):
* platform/graphics/filters/software/FETurbulenceSoftwareApplier.h: Added.
(WebCore::FETurbulenceSoftwareApplier::PaintingData::random):
(WebCore::FETurbulenceSoftwareApplier::smoothCurve):
(WebCore::FETurbulenceSoftwareApplier::linearInterpolation):
* platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/SourceAlpha.cpp.
(WebCore::SourceAlphaSoftwareApplier::apply):
* platform/graphics/filters/software/SourceAlphaSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/SourceAlpha.h.
* platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/SourceAlpha.h.
(WebCore::SourceGraphicSoftwareApplier::apply):
* platform/graphics/filters/software/SourceGraphicSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/SourceGraphic.h.
* rendering/CSSFilter.cpp:
(WebCore::createBlurEffect):
* svg/SVGFEConvolveMatrixElement.cpp:
(WebCore::SVGFEConvolveMatrixElement::parseAttribute):
* svg/SVGFEConvolveMatrixElement.h:
(WebCore::SVGPropertyTraits<EdgeModeType>::highestEnumValue):
(WebCore::SVGPropertyTraits<EdgeModeType>::initialValue):
(WebCore::SVGPropertyTraits<EdgeModeType>::toString):
(WebCore::SVGPropertyTraits<EdgeModeType>::fromString):
* svg/SVGFEGaussianBlurElement.cpp:
(WebCore::SVGFEGaussianBlurElement::parseAttribute):
* svg/SVGFEGaussianBlurElement.h:
* svg/SVGFEMorphologyElement.cpp:
(WebCore::SVGFEMorphologyElement::parseAttribute):
* svg/SVGFEMorphologyElement.h:
(WebCore::SVGPropertyTraits<MorphologyOperatorType>::highestEnumValue):
(WebCore::SVGPropertyTraits<MorphologyOperatorType>::toString):
(WebCore::SVGPropertyTraits<MorphologyOperatorType>::fromString):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEBlendcpp">trunk/Source/WebCore/platform/graphics/filters/FEBlend.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEBlendh">trunk/Source/WebCore/platform/graphics/filters/FEBlend.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEColorMatrixcpp">trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEColorMatrixh">trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEComponentTransfercpp">trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEComponentTransferh">trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFECompositecpp">trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFECompositeh">trunk/Source/WebCore/platform/graphics/filters/FEComposite.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixcpp">trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixh">trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEDiffuseLightingcpp">trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEDiffuseLightingh">trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEDisplacementMapcpp">trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEDisplacementMaph">trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEDropShadowcpp">trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEDropShadowh">trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEFloodcpp">trunk/Source/WebCore/platform/graphics/filters/FEFlood.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEFloodh">trunk/Source/WebCore/platform/graphics/filters/FEFlood.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEGaussianBlurcpp">trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEGaussianBlurh">trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFELightingcpp">trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFELightingh">trunk/Source/WebCore/platform/graphics/filters/FELighting.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEMergecpp">trunk/Source/WebCore/platform/graphics/filters/FEMerge.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEMergeh">trunk/Source/WebCore/platform/graphics/filters/FEMerge.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEMorphologycpp">trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEMorphologyh">trunk/Source/WebCore/platform/graphics/filters/FEMorphology.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEOffsetcpp">trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEOffseth">trunk/Source/WebCore/platform/graphics/filters/FEOffset.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFESpecularLightingcpp">trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFESpecularLightingh">trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFETilecpp">trunk/Source/WebCore/platform/graphics/filters/FETile.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFETileh">trunk/Source/WebCore/platform/graphics/filters/FETile.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFETurbulencecpp">trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFETurbulenceh">trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFilterEffectApplierh">trunk/Source/WebCore/platform/graphics/filters/FilterEffectApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersSourceAlphacpp">trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersSourceAlphah">trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersSourceGraphiccpp">trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersSourceGraphich">trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.h</a></li>
<li><a href="#trunkSourceWebCorerenderingCSSFiltercpp">trunk/Source/WebCore/rendering/CSSFilter.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEConvolveMatrixElementcpp">trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEConvolveMatrixElementh">trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.h</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEGaussianBlurElementcpp">trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEGaussianBlurElementh">trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEMorphologyElementcpp">trunk/Source/WebCore/svg/SVGFEMorphologyElement.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEMorphologyElementh">trunk/Source/WebCore/svg/SVGFEMorphologyElement.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/Source/WebCore/platform/graphics/filters/software/</li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEBlendSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEBlendSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEColorMatrixSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEColorMatrixSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEComponentTransferSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEComponentTransferSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFECompositeSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFECompositeSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEConvolveMatrixSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEConvolveMatrixSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDisplacementMapSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDisplacementMapSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDropShadowSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDropShadowSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEFloodSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEFloodSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEGaussianBlurSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEGaussianBlurSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFELightingSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFELightingSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMergeSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMergeSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMorphologySoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMorphologySoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEOffsetSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFEOffsetSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFETileSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFETileSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFETurbulenceSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareFETurbulenceSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceAlphaSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceAlphaSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceGraphicSoftwareAppliercpp">trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceGraphicSoftwareApplierh">trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt      2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/CMakeLists.txt 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/cpu/arm/filters"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/displaylists"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/filters"
</span><ins>+    "${WEBCORE_DIR}/platform/graphics/filters/software"
</ins><span class="cx">     "${WEBCORE_DIR}/platform/graphics/iso"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/opentype"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/transforms"
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/ChangeLog      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,3 +1,327 @@
</span><ins>+2021-11-24  Said Abou-Hallawa  <said@apple.com>
+
+        [GPU Process] Move the software FilterEffectAppliers to separate files
+        https://bugs.webkit.org/show_bug.cgi?id=232833
+        rdar://85424225
+
+        Reviewed by Simon Fraser.
+
+        This patch moves the the software FilterEffectAppliers to separate source
+        and header files. There is no change in the appliers code.
+
+        But EdgeModeType and MorphologyOperatorType have to changed to be enum
+        classes so they can be forwarded declared in the appliers' header files.
+
+        * CMakeLists.txt:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/filters/FEBlend.cpp:
+        (WebCore::FEBlendSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEBlend.h:
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrixSoftwareApplier::FEColorMatrixSoftwareApplier): Deleted.
+        (WebCore::FEColorMatrixSoftwareApplier::matrix const): Deleted.
+        (WebCore::FEColorMatrixSoftwareApplier::saturateAndHueRotate const): Deleted.
+        (WebCore::FEColorMatrixSoftwareApplier::luminance const): Deleted.
+        (WebCore::FEColorMatrixSoftwareApplier::applyPlatformAccelerated const): Deleted.
+        (WebCore::FEColorMatrixSoftwareApplier::applyPlatformUnaccelerated const): Deleted.
+        (WebCore::FEColorMatrixSoftwareApplier::applyPlatform const): Deleted.
+        (WebCore::FEColorMatrixSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEColorMatrix.h:
+        * platform/graphics/filters/FEComponentTransfer.cpp:
+        (WebCore::FEComponentTransferSoftwareApplier::computeIdentityTable): Deleted.
+        (WebCore::FEComponentTransferSoftwareApplier::computeTabularTable): Deleted.
+        (WebCore::FEComponentTransferSoftwareApplier::computeDiscreteTable): Deleted.
+        (WebCore::FEComponentTransferSoftwareApplier::computeLinearTable): Deleted.
+        (WebCore::FEComponentTransferSoftwareApplier::computeGammaTable): Deleted.
+        (WebCore::FEComponentTransferSoftwareApplier::computeLookupTable): Deleted.
+        (WebCore::FEComponentTransferSoftwareApplier::applyPlatform const): Deleted.
+        (WebCore::FEComponentTransferSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEComponentTransfer.h:
+        * platform/graphics/filters/FEComposite.cpp:
+        (WebCore::FECompositeSoftwareApplier::clampByte): Deleted.
+        (WebCore::FECompositeSoftwareApplier::computeArithmeticPixels): Deleted.
+        (WebCore::FECompositeSoftwareApplier::computeArithmeticPixelsUnclamped): Deleted.
+        (WebCore::FECompositeSoftwareApplier::applyPlatformArithmetic): Deleted.
+        (WebCore::FECompositeSoftwareApplier::applyArithmetic): Deleted.
+        (WebCore::FECompositeSoftwareApplier::applyNonArithmetic): Deleted.
+        (WebCore::FECompositeSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEComposite.h:
+        * platform/graphics/filters/FEConvolveMatrix.cpp:
+        (WebCore::operator<<):
+        (WebCore::FEConvolveMatrixSoftwareApplier::clampRGBAValue): Deleted.
+        (WebCore::FEConvolveMatrixSoftwareApplier::setDestinationPixels): Deleted.
+        (WebCore::FEConvolveMatrixSoftwareApplier::getPixelValue): Deleted.
+        (WebCore::FEConvolveMatrixSoftwareApplier::setInteriorPixels): Deleted.
+        (WebCore::FEConvolveMatrixSoftwareApplier::setOuterPixels): Deleted.
+        (WebCore::FEConvolveMatrixSoftwareApplier::applyPlatform const): Deleted.
+        (WebCore::FEConvolveMatrixSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEConvolveMatrix.h:
+        * platform/graphics/filters/FEDiffuseLighting.cpp:
+        * platform/graphics/filters/FEDiffuseLighting.h:
+        * platform/graphics/filters/FEDisplacementMap.cpp:
+        (WebCore::FEDisplacementMapSoftwareApplier::byteOffsetOfPixel): Deleted.
+        (WebCore::FEDisplacementMapSoftwareApplier::xChannelIndex const): Deleted.
+        (WebCore::FEDisplacementMapSoftwareApplier::yChannelIndex const): Deleted.
+        (WebCore::FEDisplacementMapSoftwareApplier::FEDisplacementMapSoftwareApplier): Deleted.
+        (WebCore::FEDisplacementMapSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEDisplacementMap.h:
+        * platform/graphics/filters/FEDropShadow.cpp:
+        (WebCore::FEDropShadowSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEDropShadow.h:
+        * platform/graphics/filters/FEFlood.cpp:
+        (WebCore::FEFloodSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEFlood.h:
+        * platform/graphics/filters/FEGaussianBlur.cpp:
+        (WebCore::FEGaussianBlur::determineAbsolutePaintRect):
+        (WebCore::FEGaussianBlurSoftwareApplier::kernelPosition): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurAlphaOnly): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlur): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurAccelerated): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurUnaccelerated): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurGeneric): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurWorker): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::applyPlatform): Deleted.
+        (WebCore::FEGaussianBlurSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEGaussianBlur.h:
+        * platform/graphics/filters/FELighting.cpp:
+        (): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::topLeft const): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::left const): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::bottomLeft const): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::top const): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::center const): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::bottom const): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setTop): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setCenter): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setBottom): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setTopRight): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setRight): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setBottomRight): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::shiftRow): Deleted.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::shift): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::topLeftNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::topRowNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::topRightNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::leftColumnNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::interiorNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::rightColumnNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::bottomLeftNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::bottomRowNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::LightingData::bottomRightNormal const): Deleted.
+        (WebCore::FELightingSoftwareApplier::setPixelInternal): Deleted.
+        (WebCore::FELightingSoftwareApplier::setPixel): Deleted.
+        (WebCore::FELightingSoftwareApplier::applyPlatformGenericPaint): Deleted.
+        (WebCore::FELightingSoftwareApplier::applyPlatformGenericWorker): Deleted.
+        (WebCore::FELightingSoftwareApplier::applyPlatformGeneric): Deleted.
+        (WebCore::FELightingSoftwareApplier::applyPlatform): Deleted.
+        (WebCore::FELightingSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FELighting.h:
+        * platform/graphics/filters/FEMerge.cpp:
+        (WebCore::FEMergeSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEMerge.h:
+        * platform/graphics/filters/FEMorphology.cpp:
+        (WebCore::operator<<):
+        (WebCore::FEMorphologySoftwareApplier::pixelArrayIndex): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::makePixelValueFromColorComponents): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::makeColorComponentsfromPixelValue): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::minOrMax): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::columnExtremum): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::kernelExtremum): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::applyPlatformGeneric): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::applyPlatformWorker): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::applyPlatform): Deleted.
+        (WebCore::FEMorphologySoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEMorphology.h:
+        (): Deleted.
+        * platform/graphics/filters/FEOffset.cpp:
+        (WebCore::FEOffsetSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FEOffset.h:
+        * platform/graphics/filters/FESpecularLighting.cpp:
+        * platform/graphics/filters/FESpecularLighting.h:
+        * platform/graphics/filters/FETile.cpp:
+        (WebCore::FETileSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FETile.h:
+        * platform/graphics/filters/FETurbulence.cpp:
+        (WebCore::FETurbulence::setStitchTiles):
+        (WebCore::FETurbulenceSoftwareApplier::PaintingData::random): Deleted.
+        (): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::smoothCurve): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::linearInterpolation): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::initPaintingData): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::computeStitching): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::noise2D): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::toIntBasedColorComponents): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::calculateTurbulenceValueForPoint): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::applyPlatformGeneric): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::applyPlatformWorker): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::applyPlatform): Deleted.
+        (WebCore::FETurbulenceSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/FETurbulence.h:
+        * platform/graphics/filters/FilterEffectApplier.h:
+        * platform/graphics/filters/SourceAlpha.cpp:
+        (WebCore::SourceAlphaSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/SourceAlpha.h:
+        * platform/graphics/filters/SourceGraphic.cpp:
+        (WebCore::SourceGraphicSoftwareApplier::apply): Deleted.
+        * platform/graphics/filters/SourceGraphic.h:
+        * platform/graphics/filters/software/FEBlendSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEBlend.cpp.
+        (WebCore::FEBlendSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEBlendSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
+        * platform/graphics/filters/software/FEColorMatrixSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp.
+        (WebCore::FEColorMatrixSoftwareApplier::FEColorMatrixSoftwareApplier):
+        (WebCore::FEColorMatrixSoftwareApplier::matrix const):
+        (WebCore::FEColorMatrixSoftwareApplier::saturateAndHueRotate const):
+        (WebCore::FEColorMatrixSoftwareApplier::luminance const):
+        (WebCore::FEColorMatrixSoftwareApplier::applyPlatformAccelerated const):
+        (WebCore::FEColorMatrixSoftwareApplier::applyPlatformUnaccelerated const):
+        (WebCore::FEColorMatrixSoftwareApplier::applyPlatform const):
+        (WebCore::FEColorMatrixSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEColorMatrixSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEOffset.h.
+        * platform/graphics/filters/software/FEComponentTransferSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp.
+        (WebCore::FEComponentTransferSoftwareApplier::computeIdentityTable):
+        (WebCore::FEComponentTransferSoftwareApplier::computeTabularTable):
+        (WebCore::FEComponentTransferSoftwareApplier::computeDiscreteTable):
+        (WebCore::FEComponentTransferSoftwareApplier::computeLinearTable):
+        (WebCore::FEComponentTransferSoftwareApplier::computeGammaTable):
+        (WebCore::FEComponentTransferSoftwareApplier::computeLookupTable):
+        (WebCore::FEComponentTransferSoftwareApplier::applyPlatform const):
+        (WebCore::FEComponentTransferSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEOffset.h.
+        * platform/graphics/filters/software/FECompositeSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEComposite.cpp.
+        (WebCore::FECompositeSoftwareApplier::clampByte):
+        (WebCore::FECompositeSoftwareApplier::computeArithmeticPixels):
+        (WebCore::FECompositeSoftwareApplier::computeArithmeticPixelsUnclamped):
+        (WebCore::FECompositeSoftwareApplier::applyPlatformArithmetic):
+        (WebCore::FECompositeSoftwareApplier::applyArithmetic):
+        (WebCore::FECompositeSoftwareApplier::applyNonArithmetic):
+        (WebCore::FECompositeSoftwareApplier::apply):
+        * platform/graphics/filters/software/FECompositeSoftwareApplier.h: Added.
+        * platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp.
+        (WebCore::FEConvolveMatrixSoftwareApplier::clampRGBAValue):
+        (WebCore::FEConvolveMatrixSoftwareApplier::setDestinationPixels):
+        (WebCore::FEConvolveMatrixSoftwareApplier::getPixelValue):
+        (WebCore::FEConvolveMatrixSoftwareApplier::setInteriorPixels):
+        (WebCore::FEConvolveMatrixSoftwareApplier::setOuterPixels):
+        (WebCore::FEConvolveMatrixSoftwareApplier::applyPlatform const):
+        (WebCore::FEConvolveMatrixSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.h: Added.
+        * platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp.
+        (WebCore::FEDisplacementMapSoftwareApplier::FEDisplacementMapSoftwareApplier):
+        (WebCore::FEDisplacementMapSoftwareApplier::xChannelIndex const):
+        (WebCore::FEDisplacementMapSoftwareApplier::yChannelIndex const):
+        (WebCore::FEDisplacementMapSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEOffset.h.
+        (WebCore::FEDisplacementMapSoftwareApplier::byteOffsetOfPixel):
+        * platform/graphics/filters/software/FEDropShadowSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEDropShadow.cpp.
+        (WebCore::FEDropShadowSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEDropShadowSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
+        * platform/graphics/filters/software/FEFloodSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
+        (WebCore::FEFloodSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEFloodSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
+        * platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp.
+        (WebCore::FEGaussianBlurSoftwareApplier::kernelPosition):
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurAlphaOnly):
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlur):
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurAccelerated):
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurUnaccelerated):
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurGeneric):
+        (WebCore::FEGaussianBlurSoftwareApplier::boxBlurWorker):
+        (WebCore::FEGaussianBlurSoftwareApplier::applyPlatform):
+        (WebCore::FEGaussianBlurSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.h: Added.
+        * platform/graphics/filters/software/FELightingSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FELighting.cpp.
+        (WebCore::FELightingSoftwareApplier::LightingData::topLeftNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::topRowNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::topRightNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::leftColumnNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::interiorNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::rightColumnNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::bottomLeftNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::bottomRowNormal const):
+        (WebCore::FELightingSoftwareApplier::LightingData::bottomRightNormal const):
+        (WebCore::FELightingSoftwareApplier::setPixelInternal):
+        (WebCore::FELightingSoftwareApplier::setPixel):
+        (WebCore::FELightingSoftwareApplier::applyPlatformGenericPaint):
+        (WebCore::FELightingSoftwareApplier::applyPlatformGenericWorker):
+        (WebCore::FELightingSoftwareApplier::applyPlatformGeneric):
+        (WebCore::FELightingSoftwareApplier::applyPlatform):
+        (WebCore::FELightingSoftwareApplier::apply):
+        * platform/graphics/filters/software/FELightingSoftwareApplier.h: Added.
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::topLeft const):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::left const):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::bottomLeft const):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::top const):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::center const):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::bottom const):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setTop):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setCenter):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setBottom):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setTopRight):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setRight):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::setBottomRight):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::shiftRow):
+        (WebCore::FELightingSoftwareApplier::AlphaWindow::shift):
+        * platform/graphics/filters/software/FEMergeSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEMerge.cpp.
+        (WebCore::FEMergeSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEMergeSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
+        * platform/graphics/filters/software/FEMorphologySoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEMorphology.cpp.
+        (WebCore::FEMorphologySoftwareApplier::minOrMax):
+        (WebCore::FEMorphologySoftwareApplier::columnExtremum):
+        (WebCore::FEMorphologySoftwareApplier::kernelExtremum):
+        (WebCore::FEMorphologySoftwareApplier::applyPlatformGeneric):
+        (WebCore::FEMorphologySoftwareApplier::applyPlatformWorker):
+        (WebCore::FEMorphologySoftwareApplier::applyPlatform):
+        (WebCore::FEMorphologySoftwareApplier::apply):
+        * platform/graphics/filters/software/FEMorphologySoftwareApplier.h: Added.
+        (WebCore::FEMorphologySoftwareApplier::pixelArrayIndex):
+        (WebCore::FEMorphologySoftwareApplier::makePixelValueFromColorComponents):
+        (WebCore::FEMorphologySoftwareApplier::makeColorComponentsfromPixelValue):
+        * platform/graphics/filters/software/FEOffsetSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FEOffset.cpp.
+        (WebCore::FEOffsetSoftwareApplier::apply):
+        * platform/graphics/filters/software/FEOffsetSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
+        * platform/graphics/filters/software/FETileSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FETile.cpp.
+        (WebCore::FETileSoftwareApplier::apply):
+        * platform/graphics/filters/software/FETileSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/FEMerge.h.
+        * platform/graphics/filters/software/FETurbulenceSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/FETurbulence.cpp.
+        (WebCore::FETurbulenceSoftwareApplier::initPaintingData):
+        (WebCore::FETurbulenceSoftwareApplier::computeStitching):
+        (WebCore::FETurbulenceSoftwareApplier::noise2D):
+        (WebCore::FETurbulenceSoftwareApplier::toIntBasedColorComponents):
+        (WebCore::FETurbulenceSoftwareApplier::calculateTurbulenceValueForPoint):
+        (WebCore::FETurbulenceSoftwareApplier::applyPlatformGeneric):
+        (WebCore::FETurbulenceSoftwareApplier::applyPlatformWorker):
+        (WebCore::FETurbulenceSoftwareApplier::applyPlatform):
+        (WebCore::FETurbulenceSoftwareApplier::apply):
+        * platform/graphics/filters/software/FETurbulenceSoftwareApplier.h: Added.
+        (WebCore::FETurbulenceSoftwareApplier::PaintingData::random):
+        (WebCore::FETurbulenceSoftwareApplier::smoothCurve):
+        (WebCore::FETurbulenceSoftwareApplier::linearInterpolation):
+        * platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/SourceAlpha.cpp.
+        (WebCore::SourceAlphaSoftwareApplier::apply):
+        * platform/graphics/filters/software/SourceAlphaSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/SourceAlpha.h.
+        * platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp: Copied from Source/WebCore/platform/graphics/filters/SourceAlpha.h.
+        (WebCore::SourceGraphicSoftwareApplier::apply):
+        * platform/graphics/filters/software/SourceGraphicSoftwareApplier.h: Copied from Source/WebCore/platform/graphics/filters/SourceGraphic.h.
+        * rendering/CSSFilter.cpp:
+        (WebCore::createBlurEffect):
+        * svg/SVGFEConvolveMatrixElement.cpp:
+        (WebCore::SVGFEConvolveMatrixElement::parseAttribute):
+        * svg/SVGFEConvolveMatrixElement.h:
+        (WebCore::SVGPropertyTraits<EdgeModeType>::highestEnumValue):
+        (WebCore::SVGPropertyTraits<EdgeModeType>::initialValue):
+        (WebCore::SVGPropertyTraits<EdgeModeType>::toString):
+        (WebCore::SVGPropertyTraits<EdgeModeType>::fromString):
+        * svg/SVGFEGaussianBlurElement.cpp:
+        (WebCore::SVGFEGaussianBlurElement::parseAttribute):
+        * svg/SVGFEGaussianBlurElement.h:
+        * svg/SVGFEMorphologyElement.cpp:
+        (WebCore::SVGFEMorphologyElement::parseAttribute):
+        * svg/SVGFEMorphologyElement.h:
+        (WebCore::SVGPropertyTraits<MorphologyOperatorType>::highestEnumValue):
+        (WebCore::SVGPropertyTraits<MorphologyOperatorType>::toString):
+        (WebCore::SVGPropertyTraits<MorphologyOperatorType>::fromString):
+
</ins><span class="cx"> 2021-11-24  Dean Jackson  <dino@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Make DocumentClass an OptionSet
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/Sources.txt    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2110,6 +2110,23 @@
</span><span class="cx"> platform/graphics/filters/SourceAlpha.cpp
</span><span class="cx"> platform/graphics/filters/SourceGraphic.cpp
</span><span class="cx"> platform/graphics/filters/SpotLightSource.cpp
</span><ins>+platform/graphics/filters/software/FEBlendSoftwareApplier.cpp
+platform/graphics/filters/software/FEColorMatrixSoftwareApplier.cpp
+platform/graphics/filters/software/FEComponentTransferSoftwareApplier.cpp
+platform/graphics/filters/software/FECompositeSoftwareApplier.cpp
+platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.cpp
+platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.cpp
+platform/graphics/filters/software/FEDropShadowSoftwareApplier.cpp
+platform/graphics/filters/software/FEFloodSoftwareApplier.cpp
+platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.cpp
+platform/graphics/filters/software/FELightingSoftwareApplier.cpp
+platform/graphics/filters/software/FEMergeSoftwareApplier.cpp
+platform/graphics/filters/software/FEMorphologySoftwareApplier.cpp
+platform/graphics/filters/software/FEOffsetSoftwareApplier.cpp
+platform/graphics/filters/software/FETileSoftwareApplier.cpp
+platform/graphics/filters/software/FETurbulenceSoftwareApplier.cpp
+platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp
+platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp
</ins><span class="cx"> platform/graphics/iso/ISOBox.cpp
</span><span class="cx"> platform/graphics/iso/ISOOriginalFormatBox.cpp
</span><span class="cx"> platform/graphics/iso/ISOProtectionSchemeInfoBox.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -10897,6 +10897,40 @@
</span><span class="cx">          7299BC6623D686C600CC6883 /* RenderingMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderingMode.h; sourceTree = "<group>"; };
</span><span class="cx">          729D052E25313E2600422098 /* RenderingResourceIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderingResourceIdentifier.h; sourceTree = "<group>"; };
</span><span class="cx">          72A13A9F274C5CC700E2A88E /* FilterEffectApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FilterEffectApplier.h; sourceTree = "<group>"; };
</span><ins>+               72A13AB6274DCEDC00E2A88E /* FEColorMatrixSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEColorMatrixSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AB7274DCEDC00E2A88E /* FEColorMatrixSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEColorMatrixSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AB8274DDEC000E2A88E /* FEComponentTransferSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEComponentTransferSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AB9274DDEC000E2A88E /* FEComponentTransferSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEComponentTransferSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13ABA274DE01200E2A88E /* FECompositeSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FECompositeSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13ABB274DE01200E2A88E /* FECompositeSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FECompositeSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13ABE274DE33F00E2A88E /* FEConvolveMatrixSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEConvolveMatrixSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13ABF274DE33F00E2A88E /* FEConvolveMatrixSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEConvolveMatrixSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AC0274DE35900E2A88E /* FEDisplacementMapSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEDisplacementMapSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AC1274DE35900E2A88E /* FEDisplacementMapSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEDisplacementMapSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AC2274DE38700E2A88E /* FEDropShadowSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEDropShadowSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AC3274DE38700E2A88E /* FEDropShadowSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEDropShadowSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AC4274DE39E00E2A88E /* FEFloodSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEFloodSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AC5274DE39E00E2A88E /* FEFloodSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEFloodSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AC6274DE3B700E2A88E /* FEGaussianBlurSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEGaussianBlurSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AC7274DE3B700E2A88E /* FEGaussianBlurSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEGaussianBlurSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AC8274DE3D100E2A88E /* FELightingSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FELightingSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AC9274DE3D100E2A88E /* FELightingSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FELightingSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13ACA274DE3E500E2A88E /* FEMergeSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEMergeSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13ACB274DE3E500E2A88E /* FEMergeSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEMergeSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13ACC274DE43700E2A88E /* FEMorphologySoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEMorphologySoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13ACD274DE43700E2A88E /* FEMorphologySoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEMorphologySoftwareApplier.h; sourceTree = "<group>"; };
+               72A13ACE274DE46C00E2A88E /* FEOffsetSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FEOffsetSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13ACF274DE46C00E2A88E /* FEOffsetSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEOffsetSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AD0274DE48900E2A88E /* FETileSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FETileSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AD1274DE48900E2A88E /* FETileSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FETileSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AD2274DE51800E2A88E /* FETurbulenceSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FETurbulenceSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AD3274DE51800E2A88E /* FETurbulenceSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FETurbulenceSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AD4274DE54E00E2A88E /* SourceAlphaSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SourceAlphaSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AD5274DE54E00E2A88E /* SourceAlphaSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceAlphaSoftwareApplier.h; sourceTree = "<group>"; };
+               72A13AD6274DE57800E2A88E /* SourceGraphicSoftwareApplier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SourceGraphicSoftwareApplier.cpp; sourceTree = "<group>"; };
+               72A13AD7274DE57800E2A88E /* SourceGraphicSoftwareApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceGraphicSoftwareApplier.h; sourceTree = "<group>"; };
+               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>"; };
</ins><span class="cx">           72BAC3A423E17327008D741C /* ImageBufferBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferBackend.cpp; sourceTree = "<group>"; };
</span><span class="cx">          72BAC3A523E17328008D741C /* ImageBufferBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferBackend.h; sourceTree = "<group>"; };
</span><span class="cx">          72BAC3A623E17328008D741C /* PlatformImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformImageBuffer.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -23832,6 +23866,47 @@
</span><span class="cx">                  path = "model-element";
</span><span class="cx">                  sourceTree = "<group>";
</span><span class="cx">          };
</span><ins>+               72A13AB4274DCEA300E2A88E /* software */ = {
+                       isa = PBXGroup;
+                       children = (
+                               72B4EF75274E233400293C2F /* FEBlendSoftwareApplier.cpp */,
+                               72B4EF74274E233300293C2F /* FEBlendSoftwareApplier.h */,
+                               72A13AB6274DCEDC00E2A88E /* FEColorMatrixSoftwareApplier.cpp */,
+                               72A13AB7274DCEDC00E2A88E /* FEColorMatrixSoftwareApplier.h */,
+                               72A13AB8274DDEC000E2A88E /* FEComponentTransferSoftwareApplier.cpp */,
+                               72A13AB9274DDEC000E2A88E /* FEComponentTransferSoftwareApplier.h */,
+                               72A13ABA274DE01200E2A88E /* FECompositeSoftwareApplier.cpp */,
+                               72A13ABB274DE01200E2A88E /* FECompositeSoftwareApplier.h */,
+                               72A13ABE274DE33F00E2A88E /* FEConvolveMatrixSoftwareApplier.cpp */,
+                               72A13ABF274DE33F00E2A88E /* FEConvolveMatrixSoftwareApplier.h */,
+                               72A13AC0274DE35900E2A88E /* FEDisplacementMapSoftwareApplier.cpp */,
+                               72A13AC1274DE35900E2A88E /* FEDisplacementMapSoftwareApplier.h */,
+                               72A13AC2274DE38700E2A88E /* FEDropShadowSoftwareApplier.cpp */,
+                               72A13AC3274DE38700E2A88E /* FEDropShadowSoftwareApplier.h */,
+                               72A13AC4274DE39E00E2A88E /* FEFloodSoftwareApplier.cpp */,
+                               72A13AC5274DE39E00E2A88E /* FEFloodSoftwareApplier.h */,
+                               72A13AC6274DE3B700E2A88E /* FEGaussianBlurSoftwareApplier.cpp */,
+                               72A13AC7274DE3B700E2A88E /* FEGaussianBlurSoftwareApplier.h */,
+                               72A13AC8274DE3D100E2A88E /* FELightingSoftwareApplier.cpp */,
+                               72A13AC9274DE3D100E2A88E /* FELightingSoftwareApplier.h */,
+                               72A13ACA274DE3E500E2A88E /* FEMergeSoftwareApplier.cpp */,
+                               72A13ACB274DE3E500E2A88E /* FEMergeSoftwareApplier.h */,
+                               72A13ACC274DE43700E2A88E /* FEMorphologySoftwareApplier.cpp */,
+                               72A13ACD274DE43700E2A88E /* FEMorphologySoftwareApplier.h */,
+                               72A13ACE274DE46C00E2A88E /* FEOffsetSoftwareApplier.cpp */,
+                               72A13ACF274DE46C00E2A88E /* FEOffsetSoftwareApplier.h */,
+                               72A13AD0274DE48900E2A88E /* FETileSoftwareApplier.cpp */,
+                               72A13AD1274DE48900E2A88E /* FETileSoftwareApplier.h */,
+                               72A13AD2274DE51800E2A88E /* FETurbulenceSoftwareApplier.cpp */,
+                               72A13AD3274DE51800E2A88E /* FETurbulenceSoftwareApplier.h */,
+                               72A13AD4274DE54E00E2A88E /* SourceAlphaSoftwareApplier.cpp */,
+                               72A13AD5274DE54E00E2A88E /* SourceAlphaSoftwareApplier.h */,
+                               72A13AD6274DE57800E2A88E /* SourceGraphicSoftwareApplier.cpp */,
+                               72A13AD7274DE57800E2A88E /* SourceGraphicSoftwareApplier.h */,
+                       );
+                       path = software;
+                       sourceTree = "<group>";
+               };
</ins><span class="cx">           7C011F3C24FAD360005BEF10 /* SettingsTemplates */ = {
</span><span class="cx">                  isa = PBXGroup;
</span><span class="cx">                  children = (
</span><span class="lines">@@ -25904,6 +25979,7 @@
</span><span class="cx">          A75E8B7F0E1DE2B0007F2481 /* filters */ = {
</span><span class="cx">                  isa = PBXGroup;
</span><span class="cx">                  children = (
</span><ins>+                               72A13AB4274DCEA300E2A88E /* software */,
</ins><span class="cx">                           A1E1154313015C3D0054AC8C /* DistantLightSource.cpp */,
</span><span class="cx">                          84730D5A1248F0B300D3A9C9 /* DistantLightSource.h */,
</span><span class="cx">                          A75E8B800E1DE2D6007F2481 /* FEBlend.cpp */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEBlendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEBlend.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEBlend.cpp       2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEBlend.cpp  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -5,6 +5,7 @@
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
</span><span class="cx">  * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -26,10 +27,7 @@
</span><span class="cx"> #include "FEBlend.h"
</span><span class="cx"> 
</span><span class="cx"> #include "FEBlendNEON.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "FloatPoint.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
</del><ins>+#include "FEBlendSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -53,38 +51,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEBlendSoftwareApplier to separate source and header files.
-class FEBlendSoftwareApplier : public FilterEffectConcreteApplier<FEBlend> {
-    using Base = FilterEffectConcreteApplier<FEBlend>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-#if !HAVE(ARM_NEON_INTRINSICS)
-bool FEBlendSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-    FilterEffect* in2 = inputEffects[1].get();
-
-    auto resultImage = m_effect.imageBufferResult();
-    if (!resultImage)
-        return false;
-
-    auto imageBuffer = in->imageBufferResult();
-    auto imageBuffer2 = in2->imageBufferResult();
-    if (!imageBuffer || !imageBuffer2)
-        return false;
-
-    GraphicsContext& filterContext = resultImage->context();
-    filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
-    filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, { CompositeOperator::SourceOver, m_effect.blendMode() });
-    return true;
-}
-#endif
-
</del><span class="cx"> bool FEBlend::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEBlendSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEBlendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEBlend.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEBlend.h 2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEBlend.h    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -3,6 +3,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -38,8 +39,7 @@
</span><span class="cx">     FEBlend(BlendMode);
</span><span class="cx"> 
</span><span class="cx">     bool platformApplySoftware(const Filter&) override;
</span><del>-    void platformApplyGeneric(unsigned char* srcPixelArrayA, unsigned char* srcPixelArrayB, unsigned char* dstPixelArray,
-                           unsigned colorArrayLength);
</del><ins>+
</ins><span class="cx">     void platformApplyNEON(unsigned char* srcPixelArrayA, unsigned char* srcPixelArrayB, unsigned char* dstPixelArray,
</span><span class="cx">                            unsigned colorArrayLength);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEColorMatrixcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp 2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -3,6 +3,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -23,17 +24,9 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEColorMatrix.h"
</span><span class="cx"> 
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
-#include "PixelBuffer.h"
-#include <wtf/MathExtras.h>
</del><ins>+#include "FEColorMatrixSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><del>-#if USE(ACCELERATE)
-#include <Accelerate/Accelerate.h>
-#endif
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> Ref<FEColorMatrix> FEColorMatrix::create(ColorMatrixType type, Vector<float>&& values)
</span><span class="lines">@@ -100,279 +93,6 @@
</span><span class="cx">     return normalizedValues;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEColorMatrixSoftwareApplier to separate source and header files.
-class FEColorMatrixSoftwareApplier : public FilterEffectConcreteApplier<FEColorMatrix> {
-    using Base = FilterEffectConcreteApplier<FEColorMatrix>;
-
-public:
-    FEColorMatrixSoftwareApplier(FEColorMatrix&);
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    inline void matrix(float& red, float& green, float& blue, float& alpha) const;
-    inline void saturateAndHueRotate(float& red, float& green, float& blue) const;
-    inline void luminance(float& red, float& green, float& blue, float& alpha) const;
-
-#if USE(ACCELERATE)
-    void applyPlatformAccelerated(PixelBuffer&) const;
-#endif
-    void applyPlatformUnaccelerated(PixelBuffer&) const;
-
-    void applyPlatform(PixelBuffer&) const;
-
-    float m_components[9];
-};
-
-FEColorMatrixSoftwareApplier::FEColorMatrixSoftwareApplier(FEColorMatrix& effect)
-    : Base(effect)
-{
-    if (m_effect.type() == FECOLORMATRIX_TYPE_SATURATE)
-        FEColorMatrix::calculateSaturateComponents(m_components, m_effect.values()[0]);
-    else if (m_effect.type() == FECOLORMATRIX_TYPE_HUEROTATE)
-        FEColorMatrix::calculateHueRotateComponents(m_components, m_effect.values()[0]);
-}
-
-inline void FEColorMatrixSoftwareApplier::matrix(float& red, float& green, float& blue, float& alpha) const
-{
-    float r = red;
-    float g = green;
-    float b = blue;
-    float a = alpha;
-
-    const auto& values = m_effect.values();
-
-    red   = values[ 0] * r + values[ 1] * g + values[ 2] * b + values[ 3] * a + values[ 4] * 255;
-    green = values[ 5] * r + values[ 6] * g + values[ 7] * b + values[ 8] * a + values[ 9] * 255;
-    blue  = values[10] * r + values[11] * g + values[12] * b + values[13] * a + values[14] * 255;
-    alpha = values[15] * r + values[16] * g + values[17] * b + values[18] * a + values[19] * 255;
-}
-
-inline void FEColorMatrixSoftwareApplier::saturateAndHueRotate(float& red, float& green, float& blue) const
-{
-    float r = red;
-    float g = green;
-    float b = blue;
-
-    red     = r * m_components[0] + g * m_components[1] + b * m_components[2];
-    green   = r * m_components[3] + g * m_components[4] + b * m_components[5];
-    blue    = r * m_components[6] + g * m_components[7] + b * m_components[8];
-}
-
-// FIXME: this should use the luminance(...) function in ColorLuminance.h.
-inline void FEColorMatrixSoftwareApplier::luminance(float& red, float& green, float& blue, float& alpha) const
-{
-    alpha = 0.2125 * red + 0.7154 * green + 0.0721 * blue;
-    red = 0;
-    green = 0;
-    blue = 0;
-}
-
-#if USE(ACCELERATE)
-void FEColorMatrixSoftwareApplier::applyPlatformAccelerated(PixelBuffer& pixelBuffer) const
-{
-    auto& pixelArray = pixelBuffer.data();
-    auto bufferSize = pixelBuffer.size();
-
-    ASSERT(pixelArray.length() == bufferSize.area() * 4);
-    
-    const int32_t divisor = 256;
-    uint8_t* data = pixelArray.data();
-
-    vImage_Buffer src;
-    src.width = bufferSize.width();
-    src.height = bufferSize.height();
-    src.rowBytes = bufferSize.width() * 4;
-    src.data = data;
-    
-    vImage_Buffer dest;
-    dest.width = bufferSize.width();
-    dest.height = bufferSize.height();
-    dest.rowBytes = bufferSize.width() * 4;
-    dest.data = data;
-
-    switch (m_effect.type()) {
-    case FECOLORMATRIX_TYPE_UNKNOWN:
-        break;
-
-    case FECOLORMATRIX_TYPE_MATRIX: {
-        const auto& values = m_effect.values();
-
-        const int16_t matrix[4 * 4] = {
-            static_cast<int16_t>(roundf(values[ 0] * divisor)),
-            static_cast<int16_t>(roundf(values[ 5] * divisor)),
-            static_cast<int16_t>(roundf(values[10] * divisor)),
-            static_cast<int16_t>(roundf(values[15] * divisor)),
-
-            static_cast<int16_t>(roundf(values[ 1] * divisor)),
-            static_cast<int16_t>(roundf(values[ 6] * divisor)),
-            static_cast<int16_t>(roundf(values[11] * divisor)),
-            static_cast<int16_t>(roundf(values[16] * divisor)),
-
-            static_cast<int16_t>(roundf(values[ 2] * divisor)),
-            static_cast<int16_t>(roundf(values[ 7] * divisor)),
-            static_cast<int16_t>(roundf(values[12] * divisor)),
-            static_cast<int16_t>(roundf(values[17] * divisor)),
-
-            static_cast<int16_t>(roundf(values[ 3] * divisor)),
-            static_cast<int16_t>(roundf(values[ 8] * divisor)),
-            static_cast<int16_t>(roundf(values[13] * divisor)),
-            static_cast<int16_t>(roundf(values[18] * divisor)),
-        };
-        vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags);
-        break;
-    }
-
-    case FECOLORMATRIX_TYPE_SATURATE:
-    case FECOLORMATRIX_TYPE_HUEROTATE: {
-        const int16_t matrix[4 * 4] = {
-            static_cast<int16_t>(roundf(m_components[0] * divisor)),
-            static_cast<int16_t>(roundf(m_components[3] * divisor)),
-            static_cast<int16_t>(roundf(m_components[6] * divisor)),
-            0,
-
-            static_cast<int16_t>(roundf(m_components[1] * divisor)),
-            static_cast<int16_t>(roundf(m_components[4] * divisor)),
-            static_cast<int16_t>(roundf(m_components[7] * divisor)),
-            0,
-
-            static_cast<int16_t>(roundf(m_components[2] * divisor)),
-            static_cast<int16_t>(roundf(m_components[5] * divisor)),
-            static_cast<int16_t>(roundf(m_components[8] * divisor)),
-            0,
-
-            0,
-            0,
-            0,
-            divisor,
-        };
-        vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags);
-        break;
-    }
-    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: {
-        const int16_t matrix[4 * 4] = {
-            0,
-            0,
-            0,
-            static_cast<int16_t>(roundf(0.2125 * divisor)),
-
-            0,
-            0,
-            0,
-            static_cast<int16_t>(roundf(0.7154 * divisor)),
-
-            0,
-            0,
-            0,
-            static_cast<int16_t>(roundf(0.0721 * divisor)),
-
-            0,
-            0,
-            0,
-            0,
-        };
-        vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags);
-        break;
-    }
-    }
-}
-#endif
-
-void FEColorMatrixSoftwareApplier::applyPlatformUnaccelerated(PixelBuffer& pixelBuffer) const
-{
-    auto& pixelArray = pixelBuffer.data();
-    unsigned pixelArrayLength = pixelArray.length();
-
-    switch (m_effect.type()) {
-    case FECOLORMATRIX_TYPE_UNKNOWN:
-        break;
-
-    case FECOLORMATRIX_TYPE_MATRIX:
-        for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
-            float red = pixelArray.item(pixelByteOffset);
-            float green = pixelArray.item(pixelByteOffset + 1);
-            float blue = pixelArray.item(pixelByteOffset + 2);
-            float alpha = pixelArray.item(pixelByteOffset + 3);
-            matrix(red, green, blue, alpha);
-            pixelArray.set(pixelByteOffset, red);
-            pixelArray.set(pixelByteOffset + 1, green);
-            pixelArray.set(pixelByteOffset + 2, blue);
-            pixelArray.set(pixelByteOffset + 3, alpha);
-        }
-        break;
-
-    case FECOLORMATRIX_TYPE_SATURATE:
-    case FECOLORMATRIX_TYPE_HUEROTATE:
-        for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
-            float red = pixelArray.item(pixelByteOffset);
-            float green = pixelArray.item(pixelByteOffset + 1);
-            float blue = pixelArray.item(pixelByteOffset + 2);
-            float alpha = pixelArray.item(pixelByteOffset + 3);
-            saturateAndHueRotate(red, green, blue);
-            pixelArray.set(pixelByteOffset, red);
-            pixelArray.set(pixelByteOffset + 1, green);
-            pixelArray.set(pixelByteOffset + 2, blue);
-            pixelArray.set(pixelByteOffset + 3, alpha);
-        }
-        break;
-
-    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
-        for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
-            float red = pixelArray.item(pixelByteOffset);
-            float green = pixelArray.item(pixelByteOffset + 1);
-            float blue = pixelArray.item(pixelByteOffset + 2);
-            float alpha = pixelArray.item(pixelByteOffset + 3);
-            luminance(red, green, blue, alpha);
-            pixelArray.set(pixelByteOffset, red);
-            pixelArray.set(pixelByteOffset + 1, green);
-            pixelArray.set(pixelByteOffset + 2, blue);
-            pixelArray.set(pixelByteOffset + 3, alpha);
-        }
-        break;
-    }
-}
-
-void FEColorMatrixSoftwareApplier::applyPlatform(PixelBuffer& pixelBuffer) const
-{
-#if USE(ACCELERATE)
-    const auto& values = m_effect.values();
-
-    // vImageMatrixMultiply_ARGB8888 takes a 4x4 matrix, if any value in the last column of the FEColorMatrix 5x4 matrix
-    // is not zero, fall back to non-vImage code.
-    if (m_effect.type() != FECOLORMATRIX_TYPE_MATRIX || (!values[4] && !values[9] && !values[14] && !values[19])) {
-        applyPlatformAccelerated(pixelBuffer);
-        return;
-    }
-#endif
-    applyPlatformUnaccelerated(pixelBuffer);
-}
-
-bool FEColorMatrixSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    auto in = inputEffects[0].get();
-
-    auto resultImage = m_effect.imageBufferResult();
-    if (!resultImage)
-        return false;
-
-    auto inBuffer = in->imageBufferResult();
-    if (inBuffer)
-        resultImage->context().drawImageBuffer(*inBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
-
-    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, m_effect.resultColorSpace() };
-    IntRect imageRect(IntPoint(), resultImage->truncatedLogicalSize());
-    auto pixelBuffer = resultImage->getPixelBuffer(format, imageRect);
-    if (!pixelBuffer)
-        return false;
-
-    if (m_effect.type() == FECOLORMATRIX_TYPE_LUMINANCETOALPHA)
-        m_effect.setIsAlphaImage(true);
-
-    applyPlatform(*pixelBuffer);
-    resultImage->putPixelBuffer(*pixelBuffer, imageRect);
-    return true;
-}
-
</del><span class="cx"> bool FEColorMatrix::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEColorMatrixSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEColorMatrixh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.h   2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.h      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEComponentTransfercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp   2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -24,12 +25,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEComponentTransfer.h"
</span><span class="cx"> 
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
-#include "PixelBuffer.h"
-#include <wtf/MathExtras.h>
-#include <wtf/StdLibExtras.h>
</del><ins>+#include "FEComponentTransferSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -48,141 +44,6 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEComponentTransferSoftwareApplier to separate source and header files.
-class FEComponentTransferSoftwareApplier : public FilterEffectConcreteApplier<FEComponentTransfer> {
-    using Base = FilterEffectConcreteApplier<FEComponentTransfer>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    using LookupTable = std::array<uint8_t, 256>;
-
-    static void computeIdentityTable(LookupTable&, const ComponentTransferFunction&);
-    static void computeTabularTable(LookupTable&, const ComponentTransferFunction&);
-    static void computeDiscreteTable(LookupTable&, const ComponentTransferFunction&);
-    static void computeLinearTable(LookupTable&, const ComponentTransferFunction&);
-    static void computeGammaTable(LookupTable&, const ComponentTransferFunction&);
-
-    static LookupTable computeLookupTable(const ComponentTransferFunction&);
-
-    void applyPlatform(PixelBuffer&) const;
-};
-
-void FEComponentTransferSoftwareApplier::computeIdentityTable(LookupTable&, const ComponentTransferFunction&)
-{
-}
-
-void FEComponentTransferSoftwareApplier::computeTabularTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
-{
-    const Vector<float>& tableValues = transferFunction.tableValues;
-    unsigned n = tableValues.size();
-    if (n < 1)
-        return;
-    for (unsigned i = 0; i < values.size(); ++i) {
-        double c = i / 255.0;
-        unsigned k = static_cast<unsigned>(c * (n - 1));
-        double v1 = tableValues[k];
-        double v2 = tableValues[std::min((k + 1), (n - 1))];
-        double val = 255.0 * (v1 + (c * (n - 1) - k) * (v2 - v1));
-        val = std::max(0.0, std::min(255.0, val));
-        values[i] = static_cast<uint8_t>(val);
-    }
-}
-
-void FEComponentTransferSoftwareApplier::computeDiscreteTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
-{
-    const Vector<float>& tableValues = transferFunction.tableValues;
-    unsigned n = tableValues.size();
-    if (n < 1)
-        return;
-    for (unsigned i = 0; i < values.size(); ++i) {
-        unsigned k = static_cast<unsigned>((i * n) / 255.0);
-        k = std::min(k, n - 1);
-        double val = 255 * tableValues[k];
-        val = std::max(0.0, std::min(255.0, val));
-        values[i] = static_cast<uint8_t>(val);
-    }
-}
-
-void FEComponentTransferSoftwareApplier::computeLinearTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
-{
-    for (unsigned i = 0; i < values.size(); ++i) {
-        double val = transferFunction.slope * i + 255 * transferFunction.intercept;
-        val = std::max(0.0, std::min(255.0, val));
-        values[i] = static_cast<uint8_t>(val);
-    }
-}
-
-void FEComponentTransferSoftwareApplier::computeGammaTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
-{
-    for (unsigned i = 0; i < values.size(); ++i) {
-        double exponent = transferFunction.exponent; // RCVT doesn't like passing a double and a float to pow, so promote this to double
-        double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), exponent) + transferFunction.offset);
-        val = std::max(0.0, std::min(255.0, val));
-        values[i] = static_cast<uint8_t>(val);
-    }
-}
-
-FEComponentTransferSoftwareApplier::LookupTable FEComponentTransferSoftwareApplier::computeLookupTable(const ComponentTransferFunction& function)
-{
-    LookupTable table;
-
-    for (unsigned i = 0; i < table.size(); ++i)
-        table[i] = i;
-
-    using TransferType = void (*)(LookupTable&, const ComponentTransferFunction&);
-    TransferType callEffect[] = {
-        computeIdentityTable,   // FECOMPONENTTRANSFER_TYPE_UNKNOWN
-        computeIdentityTable,   // FECOMPONENTTRANSFER_TYPE_IDENTITY
-        computeTabularTable,    // FECOMPONENTTRANSFER_TYPE_TABLE
-        computeDiscreteTable,   // FECOMPONENTTRANSFER_TYPE_DISCRETE
-        computeLinearTable,     // FECOMPONENTTRANSFER_TYPE_LINEAR
-        computeGammaTable       // FECOMPONENTTRANSFER_TYPE_GAMMA
-    };
-
-    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(function.type) < WTF_ARRAY_LENGTH(callEffect));
-    callEffect[function.type](table, function);
-
-    return table;
-}
-
-void FEComponentTransferSoftwareApplier::applyPlatform(PixelBuffer& pixelBuffer) const
-{
-    auto& pixelArray = pixelBuffer.data();
-    unsigned pixelArrayLength = pixelArray.length();
-    uint8_t* data = pixelArray.data();
-
-    auto redTable   = computeLookupTable(m_effect.redFunction());
-    auto greenTable = computeLookupTable(m_effect.greenFunction());
-    auto blueTable  = computeLookupTable(m_effect.blueFunction());
-    auto alphaTable = computeLookupTable(m_effect.alphaFunction());
-
-    for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) {
-        data[pixelOffset]     = redTable[data[pixelOffset]];
-        data[pixelOffset + 1] = greenTable[data[pixelOffset + 1]];
-        data[pixelOffset + 2] = blueTable[data[pixelOffset + 2]];
-        data[pixelOffset + 3] = alphaTable[data[pixelOffset + 3]];
-    }
-}
-
-bool FEComponentTransferSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-    
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Unpremultiplied);
-    if (!destinationPixelBuffer)
-        return false;
-
-    auto drawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
-    in->copyPixelBufferResult(*destinationPixelBuffer, drawingRect);
-
-    applyPlatform(*destinationPixelBuffer);
-    return true;
-}
-
</del><span class="cx"> bool FEComponentTransfer::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEComponentTransferSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEComponentTransferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h     2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFECompositecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp   2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -24,11 +25,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEComposite.h"
</span><span class="cx"> 
</span><del>-#include "FECompositeArithmeticNEON.h"
-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
-#include "PixelBuffer.h"
</del><ins>+#include "FECompositeSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -110,221 +107,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FECompositeSoftwareApplier to separate source and header files.
-class FECompositeSoftwareApplier : public FilterEffectConcreteApplier<FEComposite> {
-    using Base = FilterEffectConcreteApplier<FEComposite>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    static uint8_t clampByte(int);
-
-    template <int b1, int b4>
-    static inline void computeArithmeticPixels(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4);
-
-    template <int b1, int b4>
-    static inline void computeArithmeticPixelsUnclamped(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4);
-
-    static inline void applyPlatformArithmetic(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4);
-
-    bool applyArithmetic(FilterEffect* in, FilterEffect* in2);
-    bool applyNonArithmetic(FilterEffect* in, FilterEffect* in2);
-};
-
-uint8_t FECompositeSoftwareApplier::clampByte(int c)
-{
-    uint8_t buff[] = { static_cast<uint8_t>(c), 255, 0 };
-    unsigned uc = static_cast<unsigned>(c);
-    return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
-}
-
-template <int b1, int b4>
-inline void FECompositeSoftwareApplier::computeArithmeticPixels(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4)
-{
-    float scaledK1;
-    float scaledK4;
-    if (b1)
-        scaledK1 = k1 / 255.0f;
-    if (b4)
-        scaledK4 = k4 * 255.0f;
-
-    while (--pixelArrayLength >= 0) {
-        unsigned char i1 = *source;
-        unsigned char i2 = *destination;
-        float result = k2 * i1 + k3 * i2;
-        if (b1)
-            result += scaledK1 * i1 * i2;
-        if (b4)
-            result += scaledK4;
-
-        *destination = clampByte(result);
-        ++source;
-        ++destination;
-    }
-}
-
-// computeArithmeticPixelsUnclamped is a faster version of computeArithmeticPixels for the common case where clamping
-// is not necessary. This enables aggresive compiler optimizations such as auto-vectorization.
-template <int b1, int b4>
-inline void FECompositeSoftwareApplier::computeArithmeticPixelsUnclamped(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4)
-{
-    float scaledK1;
-    float scaledK4;
-    if (b1)
-        scaledK1 = k1 / 255.0f;
-    if (b4)
-        scaledK4 = k4 * 255.0f;
-
-    while (--pixelArrayLength >= 0) {
-        unsigned char i1 = *source;
-        unsigned char i2 = *destination;
-        float result = k2 * i1 + k3 * i2;
-        if (b1)
-            result += scaledK1 * i1 * i2;
-        if (b4)
-            result += scaledK4;
-
-        *destination = result;
-        ++source;
-        ++destination;
-    }
-}
-
-#if !HAVE(ARM_NEON_INTRINSICS)
-inline void FECompositeSoftwareApplier::applyPlatformArithmetic(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4)
-{
-    float upperLimit = std::max(0.0f, k1) + std::max(0.0f, k2) + std::max(0.0f, k3) + k4;
-    float lowerLimit = std::min(0.0f, k1) + std::min(0.0f, k2) + std::min(0.0f, k3) + k4;
-    if ((k4 >= 0.0f && k4 <= 1.0f) && (upperLimit >= 0.0f && upperLimit <= 1.0f) && (lowerLimit >= 0.0f && lowerLimit <= 1.0f)) {
-        if (k4) {
-            if (k1)
-                computeArithmeticPixelsUnclamped<1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-            else
-                computeArithmeticPixelsUnclamped<0, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-        } else {
-            if (k1)
-                computeArithmeticPixelsUnclamped<1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-            else
-                computeArithmeticPixelsUnclamped<0, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-        }
-        return;
-    }
-
-    if (k4) {
-        if (k1)
-            computeArithmeticPixels<1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-        else
-            computeArithmeticPixels<0, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-    } else {
-        if (k1)
-            computeArithmeticPixels<1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-        else
-            computeArithmeticPixels<0, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
-    }
-}
-#endif
-
-bool FECompositeSoftwareApplier::applyArithmetic(FilterEffect* in, FilterEffect* in2)
-{
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
-    if (!destinationPixelBuffer)
-        return false;
-
-    IntRect effectADrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
-    auto sourcePixelBuffer = in->getPixelBufferResult(AlphaPremultiplication::Premultiplied, effectADrawingRect, m_effect.operatingColorSpace());
-    if (!sourcePixelBuffer)
-        return false;
-
-    IntRect effectBDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in2->absolutePaintRect());
-    in2->copyPixelBufferResult(*destinationPixelBuffer, effectBDrawingRect);
-
-    auto& sourcePixelArray = sourcePixelBuffer->data();
-    auto& destinationPixelArray = destinationPixelBuffer->data();
-
-    int length = sourcePixelArray.length();
-    ASSERT(length == static_cast<int>(destinationPixelArray.length()));
-    applyPlatformArithmetic(sourcePixelArray.data(), destinationPixelArray.data(), length, m_effect.k1(), m_effect.k2(), m_effect.k3(), m_effect.k4());
-    return true;
-}
-
-bool FECompositeSoftwareApplier::applyNonArithmetic(FilterEffect* in, FilterEffect* in2)
-{
-    auto resultImage = m_effect.imageBufferResult();
-    if (!resultImage)
-        return false;
-
-    auto imageBuffer = in->imageBufferResult();
-    auto imageBuffer2 = in2->imageBufferResult();
-    if (!imageBuffer || !imageBuffer2)
-        return false;
-
-    auto& filterContext = resultImage->context();
-
-    switch (m_effect.operation()) {
-    case FECOMPOSITE_OPERATOR_UNKNOWN:
-        return false;
-
-    case FECOMPOSITE_OPERATOR_OVER:
-        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
-        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
-        break;
-
-    case FECOMPOSITE_OPERATOR_IN: {
-        // Applies only to the intersected region.
-        IntRect destinationRect = in->absolutePaintRect();
-        destinationRect.intersect(in2->absolutePaintRect());
-        destinationRect.intersect(m_effect.absolutePaintRect());
-        if (destinationRect.isEmpty())
-            break;
-        IntRect adjustedDestinationRect = destinationRect - m_effect.absolutePaintRect().location();
-        IntRect sourceRect = destinationRect - in->absolutePaintRect().location();
-        IntRect source2Rect = destinationRect - in2->absolutePaintRect().location();
-        filterContext.drawImageBuffer(*imageBuffer2, FloatRect(adjustedDestinationRect), FloatRect(source2Rect));
-        filterContext.drawImageBuffer(*imageBuffer, FloatRect(adjustedDestinationRect), FloatRect(sourceRect), { CompositeOperator::SourceIn });
-        break;
-    }
-
-    case FECOMPOSITE_OPERATOR_OUT:
-        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
-        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()), { { }, imageBuffer2->logicalSize() }, CompositeOperator::DestinationOut);
-        break;
-
-    case FECOMPOSITE_OPERATOR_ATOP:
-        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
-        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, CompositeOperator::SourceAtop);
-        break;
-
-    case FECOMPOSITE_OPERATOR_XOR:
-        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
-        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, CompositeOperator::XOR);
-        break;
-
-    case FECOMPOSITE_OPERATOR_ARITHMETIC:
-        ASSERT_NOT_REACHED();
-        return false;
-
-    case FECOMPOSITE_OPERATOR_LIGHTER:
-        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
-        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, CompositeOperator::PlusLighter);
-        break;
-    }
-
-    return true;
-}
-
-bool FECompositeSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-    FilterEffect* in2 = inputEffects[1].get();
-
-    if (m_effect.operation() == FECOMPOSITE_OPERATOR_ARITHMETIC)
-        return applyArithmetic(in, in2);
-    return applyNonArithmetic(in, in2);
-}
-
</del><span class="cx"> bool FEComposite::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FECompositeSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFECompositeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEComposite.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEComposite.h     2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEComposite.h        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp      2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -24,12 +25,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEConvolveMatrix.h"
</span><span class="cx"> 
</span><del>-#include "FEColorMatrix.h"
-#include "FilterEffectApplier.h"
-#include "ImageBuffer.h"
-#include "PixelBuffer.h"
-#include <wtf/ParallelJobs.h>
-#include <wtf/WorkQueue.h>
</del><ins>+#include "FEConvolveMatrixSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -117,331 +113,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEConvolveMatrixSoftwareApplier to separate source and header files.
-class FEConvolveMatrixSoftwareApplier : public FilterEffectConcreteApplier<FEConvolveMatrix> {
-    using Base = FilterEffectConcreteApplier<FEConvolveMatrix>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    struct PaintingData {
-        const Uint8ClampedArray& srcPixelArray;
-        Uint8ClampedArray& dstPixelArray;
-        int width;
-        int height;
-
-        IntSize kernelSize;
-        float divisor;
-        float bias;
-        IntPoint targetOffset;
-        EdgeModeType edgeMode;
-        bool preserveAlpha;
-        Vector<float> kernelMatrix;
-    };
-
-    static inline uint8_t clampRGBAValue(float channel, uint8_t max = 255);
-    static inline void setDestinationPixels(const Uint8ClampedArray& sourcePixels, Uint8ClampedArray& destPixels, int& pixel, float* totals, float divisor, float bias, bool preserveAlphaValues);
-
-    static inline int getPixelValue(const PaintingData&, int x, int y);
-
-    static inline void setInteriorPixels(PaintingData&, int clipRight, int clipBottom, int yStart, int yEnd);
-    static inline void setOuterPixels(PaintingData&, int x1, int y1, int x2, int y2);
-
-    void applyPlatform(PaintingData&) const;
-};
-
-/*
-   -----------------------------------
-      ConvolveMatrix implementation
-   -----------------------------------
-
-   The image rectangle is split in the following way:
-
-      +---------------------+
-      |          A          |
-      +---------------------+
-      |   |             |   |
-      | B |      C      | D |
-      |   |             |   |
-      +---------------------+
-      |          E          |
-      +---------------------+
-
-   Where region C contains those pixels, whose values
-   can be calculated without crossing the edge of the rectangle.
-
-   Example:
-      Image size: width: 10, height: 10
-
-      Order (kernel matrix size): width: 3, height 4
-      Target: x:1, y:3
-
-      The following figure shows the target inside the kernel matrix:
-
-        ...
-        ...
-        ...
-        .X.
-
-   The regions in this case are the following:
-      Note: (x1, y1) top-left and (x2, y2) is the bottom-right corner
-      Note: row x2 and column y2 is not part of the region
-            only those (x, y) pixels, where x1 <= x < x2 and y1 <= y < y2
-
-      Region A: x1: 0, y1: 0, x2: 10, y2: 3
-      Region B: x1: 0, y1: 3, x2: 1, y2: 10
-      Region C: x1: 1, y1: 3, x2: 9, y2: 10
-      Region D: x1: 9, y1: 3, x2: 10, y2: 10
-      Region E: x1: 0, y1: 10, x2: 10, y2: 10 (empty region)
-
-   Since region C (often) contains most of the pixels, we implemented
-   a fast algoritm to calculate these values, called fastSetInteriorPixels.
-   For other regions, fastSetOuterPixels is used, which calls getPixelValue,
-   to handle pixels outside of the image. In a rare situations, when
-   kernel matrix is bigger than the image, all pixels are calculated by this
-   function.
-
-   Although these two functions have lot in common, I decided not to make
-   common a template for them, since there are key differences as well,
-   and would make it really hard to understand.
-*/
-
-inline uint8_t FEConvolveMatrixSoftwareApplier::clampRGBAValue(float channel, uint8_t max)
-{
-    if (channel <= 0)
-        return 0;
-    if (channel >= max)
-        return max;
-    return channel;
-}
-
-inline void FEConvolveMatrixSoftwareApplier::setDestinationPixels(const Uint8ClampedArray& sourcePixels, Uint8ClampedArray& destPixels, int& pixel, float* totals, float divisor, float bias, bool preserveAlphaValues)
-{
-    uint8_t maxAlpha = preserveAlphaValues ? 255 : clampRGBAValue(totals[3] / divisor + bias);
-    for (int i = 0; i < 3; ++i)
-        destPixels.set(pixel++, clampRGBAValue(totals[i] / divisor + bias, maxAlpha));
-
-    if (preserveAlphaValues) {
-        destPixels.set(pixel, sourcePixels.item(pixel));
-        ++pixel;
-    } else
-        destPixels.set(pixel++, maxAlpha);
-}
-
-inline int FEConvolveMatrixSoftwareApplier::getPixelValue(const PaintingData& paintingData, int x, int y)
-{
-    if (x >= 0 && x < paintingData.width && y >= 0 && y < paintingData.height)
-        return (y * paintingData.width + x) << 2;
-
-    switch (paintingData.edgeMode) {
-    default: // EDGEMODE_NONE
-        return -1;
-    case EDGEMODE_DUPLICATE:
-        if (x < 0)
-            x = 0;
-        else if (x >= paintingData.width)
-            x = paintingData.width - 1;
-        if (y < 0)
-            y = 0;
-        else if (y >= paintingData.height)
-            y = paintingData.height - 1;
-        return (y * paintingData.width + x) << 2;
-    case EDGEMODE_WRAP:
-        while (x < 0)
-            x += paintingData.width;
-        x %= paintingData.width;
-        while (y < 0)
-            y += paintingData.height;
-        y %= paintingData.height;
-        return (y * paintingData.width + x) << 2;
-    }
-}
-
-// Only for region C
-inline void FEConvolveMatrixSoftwareApplier::setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom, int yStart, int yEnd)
-{
-    // edge mode does not affect these pixels
-    int pixel = (paintingData.targetOffset.y() * paintingData.width + paintingData.targetOffset.x()) * 4;
-    int kernelIncrease = clipRight * 4;
-    int xIncrease = (paintingData.kernelSize.width() - 1) * 4;
-    // Contains the sum of rgb(a) components
-    float totals[4];
-
-    // divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
-    ASSERT(paintingData.divisor);
-
-    // Skip the first '(clipBottom - yEnd)' lines
-    pixel += (clipBottom - yEnd) * (xIncrease + (clipRight + 1) * 4);
-    int startKernelPixel = (clipBottom - yEnd) * (xIncrease + (clipRight + 1) * 4);
-
-    for (int y = yEnd + 1; y > yStart; --y) {
-        for (int x = clipRight + 1; x > 0; --x) {
-            int kernelValue = paintingData.kernelMatrix.size() - 1;
-            int kernelPixel = startKernelPixel;
-            int width = paintingData.kernelSize.width();
-
-            totals[0] = 0;
-            totals[1] = 0;
-            totals[2] = 0;
-            totals[3] = 0;
-
-            while (kernelValue >= 0) {
-                totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel++));
-                totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel++));
-                totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel++));
-                if (!paintingData.preserveAlpha)
-                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel));
-                ++kernelPixel;
-                --kernelValue;
-                if (!--width) {
-                    kernelPixel += kernelIncrease;
-                    width = paintingData.kernelSize.width();
-                }
-            }
-
-            setDestinationPixels(paintingData.srcPixelArray, paintingData.dstPixelArray, pixel, totals, paintingData.divisor, paintingData.bias, paintingData.preserveAlpha);
-            startKernelPixel += 4;
-        }
-        pixel += xIncrease;
-        startKernelPixel += xIncrease;
-    }
-}
-
-// For other regions than C
-inline void FEConvolveMatrixSoftwareApplier::setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2)
-{
-    int pixel = (y1 * paintingData.width + x1) * 4;
-    int height = y2 - y1;
-    int width = x2 - x1;
-    int beginKernelPixelX = x1 - paintingData.targetOffset.x();
-    int startKernelPixelX = beginKernelPixelX;
-    int startKernelPixelY = y1 - paintingData.targetOffset.y();
-    int xIncrease = (paintingData.width - width) * 4;
-    // Contains the sum of rgb(a) components
-    float totals[4];
-
-    // paintingData.divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
-    ASSERT(paintingData.divisor);
-
-    for (int y = height; y > 0; --y) {
-        for (int x = width; x > 0; --x) {
-            int kernelValue = paintingData.kernelMatrix.size() - 1;
-            int kernelPixelX = startKernelPixelX;
-            int kernelPixelY = startKernelPixelY;
-            int width = paintingData.kernelSize.width();
-
-            totals[0] = 0;
-            totals[1] = 0;
-            totals[2] = 0;
-            totals[3] = 0;
-
-            while (kernelValue >= 0) {
-                int pixelIndex = getPixelValue(paintingData, kernelPixelX, kernelPixelY);
-                if (pixelIndex >= 0) {
-                    totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex));
-                    totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex + 1));
-                    totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex + 2));
-                }
-                if (!paintingData.preserveAlpha && pixelIndex >= 0)
-                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex + 3));
-                ++kernelPixelX;
-                --kernelValue;
-                if (!--width) {
-                    kernelPixelX = startKernelPixelX;
-                    ++kernelPixelY;
-                    width = paintingData.kernelSize.width();
-                }
-            }
-
-            setDestinationPixels(paintingData.srcPixelArray, paintingData.dstPixelArray, pixel, totals, paintingData.divisor, paintingData.bias, paintingData.preserveAlpha);
-            ++startKernelPixelX;
-        }
-        pixel += xIncrease;
-        startKernelPixelX = beginKernelPixelX;
-        ++startKernelPixelY;
-    }
-}
-
-void FEConvolveMatrixSoftwareApplier::applyPlatform(PaintingData& paintingData) const
-{
-    // Drawing fully covered pixels
-    int clipRight = paintingData.width - paintingData.kernelSize.width();
-    int clipBottom = paintingData.height - paintingData.kernelSize.height();
-
-    if (clipRight < 0 || clipBottom < 0) {
-        // Rare situation, not optimized for speed
-        setOuterPixels(paintingData, 0, 0, paintingData.width, paintingData.height);
-        return;
-    }
-
-    static constexpr int minimalRectDimension = (100 * 100); // Empirical data limit for parallel jobs
-
-    if (int iterations = (paintingData.width * paintingData.height) / minimalRectDimension) {
-        int stride = clipBottom / iterations;
-        int chunkCount = (clipBottom + stride - 1) / stride;
-
-        ConcurrentWorkQueue::apply(chunkCount, [&](size_t index) {
-            int yStart = (stride * index);
-            int yEnd = std::min<int>(stride * (index + 1), clipBottom);
-
-            setInteriorPixels(paintingData, clipRight, clipBottom, yStart, yEnd);
-        });
-    } else
-        setInteriorPixels(paintingData, clipRight, clipBottom, 0, clipBottom);
-
-    clipRight += paintingData.targetOffset.x() + 1;
-    clipBottom += paintingData.targetOffset.y() + 1;
-
-    if (paintingData.targetOffset.y() > 0)
-        setOuterPixels(paintingData, 0, 0, paintingData.width, paintingData.targetOffset.y());
-    if (clipBottom < paintingData.height)
-        setOuterPixels(paintingData, 0, clipBottom, paintingData.width, paintingData.height);
-    if (paintingData.targetOffset.x() > 0)
-        setOuterPixels(paintingData, 0, paintingData.targetOffset.y(), paintingData.targetOffset.x(), clipBottom);
-    if (clipRight < paintingData.width)
-        setOuterPixels(paintingData, clipRight, paintingData.targetOffset.y(), paintingData.width, clipBottom);
-}
-
-bool FEConvolveMatrixSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto alphaFormat = m_effect.preserveAlpha() ? AlphaPremultiplication::Unpremultiplied : AlphaPremultiplication::Premultiplied;
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(alphaFormat);
-    if (!destinationPixelBuffer)
-        return false;
-
-    auto effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
-    auto sourcePixelBuffer = in->getPixelBufferResult(alphaFormat, effectDrawingRect, m_effect.operatingColorSpace());
-    if (!sourcePixelBuffer)
-        return false;
-
-    auto& sourcePixelArray = sourcePixelBuffer->data();
-    auto& destinationPixelArray = destinationPixelBuffer->data();
-    
-    auto paintSize = m_effect.absolutePaintRect().size();
-
-    PaintingData paintingData = {
-        sourcePixelArray,
-        destinationPixelArray,
-        paintSize.width(),
-        paintSize.height(),
-        m_effect.kernelSize(),
-        m_effect.divisor(),
-        m_effect.bias() * 255,
-        m_effect.targetOffset(),
-        m_effect.edgeMode(),
-        m_effect.preserveAlpha(),
-        FEColorMatrix::normalizedFloats(m_effect.kernel())
-    };
-
-    applyPlatform(paintingData);
-    return true;
-}
-
</del><span class="cx"> bool FEConvolveMatrix::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEConvolveMatrixSoftwareApplier(*this).apply(filter, inputEffects());
</span><span class="lines">@@ -450,16 +121,16 @@
</span><span class="cx"> static TextStream& operator<<(TextStream& ts, const EdgeModeType& type)
</span><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><del>-    case EDGEMODE_UNKNOWN:
</del><ins>+    case EdgeModeType::Unknown:
</ins><span class="cx">         ts << "UNKNOWN";
</span><span class="cx">         break;
</span><del>-    case EDGEMODE_DUPLICATE:
</del><ins>+    case EdgeModeType::Duplicate:
</ins><span class="cx">         ts << "DUPLICATE";
</span><span class="cx">         break;
</span><del>-    case EDGEMODE_WRAP:
</del><ins>+    case EdgeModeType::Wrap:
</ins><span class="cx">         ts << "WRAP";
</span><span class="cx">         break;
</span><del>-    case EDGEMODE_NONE:
</del><ins>+    case EdgeModeType::None:
</ins><span class="cx">         ts << "NONE";
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h        2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -3,6 +3,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -28,11 +29,11 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-enum EdgeModeType {
-    EDGEMODE_UNKNOWN   = 0,
-    EDGEMODE_DUPLICATE = 1,
-    EDGEMODE_WRAP      = 2,
-    EDGEMODE_NONE      = 3
</del><ins>+enum class EdgeModeType {
+    Unknown,
+    Duplicate,
+    Wrap,
+    None
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class FEConvolveMatrix : public FilterEffect {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEDiffuseLightingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp     2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEDiffuseLightingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h       2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEDisplacementMapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp     2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -24,10 +25,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEDisplacementMap.h"
</span><span class="cx"> 
</span><del>-#include "Filter.h"
-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "PixelBuffer.h"
</del><ins>+#include "FEDisplacementMapSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -85,93 +83,6 @@
</span><span class="cx">         in->transformResultColorSpace(operatingColorSpace());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FECompositeSoftwareApplier to separate source and header files.
-class FEDisplacementMapSoftwareApplier : public FilterEffectConcreteApplier<FEDisplacementMap> {
-    using Base = FilterEffectConcreteApplier<FEDisplacementMap>;
-
-public:
-    FEDisplacementMapSoftwareApplier(FEDisplacementMap&);
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    static inline unsigned byteOffsetOfPixel(unsigned x, unsigned y, unsigned rowBytes)
-    {
-        const unsigned bytesPerPixel = 4;
-        return x * bytesPerPixel + y * rowBytes;
-    }
-
-    int xChannelIndex() const { return m_effect.xChannelSelector() - 1; }
-    int yChannelIndex() const { return m_effect.yChannelSelector() - 1; }
-};
-
-FEDisplacementMapSoftwareApplier::FEDisplacementMapSoftwareApplier(FEDisplacementMap& effect)
-    : Base(effect)
-{
-    ASSERT(m_effect.xChannelSelector() != CHANNEL_UNKNOWN);
-    ASSERT(m_effect.yChannelSelector() != CHANNEL_UNKNOWN);
-}
-
-bool FEDisplacementMapSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-    FilterEffect* in2 = inputEffects[1].get();
-
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
-    if (!destinationPixelBuffer)
-        return false;
-
-    auto& destinationPixelArray = destinationPixelBuffer->data();
-
-    auto effectADrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
-    auto inputPixelBuffer = in->getPixelBufferResult(AlphaPremultiplication::Premultiplied, effectADrawingRect);
-
-    auto effectBDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in2->absolutePaintRect());
-    // The calculations using the pixel values from ‘in2’ are performed using non-premultiplied color values.
-    auto displacementPixelBuffer = in2->getPixelBufferResult(AlphaPremultiplication::Unpremultiplied, effectBDrawingRect);
-    
-    if (!inputPixelBuffer || !displacementPixelBuffer)
-        return false;
-
-    auto& inputImage = inputPixelBuffer->data();
-    auto& displacementImage = displacementPixelBuffer->data();
-    ASSERT(inputImage.length() == displacementImage.length());
-
-    IntSize paintSize = m_effect.absolutePaintRect().size();
-
-    FloatSize scale = filter.scaledByFilterScale({ m_effect.scale(), m_effect.scale() });
-    float scaleForColorX = scale.width() / 255.0;
-    float scaleForColorY = scale.height() / 255.0;
-    float scaledOffsetX = 0.5 - scale.width() * 0.5;
-    float scaledOffsetY = 0.5 - scale.height() * 0.5;
-    
-    int displacementChannelX = xChannelIndex();
-    int displacementChannelY = yChannelIndex();
-
-    int rowBytes = paintSize.width() * 4;
-
-    for (int y = 0; y < paintSize.height(); ++y) {
-        int lineStartOffset = y * rowBytes;
-
-        for (int x = 0; x < paintSize.width(); ++x) {
-            int destinationIndex = lineStartOffset + x * 4;
-            
-            int srcX = x + static_cast<int>(scaleForColorX * displacementImage.item(destinationIndex + displacementChannelX) + scaledOffsetX);
-            int srcY = y + static_cast<int>(scaleForColorY * displacementImage.item(destinationIndex + displacementChannelY) + scaledOffsetY);
-
-            unsigned* destinationPixelPtr = reinterpret_cast<unsigned*>(destinationPixelArray.data() + destinationIndex);
-            if (srcX < 0 || srcX >= paintSize.width() || srcY < 0 || srcY >= paintSize.height()) {
-                *destinationPixelPtr = 0;
-                continue;
-            }
-
-            *destinationPixelPtr = *reinterpret_cast<unsigned*>(inputImage.data() + byteOffsetOfPixel(srcX, srcY, rowBytes));
-        }
-    }
-
-    return true;
-}
-
</del><span class="cx"> bool FEDisplacementMap::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEDisplacementMapSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEDisplacementMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h       2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEDropShadowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp  2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -21,14 +22,9 @@
</span><span class="cx"> #include "FEDropShadow.h"
</span><span class="cx"> 
</span><span class="cx"> #include "ColorSerialization.h"
</span><ins>+#include "FEDropShadowSoftwareApplier.h"
</ins><span class="cx"> #include "FEGaussianBlur.h"
</span><span class="cx"> #include "Filter.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
-#include "PixelBuffer.h"
-#include "ShadowBlur.h"
-#include <wtf/MathExtras.h>
</del><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -70,61 +66,6 @@
</span><span class="cx">     setAbsolutePaintRect(enclosingIntRect(absolutePaintRect));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEDropShadowSoftwareApplier to separate source and header files.
-class FEDropShadowSoftwareApplier : public FilterEffectConcreteApplier<FEDropShadow> {
-    using Base = FilterEffectConcreteApplier<FEDropShadow>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-bool FEDropShadowSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto resultImage = m_effect.imageBufferResult();
-    if (!resultImage)
-        return false;
-
-    FloatSize blurRadius = 2 * filter.scaledByFilterScale({ m_effect.stdDeviationX(), m_effect.stdDeviationY() });
-    FloatSize offset = filter.scaledByFilterScale({ m_effect.dx(), m_effect.dy() });
-
-    FloatRect drawingRegion = m_effect.drawingRegionOfInputImage(in->absolutePaintRect());
-    FloatRect drawingRegionWithOffset(drawingRegion);
-    drawingRegionWithOffset.move(offset);
-
-    auto sourceImage = in->imageBufferResult();
-    if (!sourceImage)
-        return false;
-
-    GraphicsContext& resultContext = resultImage->context();
-    resultContext.setAlpha(m_effect.shadowOpacity());
-    resultContext.drawImageBuffer(*sourceImage, drawingRegionWithOffset);
-    resultContext.setAlpha(1);
-
-    ShadowBlur contextShadow(blurRadius, offset, m_effect.shadowColor());
-
-    PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, m_effect.resultColorSpace() };
-    IntRect shadowArea(IntPoint(), resultImage->truncatedLogicalSize());
-    auto pixelBuffer = resultImage->getPixelBuffer(format, shadowArea);
-    if (!pixelBuffer)
-        return false;
-
-    auto& sourcePixelArray = pixelBuffer->data();
-    contextShadow.blurLayerImage(sourcePixelArray.data(), pixelBuffer->size(), 4 * pixelBuffer->size().width());
-    
-    resultImage->putPixelBuffer(*pixelBuffer, shadowArea);
-
-    resultContext.setCompositeOperation(CompositeOperator::SourceIn);
-    resultContext.fillRect(FloatRect(FloatPoint(), m_effect.absolutePaintRect().size()), m_effect.shadowColor());
-    resultContext.setCompositeOperation(CompositeOperator::DestinationOver);
-
-    resultImage->context().drawImageBuffer(*sourceImage, drawingRegion);
-    return true;
-}
-
</del><span class="cx"> bool FEDropShadow::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEDropShadowSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEDropShadowh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h    2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEFloodcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEFlood.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEFlood.cpp       2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEFlood.cpp  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -3,6 +3,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -24,9 +25,7 @@
</span><span class="cx"> #include "FEFlood.h"
</span><span class="cx"> 
</span><span class="cx"> #include "ColorSerialization.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
</del><ins>+#include "FEFloodSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -59,28 +58,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEDropShadowSoftwareApplier to separate source and header files.
-class FEFloodSoftwareApplier : public FilterEffectConcreteApplier<FEFlood> {
-    using Base = FilterEffectConcreteApplier<FEFlood>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-bool FEFloodSoftwareApplier::apply(const Filter&, const FilterEffectVector&)
-{
-    auto resultImage = m_effect.imageBufferResult();
-    if (!resultImage)
-        return false;
-
-    auto color = m_effect.floodColor().colorWithAlphaMultipliedBy(m_effect.floodOpacity());
-    resultImage->context().fillRect(FloatRect(FloatPoint(), m_effect.absolutePaintRect().size()), color);
-
-    return true;
-}
-
</del><span class="cx"> bool FEFlood::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEFloodSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEFloodh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEFlood.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEFlood.h 2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEFlood.h    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEGaussianBlurcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp        2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) 2010 Igalia, S.L.
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
</span><del>- * Copyright (C) 2015-2016 Apple, Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2021 Apple, Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -26,21 +26,10 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEGaussianBlur.h"
</span><span class="cx"> 
</span><del>-#include "FEGaussianBlurNEON.h"
</del><ins>+#include "FEGaussianBlurSoftwareApplier.h"
</ins><span class="cx"> #include "Filter.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "PixelBuffer.h"
-#include <wtf/MathExtras.h>
</del><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><del>-#if USE(ACCELERATE)
-#include <Accelerate/Accelerate.h>
-#else
-#include <JavaScriptCore/TypedArrayInlines.h>
-#include <wtf/ParallelJobs.h>
-#endif
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> Ref<FEGaussianBlur> FEGaussianBlur::create(float x, float y, EdgeModeType edgeMode)
</span><span class="lines">@@ -119,7 +108,7 @@
</span><span class="cx"> 
</span><span class="cx">     FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect();
</span><span class="cx">     // Edge modes other than 'none' do not inflate the affected paint rect.
</span><del>-    if (m_edgeMode != EDGEMODE_NONE) {
</del><ins>+    if (m_edgeMode != EdgeModeType::None) {
</ins><span class="cx">         setAbsolutePaintRect(enclosingIntRect(absolutePaintRect));
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -136,453 +125,6 @@
</span><span class="cx">     setAbsolutePaintRect(enclosingIntRect(absolutePaintRect));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEGaussianBlurSoftwareApplier to separate source and header files.
-class FEGaussianBlurSoftwareApplier : public FilterEffectConcreteApplier<FEGaussianBlur> {
-    using Base = FilterEffectConcreteApplier<FEGaussianBlur>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    struct ApplyParameters {
-        RefPtr<Uint8ClampedArray> ioPixelArray;
-        RefPtr<Uint8ClampedArray> tmpPixelArray;
-        int width;
-        int height;
-        unsigned kernelSizeX;
-        unsigned kernelSizeY;
-        bool isAlphaImage;
-        EdgeModeType edgeMode;
-    };
-
-    static inline void kernelPosition(int blurIteration, unsigned& radius, int& deltaLeft, int& deltaRight);
-
-    static inline void boxBlurAlphaOnly(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int& dxLeft, int& dxRight, int& stride, int& strideLine, int& effectWidth, int& effectHeight, const int& maxKernelSize);
-    static inline void boxBlur(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage, EdgeModeType);
-
-    static inline void boxBlurAccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSize, int stride, int effectWidth, int effectHeight);
-    static inline void boxBlurUnaccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSizeX, unsigned kernelSizeY, int stride, IntSize& paintSize, bool isAlphaImage, EdgeModeType);
-
-    static inline void boxBlurGeneric(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType);
-    static inline void boxBlurWorker(ApplyParameters*);
-
-    static inline void applyPlatform(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType);
-};
-
-inline void FEGaussianBlurSoftwareApplier::kernelPosition(int blurIteration, unsigned& radius, int& deltaLeft, int& deltaRight)
-{
-    // Check http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement for details.
-    switch (blurIteration) {
-    case 0:
-        if (!(radius % 2)) {
-            deltaLeft = radius / 2 - 1;
-            deltaRight = radius - deltaLeft;
-        } else {
-            deltaLeft = radius / 2;
-            deltaRight = radius - deltaLeft;
-        }
-        break;
-    case 1:
-        if (!(radius % 2)) {
-            deltaLeft++;
-            deltaRight--;
-        }
-        break;
-    case 2:
-        if (!(radius % 2)) {
-            deltaRight++;
-            radius++;
-        }
-        break;
-    }
-}
-
-// This function only operates on Alpha channel.
-inline void FEGaussianBlurSoftwareApplier::boxBlurAlphaOnly(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int& dxLeft, int& dxRight, int& stride, int& strideLine, int& effectWidth, int& effectHeight, const int& maxKernelSize)
-{
-    const uint8_t* srcData = srcPixelArray.data();
-    uint8_t* dstData = dstPixelArray.data();
-    // Memory alignment is: RGBA, zero-index based.
-    const int channel = 3;
-
-    for (int y = 0; y < effectHeight; ++y) {
-        int line = y * strideLine;
-        int sum = 0;
-
-        // Fill the kernel.
-        for (int i = 0; i < maxKernelSize; ++i) {
-            unsigned offset = line + i * stride;
-            const uint8_t* srcPtr = srcData + offset;
-            sum += srcPtr[channel];
-        }
-
-        // Blurring.
-        for (int x = 0; x < effectWidth; ++x) {
-            unsigned pixelByteOffset = line + x * stride + channel;
-            uint8_t* dstPtr = dstData + pixelByteOffset;
-            *dstPtr = static_cast<uint8_t>(sum / dx);
-
-            // Shift kernel.
-            if (x >= dxLeft) {
-                unsigned leftOffset = pixelByteOffset - dxLeft * stride;
-                const uint8_t* srcPtr = srcData + leftOffset;
-                sum -= *srcPtr;
-            }
-
-            if (x + dxRight < effectWidth) {
-                unsigned rightOffset = pixelByteOffset + dxRight * stride;
-                const uint8_t* srcPtr = srcData + rightOffset;
-                sum += *srcPtr;
-            }
-        }
-    }
-}
-
-inline void FEGaussianBlurSoftwareApplier::boxBlur(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage, EdgeModeType edgeMode)
-{
-    const int maxKernelSize = std::min(dxRight, effectWidth);
-    if (alphaImage)
-        return boxBlurAlphaOnly(srcPixelArray, dstPixelArray, dx, dxLeft, dxRight, stride, strideLine,  effectWidth, effectHeight, maxKernelSize);
-
-    const uint8_t* srcData = srcPixelArray.data();
-    uint8_t* dstData = dstPixelArray.data();
-
-    // Concerning the array width/length: it is Element size + Margin + Border. The number of pixels will be
-    // P = width * height * channels.
-    for (int y = 0; y < effectHeight; ++y) {
-        int line = y * strideLine;
-        int sumR = 0, sumG = 0, sumB = 0, sumA = 0;
-
-        if (edgeMode == EDGEMODE_NONE) {
-            // Fill the kernel.
-            for (int i = 0; i < maxKernelSize; ++i) {
-                unsigned offset = line + i * stride;
-                const uint8_t* srcPtr = srcData + offset;
-                sumR += *srcPtr++;
-                sumG += *srcPtr++;
-                sumB += *srcPtr++;
-                sumA += *srcPtr;
-            }
-
-            // Blurring.
-            for (int x = 0; x < effectWidth; ++x) {
-                unsigned pixelByteOffset = line + x * stride;
-                uint8_t* dstPtr = dstData + pixelByteOffset;
-
-                *dstPtr++ = static_cast<uint8_t>(sumR / dx);
-                *dstPtr++ = static_cast<uint8_t>(sumG / dx);
-                *dstPtr++ = static_cast<uint8_t>(sumB / dx);
-                *dstPtr = static_cast<uint8_t>(sumA / dx);
-
-                // Shift kernel.
-                if (x >= dxLeft) {
-                    unsigned leftOffset = pixelByteOffset - dxLeft * stride;
-                    const uint8_t* srcPtr = srcData + leftOffset;
-                    sumR -= srcPtr[0];
-                    sumG -= srcPtr[1];
-                    sumB -= srcPtr[2];
-                    sumA -= srcPtr[3];
-                }
-
-                if (x + dxRight < effectWidth) {
-                    unsigned rightOffset = pixelByteOffset + dxRight * stride;
-                    const uint8_t* srcPtr = srcData + rightOffset;
-                    sumR += srcPtr[0];
-                    sumG += srcPtr[1];
-                    sumB += srcPtr[2];
-                    sumA += srcPtr[3];
-                }
-            }
-
-        } else {
-            // FIXME: Add support for 'wrap' here.
-            // Get edge values for edgeMode 'duplicate'.
-            const uint8_t* edgeValueLeft = srcData + line;
-            const uint8_t* edgeValueRight  = srcData + (line + (effectWidth - 1) * stride);
-
-            // Fill the kernel.
-            for (int i = dxLeft * -1; i < dxRight; ++i) {
-                // Is this right for negative values of 'i'?
-                unsigned offset = line + i * stride;
-                const uint8_t* srcPtr = srcData + offset;
-
-                if (i < 0) {
-                    sumR += edgeValueLeft[0];
-                    sumG += edgeValueLeft[1];
-                    sumB += edgeValueLeft[2];
-                    sumA += edgeValueLeft[3];
-                } else if (i >= effectWidth) {
-                    sumR += edgeValueRight[0];
-                    sumG += edgeValueRight[1];
-                    sumB += edgeValueRight[2];
-                    sumA += edgeValueRight[3];
-                } else {
-                    sumR += *srcPtr++;
-                    sumG += *srcPtr++;
-                    sumB += *srcPtr++;
-                    sumA += *srcPtr;
-                }
-            }
-
-            // Blurring.
-            for (int x = 0; x < effectWidth; ++x) {
-                unsigned pixelByteOffset = line + x * stride;
-                uint8_t* dstPtr = dstData + pixelByteOffset;
-
-                *dstPtr++ = static_cast<uint8_t>(sumR / dx);
-                *dstPtr++ = static_cast<uint8_t>(sumG / dx);
-                *dstPtr++ = static_cast<uint8_t>(sumB / dx);
-                *dstPtr = static_cast<uint8_t>(sumA / dx);
-
-                // Shift kernel.
-                if (x < dxLeft) {
-                    sumR -= edgeValueLeft[0];
-                    sumG -= edgeValueLeft[1];
-                    sumB -= edgeValueLeft[2];
-                    sumA -= edgeValueLeft[3];
-                } else {
-                    unsigned leftOffset = pixelByteOffset - dxLeft * stride;
-                    const uint8_t* srcPtr = srcData + leftOffset;
-                    sumR -= srcPtr[0];
-                    sumG -= srcPtr[1];
-                    sumB -= srcPtr[2];
-                    sumA -= srcPtr[3];
-                }
-
-                if (x + dxRight >= effectWidth) {
-                    sumR += edgeValueRight[0];
-                    sumG += edgeValueRight[1];
-                    sumB += edgeValueRight[2];
-                    sumA += edgeValueRight[3];
-                } else {
-                    unsigned rightOffset = pixelByteOffset + dxRight * stride;
-                    const uint8_t* srcPtr = srcData + rightOffset;
-                    sumR += srcPtr[0];
-                    sumG += srcPtr[1];
-                    sumB += srcPtr[2];
-                    sumA += srcPtr[3];
-                }
-            }
-        }
-    }
-}
-
-#if USE(ACCELERATE)
-inline void FEGaussianBlurSoftwareApplier::boxBlurAccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSize, int stride, int effectWidth, int effectHeight)
-{
-    if (!ioBuffer.data() || !tempBuffer.data()) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-
-    if (effectWidth <= 0 || effectHeight <= 0 || stride <= 0) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-
-    // We must always use an odd radius.
-    if (kernelSize % 2 != 1)
-        kernelSize += 1;
-
-    vImage_Buffer effectInBuffer;
-    effectInBuffer.data = static_cast<void*>(ioBuffer.data());
-    effectInBuffer.width = effectWidth;
-    effectInBuffer.height = effectHeight;
-    effectInBuffer.rowBytes = stride;
-
-    vImage_Buffer effectOutBuffer;
-    effectOutBuffer.data = tempBuffer.data();
-    effectOutBuffer.width = effectWidth;
-    effectOutBuffer.height = effectHeight;
-    effectOutBuffer.rowBytes = stride;
-
-    // Determine the size of a temporary buffer by calling the function first with a special flag. vImage will return
-    // the size needed, or an error (which are all negative).
-    size_t tmpBufferSize = vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, 0, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend | kvImageGetTempBufferSize);
-    if (tmpBufferSize <= 0)
-        return;
-
-    void* tmpBuffer = fastMalloc(tmpBufferSize);
-    vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, tmpBuffer, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend);
-    vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, tmpBuffer, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend);
-    vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, tmpBuffer, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend);
-    fastFree(tmpBuffer);
-
-    // The final result should be stored in ioBuffer.
-    ASSERT(ioBuffer.length() == tempBuffer.length());
-    memcpy(ioBuffer.data(), tempBuffer.data(), ioBuffer.length());
-}
-#endif
-
-inline void FEGaussianBlurSoftwareApplier::boxBlurUnaccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSizeX, unsigned kernelSizeY, int stride, IntSize& paintSize, bool isAlphaImage, EdgeModeType edgeMode)
-{
-    int dxLeft = 0;
-    int dxRight = 0;
-    int dyLeft = 0;
-    int dyRight = 0;
-    
-    Uint8ClampedArray* fromBuffer = &ioBuffer;
-    Uint8ClampedArray* toBuffer = &tempBuffer;
-
-    for (int i = 0; i < 3; ++i) {
-        if (kernelSizeX) {
-            kernelPosition(i, kernelSizeX, dxLeft, dxRight);
-#if HAVE(ARM_NEON_INTRINSICS)
-            if (!isAlphaImage)
-                boxBlurNEON(*fromBuffer, *toBuffer, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height());
-            else
-                boxBlur(*fromBuffer, *toBuffer, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), true, edgeMode);
-#else
-            boxBlur(*fromBuffer, *toBuffer, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), isAlphaImage, edgeMode);
-#endif
-            std::swap(fromBuffer, toBuffer);
-        }
-
-        if (kernelSizeY) {
-            kernelPosition(i, kernelSizeY, dyLeft, dyRight);
-#if HAVE(ARM_NEON_INTRINSICS)
-            if (!isAlphaImage)
-                boxBlurNEON(*fromBuffer, *toBuffer, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width());
-            else
-                boxBlur(*fromBuffer, *toBuffer, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), true, edgeMode);
-#else
-            boxBlur(*fromBuffer, *toBuffer, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), isAlphaImage, edgeMode);
-#endif
-            std::swap(fromBuffer, toBuffer);
-        }
-    }
-
-    // The final result should be stored in ioBuffer.
-    if (&ioBuffer != fromBuffer) {
-        ASSERT(ioBuffer.length() == fromBuffer->length());
-        memcpy(ioBuffer.data(), fromBuffer->data(), ioBuffer.length());
-    }
-}
-
-inline void FEGaussianBlurSoftwareApplier::boxBlurGeneric(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType edgeMode)
-{
-    int stride = 4 * paintSize.width();
-
-#if USE(ACCELERATE)
-    if (kernelSizeX == kernelSizeY && (edgeMode == EDGEMODE_NONE || edgeMode == EDGEMODE_DUPLICATE)) {
-        boxBlurAccelerated(ioBuffer, tmpPixelArray, kernelSizeX, stride, paintSize.width(), paintSize.height());
-        return;
-    }
-#endif
-
-    boxBlurUnaccelerated(ioBuffer, tmpPixelArray, kernelSizeX, kernelSizeY, stride, paintSize, isAlphaImage, edgeMode);
-}
-
-#if !USE(ACCELERATE)
-inline void FEGaussianBlurSoftwareApplier::boxBlurWorker(ApplyParameters* parameters)
-{
-    IntSize paintSize(parameters->width, parameters->height);
-    boxBlurGeneric(*parameters->ioPixelArray, *parameters->tmpPixelArray, parameters->kernelSizeX, parameters->kernelSizeY, paintSize, parameters->isAlphaImage, parameters->edgeMode);
-}
-#endif
-
-inline void FEGaussianBlurSoftwareApplier::applyPlatform(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType edgeMode)
-{
-#if !USE(ACCELERATE)
-    int scanline = 4 * paintSize.width();
-    int extraHeight = 3 * kernelSizeY * 0.5f;
-
-    static constexpr int minimalRectDimension = 100 * 100; // Empirical data limit for parallel jobs
-    int optimalThreadNumber = (paintSize.width() * paintSize.height()) / (minimalRectDimension + extraHeight * paintSize.width());
-
-    if (optimalThreadNumber > 1) {
-        ParallelJobs<ApplyParameters> parallelJobs(&boxBlurWorker, optimalThreadNumber);
-
-        int jobs = parallelJobs.numberOfJobs();
-        if (jobs > 1) {
-            // Split the job into "blockHeight"-sized jobs but there a few jobs that need to be slightly larger since
-            // blockHeight * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
-            const int blockHeight = paintSize.height() / jobs;
-            const int jobsWithExtra = paintSize.height() % jobs;
-
-            int currentY = 0;
-            for (int job = 0; job < jobs; job++) {
-                ApplyParameters& params = parallelJobs.parameter(job);
-
-                int startY = !job ? 0 : currentY - extraHeight;
-                currentY += job < jobsWithExtra ? blockHeight + 1 : blockHeight;
-                int endY = job == jobs - 1 ? currentY : currentY + extraHeight;
-
-                int blockSize = (endY - startY) * scanline;
-                if (!job) {
-                    params.ioPixelArray = &ioBuffer;
-                    params.tmpPixelArray = &tmpPixelArray;
-                } else {
-                    params.ioPixelArray = Uint8ClampedArray::createUninitialized(blockSize);
-                    params.tmpPixelArray = Uint8ClampedArray::createUninitialized(blockSize);
-                    memcpy(params.ioPixelArray->data(), ioBuffer.data() + startY * scanline, blockSize);
-                }
-
-                params.width = paintSize.width();
-                params.height = endY - startY;
-                params.kernelSizeX = kernelSizeX;
-                params.kernelSizeY = kernelSizeY;
-                params.isAlphaImage = isAlphaImage;
-                params.edgeMode = edgeMode;
-            }
-
-            parallelJobs.execute();
-
-            // Copy together the parts of the image.
-            currentY = 0;
-            for (int job = 1; job < jobs; job++) {
-                ApplyParameters& params = parallelJobs.parameter(job);
-                int sourceOffset;
-                int destinationOffset;
-                int size;
-                int adjustedBlockHeight = job < jobsWithExtra ? blockHeight + 1 : blockHeight;
-
-                currentY += adjustedBlockHeight;
-                sourceOffset = extraHeight * scanline;
-                destinationOffset = currentY * scanline;
-                size = adjustedBlockHeight * scanline;
-
-                memcpy(ioBuffer.data() + destinationOffset, params.ioPixelArray->data() + sourceOffset, size);
-            }
-            return;
-        }
-        // Fallback to single threaded mode.
-    }
-#endif
-
-    // The selection here eventually should happen dynamically on some platforms.
-    boxBlurGeneric(ioBuffer, tmpPixelArray, kernelSizeX, kernelSizeY, paintSize, isAlphaImage, edgeMode);
-}
-
-bool FEGaussianBlurSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
-    if (!destinationPixelBuffer)
-        return false;
-
-    m_effect.setIsAlphaImage(in->isAlphaImage());
-
-    auto effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
-    in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
-    if (!m_effect.stdDeviationX() && !m_effect.stdDeviationY())
-        return true;
-
-    auto kernelSize = m_effect.calculateKernelSize(filter, { m_effect.stdDeviationX(), m_effect.stdDeviationY() });
-
-    IntSize paintSize = m_effect.absolutePaintRect().size();
-    auto tmpImageData = Uint8ClampedArray::tryCreateUninitialized(paintSize.area() * 4);
-    if (!tmpImageData)
-        return false;
-
-    auto& destinationPixelArray = destinationPixelBuffer->data();
-    applyPlatform(destinationPixelArray, *tmpImageData, kernelSize.width(), kernelSize.height(), paintSize, m_effect.isAlphaImage(), m_effect.edgeMode());
-    return true;
-}
-
</del><span class="cx"> bool FEGaussianBlur::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEGaussianBlurSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEGaussianBlurh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h  2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFELightingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp    2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2010 University of Szeged
</span><span class="cx">  * Copyright (C) 2010 Zoltan Herczeg
</span><del>- * Copyright (C) 2018 Apple Inc.
</del><ins>+ * Copyright (C) 2018-2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,12 +28,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FELighting.h"
</span><span class="cx"> 
</span><del>-#include "ColorConversion.h"
-#include "FELightingNEON.h"
-#include "FilterEffectApplier.h"
-#include "ImageBuffer.h"
-#include "PixelBuffer.h"
-#include <wtf/ParallelJobs.h>
</del><ins>+#include "FELightingSoftwareApplier.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -86,507 +81,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FELightingSoftwareApplier to separate source and header files.
-class FELightingSoftwareApplier : public FilterEffectConcreteApplier<FELighting> {
-    using Base = FilterEffectConcreteApplier<FELighting>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    static constexpr int cPixelSize = 4;
-    static constexpr int cAlphaChannelOffset = 3;
-    static constexpr uint8_t cOpaqueAlpha = static_cast<uint8_t>(0xFF);
-
-    // These factors and the normal coefficients come from the table under https://www.w3.org/TR/SVG/filters.html#feDiffuseLightingElement.
-    static constexpr float cFactor1div2 = -1 / 2.f;
-    static constexpr float cFactor1div3 = -1 / 3.f;
-    static constexpr float cFactor1div4 = -1 / 4.f;
-    static constexpr float cFactor2div3 = -2 / 3.f;
-
-    struct AlphaWindow {
-        uint8_t alpha[3][3] { };
-    
-        // The implementations are lined up to make comparing indices easier.
-        uint8_t topLeft() const             { return alpha[0][0]; }
-        uint8_t left() const                { return alpha[1][0]; }
-        uint8_t bottomLeft() const          { return alpha[2][0]; }
-
-        uint8_t top() const                 { return alpha[0][1]; }
-        uint8_t center() const              { return alpha[1][1]; }
-        uint8_t bottom() const              { return alpha[2][1]; }
-
-        void setTop(uint8_t value)          { alpha[0][1] = value; }
-        void setCenter(uint8_t value)       { alpha[1][1] = value; }
-        void setBottom(uint8_t value)       { alpha[2][1] = value; }
-
-        void setTopRight(uint8_t value)     { alpha[0][2] = value; }
-        void setRight(uint8_t value)        { alpha[1][2] = value; }
-        void setBottomRight(uint8_t value)  { alpha[2][2] = value; }
-
-        static void shiftRow(uint8_t alpha[3])
-        {
-            alpha[0] = alpha[1];
-            alpha[1] = alpha[2];
-        }
-    
-        void shift()
-        {
-            shiftRow(alpha[0]);
-            shiftRow(alpha[1]);
-            shiftRow(alpha[2]);
-        }
-    };
-
-    struct LightingData {
-        // This structure contains only read-only (SMP safe) data
-        FELighting* effect;
-        FilterEffect::Type filterType;
-        Color lightingColor;
-        float surfaceScale;
-        float diffuseConstant;
-        float specularConstant;
-        float specularExponent;
-        const LightSource* lightSource;
-        const DestinationColorSpace* operatingColorSpace;
-
-        Uint8ClampedArray* pixels;
-        int widthMultipliedByPixelSize;
-        int width;
-        int height;
-
-        inline IntSize topLeftNormal(int offset) const;
-        inline IntSize topRowNormal(int offset) const;
-        inline IntSize topRightNormal(int offset) const;
-        inline IntSize leftColumnNormal(int offset) const;
-        inline IntSize interiorNormal(int offset, AlphaWindow&) const;
-        inline IntSize rightColumnNormal(int offset) const;
-        inline IntSize bottomLeftNormal(int offset) const;
-        inline IntSize bottomRowNormal(int offset) const;
-        inline IntSize bottomRightNormal(int offset) const;
-    };
-
-    struct ApplyParameters {
-        LightingData data;
-        LightSource::PaintingData paintingData;
-        int yStart;
-        int yEnd;
-    };
-
-    static void setPixelInternal(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normal2DVector, float alpha);
-    static void setPixel(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normal2DVector);
-
-    static void applyPlatformGenericPaint(const LightingData&, const LightSource::PaintingData&, int startY, int endY);
-    static void applyPlatformGenericWorker(ApplyParameters*);
-    static void applyPlatformGeneric(const LightingData&, const LightSource::PaintingData&);
-    static void applyPlatform(const LightingData&);
-};
-
-inline IntSize FELightingSoftwareApplier::LightingData::topLeftNormal(int offset) const
-{
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    offset += widthMultipliedByPixelSize;
-    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int bottomRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    return {
-        -2 * center + 2 * right - bottom + bottomRight,
-        -2 * center - right + 2 * bottom + bottomRight
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::topRowNormal(int offset) const
-{
-    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    offset += widthMultipliedByPixelSize;
-    int bottomLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int bottomRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    return {
-        -2 * left + 2 * right - bottomLeft + bottomRight,
-        -left - 2 * center - right + bottomLeft + 2 * bottom + bottomRight
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::topRightNormal(int offset) const
-{
-    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    offset += widthMultipliedByPixelSize;
-    int bottomLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    return {
-        -2 * left + 2 * center - bottomLeft + bottom,
-        -left - 2 * center + bottomLeft + 2 * bottom
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::leftColumnNormal(int offset) const
-{
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    offset -= widthMultipliedByPixelSize;
-    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int topRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    offset += 2 * widthMultipliedByPixelSize;
-    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int bottomRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    return {
-        -top + topRight - 2 * center + 2 * right - bottom + bottomRight,
-        -2 * top - topRight + 2 * bottom + bottomRight
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::interiorNormal(int offset, AlphaWindow& alphaWindow) const
-{
-    int rightAlphaOffset = offset + cPixelSize + cAlphaChannelOffset;
-    
-    int right = static_cast<int>(pixels->item(rightAlphaOffset));
-    int topRight = static_cast<int>(pixels->item(rightAlphaOffset - widthMultipliedByPixelSize));
-    int bottomRight = static_cast<int>(pixels->item(rightAlphaOffset + widthMultipliedByPixelSize));
-
-    int left = alphaWindow.left();
-    int topLeft = alphaWindow.topLeft();
-    int top = alphaWindow.top();
-
-    int bottomLeft = alphaWindow.bottomLeft();
-    int bottom = alphaWindow.bottom();
-
-    // The alphaWindow has been shifted, and here we fill in the right column.
-    alphaWindow.alpha[0][2] = topRight;
-    alphaWindow.alpha[1][2] = right;
-    alphaWindow.alpha[2][2] = bottomRight;
-    
-    // Check that the alphaWindow is working with some spot-checks.
-    ASSERT(alphaWindow.topLeft() == pixels->item(offset - cPixelSize - widthMultipliedByPixelSize + cAlphaChannelOffset)); // topLeft
-    ASSERT(alphaWindow.top() == pixels->item(offset - widthMultipliedByPixelSize + cAlphaChannelOffset)); // top
-
-    return {
-        -topLeft + topRight - 2 * left + 2 * right - bottomLeft + bottomRight,
-        -topLeft - 2 * top - topRight + bottomLeft + 2 * bottom + bottomRight
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::rightColumnNormal(int offset) const
-{
-    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    offset -= widthMultipliedByPixelSize;
-    int topLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    offset += 2 * widthMultipliedByPixelSize;
-    int bottomLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    return {
-        -topLeft + top - 2 * left + 2 * center - bottomLeft + bottom,
-        -topLeft - 2 * top + bottomLeft + 2 * bottom
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::bottomLeftNormal(int offset) const
-{
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    offset -= widthMultipliedByPixelSize;
-    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int topRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    return {
-        -top + topRight - 2 * center + 2 * right,
-        -2 * top - topRight + 2 * center + right
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::bottomRowNormal(int offset) const
-{
-    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    offset -= widthMultipliedByPixelSize;
-    int topLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    int topRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
-    return {
-        -topLeft + topRight - 2 * left + 2 * right,
-        -topLeft - 2 * top - topRight + left + 2 * center + right
-    };
-}
-
-inline IntSize FELightingSoftwareApplier::LightingData::bottomRightNormal(int offset) const
-{
-    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    offset -= widthMultipliedByPixelSize;
-    int topLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
-    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
-    return {
-        -topLeft + top - 2 * left + 2 * center,
-        -topLeft - 2 * top + left + 2 * center
-    };
-}
-
-void FELightingSoftwareApplier::setPixelInternal(int offset, const LightingData& data, const LightSource::PaintingData& paintingData, int x, int y, float factorX, float factorY, IntSize normal2DVector, float alpha)
-{
-    float z = alpha * data.surfaceScale;
-    LightSource::ComputedLightingData lightingData = data.lightSource->computePixelLightingData(paintingData, x, y, z);
-
-    float lightStrength;
-    if (normal2DVector.isZero()) {
-        // Normal vector is (0, 0, 1). This is a quite frequent case.
-        if (data.effect->filterType() == FilterEffect::Type::FEDiffuseLighting)
-            lightStrength = data.diffuseConstant * lightingData.lightVector.z() / lightingData.lightVectorLength;
-        else {
-            FloatPoint3D halfwayVector = {
-                lightingData.lightVector.x(),
-                lightingData.lightVector.y(),
-                lightingData.lightVector.z() + lightingData.lightVectorLength
-            };
-            float halfwayVectorLength = halfwayVector.length();
-            if (data.specularExponent == 1)
-                lightStrength = data.specularConstant * halfwayVector.z() / halfwayVectorLength;
-            else
-                lightStrength = data.specularConstant * powf(halfwayVector.z() / halfwayVectorLength, data.specularExponent);
-        }
-    } else {
-        FloatPoint3D normalVector = {
-            factorX * normal2DVector.width() * data.surfaceScale,
-            factorY * normal2DVector.height() * data.surfaceScale,
-            1.0f
-        };
-        float normalVectorLength = normalVector.length();
-
-        if (data.effect->filterType() == FilterEffect::Type::FEDiffuseLighting)
-            lightStrength = data.diffuseConstant * (normalVector * lightingData.lightVector) / (normalVectorLength * lightingData.lightVectorLength);
-        else {
-            FloatPoint3D halfwayVector = {
-                lightingData.lightVector.x(),
-                lightingData.lightVector.y(),
-                lightingData.lightVector.z() + lightingData.lightVectorLength
-            };
-            float halfwayVectorLength = halfwayVector.length();
-            if (data.specularExponent == 1)
-                lightStrength = data.specularConstant * (normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength);
-            else
-                lightStrength = data.specularConstant * powf((normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength), data.specularExponent);
-        }
-    }
-
-    if (lightStrength > 1)
-        lightStrength = 1;
-    if (lightStrength < 0)
-        lightStrength = 0;
-
-    uint8_t pixelValue[3] = {
-        static_cast<uint8_t>(lightStrength * lightingData.colorVector.x() * 255.0f),
-        static_cast<uint8_t>(lightStrength * lightingData.colorVector.y() * 255.0f),
-        static_cast<uint8_t>(lightStrength * lightingData.colorVector.z() * 255.0f)
-    };
-    
-    data.pixels->setRange(pixelValue, 3, offset);
-}
-
-void FELightingSoftwareApplier::setPixel(int offset, const LightingData& data, const LightSource::PaintingData& paintingData, int x, int y, float factorX, float factorY, IntSize normal2DVector)
-{
-    setPixelInternal(offset, data, paintingData, x, y, factorX, factorY, normal2DVector, data.pixels->item(offset + cAlphaChannelOffset));
-}
-
-// This appears to read from and write to the same pixel buffer, but it only reads the alpha channel, and writes the non-alpha channels.
-void FELightingSoftwareApplier::applyPlatformGenericPaint(const LightingData& data, const LightSource::PaintingData& paintingData, int startY, int endY)
-{
-    // Make sure startY is > 0 since we read from the previous row in the loop.
-    ASSERT(startY);
-    ASSERT(endY > startY);
-
-    for (int y = startY; y < endY; ++y) {
-        int rowStartOffset = y * data.widthMultipliedByPixelSize;
-        int previousRowStart = rowStartOffset - data.widthMultipliedByPixelSize;
-        int nextRowStart = rowStartOffset + data.widthMultipliedByPixelSize;
-
-        // alphaWindow is a local cache of alpha values.
-        // Fill the two right columns putting the left edge value in the center column.
-        // For each pixel, we shift each row left then fill the right column.
-        AlphaWindow alphaWindow;
-        alphaWindow.setTop(data.pixels->item(previousRowStart + cAlphaChannelOffset));
-        alphaWindow.setTopRight(data.pixels->item(previousRowStart + cPixelSize + cAlphaChannelOffset));
-
-        alphaWindow.setCenter(data.pixels->item(rowStartOffset + cAlphaChannelOffset));
-        alphaWindow.setRight(data.pixels->item(rowStartOffset + cPixelSize + cAlphaChannelOffset));
-
-        alphaWindow.setBottom(data.pixels->item(nextRowStart + cAlphaChannelOffset));
-        alphaWindow.setBottomRight(data.pixels->item(nextRowStart + cPixelSize + cAlphaChannelOffset));
-
-        int offset = rowStartOffset + cPixelSize;
-        for (int x = 1; x < data.width - 1; ++x, offset += cPixelSize) {
-            alphaWindow.shift();
-            setPixelInternal(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, data.interiorNormal(offset, alphaWindow), alphaWindow.center());
-        }
-    }
-}
-
-void FELightingSoftwareApplier::applyPlatformGenericWorker(ApplyParameters* parameters)
-{
-    applyPlatformGenericPaint(parameters->data, parameters->paintingData, parameters->yStart, parameters->yEnd);
-}
-
-#if !(CPU(ARM_NEON) && CPU(ARM_TRADITIONAL) && COMPILER(GCC_COMPATIBLE))
-void FELightingSoftwareApplier::applyPlatformGeneric(const LightingData& data, const LightSource::PaintingData& paintingData)
-{
-    unsigned rowsToProcess = data.height - 2;
-    unsigned maxNumThreads = rowsToProcess / 8;
-    
-    static constexpr int minimalRectDimension = 100 * 100; // Empirical data limit for parallel jobs
-    unsigned optimalThreadNumber = std::min<unsigned>(((data.width - 2) * rowsToProcess) / minimalRectDimension, maxNumThreads);
-
-    if (optimalThreadNumber > 1) {
-        // Initialize parallel jobs
-        ParallelJobs<ApplyParameters> parallelJobs(&applyPlatformGenericWorker, optimalThreadNumber);
-
-        // Fill the parameter array
-        int job = parallelJobs.numberOfJobs();
-        if (job > 1) {
-            // Split the job into "yStep"-sized jobs but there a few jobs that need to be slightly larger since
-            // yStep * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
-            const int yStep = rowsToProcess / job;
-            const int jobsWithExtra = rowsToProcess % job;
-
-            int yStart = 1;
-            for (--job; job >= 0; --job) {
-                ApplyParameters& params = parallelJobs.parameter(job);
-                params.data = data;
-                params.paintingData = paintingData;
-                params.yStart = yStart;
-                yStart += job < jobsWithExtra ? yStep + 1 : yStep;
-                params.yEnd = yStart;
-            }
-            parallelJobs.execute();
-            return;
-        }
-        // Fallback to single threaded mode.
-    }
-
-    applyPlatformGenericPaint(data, paintingData, 1, data.height - 1);
-}
-#endif
-
-void FELightingSoftwareApplier::applyPlatform(const LightingData& data)
-{
-    LightSource::PaintingData paintingData;
-
-    auto [r, g, b, a] = data.lightingColor.toColorComponentsInColorSpace(*data.operatingColorSpace);
-    paintingData.initialLightingData.colorVector = FloatPoint3D(r, g, b);
-
-    data.lightSource->initPaintingData(*data.effect, paintingData);
-
-    // Top left.
-    int offset = 0;
-    setPixel(offset, data, paintingData, 0, 0, cFactor2div3, cFactor2div3, data.topLeftNormal(offset));
-
-    // Top right.
-    offset = data.widthMultipliedByPixelSize - cPixelSize;
-    setPixel(offset, data, paintingData, data.width - 1, 0, cFactor2div3, cFactor2div3, data.topRightNormal(offset));
-
-    // Bottom left.
-    offset = (data.height - 1) * data.widthMultipliedByPixelSize;
-    setPixel(offset, data, paintingData, 0, data.height - 1, cFactor2div3, cFactor2div3, data.bottomLeftNormal(offset));
-
-    // Bottom right.
-    offset = data.height * data.widthMultipliedByPixelSize - cPixelSize;
-    setPixel(offset, data, paintingData, data.width - 1, data.height - 1, cFactor2div3, cFactor2div3, data.bottomRightNormal(offset));
-
-    if (data.width >= 3) {
-        // Top row.
-        offset = cPixelSize;
-        for (int x = 1; x < data.width - 1; ++x, offset += cPixelSize)
-            setPixel(offset, data, paintingData, x, 0, cFactor1div3, cFactor1div2, data.topRowNormal(offset));
-
-        // Bottom row.
-        offset = (data.height - 1) * data.widthMultipliedByPixelSize + cPixelSize;
-        for (int x = 1; x < data.width - 1; ++x, offset += cPixelSize)
-            setPixel(offset, data, paintingData, x, data.height - 1, cFactor1div3, cFactor1div2, data.bottomRowNormal(offset));
-    }
-
-    if (data.height >= 3) {
-        // Left column.
-        offset = data.widthMultipliedByPixelSize;
-        for (int y = 1; y < data.height - 1; ++y, offset += data.widthMultipliedByPixelSize)
-            setPixel(offset, data, paintingData, 0, y, cFactor1div2, cFactor1div3, data.leftColumnNormal(offset));
-
-        // Right column.
-        offset = 2 * data.widthMultipliedByPixelSize - cPixelSize;
-        for (int y = 1; y < data.height - 1; ++y, offset += data.widthMultipliedByPixelSize)
-            setPixel(offset, data, paintingData, data.width - 1, y, cFactor1div2, cFactor1div3, data.rightColumnNormal(offset));
-    }
-
-    if (data.width >= 3 && data.height >= 3) {
-        // Interior pixels.
-        applyPlatformGeneric(data, paintingData);
-    }
-
-    int lastPixel = data.widthMultipliedByPixelSize * data.height;
-    if (data.effect->filterType() == FilterEffect::Type::FEDiffuseLighting) {
-        for (int i = cAlphaChannelOffset; i < lastPixel; i += cPixelSize)
-            data.pixels->set(i, cOpaqueAlpha);
-    } else {
-        for (int i = 0; i < lastPixel; i += cPixelSize) {
-            uint8_t a1 = data.pixels->item(i);
-            uint8_t a2 = data.pixels->item(i + 1);
-            uint8_t a3 = data.pixels->item(i + 2);
-            // alpha set to set to max(a1, a2, a3)
-            data.pixels->set(i + 3, a1 >= a2 ? (a1 >= a3 ? a1 : a3) : (a2 >= a3 ? a2 : a3));
-        }
-    }
-}
-
-bool FELightingSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
-    if (!destinationPixelBuffer)
-        return false;
-
-    auto& destinationPixelArray = destinationPixelBuffer->data();
-
-    m_effect.setIsAlphaImage(false);
-
-    auto effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
-    in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
-
-    // FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3
-    // standard has no test case for them, and other browsers (like Firefox) has strange
-    // output for various kernelUnitLengths, and I am not sure they are reliable.
-    // Anyway, feConvolveMatrix should also use the implementation
-
-    IntSize size = IntSize(m_effect.absolutePaintRect().size());
-
-    // FIXME: do something if width or height (or both) is 1 pixel.
-    // The W3 spec does not define this case. Now the filter just returns.
-    if (size.width() <= 2 || size.height() <= 2)
-        return true;
-
-    LightingData data;
-    data.effect = &m_effect;
-    data.filterType = m_effect.filterType();
-    data.lightingColor = m_effect.lightingColor();
-    data.surfaceScale = m_effect.surfaceScale() / 255.0f;
-    data.diffuseConstant = m_effect.diffuseConstant();
-    data.specularConstant = m_effect.specularConstant();
-    data.specularExponent = m_effect.specularExponent();
-    data.lightSource = &m_effect.lightSource();
-    data.operatingColorSpace = &m_effect.operatingColorSpace();
-
-    data.pixels = &destinationPixelArray;
-    data.widthMultipliedByPixelSize = size.width() * cPixelSize;
-    data.width = size.width();
-    data.height = size.height();
-
-    applyPlatform(data);
-    return true;
-}
-
</del><span class="cx"> bool FELighting::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FELightingSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFELightingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FELighting.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FELighting.h      2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FELighting.h 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2010 University of Szeged
</span><span class="cx">  * Copyright (C) 2010 Zoltan Herczeg
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEMergecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEMerge.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEMerge.cpp       2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEMerge.cpp  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) Apple Inc. 2021 All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -22,9 +23,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEMerge.h"
</span><span class="cx"> 
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
</del><ins>+#include "FEMergeSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -39,36 +38,6 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEMergeSoftwareApplier to separate source and header files.
-class FEMergeSoftwareApplier : public FilterEffectConcreteApplier<FEMerge> {
-    using Base = FilterEffectConcreteApplier<FEMerge>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-bool FEMergeSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    ASSERT(inputEffects.size() > 0);
-
-    auto resultImage = m_effect.imageBufferResult();
-    if (!resultImage)
-        return false;
-
-    auto& filterContext = resultImage->context();
-
-    for (auto& in : inputEffects) {
-        auto inBuffer = in->imageBufferResult();
-        if (!inBuffer)
-            continue;
-        filterContext.drawImageBuffer(*inBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
-    }
-
-    return true;
-}
-
</del><span class="cx"> bool FEMerge::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEMergeSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEMerge.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEMerge.h 2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEMerge.h    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) Apple Inc. 2021 All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEMorphologycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp  2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -4,7 +4,7 @@
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
</span><del>- * Copyright (C) Apple Inc. 2017-2018 All rights reserved.
</del><ins>+ * Copyright (C) Apple Inc. 2017-2021 All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -25,13 +25,8 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FEMorphology.h"
</span><span class="cx"> 
</span><del>-#include "ColorComponents.h"
-#include "ColorTypes.h"
</del><span class="cx"> #include "Filter.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "PixelBuffer.h"
-#include <wtf/ParallelJobs.h>
-#include <wtf/Vector.h>
</del><ins>+#include "FEMorphologySoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -84,207 +79,6 @@
</span><span class="cx">     setAbsolutePaintRect(enclosingIntRect(paintRect));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEMorphologySoftwareApplier to separate source and header files.
-class FEMorphologySoftwareApplier : public FilterEffectConcreteApplier<FEMorphology> {
-    using Base = FilterEffectConcreteApplier<FEMorphology>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    using ColumnExtrema = Vector<ColorComponents<uint8_t, 4>, 16>;
-
-    struct PaintingData {
-        MorphologyOperatorType type;
-        int radiusX;
-        int radiusY;
-        const Uint8ClampedArray* srcPixelArray;
-        Uint8ClampedArray* dstPixelArray;
-        int width;
-        int height;
-    };
-
-    struct ApplyParameters {
-        const PaintingData* paintingData;
-        int startY;
-        int endY;
-    };
-
-    static inline int pixelArrayIndex(int x, int y, int width) { return (y * width + x) * 4; }
-    static inline PackedColor::RGBA makePixelValueFromColorComponents(const ColorComponents<uint8_t, 4>& components) { return PackedColor::RGBA { makeFromComponents<SRGBA<uint8_t>>(components) }; }
-
-    static inline ColorComponents<uint8_t, 4> makeColorComponentsfromPixelValue(PackedColor::RGBA pixel) { return asColorComponents(asSRGBA(pixel)); }
-    static inline ColorComponents<uint8_t, 4> minOrMax(const ColorComponents<uint8_t, 4>& a, const ColorComponents<uint8_t, 4>& b, MorphologyOperatorType);
-    static inline ColorComponents<uint8_t, 4> columnExtremum(const Uint8ClampedArray& srcPixelArray, int x, int yStart, int yEnd, int width, MorphologyOperatorType);
-    static inline ColorComponents<uint8_t, 4> kernelExtremum(const ColumnExtrema& kernel, MorphologyOperatorType);
-
-    static void applyPlatformGeneric(const PaintingData&, int startY, int endY);
-    static void applyPlatformWorker(ApplyParameters*);
-    static void applyPlatform(const PaintingData&);
-};
-
-inline ColorComponents<uint8_t, 4> FEMorphologySoftwareApplier::minOrMax(const ColorComponents<uint8_t, 4>& a, const ColorComponents<uint8_t, 4>& b, MorphologyOperatorType type)
-{
-    if (type == FEMORPHOLOGY_OPERATOR_ERODE)
-        return perComponentMin(a, b);
-
-    return perComponentMax(a, b);
-}
-
-inline ColorComponents<uint8_t, 4> FEMorphologySoftwareApplier::columnExtremum(const Uint8ClampedArray& srcPixelArray, int x, int yStart, int yEnd, int width, MorphologyOperatorType type)
-{
-    auto extremum = makeColorComponentsfromPixelValue(PackedColor::RGBA { *reinterpret_cast<const unsigned*>(srcPixelArray.data() + pixelArrayIndex(x, yStart, width)) });
-
-    for (int y = yStart + 1; y < yEnd; ++y) {
-        auto pixel = makeColorComponentsfromPixelValue(PackedColor::RGBA { *reinterpret_cast<const unsigned*>(srcPixelArray.data() + pixelArrayIndex(x, y, width)) });
-        extremum = minOrMax(extremum, pixel, type);
-    }
-    return extremum;
-}
-
-inline ColorComponents<uint8_t, 4> FEMorphologySoftwareApplier::kernelExtremum(const ColumnExtrema& kernel, MorphologyOperatorType type)
-{
-    auto extremum = kernel[0];
-    for (size_t i = 1; i < kernel.size(); ++i)
-        extremum = minOrMax(extremum, kernel[i], type);
-
-    return extremum;
-}
-
-void FEMorphologySoftwareApplier::applyPlatformGeneric(const PaintingData& paintingData, int startY, int endY)
-{
-    ASSERT(endY > startY);
-
-    const auto& srcPixelArray = *paintingData.srcPixelArray;
-    auto& dstPixelArray = *paintingData.dstPixelArray;
-
-    const int radiusX = paintingData.radiusX;
-    const int radiusY = paintingData.radiusY;
-    const int width = paintingData.width;
-    const int height = paintingData.height;
-
-    ASSERT(radiusX <= width || radiusY <= height);
-    ASSERT(startY >= 0 && endY <= height && startY < endY);
-
-    ColumnExtrema extrema;
-    extrema.reserveInitialCapacity(2 * radiusX + 1);
-
-    for (int y = startY; y < endY; ++y) {
-        int yRadiusStart = std::max(0, y - radiusY);
-        int yRadiusEnd = std::min(height, y + radiusY + 1);
-
-        extrema.shrink(0);
-
-        // We start at the left edge, so compute extreme for the radiusX columns.
-        for (int x = 0; x < radiusX; ++x)
-            extrema.append(columnExtremum(srcPixelArray, x, yRadiusStart, yRadiusEnd, width, paintingData.type));
-
-        // Kernel is filled, get extrema of next column
-        for (int x = 0; x < width; ++x) {
-            if (x < width - radiusX)
-                extrema.append(columnExtremum(srcPixelArray, x + radiusX, yRadiusStart, yRadiusEnd, width, paintingData.type));
-
-            if (x > radiusX)
-                extrema.remove(0);
-
-            unsigned* destPixel = reinterpret_cast<unsigned*>(dstPixelArray.data() + pixelArrayIndex(x, y, width));
-            *destPixel = makePixelValueFromColorComponents(kernelExtremum(extrema, paintingData.type)).value;
-        }
-    }
-}
-
-void FEMorphologySoftwareApplier::applyPlatformWorker(ApplyParameters* params)
-{
-    applyPlatformGeneric(*params->paintingData, params->startY, params->endY);
-}
-
-void FEMorphologySoftwareApplier::applyPlatform(const PaintingData& paintingData)
-{
-    // Empirically, runtime is approximately linear over reasonable kernel sizes with a slope of about 0.65.
-    float kernelFactor = sqrt(paintingData.radiusX * paintingData.radiusY) * 0.65;
-
-    static const int minimalArea = (160 * 160); // Empirical data limit for parallel jobs
-    
-    unsigned maxNumThreads = paintingData.height / 8;
-    unsigned optimalThreadNumber = std::min<unsigned>((paintingData.width * paintingData.height * kernelFactor) / minimalArea, maxNumThreads);
-    if (optimalThreadNumber > 1) {
-        ParallelJobs<ApplyParameters> parallelJobs(&applyPlatformWorker, optimalThreadNumber);
-        auto numOfThreads = parallelJobs.numberOfJobs();
-        if (numOfThreads > 1) {
-            // Split the job into "jobSize"-sized jobs but there a few jobs that need to be slightly larger since
-            // jobSize * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
-            int jobSize = paintingData.height / numOfThreads;
-            int jobsWithExtra = paintingData.height % numOfThreads;
-            int currentY = 0;
-            for (int job = numOfThreads - 1; job >= 0; --job) {
-                ApplyParameters& param = parallelJobs.parameter(job);
-                param.startY = currentY;
-                currentY += job < jobsWithExtra ? jobSize + 1 : jobSize;
-                param.endY = currentY;
-                param.paintingData = &paintingData;
-            }
-            parallelJobs.execute();
-            return;
-        }
-        // Fallback to single thread model
-    }
-
-    applyPlatformGeneric(paintingData, 0, paintingData.height);
-}
-
-bool FEMorphologySoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
-    if (!destinationPixelBuffer)
-        return false;
-
-    m_effect.setIsAlphaImage(in->isAlphaImage());
-
-    auto isDegenerate = [](int radiusX, int radiusY) -> bool {
-        return radiusX < 0 || radiusY < 0 || (!radiusX && !radiusY);
-    };
-
-    IntRect effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
-    IntSize radius = flooredIntSize(FloatSize(m_effect.radiusX(), m_effect.radiusY()));
-
-    if (isDegenerate(radius.width(), radius.height())) {
-        in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
-        return true;
-    }
-
-    radius = flooredIntSize(filter.scaledByFilterScale({ m_effect.radiusX(), m_effect.radiusY() }));
-    int radiusX = std::min(effectDrawingRect.width() - 1, radius.width());
-    int radiusY = std::min(effectDrawingRect.height() - 1, radius.height());
-
-    if (isDegenerate(radiusX, radiusY)) {
-        in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
-        return true;
-    }
-
-    auto sourcePixelBuffer = in->getPixelBufferResult(AlphaPremultiplication::Premultiplied, effectDrawingRect, m_effect.operatingColorSpace());
-    if (!sourcePixelBuffer)
-        return false;
-
-    auto& sourcePixelArray = sourcePixelBuffer->data();
-    auto& destinationPixelArray = destinationPixelBuffer->data();
-
-    PaintingData paintingData;
-    paintingData.type = m_effect.morphologyOperator();
-    paintingData.srcPixelArray = &sourcePixelArray;
-    paintingData.dstPixelArray = &destinationPixelArray;
-    paintingData.width = ceilf(effectDrawingRect.width());
-    paintingData.height = ceilf(effectDrawingRect.height());
-    paintingData.radiusX = ceilf(radiusX);
-    paintingData.radiusY = ceilf(radiusY);
-
-    applyPlatform(paintingData);
-    return true;
-}
-
</del><span class="cx"> bool FEMorphology::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEMorphologySoftwareApplier(*this).apply(filter, inputEffects());
</span><span class="lines">@@ -293,13 +87,13 @@
</span><span class="cx"> static TextStream& operator<<(TextStream& ts, const MorphologyOperatorType& type)
</span><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><del>-    case FEMORPHOLOGY_OPERATOR_UNKNOWN:
</del><ins>+    case MorphologyOperatorType::Unknown:
</ins><span class="cx">         ts << "UNKNOWN";
</span><span class="cx">         break;
</span><del>-    case FEMORPHOLOGY_OPERATOR_ERODE:
</del><ins>+    case MorphologyOperatorType::Erode:
</ins><span class="cx">         ts << "ERODE";
</span><span class="cx">         break;
</span><del>-    case FEMORPHOLOGY_OPERATOR_DILATE:
</del><ins>+    case MorphologyOperatorType::Dilate:
</ins><span class="cx">         ts << "DILATE";
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEMorphologyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEMorphology.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEMorphology.h    2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEMorphology.h       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) Apple Inc. 2021 All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -25,10 +26,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-enum MorphologyOperatorType {
-    FEMORPHOLOGY_OPERATOR_UNKNOWN = 0,
-    FEMORPHOLOGY_OPERATOR_ERODE = 1,
-    FEMORPHOLOGY_OPERATOR_DILATE = 2
</del><ins>+enum class MorphologyOperatorType {
+    Unknown,
+    Erode,
+    Dilate
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class FEMorphology : public FilterEffect {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEOffsetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp      2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -25,9 +26,7 @@
</span><span class="cx"> #include "FEOffset.h"
</span><span class="cx"> 
</span><span class="cx"> #include "Filter.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
</del><ins>+#include "FEOffsetSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -65,34 +64,6 @@
</span><span class="cx">     setAbsolutePaintRect(enclosingIntRect(paintRect));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FEOffsetSoftwareApplier to separate source and header files.
-class FEOffsetSoftwareApplier : public FilterEffectConcreteApplier<FEOffset> {
-    using Base = FilterEffectConcreteApplier<FEOffset>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-bool FEOffsetSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto resultImage = m_effect.imageBufferResult();
-    auto inBuffer = in->imageBufferResult();
-    if (!resultImage || !inBuffer)
-        return false;
-
-    m_effect.setIsAlphaImage(in->isAlphaImage());
-
-    FloatRect drawingRegion = m_effect.drawingRegionOfInputImage(in->absolutePaintRect());
-    drawingRegion.move(filter.scaledByFilterScale({ m_effect.dx(), m_effect.dy() }));
-    resultImage->context().drawImageBuffer(*inBuffer, drawingRegion);
-
-    return true;
-}
-
</del><span class="cx"> bool FEOffset::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FEOffsetSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEOffseth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEOffset.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEOffset.h        2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FEOffset.h   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFESpecularLightingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp    2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFESpecularLightingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.h      2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.h 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFETilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FETile.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FETile.cpp        2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FETile.cpp   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -21,14 +22,8 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FETile.h"
</span><span class="cx"> 
</span><del>-#include "AffineTransform.h"
-#include "Filter.h"
-#include "FilterEffectApplier.h"
</del><ins>+#include "FETileSoftwareApplier.h"
</ins><span class="cx"> #include "GraphicsContext.h"
</span><del>-#include "ImageBuffer.h"
-#include "Pattern.h"
-#include "RenderTreeAsText.h"
-#include "SVGRenderingContext.h"
</del><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -43,61 +38,6 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class FETileSoftwareApplier to separate source and header files.
-class FETileSoftwareApplier : public FilterEffectConcreteApplier<FETile> {
-    using Base = FilterEffectConcreteApplier<FETile>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-bool FETileSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto resultImage = m_effect.imageBufferResult();
-    auto inBuffer = in->imageBufferResult();
-    if (!resultImage || !inBuffer)
-        return false;
-
-    m_effect.setIsAlphaImage(in->isAlphaImage());
-
-    // Source input needs more attention. It has the size of the filterRegion but gives the
-    // size of the cutted sourceImage back. This is part of the specification and optimization.
-    FloatRect tileRect = in->maxEffectRect();
-    FloatPoint inMaxEffectLocation = tileRect.location();
-    FloatPoint maxEffectLocation = m_effect.maxEffectRect().location();
-    if (in->filterType() == FilterEffect::Type::SourceGraphic || in->filterType() == FilterEffect::Type::SourceAlpha) {
-        tileRect = filter.filterRegion();
-        tileRect.scale(filter.filterScale());
-    }
-
-    auto tileImage = SVGRenderingContext::createImageBuffer(tileRect, tileRect, DestinationColorSpace::SRGB(), filter.renderingMode());
-    if (!tileImage)
-        return false;
-
-    GraphicsContext& tileImageContext = tileImage->context();
-    tileImageContext.translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
-    tileImageContext.drawImageBuffer(*inBuffer, in->absolutePaintRect().location());
-
-    auto tileImageCopy = ImageBuffer::sinkIntoNativeImage(WTFMove(tileImage));
-    if (!tileImageCopy)
-        return false;
-
-    AffineTransform patternTransform;
-    patternTransform.translate(inMaxEffectLocation - maxEffectLocation);
-
-    auto pattern = Pattern::create(tileImageCopy.releaseNonNull(), { true, true, patternTransform });
-
-    GraphicsContext& filterContext = resultImage->context();
-    filterContext.setFillPattern(WTFMove(pattern));
-    filterContext.fillRect(FloatRect(FloatPoint(), m_effect.absolutePaintRect().size()));
-
-    return true;
-}
-
</del><span class="cx"> bool FETile::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FETileSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFETileh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FETile.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FETile.h  2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FETile.h     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -2,6 +2,7 @@
</span><span class="cx">  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
</span><span class="cx">  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFETurbulencecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp  2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
</span><span class="cx">  * Copyright (C) 2011 Gabor Loki <loki@webkit.org>
</span><del>- * Copyright (C) 2017-2018 Apple Inc.
</del><ins>+ * Copyright (C) 2017-2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -26,11 +26,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "FETurbulence.h"
</span><span class="cx"> 
</span><del>-#include "Filter.h"
-#include "FilterEffectApplier.h"
-#include "PixelBuffer.h"
-#include <wtf/MathExtras.h>
-#include <wtf/ParallelJobs.h>
</del><ins>+#include "FETurbulenceSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -99,420 +95,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// The turbulence calculation code is an adapted version of what appears in the SVG 1.1 specification:
-// http://www.w3.org/TR/SVG11/filters.html#feTurbulence
-
-// FIXME: Move the class FETurbulenceSoftwareApplier to separate source and header files.
-class FETurbulenceSoftwareApplier : public FilterEffectConcreteApplier<FETurbulence> {
-    using Base = FilterEffectConcreteApplier<FETurbulence>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-
-private:
-    // Produces results in the range [1, 2**31 - 2]. Algorithm is:
-    // r = (a * r) mod m where a = s_randAmplitude = 16807 and
-    // m = s_randMaximum = 2**31 - 1 = 2147483647, r = seed.
-    // See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
-    // To test: the algorithm should produce the result 1043618065
-    // as the 10,000th generated number if the original seed is 1.
-    static const int s_perlinNoise = 4096;
-    static const long s_randMaximum = 2147483647; // 2**31 - 1
-    static const int s_randAmplitude = 16807; // 7**5; primitive root of m
-    static const int s_randQ = 127773; // m / a
-    static const int s_randR = 2836; // m % a
-
-    static const int s_blockSize = 256;
-    static const int s_blockMask = s_blockSize - 1;
-
-    struct PaintingData {
-        // Compute pseudo random number.
-        long random()
-        {
-            long result = s_randAmplitude * (seed % s_randQ) - s_randR * (seed / s_randQ);
-            if (result <= 0)
-                result += s_randMaximum;
-            seed = result;
-            return result;
-        }
-
-        TurbulenceType type;
-        float baseFrequencyX;
-        float baseFrequencyY;
-        int numOctaves;
-        long seed;
-        bool stitchTiles;
-        IntSize paintingSize;
-
-        int latticeSelector[2 * s_blockSize + 2];
-        float gradient[4][2 * s_blockSize + 2][2];
-    };
-
-    struct StitchData {
-        int width { 0 }; // How much to subtract to wrap for stitching.
-        int wrapX { 0 }; // Minimum value to wrap.
-        int height { 0 };
-        int wrapY { 0 };
-    };
-
-    struct ApplyParameters {
-        IntRect filterRegion;
-        FloatSize filterScale;
-        Uint8ClampedArray* pixelArray;
-        PaintingData* paintingData;
-        StitchData stitchData;
-        int startY;
-        int endY;
-    };
-
-    static inline float smoothCurve(float t) { return t * t * (3 - 2 * t); }
-    static inline float linearInterpolation(float t, float a, float b) { return a + t * (b - a); }
-
-    static PaintingData initPaintingData(TurbulenceType, float baseFrequencyX, float baseFrequencyY, int numOctaves, long seed, bool stitchTiles, const IntSize& paintingSize);
-    static StitchData computeStitching(IntSize tileSize, float& baseFrequencyX, float& baseFrequencyY, bool stitchTiles);
-
-    static ColorComponents<float, 4> noise2D(const PaintingData&, const StitchData&, const FloatPoint& noiseVector);
-    static ColorComponents<uint8_t, 4> toIntBasedColorComponents(const ColorComponents<float, 4>& floatComponents);
-    static ColorComponents<uint8_t, 4> calculateTurbulenceValueForPoint(const PaintingData&, StitchData, const FloatPoint&);
-
-    static void applyPlatformGeneric(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, const PaintingData&, StitchData, int startY, int endY);
-    static void applyPlatformWorker(ApplyParameters*);
-    static void applyPlatform(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, PaintingData&, StitchData&);
-};
-
-FETurbulenceSoftwareApplier::PaintingData FETurbulenceSoftwareApplier::initPaintingData(TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, long seed, bool stitchTiles, const IntSize& paintingSize)
-{
-    PaintingData paintingData { type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles, paintingSize, { }, { } };
-
-    // The seed value clamp to the range [1, s_randMaximum - 1].
-    if (paintingData.seed <= 0)
-        paintingData.seed = -(paintingData.seed % (s_randMaximum - 1)) + 1;
-    if (paintingData.seed > s_randMaximum - 1)
-        paintingData.seed = s_randMaximum - 1;
-
-    float* gradient;
-    for (int channel = 0; channel < 4; ++channel) {
-        for (int i = 0; i < s_blockSize; ++i) {
-            paintingData.latticeSelector[i] = i;
-            gradient = paintingData.gradient[channel][i];
-            do {
-                gradient[0] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
-                gradient[1] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
-            } while (!gradient[0] && !gradient[1]);
-            float normalizationFactor = std::hypot(gradient[0], gradient[1]);
-            gradient[0] /= normalizationFactor;
-            gradient[1] /= normalizationFactor;
-        }
-    }
-
-    for (int i = s_blockSize - 1; i > 0; --i) {
-        int k = paintingData.latticeSelector[i];
-        int j = paintingData.random() % s_blockSize;
-        ASSERT(j >= 0);
-        ASSERT(j < 2 * s_blockSize + 2);
-        paintingData.latticeSelector[i] = paintingData.latticeSelector[j];
-        paintingData.latticeSelector[j] = k;
-    }
-
-    for (int i = 0; i < s_blockSize + 2; ++i) {
-        paintingData.latticeSelector[s_blockSize + i] = paintingData.latticeSelector[i];
-        for (int channel = 0; channel < 4; ++channel) {
-            paintingData.gradient[channel][s_blockSize + i][0] = paintingData.gradient[channel][i][0];
-            paintingData.gradient[channel][s_blockSize + i][1] = paintingData.gradient[channel][i][1];
-        }
-    }
-
-    return paintingData;
-}
-
-FETurbulenceSoftwareApplier::StitchData FETurbulenceSoftwareApplier::computeStitching(IntSize tileSize, float& baseFrequencyX, float& baseFrequencyY, bool stitchTiles)
-{
-    if (!stitchTiles)
-        return { };
-
-    float tileWidth = tileSize.width();
-    float tileHeight = tileSize.height();
-    ASSERT(tileWidth > 0 && tileHeight > 0);
-
-    // When stitching tiled turbulence, the frequencies must be adjusted
-    // so that the tile borders will be continuous.
-    if (baseFrequencyX) {
-        float lowFrequency = floorf(tileWidth * baseFrequencyX) / tileWidth;
-        float highFrequency = ceilf(tileWidth * baseFrequencyX) / tileWidth;
-        // BaseFrequency should be non-negative according to the standard.
-        if (baseFrequencyX / lowFrequency < highFrequency / baseFrequencyX)
-            baseFrequencyX = lowFrequency;
-        else
-            baseFrequencyX = highFrequency;
-    }
-    if (baseFrequencyY) {
-        float lowFrequency = floorf(tileHeight * baseFrequencyY) / tileHeight;
-        float highFrequency = ceilf(tileHeight * baseFrequencyY) / tileHeight;
-        if (baseFrequencyY / lowFrequency < highFrequency / baseFrequencyY)
-            baseFrequencyY = lowFrequency;
-        else
-            baseFrequencyY = highFrequency;
-    }
-
-    StitchData stitchData;
-    stitchData.width = roundf(tileWidth * baseFrequencyX);
-    stitchData.wrapX = s_perlinNoise + stitchData.width;
-    stitchData.height = roundf(tileHeight * baseFrequencyY);
-    stitchData.wrapY = s_perlinNoise + stitchData.height;
-
-    return stitchData;
-}
-
-// This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
-ColorComponents<float, 4> FETurbulenceSoftwareApplier::noise2D(const PaintingData& paintingData, const StitchData& stitchData, const FloatPoint& noiseVector)
-{
-    struct NoisePosition {
-        int index; // bx0, by0 in the spec text.
-        int nextIndex; // bx1, by1 in the spec text.
-        float fraction; // rx0, ry0 in the spec text.
-
-        NoisePosition(float component)
-        {
-            //  t = vec[0] + PerlinN;
-            //  bx0 = (int)t;
-            //  bx1 = bx0+1;
-            //  rx0 = t - (int)t;
-            float position = component + s_perlinNoise;
-            index = static_cast<int>(position);
-            nextIndex = index + 1;
-            fraction = position - index;
-        }
-        
-        void stitch(int size, int wrapSize)
-        {
-            // if (bx0 >= pStitchInfo->nWrapX)
-            //   bx0 -= pStitchInfo->nWidth;
-            if (index >= wrapSize)
-                index -= size;
-
-            // if (bx1 >= pStitchInfo->nWrapX)
-            //   bx1 -= pStitchInfo->nWidth;
-            if (nextIndex >= wrapSize)
-                nextIndex -= size;
-        }
-    };
-
-    NoisePosition noiseX(noiseVector.x());
-    NoisePosition noiseY(noiseVector.y());
-
-    // If stitching, adjust lattice points accordingly.
-    if (paintingData.stitchTiles) {
-        noiseX.stitch(stitchData.width, stitchData.wrapX);
-        noiseY.stitch(stitchData.height, stitchData.wrapY);
-    }
-
-    // bx0 &= BM;
-    // bx1 &= BM;
-    // by0 &= BM;
-    // by1 &= BM;
-    noiseX.index &= s_blockMask;
-    noiseX.nextIndex &= s_blockMask;
-    noiseY.index &= s_blockMask;
-    noiseY.nextIndex &= s_blockMask;
-
-    // i = uLatticeSelector[bx0];
-    // j = uLatticeSelector[bx1];
-    int latticeIndex = paintingData.latticeSelector[noiseX.index];
-    int nextLatticeIndex = paintingData.latticeSelector[noiseX.nextIndex];
-
-    // sx = double(s_curve(rx0));
-    // sy = double(s_curve(ry0));
-    float sx = smoothCurve(noiseX.fraction);
-    float sy = smoothCurve(noiseY.fraction);
-
-    auto noiseForChannel = [&](int channel) {
-        // b00 = uLatticeSelector[i + by0]
-        int b00 = paintingData.latticeSelector[latticeIndex + noiseY.index];
-        // q = fGradient[nColorChannel][b00]; u = rx0 * q[0] + ry0 * q[1];
-        const float* q = paintingData.gradient[channel][b00];
-        float u = noiseX.fraction * q[0] + noiseY.fraction * q[1];
-
-        // b10 = uLatticeSelector[j + by0];
-        int b10 = paintingData.latticeSelector[nextLatticeIndex + noiseY.index];
-        // rx1 = rx0 - 1.0f;
-        // q = fGradient[nColorChannel][b10]; v = rx1 * q[0] + ry0 * q[1];
-        q = paintingData.gradient[channel][b10];
-        float v = (noiseX.fraction - 1) * q[0] + noiseY.fraction * q[1];
-        // a = lerp(sx, u, v);
-        float a = linearInterpolation(sx, u, v);
-
-        // b01 = uLatticeSelector[i + by1];
-        int b01 = paintingData.latticeSelector[latticeIndex + noiseY.nextIndex];
-        // ry1 = ry0 - 1.0f;
-        // q = fGradient[nColorChannel][b01]; u = rx0 * q[0] + ry1 * q[1];
-        q = paintingData.gradient[channel][b01];
-        u = noiseX.fraction * q[0] + (noiseY.fraction - 1) * q[1];
-
-        // b11 = uLatticeSelector[j + by1];
-        int b11 = paintingData.latticeSelector[nextLatticeIndex + noiseY.nextIndex];
-        // q = fGradient[nColorChannel][b11]; v = rx1 * q[0] + ry1 * q[1];
-        q = paintingData.gradient[channel][b11];
-        v = (noiseX.fraction - 1) * q[0] + (noiseY.fraction - 1) * q[1];
-        // b = lerp(sx, u, v);
-        float b = linearInterpolation(sx, u, v);
-
-        // return lerp(sy, a, b);
-        return linearInterpolation(sy, a, b);
-    };
-
-    return {
-        noiseForChannel(0),
-        noiseForChannel(1),
-        noiseForChannel(2),
-        noiseForChannel(3)
-    };
-}
-
-// https://www.w3.org/TR/SVG/filters.html#feTurbulenceElement describes this conversion to color components.
-// FIXME: This should use colorConvert<SRGBA<uint8>>(SRGBA<float>) to get the same behavior.
-ColorComponents<uint8_t, 4> FETurbulenceSoftwareApplier::toIntBasedColorComponents(const ColorComponents<float, 4>& floatComponents)
-{
-    return {
-        std::clamp<uint8_t>(static_cast<int>(floatComponents[0] * 255), 0, 255),
-        std::clamp<uint8_t>(static_cast<int>(floatComponents[1] * 255), 0, 255),
-        std::clamp<uint8_t>(static_cast<int>(floatComponents[2] * 255), 0, 255),
-        std::clamp<uint8_t>(static_cast<int>(floatComponents[3] * 255), 0, 255),
-    };
-}
-
-ColorComponents<uint8_t, 4> FETurbulenceSoftwareApplier::calculateTurbulenceValueForPoint(const PaintingData& paintingData, StitchData stitchData, const FloatPoint& point)
-{
-    ColorComponents<float, 4> turbulenceFunctionResult;
-    FloatPoint noiseVector(point.x() * paintingData.baseFrequencyX, point.y() * paintingData.baseFrequencyY);
-    float ratio = 1;
-    for (int octave = 0; octave < paintingData.numOctaves; ++octave) {
-        if (paintingData.type == TurbulenceType::FractalNoise)
-            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector) / ratio;
-        else
-            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector).abs() / ratio;
-
-        noiseVector.setX(noiseVector.x() * 2);
-        noiseVector.setY(noiseVector.y() * 2);
-        ratio *= 2;
-
-        if (paintingData.stitchTiles) {
-            // Update stitch values. Subtracting s_perlinNoise before the multiplication and
-            // adding it afterward simplifies to subtracting it once.
-            stitchData.width *= 2;
-            stitchData.wrapX = 2 * stitchData.wrapX - s_perlinNoise;
-            stitchData.height *= 2;
-            stitchData.wrapY = 2 * stitchData.wrapY - s_perlinNoise;
-        }
-    }
-
-    // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult * 255) + 255) / 2 by fractalNoise
-    // and (turbulenceFunctionResult * 255) by turbulence.
-    if (paintingData.type == TurbulenceType::FractalNoise)
-        turbulenceFunctionResult = turbulenceFunctionResult * 0.5f + 0.5f;
-
-    return toIntBasedColorComponents(turbulenceFunctionResult);
-}
-
-void FETurbulenceSoftwareApplier::applyPlatformGeneric(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, const PaintingData& paintingData, StitchData stitchData, int startY, int endY)
-{
-    ASSERT(endY > startY);
-
-    FloatPoint point(0, filterRegion.y() + startY);
-    int indexOfPixelChannel = startY * (filterRegion.width() << 2);
-    FloatSize inverseScale = { 1 / filterScale.width(), 1 / filterScale.height() };
-
-    for (int y = startY; y < endY; ++y) {
-        point.setY(point.y() + 1);
-        point.setX(filterRegion.x());
-        for (int x = 0; x < filterRegion.width(); ++x) {
-            point.setX(point.x() + 1);
-            FloatPoint localPoint = point.scaled(inverseScale.width(), inverseScale.height());
-            auto values = calculateTurbulenceValueForPoint(paintingData, stitchData, localPoint);
-            pixelArray.setRange(values.components.data(), 4, indexOfPixelChannel);
-            indexOfPixelChannel += 4;
-        }
-    }
-}
-
-void FETurbulenceSoftwareApplier::applyPlatformWorker(ApplyParameters* parameters)
-{
-    applyPlatformGeneric(parameters->filterRegion, parameters->filterScale, *parameters->pixelArray, *parameters->paintingData, parameters->stitchData, parameters->startY, parameters->endY);
-}
-
-void FETurbulenceSoftwareApplier::applyPlatform(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, PaintingData& paintingData, StitchData& stitchData)
-{
-    int height = filterRegion.height();
-    unsigned area = filterRegion.area();
-
-    static const int minimalRectDimension = (100 * 100); // Empirical data limit for parallel jobs.
-    unsigned maxNumThreads = filterRegion.height() / 8;
-    unsigned optimalThreadNumber = std::min<unsigned>(area / minimalRectDimension, maxNumThreads);
-
-    if (optimalThreadNumber > 1) {
-        ParallelJobs<ApplyParameters> parallelJobs(&applyPlatformWorker, optimalThreadNumber);
-
-        // Fill the parameter array
-        auto numJobs = parallelJobs.numberOfJobs();
-        if (numJobs > 1) {
-            // Split the job into "stepY"-sized jobs, distributing the extra rows into the first "jobsWithExtra" jobs.
-            unsigned stepY = height / numJobs;
-            unsigned jobsWithExtra = height % numJobs;
-            unsigned startY = 0;
-
-            for (unsigned i = 0; i < numJobs; ++i) {
-                ApplyParameters& params = parallelJobs.parameter(i);
-                params.filterRegion = filterRegion;
-                params.filterScale = filterScale;
-                params.pixelArray = &pixelArray;
-                params.paintingData = &paintingData;
-                params.stitchData = stitchData;
-                params.startY = startY;
-
-                unsigned jobHeight = (i < jobsWithExtra) ? stepY + 1 : stepY;
-                params.endY = params.startY + jobHeight;
-                startY += jobHeight;
-            }
-
-            parallelJobs.execute();
-            return;
-        }
-    }
-
-    // Fallback to single threaded mode if there is no room for a new thread or the paint area is too small.
-    applyPlatformGeneric(filterRegion, filterScale, pixelArray, paintingData, stitchData, 0, height);
-}
-
-bool FETurbulenceSoftwareApplier::apply(const Filter& filter, const FilterEffectVector&)
-{
-    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Unpremultiplied);
-    if (!destinationPixelBuffer)
-        return false;
-
-    IntSize resultSize(m_effect.absolutePaintRect().size());
-    if (resultSize.area().hasOverflowed())
-        return false;
-
-    auto& destinationPixelArray = destinationPixelBuffer->data();
-
-    if (resultSize.isEmpty()) {
-        destinationPixelArray.zeroFill();
-        return true;
-    }
-
-    auto tileSize = roundedIntSize(m_effect.filterPrimitiveSubregion().size());
-
-    float baseFrequencyX = m_effect.baseFrequencyX();
-    float baseFrequencyY = m_effect.baseFrequencyY();
-    auto stitchData = computeStitching(tileSize, baseFrequencyX, baseFrequencyY, m_effect.stitchTiles());
-
-    auto paintingData = initPaintingData(m_effect.type(), baseFrequencyX, baseFrequencyY, m_effect.numOctaves(), m_effect.seed(), m_effect.stitchTiles(), tileSize);
-
-    applyPlatform(m_effect.absolutePaintRect(), filter.filterScale(), destinationPixelArray, paintingData, stitchData);
-    return true;
-}
-
</del><span class="cx"> bool FETurbulence::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return FETurbulenceSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFETurbulenceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h    2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -4,7 +4,7 @@
</span><span class="cx">  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><span class="cx">  * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
</span><del>- * Copyright (C) 2017 Apple Inc.
</del><ins>+ * Copyright (C) 2017-2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFilterEffectApplierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffectApplier.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FilterEffectApplier.h     2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffectApplier.h        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -25,8 +25,12 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include "FilterEffectVector.h"
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class Filter;
+
</ins><span class="cx"> class FilterEffectApplier {
</span><span class="cx"> public:
</span><span class="cx">     FilterEffectApplier() = default;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersSourceAlphacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp   2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -20,10 +21,8 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "SourceAlpha.h"
</span><span class="cx"> 
</span><del>-#include "Color.h"
</del><span class="cx"> #include "Filter.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
</del><ins>+#include "SourceAlphaSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -46,37 +45,6 @@
</span><span class="cx">     setAbsolutePaintRect(inputEffect(0)->absolutePaintRect());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class SourceAlphaSoftwareApplier to separate source and header files.
-class SourceAlphaSoftwareApplier : public FilterEffectConcreteApplier<SourceAlpha> {
-    using Base = FilterEffectConcreteApplier<SourceAlpha>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-bool SourceAlphaSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
-{
-    FilterEffect* in = inputEffects[0].get();
-
-    auto resultImage = m_effect.imageBufferResult();
-    if (!resultImage)
-        return false;
-    
-    auto imageBuffer = in->imageBufferResult();
-    if (!imageBuffer)
-        return false;
-
-    FloatRect imageRect(FloatPoint(), m_effect.absolutePaintRect().size());
-    GraphicsContext& filterContext = resultImage->context();
-
-    filterContext.fillRect(imageRect, Color::black);
-    filterContext.drawImageBuffer(*imageBuffer, IntPoint(), CompositeOperator::DestinationIn);
-
-    return true;
-}
-
</del><span class="cx"> bool SourceAlpha::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return SourceAlphaSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersSourceAlphah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h     2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersSourceGraphiccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp 2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -21,8 +22,7 @@
</span><span class="cx"> #include "SourceGraphic.h"
</span><span class="cx"> 
</span><span class="cx"> #include "Filter.h"
</span><del>-#include "FilterEffectApplier.h"
-#include "GraphicsContext.h"
</del><ins>+#include "SourceGraphicSoftwareApplier.h"
</ins><span class="cx"> #include <wtf/text/TextStream.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -43,27 +43,6 @@
</span><span class="cx">     setAbsolutePaintRect(enclosingIntRect(paintRect));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Move the class SourceGraphicSoftwareApplier to separate source and header files.
-class SourceGraphicSoftwareApplier : public FilterEffectConcreteApplier<SourceGraphic> {
-    using Base = FilterEffectConcreteApplier<SourceGraphic>;
-
-public:
-    using Base::Base;
-
-    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
-};
-
-bool SourceGraphicSoftwareApplier::apply(const Filter& filter, const FilterEffectVector&)
-{
-    auto resultImage = m_effect.imageBufferResult();
-    auto sourceImage = filter.sourceImage();
-    if (!resultImage || !sourceImage)
-        return false;
-
-    resultImage->context().drawImageBuffer(*sourceImage, IntPoint());
-    return true;
-}
-
</del><span class="cx"> bool SourceGraphic::platformApplySoftware(const Filter& filter)
</span><span class="cx"> {
</span><span class="cx">     return SourceGraphicSoftwareApplier(*this).apply(filter, inputEffects());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersSourceGraphich"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.h   2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.h      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
</span><span class="cx">  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
</span><ins>+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEBlendSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEBlendcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEBlend.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.cpp                               (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.cpp  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEBlendSoftwareApplier.h"
+
+#include "FEBlend.h"
+#include "FloatPoint.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+
+namespace WebCore {
+
+#if !HAVE(ARM_NEON_INTRINSICS)
+bool FEBlendSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+    FilterEffect* in2 = inputEffects[1].get();
+
+    auto resultImage = m_effect.imageBufferResult();
+    if (!resultImage)
+        return false;
+
+    auto imageBuffer = in->imageBufferResult();
+    auto imageBuffer2 = in2->imageBufferResult();
+    if (!imageBuffer || !imageBuffer2)
+        return false;
+
+    GraphicsContext& filterContext = resultImage->context();
+    filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
+    filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, { CompositeOperator::SourceOver, m_effect.blendMode() });
+    return true;
+}
+#endif
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEBlendSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.h                         (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEBlendSoftwareApplier.h    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEBlend;
+
+class FEBlendSoftwareApplier : public FilterEffectConcreteApplier<FEBlend> {
+    using Base = FilterEffectConcreteApplier<FEBlend>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEColorMatrixSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEColorMatrixcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.cpp                         (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.cpp    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,288 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEColorMatrixSoftwareApplier.h"
+
+#include "FEColorMatrix.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "PixelBuffer.h"
+#include <wtf/MathExtras.h>
+
+#if USE(ACCELERATE)
+#include <Accelerate/Accelerate.h>
+#endif
+
+namespace WebCore {
+
+FEColorMatrixSoftwareApplier::FEColorMatrixSoftwareApplier(FEColorMatrix& effect)
+    : Base(effect)
+{
+    if (m_effect.type() == FECOLORMATRIX_TYPE_SATURATE)
+        FEColorMatrix::calculateSaturateComponents(m_components, m_effect.values()[0]);
+    else if (m_effect.type() == FECOLORMATRIX_TYPE_HUEROTATE)
+        FEColorMatrix::calculateHueRotateComponents(m_components, m_effect.values()[0]);
+}
+
+inline void FEColorMatrixSoftwareApplier::matrix(float& red, float& green, float& blue, float& alpha) const
+{
+    float r = red;
+    float g = green;
+    float b = blue;
+    float a = alpha;
+
+    const auto& values = m_effect.values();
+
+    red   = values[ 0] * r + values[ 1] * g + values[ 2] * b + values[ 3] * a + values[ 4] * 255;
+    green = values[ 5] * r + values[ 6] * g + values[ 7] * b + values[ 8] * a + values[ 9] * 255;
+    blue  = values[10] * r + values[11] * g + values[12] * b + values[13] * a + values[14] * 255;
+    alpha = values[15] * r + values[16] * g + values[17] * b + values[18] * a + values[19] * 255;
+}
+
+inline void FEColorMatrixSoftwareApplier::saturateAndHueRotate(float& red, float& green, float& blue) const
+{
+    float r = red;
+    float g = green;
+    float b = blue;
+
+    red     = r * m_components[0] + g * m_components[1] + b * m_components[2];
+    green   = r * m_components[3] + g * m_components[4] + b * m_components[5];
+    blue    = r * m_components[6] + g * m_components[7] + b * m_components[8];
+}
+
+// FIXME: this should use the luminance(...) function in ColorLuminance.h.
+inline void FEColorMatrixSoftwareApplier::luminance(float& red, float& green, float& blue, float& alpha) const
+{
+    alpha = 0.2125 * red + 0.7154 * green + 0.0721 * blue;
+    red = 0;
+    green = 0;
+    blue = 0;
+}
+
+#if USE(ACCELERATE)
+void FEColorMatrixSoftwareApplier::applyPlatformAccelerated(PixelBuffer& pixelBuffer) const
+{
+    auto& pixelArray = pixelBuffer.data();
+    auto bufferSize = pixelBuffer.size();
+
+    ASSERT(pixelArray.length() == bufferSize.area() * 4);
+    
+    const int32_t divisor = 256;
+    uint8_t* data = pixelArray.data();
+
+    vImage_Buffer src;
+    src.width = bufferSize.width();
+    src.height = bufferSize.height();
+    src.rowBytes = bufferSize.width() * 4;
+    src.data = data;
+    
+    vImage_Buffer dest;
+    dest.width = bufferSize.width();
+    dest.height = bufferSize.height();
+    dest.rowBytes = bufferSize.width() * 4;
+    dest.data = data;
+
+    switch (m_effect.type()) {
+    case FECOLORMATRIX_TYPE_UNKNOWN:
+        break;
+
+    case FECOLORMATRIX_TYPE_MATRIX: {
+        const auto& values = m_effect.values();
+
+        const int16_t matrix[4 * 4] = {
+            static_cast<int16_t>(roundf(values[ 0] * divisor)),
+            static_cast<int16_t>(roundf(values[ 5] * divisor)),
+            static_cast<int16_t>(roundf(values[10] * divisor)),
+            static_cast<int16_t>(roundf(values[15] * divisor)),
+
+            static_cast<int16_t>(roundf(values[ 1] * divisor)),
+            static_cast<int16_t>(roundf(values[ 6] * divisor)),
+            static_cast<int16_t>(roundf(values[11] * divisor)),
+            static_cast<int16_t>(roundf(values[16] * divisor)),
+
+            static_cast<int16_t>(roundf(values[ 2] * divisor)),
+            static_cast<int16_t>(roundf(values[ 7] * divisor)),
+            static_cast<int16_t>(roundf(values[12] * divisor)),
+            static_cast<int16_t>(roundf(values[17] * divisor)),
+
+            static_cast<int16_t>(roundf(values[ 3] * divisor)),
+            static_cast<int16_t>(roundf(values[ 8] * divisor)),
+            static_cast<int16_t>(roundf(values[13] * divisor)),
+            static_cast<int16_t>(roundf(values[18] * divisor)),
+        };
+        vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags);
+        break;
+    }
+
+    case FECOLORMATRIX_TYPE_SATURATE:
+    case FECOLORMATRIX_TYPE_HUEROTATE: {
+        const int16_t matrix[4 * 4] = {
+            static_cast<int16_t>(roundf(m_components[0] * divisor)),
+            static_cast<int16_t>(roundf(m_components[3] * divisor)),
+            static_cast<int16_t>(roundf(m_components[6] * divisor)),
+            0,
+
+            static_cast<int16_t>(roundf(m_components[1] * divisor)),
+            static_cast<int16_t>(roundf(m_components[4] * divisor)),
+            static_cast<int16_t>(roundf(m_components[7] * divisor)),
+            0,
+
+            static_cast<int16_t>(roundf(m_components[2] * divisor)),
+            static_cast<int16_t>(roundf(m_components[5] * divisor)),
+            static_cast<int16_t>(roundf(m_components[8] * divisor)),
+            0,
+
+            0,
+            0,
+            0,
+            divisor,
+        };
+        vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags);
+        break;
+    }
+    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: {
+        const int16_t matrix[4 * 4] = {
+            0,
+            0,
+            0,
+            static_cast<int16_t>(roundf(0.2125 * divisor)),
+
+            0,
+            0,
+            0,
+            static_cast<int16_t>(roundf(0.7154 * divisor)),
+
+            0,
+            0,
+            0,
+            static_cast<int16_t>(roundf(0.0721 * divisor)),
+
+            0,
+            0,
+            0,
+            0,
+        };
+        vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags);
+        break;
+    }
+    }
+}
+#endif
+
+void FEColorMatrixSoftwareApplier::applyPlatformUnaccelerated(PixelBuffer& pixelBuffer) const
+{
+    auto& pixelArray = pixelBuffer.data();
+    unsigned pixelArrayLength = pixelArray.length();
+
+    switch (m_effect.type()) {
+    case FECOLORMATRIX_TYPE_UNKNOWN:
+        break;
+
+    case FECOLORMATRIX_TYPE_MATRIX:
+        for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
+            float red = pixelArray.item(pixelByteOffset);
+            float green = pixelArray.item(pixelByteOffset + 1);
+            float blue = pixelArray.item(pixelByteOffset + 2);
+            float alpha = pixelArray.item(pixelByteOffset + 3);
+            matrix(red, green, blue, alpha);
+            pixelArray.set(pixelByteOffset, red);
+            pixelArray.set(pixelByteOffset + 1, green);
+            pixelArray.set(pixelByteOffset + 2, blue);
+            pixelArray.set(pixelByteOffset + 3, alpha);
+        }
+        break;
+
+    case FECOLORMATRIX_TYPE_SATURATE:
+    case FECOLORMATRIX_TYPE_HUEROTATE:
+        for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
+            float red = pixelArray.item(pixelByteOffset);
+            float green = pixelArray.item(pixelByteOffset + 1);
+            float blue = pixelArray.item(pixelByteOffset + 2);
+            float alpha = pixelArray.item(pixelByteOffset + 3);
+            saturateAndHueRotate(red, green, blue);
+            pixelArray.set(pixelByteOffset, red);
+            pixelArray.set(pixelByteOffset + 1, green);
+            pixelArray.set(pixelByteOffset + 2, blue);
+            pixelArray.set(pixelByteOffset + 3, alpha);
+        }
+        break;
+
+    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
+        for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
+            float red = pixelArray.item(pixelByteOffset);
+            float green = pixelArray.item(pixelByteOffset + 1);
+            float blue = pixelArray.item(pixelByteOffset + 2);
+            float alpha = pixelArray.item(pixelByteOffset + 3);
+            luminance(red, green, blue, alpha);
+            pixelArray.set(pixelByteOffset, red);
+            pixelArray.set(pixelByteOffset + 1, green);
+            pixelArray.set(pixelByteOffset + 2, blue);
+            pixelArray.set(pixelByteOffset + 3, alpha);
+        }
+        break;
+    }
+}
+
+void FEColorMatrixSoftwareApplier::applyPlatform(PixelBuffer& pixelBuffer) const
+{
+#if USE(ACCELERATE)
+    const auto& values = m_effect.values();
+
+    // vImageMatrixMultiply_ARGB8888 takes a 4x4 matrix, if any value in the last column of the FEColorMatrix 5x4 matrix
+    // is not zero, fall back to non-vImage code.
+    if (m_effect.type() != FECOLORMATRIX_TYPE_MATRIX || (!values[4] && !values[9] && !values[14] && !values[19])) {
+        applyPlatformAccelerated(pixelBuffer);
+        return;
+    }
+#endif
+    applyPlatformUnaccelerated(pixelBuffer);
+}
+
+bool FEColorMatrixSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    auto in = inputEffects[0].get();
+
+    auto resultImage = m_effect.imageBufferResult();
+    if (!resultImage)
+        return false;
+
+    auto inBuffer = in->imageBufferResult();
+    if (inBuffer)
+        resultImage->context().drawImageBuffer(*inBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
+
+    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, m_effect.resultColorSpace() };
+    IntRect imageRect(IntPoint(), resultImage->truncatedLogicalSize());
+    auto pixelBuffer = resultImage->getPixelBuffer(format, imageRect);
+    if (!pixelBuffer)
+        return false;
+
+    if (m_effect.type() == FECOLORMATRIX_TYPE_LUMINANCETOALPHA)
+        m_effect.setIsAlphaImage(true);
+
+    applyPlatform(*pixelBuffer);
+    resultImage->putPixelBuffer(*pixelBuffer, imageRect);
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEColorMatrixSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEOffseth"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEOffset.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.h                           (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEColorMatrixSoftwareApplier.h      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEColorMatrix;
+
+class FEColorMatrixSoftwareApplier : public FilterEffectConcreteApplier<FEColorMatrix> {
+    using Base = FilterEffectConcreteApplier<FEColorMatrix>;
+
+public:
+    FEColorMatrixSoftwareApplier(FEColorMatrix&);
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    inline void matrix(float& red, float& green, float& blue, float& alpha) const;
+    inline void saturateAndHueRotate(float& red, float& green, float& blue) const;
+    inline void luminance(float& red, float& green, float& blue, float& alpha) const;
+
+#if USE(ACCELERATE)
+    void applyPlatformAccelerated(PixelBuffer&) const;
+#endif
+    void applyPlatformUnaccelerated(PixelBuffer&) const;
+
+    void applyPlatform(PixelBuffer&) const;
+
+    float m_components[9];
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEComponentTransferSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEComponentTransfercpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.cpp                           (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.cpp      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,149 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEComponentTransferSoftwareApplier.h"
+
+#include "FEComponentTransfer.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "PixelBuffer.h"
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+void FEComponentTransferSoftwareApplier::computeIdentityTable(LookupTable&, const ComponentTransferFunction&)
+{
+}
+
+void FEComponentTransferSoftwareApplier::computeTabularTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
+{
+    const Vector<float>& tableValues = transferFunction.tableValues;
+    unsigned n = tableValues.size();
+    if (n < 1)
+        return;
+    for (unsigned i = 0; i < values.size(); ++i) {
+        double c = i / 255.0;
+        unsigned k = static_cast<unsigned>(c * (n - 1));
+        double v1 = tableValues[k];
+        double v2 = tableValues[std::min((k + 1), (n - 1))];
+        double val = 255.0 * (v1 + (c * (n - 1) - k) * (v2 - v1));
+        val = std::max(0.0, std::min(255.0, val));
+        values[i] = static_cast<uint8_t>(val);
+    }
+}
+
+void FEComponentTransferSoftwareApplier::computeDiscreteTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
+{
+    const Vector<float>& tableValues = transferFunction.tableValues;
+    unsigned n = tableValues.size();
+    if (n < 1)
+        return;
+    for (unsigned i = 0; i < values.size(); ++i) {
+        unsigned k = static_cast<unsigned>((i * n) / 255.0);
+        k = std::min(k, n - 1);
+        double val = 255 * tableValues[k];
+        val = std::max(0.0, std::min(255.0, val));
+        values[i] = static_cast<uint8_t>(val);
+    }
+}
+
+void FEComponentTransferSoftwareApplier::computeLinearTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
+{
+    for (unsigned i = 0; i < values.size(); ++i) {
+        double val = transferFunction.slope * i + 255 * transferFunction.intercept;
+        val = std::max(0.0, std::min(255.0, val));
+        values[i] = static_cast<uint8_t>(val);
+    }
+}
+
+void FEComponentTransferSoftwareApplier::computeGammaTable(LookupTable& values, const ComponentTransferFunction& transferFunction)
+{
+    for (unsigned i = 0; i < values.size(); ++i) {
+        double exponent = transferFunction.exponent; // RCVT doesn't like passing a double and a float to pow, so promote this to double
+        double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), exponent) + transferFunction.offset);
+        val = std::max(0.0, std::min(255.0, val));
+        values[i] = static_cast<uint8_t>(val);
+    }
+}
+
+FEComponentTransferSoftwareApplier::LookupTable FEComponentTransferSoftwareApplier::computeLookupTable(const ComponentTransferFunction& function)
+{
+    LookupTable table;
+
+    for (unsigned i = 0; i < table.size(); ++i)
+        table[i] = i;
+
+    using TransferType = void (*)(LookupTable&, const ComponentTransferFunction&);
+    TransferType callEffect[] = {
+        computeIdentityTable,   // FECOMPONENTTRANSFER_TYPE_UNKNOWN
+        computeIdentityTable,   // FECOMPONENTTRANSFER_TYPE_IDENTITY
+        computeTabularTable,    // FECOMPONENTTRANSFER_TYPE_TABLE
+        computeDiscreteTable,   // FECOMPONENTTRANSFER_TYPE_DISCRETE
+        computeLinearTable,     // FECOMPONENTTRANSFER_TYPE_LINEAR
+        computeGammaTable       // FECOMPONENTTRANSFER_TYPE_GAMMA
+    };
+
+    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(function.type) < WTF_ARRAY_LENGTH(callEffect));
+    callEffect[function.type](table, function);
+
+    return table;
+}
+
+void FEComponentTransferSoftwareApplier::applyPlatform(PixelBuffer& pixelBuffer) const
+{
+    auto& pixelArray = pixelBuffer.data();
+    unsigned pixelArrayLength = pixelArray.length();
+    uint8_t* data = pixelArray.data();
+
+    auto redTable   = computeLookupTable(m_effect.redFunction());
+    auto greenTable = computeLookupTable(m_effect.greenFunction());
+    auto blueTable  = computeLookupTable(m_effect.blueFunction());
+    auto alphaTable = computeLookupTable(m_effect.alphaFunction());
+
+    for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) {
+        data[pixelOffset]     = redTable[data[pixelOffset]];
+        data[pixelOffset + 1] = greenTable[data[pixelOffset + 1]];
+        data[pixelOffset + 2] = blueTable[data[pixelOffset + 2]];
+        data[pixelOffset + 3] = alphaTable[data[pixelOffset + 3]];
+    }
+}
+
+bool FEComponentTransferSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+    
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Unpremultiplied);
+    if (!destinationPixelBuffer)
+        return false;
+
+    auto drawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
+    in->copyPixelBufferResult(*destinationPixelBuffer, drawingRect);
+
+    applyPlatform(*destinationPixelBuffer);
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEComponentTransferSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMorphologyh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMorphology.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h                             (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEComponentTransfer;
+struct ComponentTransferFunction;
+
+class FEComponentTransferSoftwareApplier : public FilterEffectConcreteApplier<FEComponentTransfer> {
+    using Base = FilterEffectConcreteApplier<FEComponentTransfer>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    using LookupTable = std::array<uint8_t, 256>;
+
+    static void computeIdentityTable(LookupTable&, const ComponentTransferFunction&);
+    static void computeTabularTable(LookupTable&, const ComponentTransferFunction&);
+    static void computeDiscreteTable(LookupTable&, const ComponentTransferFunction&);
+    static void computeLinearTable(LookupTable&, const ComponentTransferFunction&);
+    static void computeGammaTable(LookupTable&, const ComponentTransferFunction&);
+
+    static LookupTable computeLookupTable(const ComponentTransferFunction&);
+
+    void applyPlatform(PixelBuffer&) const;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFECompositeSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFECompositecpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.cpp                           (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.cpp      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,227 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FECompositeSoftwareApplier.h"
+
+#include "FEComposite.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "PixelBuffer.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+uint8_t FECompositeSoftwareApplier::clampByte(int c)
+{
+    uint8_t buff[] = { static_cast<uint8_t>(c), 255, 0 };
+    unsigned uc = static_cast<unsigned>(c);
+    return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
+}
+
+template <int b1, int b4>
+inline void FECompositeSoftwareApplier::computeArithmeticPixels(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4)
+{
+    float scaledK1;
+    float scaledK4;
+    if (b1)
+        scaledK1 = k1 / 255.0f;
+    if (b4)
+        scaledK4 = k4 * 255.0f;
+
+    while (--pixelArrayLength >= 0) {
+        unsigned char i1 = *source;
+        unsigned char i2 = *destination;
+        float result = k2 * i1 + k3 * i2;
+        if (b1)
+            result += scaledK1 * i1 * i2;
+        if (b4)
+            result += scaledK4;
+
+        *destination = clampByte(result);
+        ++source;
+        ++destination;
+    }
+}
+
+// computeArithmeticPixelsUnclamped is a faster version of computeArithmeticPixels for the common case where clamping
+// is not necessary. This enables aggresive compiler optimizations such as auto-vectorization.
+template <int b1, int b4>
+inline void FECompositeSoftwareApplier::computeArithmeticPixelsUnclamped(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4)
+{
+    float scaledK1;
+    float scaledK4;
+    if (b1)
+        scaledK1 = k1 / 255.0f;
+    if (b4)
+        scaledK4 = k4 * 255.0f;
+
+    while (--pixelArrayLength >= 0) {
+        unsigned char i1 = *source;
+        unsigned char i2 = *destination;
+        float result = k2 * i1 + k3 * i2;
+        if (b1)
+            result += scaledK1 * i1 * i2;
+        if (b4)
+            result += scaledK4;
+
+        *destination = result;
+        ++source;
+        ++destination;
+    }
+}
+
+#if !HAVE(ARM_NEON_INTRINSICS)
+inline void FECompositeSoftwareApplier::applyPlatformArithmetic(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4)
+{
+    float upperLimit = std::max(0.0f, k1) + std::max(0.0f, k2) + std::max(0.0f, k3) + k4;
+    float lowerLimit = std::min(0.0f, k1) + std::min(0.0f, k2) + std::min(0.0f, k3) + k4;
+    if ((k4 >= 0.0f && k4 <= 1.0f) && (upperLimit >= 0.0f && upperLimit <= 1.0f) && (lowerLimit >= 0.0f && lowerLimit <= 1.0f)) {
+        if (k4) {
+            if (k1)
+                computeArithmeticPixelsUnclamped<1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+            else
+                computeArithmeticPixelsUnclamped<0, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+        } else {
+            if (k1)
+                computeArithmeticPixelsUnclamped<1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+            else
+                computeArithmeticPixelsUnclamped<0, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+        }
+        return;
+    }
+
+    if (k4) {
+        if (k1)
+            computeArithmeticPixels<1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+        else
+            computeArithmeticPixels<0, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+    } else {
+        if (k1)
+            computeArithmeticPixels<1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+        else
+            computeArithmeticPixels<0, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+    }
+}
+#endif
+
+bool FECompositeSoftwareApplier::applyArithmetic(FilterEffect* in, FilterEffect* in2)
+{
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
+    if (!destinationPixelBuffer)
+        return false;
+
+    IntRect effectADrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
+    auto sourcePixelBuffer = in->getPixelBufferResult(AlphaPremultiplication::Premultiplied, effectADrawingRect, m_effect.operatingColorSpace());
+    if (!sourcePixelBuffer)
+        return false;
+
+    IntRect effectBDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in2->absolutePaintRect());
+    in2->copyPixelBufferResult(*destinationPixelBuffer, effectBDrawingRect);
+
+    auto& sourcePixelArray = sourcePixelBuffer->data();
+    auto& destinationPixelArray = destinationPixelBuffer->data();
+
+    int length = sourcePixelArray.length();
+    ASSERT(length == static_cast<int>(destinationPixelArray.length()));
+    applyPlatformArithmetic(sourcePixelArray.data(), destinationPixelArray.data(), length, m_effect.k1(), m_effect.k2(), m_effect.k3(), m_effect.k4());
+    return true;
+}
+
+bool FECompositeSoftwareApplier::applyNonArithmetic(FilterEffect* in, FilterEffect* in2)
+{
+    auto resultImage = m_effect.imageBufferResult();
+    if (!resultImage)
+        return false;
+
+    auto imageBuffer = in->imageBufferResult();
+    auto imageBuffer2 = in2->imageBufferResult();
+    if (!imageBuffer || !imageBuffer2)
+        return false;
+
+    auto& filterContext = resultImage->context();
+
+    switch (m_effect.operation()) {
+    case FECOMPOSITE_OPERATOR_UNKNOWN:
+        return false;
+
+    case FECOMPOSITE_OPERATOR_OVER:
+        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
+        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
+        break;
+
+    case FECOMPOSITE_OPERATOR_IN: {
+        // Applies only to the intersected region.
+        IntRect destinationRect = in->absolutePaintRect();
+        destinationRect.intersect(in2->absolutePaintRect());
+        destinationRect.intersect(m_effect.absolutePaintRect());
+        if (destinationRect.isEmpty())
+            break;
+        IntRect adjustedDestinationRect = destinationRect - m_effect.absolutePaintRect().location();
+        IntRect sourceRect = destinationRect - in->absolutePaintRect().location();
+        IntRect source2Rect = destinationRect - in2->absolutePaintRect().location();
+        filterContext.drawImageBuffer(*imageBuffer2, FloatRect(adjustedDestinationRect), FloatRect(source2Rect));
+        filterContext.drawImageBuffer(*imageBuffer, FloatRect(adjustedDestinationRect), FloatRect(sourceRect), { CompositeOperator::SourceIn });
+        break;
+    }
+
+    case FECOMPOSITE_OPERATOR_OUT:
+        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
+        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()), { { }, imageBuffer2->logicalSize() }, CompositeOperator::DestinationOut);
+        break;
+
+    case FECOMPOSITE_OPERATOR_ATOP:
+        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
+        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, CompositeOperator::SourceAtop);
+        break;
+
+    case FECOMPOSITE_OPERATOR_XOR:
+        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
+        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, CompositeOperator::XOR);
+        break;
+
+    case FECOMPOSITE_OPERATOR_ARITHMETIC:
+        ASSERT_NOT_REACHED();
+        return false;
+
+    case FECOMPOSITE_OPERATOR_LIGHTER:
+        filterContext.drawImageBuffer(*imageBuffer2, m_effect.drawingRegionOfInputImage(in2->absolutePaintRect()));
+        filterContext.drawImageBuffer(*imageBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()), { { }, imageBuffer->logicalSize() }, CompositeOperator::PlusLighter);
+        break;
+    }
+
+    return true;
+}
+
+bool FECompositeSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+    FilterEffect* in2 = inputEffects[1].get();
+
+    if (m_effect.operation() == FECOMPOSITE_OPERATOR_ARITHMETIC)
+        return applyArithmetic(in, in2);
+    return applyNonArithmetic(in, in2);
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFECompositeSoftwareApplierh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.h (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.h                             (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FECompositeSoftwareApplier.h        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEComposite;
+
+class FECompositeSoftwareApplier : public FilterEffectConcreteApplier<FEComposite> {
+    using Base = FilterEffectConcreteApplier<FEComposite>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    static uint8_t clampByte(int);
+
+    template <int b1, int b4>
+    static inline void computeArithmeticPixels(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4);
+
+    template <int b1, int b4>
+    static inline void computeArithmeticPixelsUnclamped(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4);
+
+    static inline void applyPlatformArithmetic(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4);
+
+    bool applyArithmetic(FilterEffect* in, FilterEffect* in2);
+    bool applyNonArithmetic(FilterEffect* in, FilterEffect* in2);
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEConvolveMatrixSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.cpp                              (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.cpp 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,326 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEConvolveMatrixSoftwareApplier.h"
+
+#include "FEColorMatrix.h"
+#include "FEConvolveMatrix.h"
+#include "ImageBuffer.h"
+#include "PixelBuffer.h"
+#include <wtf/ParallelJobs.h>
+#include <wtf/WorkQueue.h>
+
+namespace WebCore {
+
+/*
+   -----------------------------------
+      ConvolveMatrix implementation
+   -----------------------------------
+
+   The image rectangle is split in the following way:
+
+      +---------------------+
+      |          A          |
+      +---------------------+
+      |   |             |   |
+      | B |      C      | D |
+      |   |             |   |
+      +---------------------+
+      |          E          |
+      +---------------------+
+
+   Where region C contains those pixels, whose values
+   can be calculated without crossing the edge of the rectangle.
+
+   Example:
+      Image size: width: 10, height: 10
+
+      Order (kernel matrix size): width: 3, height 4
+      Target: x:1, y:3
+
+      The following figure shows the target inside the kernel matrix:
+
+        ...
+        ...
+        ...
+        .X.
+
+   The regions in this case are the following:
+      Note: (x1, y1) top-left and (x2, y2) is the bottom-right corner
+      Note: row x2 and column y2 is not part of the region
+            only those (x, y) pixels, where x1 <= x < x2 and y1 <= y < y2
+
+      Region A: x1: 0, y1: 0, x2: 10, y2: 3
+      Region B: x1: 0, y1: 3, x2: 1, y2: 10
+      Region C: x1: 1, y1: 3, x2: 9, y2: 10
+      Region D: x1: 9, y1: 3, x2: 10, y2: 10
+      Region E: x1: 0, y1: 10, x2: 10, y2: 10 (empty region)
+
+   Since region C (often) contains most of the pixels, we implemented
+   a fast algoritm to calculate these values, called fastSetInteriorPixels.
+   For other regions, fastSetOuterPixels is used, which calls getPixelValue,
+   to handle pixels outside of the image. In a rare situations, when
+   kernel matrix is bigger than the image, all pixels are calculated by this
+   function.
+
+   Although these two functions have lot in common, I decided not to make
+   common a template for them, since there are key differences as well,
+   and would make it really hard to understand.
+*/
+
+inline uint8_t FEConvolveMatrixSoftwareApplier::clampRGBAValue(float channel, uint8_t max)
+{
+    if (channel <= 0)
+        return 0;
+    if (channel >= max)
+        return max;
+    return channel;
+}
+
+inline void FEConvolveMatrixSoftwareApplier::setDestinationPixels(const Uint8ClampedArray& sourcePixels, Uint8ClampedArray& destPixels, int& pixel, float* totals, float divisor, float bias, bool preserveAlphaValues)
+{
+    uint8_t maxAlpha = preserveAlphaValues ? 255 : clampRGBAValue(totals[3] / divisor + bias);
+    for (int i = 0; i < 3; ++i)
+        destPixels.set(pixel++, clampRGBAValue(totals[i] / divisor + bias, maxAlpha));
+
+    if (preserveAlphaValues) {
+        destPixels.set(pixel, sourcePixels.item(pixel));
+        ++pixel;
+    } else
+        destPixels.set(pixel++, maxAlpha);
+}
+
+inline int FEConvolveMatrixSoftwareApplier::getPixelValue(const PaintingData& paintingData, int x, int y)
+{
+    if (x >= 0 && x < paintingData.width && y >= 0 && y < paintingData.height)
+        return (y * paintingData.width + x) << 2;
+
+    switch (paintingData.edgeMode) {
+    default: // EdgeModeType::None
+        return -1;
+    case EdgeModeType::Duplicate:
+        if (x < 0)
+            x = 0;
+        else if (x >= paintingData.width)
+            x = paintingData.width - 1;
+        if (y < 0)
+            y = 0;
+        else if (y >= paintingData.height)
+            y = paintingData.height - 1;
+        return (y * paintingData.width + x) << 2;
+    case EdgeModeType::Wrap:
+        while (x < 0)
+            x += paintingData.width;
+        x %= paintingData.width;
+        while (y < 0)
+            y += paintingData.height;
+        y %= paintingData.height;
+        return (y * paintingData.width + x) << 2;
+    }
+}
+
+// Only for region C
+inline void FEConvolveMatrixSoftwareApplier::setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom, int yStart, int yEnd)
+{
+    // edge mode does not affect these pixels
+    int pixel = (paintingData.targetOffset.y() * paintingData.width + paintingData.targetOffset.x()) * 4;
+    int kernelIncrease = clipRight * 4;
+    int xIncrease = (paintingData.kernelSize.width() - 1) * 4;
+    // Contains the sum of rgb(a) components
+    float totals[4];
+
+    // divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
+    ASSERT(paintingData.divisor);
+
+    // Skip the first '(clipBottom - yEnd)' lines
+    pixel += (clipBottom - yEnd) * (xIncrease + (clipRight + 1) * 4);
+    int startKernelPixel = (clipBottom - yEnd) * (xIncrease + (clipRight + 1) * 4);
+
+    for (int y = yEnd + 1; y > yStart; --y) {
+        for (int x = clipRight + 1; x > 0; --x) {
+            int kernelValue = paintingData.kernelMatrix.size() - 1;
+            int kernelPixel = startKernelPixel;
+            int width = paintingData.kernelSize.width();
+
+            totals[0] = 0;
+            totals[1] = 0;
+            totals[2] = 0;
+            totals[3] = 0;
+
+            while (kernelValue >= 0) {
+                totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel++));
+                totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel++));
+                totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel++));
+                if (!paintingData.preserveAlpha)
+                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(kernelPixel));
+                ++kernelPixel;
+                --kernelValue;
+                if (!--width) {
+                    kernelPixel += kernelIncrease;
+                    width = paintingData.kernelSize.width();
+                }
+            }
+
+            setDestinationPixels(paintingData.srcPixelArray, paintingData.dstPixelArray, pixel, totals, paintingData.divisor, paintingData.bias, paintingData.preserveAlpha);
+            startKernelPixel += 4;
+        }
+        pixel += xIncrease;
+        startKernelPixel += xIncrease;
+    }
+}
+
+// For other regions than C
+inline void FEConvolveMatrixSoftwareApplier::setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2)
+{
+    int pixel = (y1 * paintingData.width + x1) * 4;
+    int height = y2 - y1;
+    int width = x2 - x1;
+    int beginKernelPixelX = x1 - paintingData.targetOffset.x();
+    int startKernelPixelX = beginKernelPixelX;
+    int startKernelPixelY = y1 - paintingData.targetOffset.y();
+    int xIncrease = (paintingData.width - width) * 4;
+    // Contains the sum of rgb(a) components
+    float totals[4];
+
+    // paintingData.divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
+    ASSERT(paintingData.divisor);
+
+    for (int y = height; y > 0; --y) {
+        for (int x = width; x > 0; --x) {
+            int kernelValue = paintingData.kernelMatrix.size() - 1;
+            int kernelPixelX = startKernelPixelX;
+            int kernelPixelY = startKernelPixelY;
+            int width = paintingData.kernelSize.width();
+
+            totals[0] = 0;
+            totals[1] = 0;
+            totals[2] = 0;
+            totals[3] = 0;
+
+            while (kernelValue >= 0) {
+                int pixelIndex = getPixelValue(paintingData, kernelPixelX, kernelPixelY);
+                if (pixelIndex >= 0) {
+                    totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex));
+                    totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex + 1));
+                    totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex + 2));
+                }
+                if (!paintingData.preserveAlpha && pixelIndex >= 0)
+                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray.item(pixelIndex + 3));
+                ++kernelPixelX;
+                --kernelValue;
+                if (!--width) {
+                    kernelPixelX = startKernelPixelX;
+                    ++kernelPixelY;
+                    width = paintingData.kernelSize.width();
+                }
+            }
+
+            setDestinationPixels(paintingData.srcPixelArray, paintingData.dstPixelArray, pixel, totals, paintingData.divisor, paintingData.bias, paintingData.preserveAlpha);
+            ++startKernelPixelX;
+        }
+        pixel += xIncrease;
+        startKernelPixelX = beginKernelPixelX;
+        ++startKernelPixelY;
+    }
+}
+
+void FEConvolveMatrixSoftwareApplier::applyPlatform(PaintingData& paintingData) const
+{
+    // Drawing fully covered pixels
+    int clipRight = paintingData.width - paintingData.kernelSize.width();
+    int clipBottom = paintingData.height - paintingData.kernelSize.height();
+
+    if (clipRight < 0 || clipBottom < 0) {
+        // Rare situation, not optimized for speed
+        setOuterPixels(paintingData, 0, 0, paintingData.width, paintingData.height);
+        return;
+    }
+
+    static constexpr int minimalRectDimension = (100 * 100); // Empirical data limit for parallel jobs
+
+    if (int iterations = (paintingData.width * paintingData.height) / minimalRectDimension) {
+        int stride = clipBottom / iterations;
+        int chunkCount = (clipBottom + stride - 1) / stride;
+
+        ConcurrentWorkQueue::apply(chunkCount, [&](size_t index) {
+            int yStart = (stride * index);
+            int yEnd = std::min<int>(stride * (index + 1), clipBottom);
+
+            setInteriorPixels(paintingData, clipRight, clipBottom, yStart, yEnd);
+        });
+    } else
+        setInteriorPixels(paintingData, clipRight, clipBottom, 0, clipBottom);
+
+    clipRight += paintingData.targetOffset.x() + 1;
+    clipBottom += paintingData.targetOffset.y() + 1;
+
+    if (paintingData.targetOffset.y() > 0)
+        setOuterPixels(paintingData, 0, 0, paintingData.width, paintingData.targetOffset.y());
+    if (clipBottom < paintingData.height)
+        setOuterPixels(paintingData, 0, clipBottom, paintingData.width, paintingData.height);
+    if (paintingData.targetOffset.x() > 0)
+        setOuterPixels(paintingData, 0, paintingData.targetOffset.y(), paintingData.targetOffset.x(), clipBottom);
+    if (clipRight < paintingData.width)
+        setOuterPixels(paintingData, clipRight, paintingData.targetOffset.y(), paintingData.width, clipBottom);
+}
+
+bool FEConvolveMatrixSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto alphaFormat = m_effect.preserveAlpha() ? AlphaPremultiplication::Unpremultiplied : AlphaPremultiplication::Premultiplied;
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(alphaFormat);
+    if (!destinationPixelBuffer)
+        return false;
+
+    auto effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
+    auto sourcePixelBuffer = in->getPixelBufferResult(alphaFormat, effectDrawingRect, m_effect.operatingColorSpace());
+    if (!sourcePixelBuffer)
+        return false;
+
+    auto& sourcePixelArray = sourcePixelBuffer->data();
+    auto& destinationPixelArray = destinationPixelBuffer->data();
+    
+    auto paintSize = m_effect.absolutePaintRect().size();
+
+    PaintingData paintingData = {
+        sourcePixelArray,
+        destinationPixelArray,
+        paintSize.width(),
+        paintSize.height(),
+        m_effect.kernelSize(),
+        m_effect.divisor(),
+        m_effect.bias() * 255,
+        m_effect.targetOffset(),
+        m_effect.edgeMode(),
+        m_effect.preserveAlpha(),
+        FEColorMatrix::normalizedFloats(m_effect.kernel())
+    };
+
+    applyPlatform(paintingData);
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEConvolveMatrixSoftwareApplierh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.h (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEConvolveMatrixSoftwareApplier.h   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FEConvolveMatrix;
+enum class EdgeModeType;
+
+class FEConvolveMatrixSoftwareApplier : public FilterEffectConcreteApplier<FEConvolveMatrix> {
+    using Base = FilterEffectConcreteApplier<FEConvolveMatrix>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    struct PaintingData {
+        const Uint8ClampedArray& srcPixelArray;
+        Uint8ClampedArray& dstPixelArray;
+        int width;
+        int height;
+
+        IntSize kernelSize;
+        float divisor;
+        float bias;
+        IntPoint targetOffset;
+        EdgeModeType edgeMode;
+        bool preserveAlpha;
+        Vector<float> kernelMatrix;
+    };
+
+    static inline uint8_t clampRGBAValue(float channel, uint8_t max = 255);
+    static inline void setDestinationPixels(const Uint8ClampedArray& sourcePixels, Uint8ClampedArray& destPixels, int& pixel, float* totals, float divisor, float bias, bool preserveAlphaValues);
+
+    static inline int getPixelValue(const PaintingData&, int x, int y);
+
+    static inline void setInteriorPixels(PaintingData&, int clipRight, int clipBottom, int yStart, int yEnd);
+    static inline void setOuterPixels(PaintingData&, int x1, int y1, int x2, int y2);
+
+    void applyPlatform(PaintingData&) const;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDisplacementMapSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEDisplacementMapcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.cpp                             (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.cpp        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,112 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEDisplacementMapSoftwareApplier.h"
+
+#include "FEDisplacementMap.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "PixelBuffer.h"
+
+namespace WebCore {
+
+FEDisplacementMapSoftwareApplier::FEDisplacementMapSoftwareApplier(FEDisplacementMap& effect)
+    : Base(effect)
+{
+    ASSERT(m_effect.xChannelSelector() != CHANNEL_UNKNOWN);
+    ASSERT(m_effect.yChannelSelector() != CHANNEL_UNKNOWN);
+}
+
+int FEDisplacementMapSoftwareApplier::xChannelIndex() const
+{
+    return m_effect.xChannelSelector() - 1;
+}
+
+int FEDisplacementMapSoftwareApplier::yChannelIndex() const
+{
+    return m_effect.yChannelSelector() - 1;
+}
+
+bool FEDisplacementMapSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+    FilterEffect* in2 = inputEffects[1].get();
+
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
+    if (!destinationPixelBuffer)
+        return false;
+
+    auto& destinationPixelArray = destinationPixelBuffer->data();
+
+    auto effectADrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
+    auto inputPixelBuffer = in->getPixelBufferResult(AlphaPremultiplication::Premultiplied, effectADrawingRect);
+
+    auto effectBDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in2->absolutePaintRect());
+    // The calculations using the pixel values from ‘in2’ are performed using non-premultiplied color values.
+    auto displacementPixelBuffer = in2->getPixelBufferResult(AlphaPremultiplication::Unpremultiplied, effectBDrawingRect);
+    
+    if (!inputPixelBuffer || !displacementPixelBuffer)
+        return false;
+
+    auto& inputImage = inputPixelBuffer->data();
+    auto& displacementImage = displacementPixelBuffer->data();
+    ASSERT(inputImage.length() == displacementImage.length());
+
+    IntSize paintSize = m_effect.absolutePaintRect().size();
+
+    FloatSize scale = filter.scaledByFilterScale({ m_effect.scale(), m_effect.scale() });
+    float scaleForColorX = scale.width() / 255.0;
+    float scaleForColorY = scale.height() / 255.0;
+    float scaledOffsetX = 0.5 - scale.width() * 0.5;
+    float scaledOffsetY = 0.5 - scale.height() * 0.5;
+    
+    int displacementChannelX = xChannelIndex();
+    int displacementChannelY = yChannelIndex();
+
+    int rowBytes = paintSize.width() * 4;
+
+    for (int y = 0; y < paintSize.height(); ++y) {
+        int lineStartOffset = y * rowBytes;
+
+        for (int x = 0; x < paintSize.width(); ++x) {
+            int destinationIndex = lineStartOffset + x * 4;
+            
+            int srcX = x + static_cast<int>(scaleForColorX * displacementImage.item(destinationIndex + displacementChannelX) + scaledOffsetX);
+            int srcY = y + static_cast<int>(scaleForColorY * displacementImage.item(destinationIndex + displacementChannelY) + scaledOffsetY);
+
+            unsigned* destinationPixelPtr = reinterpret_cast<unsigned*>(destinationPixelArray.data() + destinationIndex);
+            if (srcX < 0 || srcX >= paintSize.width() || srcY < 0 || srcY >= paintSize.height()) {
+                *destinationPixelPtr = 0;
+                continue;
+            }
+
+            *destinationPixelPtr = *reinterpret_cast<unsigned*>(inputImage.data() + byteOffsetOfPixel(srcX, srcY, rowBytes));
+        }
+    }
+
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDisplacementMapSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEOffseth"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEOffset.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.h                               (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEDisplacementMapSoftwareApplier.h  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEDisplacementMap;
+
+class FEDisplacementMapSoftwareApplier : public FilterEffectConcreteApplier<FEDisplacementMap> {
+    using Base = FilterEffectConcreteApplier<FEDisplacementMap>;
+
+public:
+    FEDisplacementMapSoftwareApplier(FEDisplacementMap&);
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    static inline unsigned byteOffsetOfPixel(unsigned x, unsigned y, unsigned rowBytes)
+    {
+        const unsigned bytesPerPixel = 4;
+        return x * bytesPerPixel + y * rowBytes;
+    }
+
+    int xChannelIndex() const;
+    int yChannelIndex() const;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDropShadowSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEDropShadowcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.cpp                          (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.cpp     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/*
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEDropShadowSoftwareApplier.h"
+
+#include "FEDropShadow.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "PixelBuffer.h"
+#include "ShadowBlur.h"
+
+namespace WebCore {
+
+bool FEDropShadowSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto resultImage = m_effect.imageBufferResult();
+    if (!resultImage)
+        return false;
+
+    FloatSize blurRadius = 2 * filter.scaledByFilterScale({ m_effect.stdDeviationX(), m_effect.stdDeviationY() });
+    FloatSize offset = filter.scaledByFilterScale({ m_effect.dx(), m_effect.dy() });
+
+    FloatRect drawingRegion = m_effect.drawingRegionOfInputImage(in->absolutePaintRect());
+    FloatRect drawingRegionWithOffset(drawingRegion);
+    drawingRegionWithOffset.move(offset);
+
+    auto sourceImage = in->imageBufferResult();
+    if (!sourceImage)
+        return false;
+
+    GraphicsContext& resultContext = resultImage->context();
+    resultContext.setAlpha(m_effect.shadowOpacity());
+    resultContext.drawImageBuffer(*sourceImage, drawingRegionWithOffset);
+    resultContext.setAlpha(1);
+
+    ShadowBlur contextShadow(blurRadius, offset, m_effect.shadowColor());
+
+    PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, m_effect.resultColorSpace() };
+    IntRect shadowArea(IntPoint(), resultImage->truncatedLogicalSize());
+    auto pixelBuffer = resultImage->getPixelBuffer(format, shadowArea);
+    if (!pixelBuffer)
+        return false;
+
+    auto& sourcePixelArray = pixelBuffer->data();
+    contextShadow.blurLayerImage(sourcePixelArray.data(), pixelBuffer->size(), 4 * pixelBuffer->size().width());
+    
+    resultImage->putPixelBuffer(*pixelBuffer, shadowArea);
+
+    resultContext.setCompositeOperation(CompositeOperator::SourceIn);
+    resultContext.fillRect(FloatRect(FloatPoint(), m_effect.absolutePaintRect().size()), m_effect.shadowColor());
+    resultContext.setCompositeOperation(CompositeOperator::DestinationOver);
+
+    resultImage->context().drawImageBuffer(*sourceImage, drawingRegion);
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEDropShadowSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.h                            (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEDropShadowSoftwareApplier.h       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+/*
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEDropShadow;
+
+class FEDropShadowSoftwareApplier : public FilterEffectConcreteApplier<FEDropShadow> {
+    using Base = FilterEffectConcreteApplier<FEDropShadow>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEFloodSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFETileh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FETile.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.cpp                               (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.cpp  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEFloodSoftwareApplier.h"
+
+#include "FEFlood.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+
+namespace WebCore {
+
+bool FEFloodSoftwareApplier::apply(const Filter&, const FilterEffectVector&)
+{
+    auto resultImage = m_effect.imageBufferResult();
+    if (!resultImage)
+        return false;
+
+    auto color = m_effect.floodColor().colorWithAlphaMultipliedBy(m_effect.floodOpacity());
+    resultImage->context().fillRect(FloatRect(FloatPoint(), m_effect.absolutePaintRect().size()), color);
+
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEFloodSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.h                         (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEFloodSoftwareApplier.h    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEFlood;
+
+class FEFloodSoftwareApplier : public FilterEffectConcreteApplier<FEFlood> {
+    using Base = FilterEffectConcreteApplier<FEFlood>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEGaussianBlurSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEGaussianBlurcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.cpp   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,455 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Igalia, S.L.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2015-2021 Apple, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEGaussianBlurSoftwareApplier.h"
+
+#include "FEGaussianBlur.h"
+#include "GraphicsContext.h"
+#include "PixelBuffer.h"
+#include <wtf/MathExtras.h>
+
+#if USE(ACCELERATE)
+#include <Accelerate/Accelerate.h>
+#else
+#include <JavaScriptCore/TypedArrayInlines.h>
+#include <wtf/ParallelJobs.h>
+#endif
+
+namespace WebCore {
+
+inline void FEGaussianBlurSoftwareApplier::kernelPosition(int blurIteration, unsigned& radius, int& deltaLeft, int& deltaRight)
+{
+    // Check http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement for details.
+    switch (blurIteration) {
+    case 0:
+        if (!(radius % 2)) {
+            deltaLeft = radius / 2 - 1;
+            deltaRight = radius - deltaLeft;
+        } else {
+            deltaLeft = radius / 2;
+            deltaRight = radius - deltaLeft;
+        }
+        break;
+    case 1:
+        if (!(radius % 2)) {
+            deltaLeft++;
+            deltaRight--;
+        }
+        break;
+    case 2:
+        if (!(radius % 2)) {
+            deltaRight++;
+            radius++;
+        }
+        break;
+    }
+}
+
+// This function only operates on Alpha channel.
+inline void FEGaussianBlurSoftwareApplier::boxBlurAlphaOnly(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int& dxLeft, int& dxRight, int& stride, int& strideLine, int& effectWidth, int& effectHeight, const int& maxKernelSize)
+{
+    const uint8_t* srcData = srcPixelArray.data();
+    uint8_t* dstData = dstPixelArray.data();
+    // Memory alignment is: RGBA, zero-index based.
+    const int channel = 3;
+
+    for (int y = 0; y < effectHeight; ++y) {
+        int line = y * strideLine;
+        int sum = 0;
+
+        // Fill the kernel.
+        for (int i = 0; i < maxKernelSize; ++i) {
+            unsigned offset = line + i * stride;
+            const uint8_t* srcPtr = srcData + offset;
+            sum += srcPtr[channel];
+        }
+
+        // Blurring.
+        for (int x = 0; x < effectWidth; ++x) {
+            unsigned pixelByteOffset = line + x * stride + channel;
+            uint8_t* dstPtr = dstData + pixelByteOffset;
+            *dstPtr = static_cast<uint8_t>(sum / dx);
+
+            // Shift kernel.
+            if (x >= dxLeft) {
+                unsigned leftOffset = pixelByteOffset - dxLeft * stride;
+                const uint8_t* srcPtr = srcData + leftOffset;
+                sum -= *srcPtr;
+            }
+
+            if (x + dxRight < effectWidth) {
+                unsigned rightOffset = pixelByteOffset + dxRight * stride;
+                const uint8_t* srcPtr = srcData + rightOffset;
+                sum += *srcPtr;
+            }
+        }
+    }
+}
+
+inline void FEGaussianBlurSoftwareApplier::boxBlur(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage, EdgeModeType edgeMode)
+{
+    const int maxKernelSize = std::min(dxRight, effectWidth);
+    if (alphaImage)
+        return boxBlurAlphaOnly(srcPixelArray, dstPixelArray, dx, dxLeft, dxRight, stride, strideLine,  effectWidth, effectHeight, maxKernelSize);
+
+    const uint8_t* srcData = srcPixelArray.data();
+    uint8_t* dstData = dstPixelArray.data();
+
+    // Concerning the array width/length: it is Element size + Margin + Border. The number of pixels will be
+    // P = width * height * channels.
+    for (int y = 0; y < effectHeight; ++y) {
+        int line = y * strideLine;
+        int sumR = 0, sumG = 0, sumB = 0, sumA = 0;
+
+        if (edgeMode == EdgeModeType::None) {
+            // Fill the kernel.
+            for (int i = 0; i < maxKernelSize; ++i) {
+                unsigned offset = line + i * stride;
+                const uint8_t* srcPtr = srcData + offset;
+                sumR += *srcPtr++;
+                sumG += *srcPtr++;
+                sumB += *srcPtr++;
+                sumA += *srcPtr;
+            }
+
+            // Blurring.
+            for (int x = 0; x < effectWidth; ++x) {
+                unsigned pixelByteOffset = line + x * stride;
+                uint8_t* dstPtr = dstData + pixelByteOffset;
+
+                *dstPtr++ = static_cast<uint8_t>(sumR / dx);
+                *dstPtr++ = static_cast<uint8_t>(sumG / dx);
+                *dstPtr++ = static_cast<uint8_t>(sumB / dx);
+                *dstPtr = static_cast<uint8_t>(sumA / dx);
+
+                // Shift kernel.
+                if (x >= dxLeft) {
+                    unsigned leftOffset = pixelByteOffset - dxLeft * stride;
+                    const uint8_t* srcPtr = srcData + leftOffset;
+                    sumR -= srcPtr[0];
+                    sumG -= srcPtr[1];
+                    sumB -= srcPtr[2];
+                    sumA -= srcPtr[3];
+                }
+
+                if (x + dxRight < effectWidth) {
+                    unsigned rightOffset = pixelByteOffset + dxRight * stride;
+                    const uint8_t* srcPtr = srcData + rightOffset;
+                    sumR += srcPtr[0];
+                    sumG += srcPtr[1];
+                    sumB += srcPtr[2];
+                    sumA += srcPtr[3];
+                }
+            }
+
+        } else {
+            // FIXME: Add support for 'wrap' here.
+            // Get edge values for edgeMode 'duplicate'.
+            const uint8_t* edgeValueLeft = srcData + line;
+            const uint8_t* edgeValueRight  = srcData + (line + (effectWidth - 1) * stride);
+
+            // Fill the kernel.
+            for (int i = dxLeft * -1; i < dxRight; ++i) {
+                // Is this right for negative values of 'i'?
+                unsigned offset = line + i * stride;
+                const uint8_t* srcPtr = srcData + offset;
+
+                if (i < 0) {
+                    sumR += edgeValueLeft[0];
+                    sumG += edgeValueLeft[1];
+                    sumB += edgeValueLeft[2];
+                    sumA += edgeValueLeft[3];
+                } else if (i >= effectWidth) {
+                    sumR += edgeValueRight[0];
+                    sumG += edgeValueRight[1];
+                    sumB += edgeValueRight[2];
+                    sumA += edgeValueRight[3];
+                } else {
+                    sumR += *srcPtr++;
+                    sumG += *srcPtr++;
+                    sumB += *srcPtr++;
+                    sumA += *srcPtr;
+                }
+            }
+
+            // Blurring.
+            for (int x = 0; x < effectWidth; ++x) {
+                unsigned pixelByteOffset = line + x * stride;
+                uint8_t* dstPtr = dstData + pixelByteOffset;
+
+                *dstPtr++ = static_cast<uint8_t>(sumR / dx);
+                *dstPtr++ = static_cast<uint8_t>(sumG / dx);
+                *dstPtr++ = static_cast<uint8_t>(sumB / dx);
+                *dstPtr = static_cast<uint8_t>(sumA / dx);
+
+                // Shift kernel.
+                if (x < dxLeft) {
+                    sumR -= edgeValueLeft[0];
+                    sumG -= edgeValueLeft[1];
+                    sumB -= edgeValueLeft[2];
+                    sumA -= edgeValueLeft[3];
+                } else {
+                    unsigned leftOffset = pixelByteOffset - dxLeft * stride;
+                    const uint8_t* srcPtr = srcData + leftOffset;
+                    sumR -= srcPtr[0];
+                    sumG -= srcPtr[1];
+                    sumB -= srcPtr[2];
+                    sumA -= srcPtr[3];
+                }
+
+                if (x + dxRight >= effectWidth) {
+                    sumR += edgeValueRight[0];
+                    sumG += edgeValueRight[1];
+                    sumB += edgeValueRight[2];
+                    sumA += edgeValueRight[3];
+                } else {
+                    unsigned rightOffset = pixelByteOffset + dxRight * stride;
+                    const uint8_t* srcPtr = srcData + rightOffset;
+                    sumR += srcPtr[0];
+                    sumG += srcPtr[1];
+                    sumB += srcPtr[2];
+                    sumA += srcPtr[3];
+                }
+            }
+        }
+    }
+}
+
+#if USE(ACCELERATE)
+inline void FEGaussianBlurSoftwareApplier::boxBlurAccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSize, int stride, int effectWidth, int effectHeight)
+{
+    if (!ioBuffer.data() || !tempBuffer.data()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    if (effectWidth <= 0 || effectHeight <= 0 || stride <= 0) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    // We must always use an odd radius.
+    if (kernelSize % 2 != 1)
+        kernelSize += 1;
+
+    vImage_Buffer effectInBuffer;
+    effectInBuffer.data = static_cast<void*>(ioBuffer.data());
+    effectInBuffer.width = effectWidth;
+    effectInBuffer.height = effectHeight;
+    effectInBuffer.rowBytes = stride;
+
+    vImage_Buffer effectOutBuffer;
+    effectOutBuffer.data = tempBuffer.data();
+    effectOutBuffer.width = effectWidth;
+    effectOutBuffer.height = effectHeight;
+    effectOutBuffer.rowBytes = stride;
+
+    // Determine the size of a temporary buffer by calling the function first with a special flag. vImage will return
+    // the size needed, or an error (which are all negative).
+    size_t tmpBufferSize = vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, 0, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend | kvImageGetTempBufferSize);
+    if (tmpBufferSize <= 0)
+        return;
+
+    void* tmpBuffer = fastMalloc(tmpBufferSize);
+    vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, tmpBuffer, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend);
+    vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, tmpBuffer, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend);
+    vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, tmpBuffer, 0, 0, kernelSize, kernelSize, 0, kvImageEdgeExtend);
+    fastFree(tmpBuffer);
+
+    // The final result should be stored in ioBuffer.
+    ASSERT(ioBuffer.length() == tempBuffer.length());
+    memcpy(ioBuffer.data(), tempBuffer.data(), ioBuffer.length());
+}
+#endif
+
+inline void FEGaussianBlurSoftwareApplier::boxBlurUnaccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSizeX, unsigned kernelSizeY, int stride, IntSize& paintSize, bool isAlphaImage, EdgeModeType edgeMode)
+{
+    int dxLeft = 0;
+    int dxRight = 0;
+    int dyLeft = 0;
+    int dyRight = 0;
+    
+    Uint8ClampedArray* fromBuffer = &ioBuffer;
+    Uint8ClampedArray* toBuffer = &tempBuffer;
+
+    for (int i = 0; i < 3; ++i) {
+        if (kernelSizeX) {
+            kernelPosition(i, kernelSizeX, dxLeft, dxRight);
+#if HAVE(ARM_NEON_INTRINSICS)
+            if (!isAlphaImage)
+                boxBlurNEON(*fromBuffer, *toBuffer, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height());
+            else
+                boxBlur(*fromBuffer, *toBuffer, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), true, edgeMode);
+#else
+            boxBlur(*fromBuffer, *toBuffer, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), isAlphaImage, edgeMode);
+#endif
+            std::swap(fromBuffer, toBuffer);
+        }
+
+        if (kernelSizeY) {
+            kernelPosition(i, kernelSizeY, dyLeft, dyRight);
+#if HAVE(ARM_NEON_INTRINSICS)
+            if (!isAlphaImage)
+                boxBlurNEON(*fromBuffer, *toBuffer, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width());
+            else
+                boxBlur(*fromBuffer, *toBuffer, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), true, edgeMode);
+#else
+            boxBlur(*fromBuffer, *toBuffer, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), isAlphaImage, edgeMode);
+#endif
+            std::swap(fromBuffer, toBuffer);
+        }
+    }
+
+    // The final result should be stored in ioBuffer.
+    if (&ioBuffer != fromBuffer) {
+        ASSERT(ioBuffer.length() == fromBuffer->length());
+        memcpy(ioBuffer.data(), fromBuffer->data(), ioBuffer.length());
+    }
+}
+
+inline void FEGaussianBlurSoftwareApplier::boxBlurGeneric(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType edgeMode)
+{
+    int stride = 4 * paintSize.width();
+
+#if USE(ACCELERATE)
+    if (kernelSizeX == kernelSizeY && (edgeMode == EdgeModeType::None || edgeMode == EdgeModeType::Duplicate)) {
+        boxBlurAccelerated(ioBuffer, tmpPixelArray, kernelSizeX, stride, paintSize.width(), paintSize.height());
+        return;
+    }
+#endif
+
+    boxBlurUnaccelerated(ioBuffer, tmpPixelArray, kernelSizeX, kernelSizeY, stride, paintSize, isAlphaImage, edgeMode);
+}
+
+#if !USE(ACCELERATE)
+inline void FEGaussianBlurSoftwareApplier::boxBlurWorker(ApplyParameters* parameters)
+{
+    IntSize paintSize(parameters->width, parameters->height);
+    boxBlurGeneric(*parameters->ioPixelArray, *parameters->tmpPixelArray, parameters->kernelSizeX, parameters->kernelSizeY, paintSize, parameters->isAlphaImage, parameters->edgeMode);
+}
+#endif
+
+inline void FEGaussianBlurSoftwareApplier::applyPlatform(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType edgeMode)
+{
+#if !USE(ACCELERATE)
+    int scanline = 4 * paintSize.width();
+    int extraHeight = 3 * kernelSizeY * 0.5f;
+
+    static constexpr int minimalRectDimension = 100 * 100; // Empirical data limit for parallel jobs
+    int optimalThreadNumber = (paintSize.width() * paintSize.height()) / (minimalRectDimension + extraHeight * paintSize.width());
+
+    if (optimalThreadNumber > 1) {
+        ParallelJobs<ApplyParameters> parallelJobs(&boxBlurWorker, optimalThreadNumber);
+
+        int jobs = parallelJobs.numberOfJobs();
+        if (jobs > 1) {
+            // Split the job into "blockHeight"-sized jobs but there a few jobs that need to be slightly larger since
+            // blockHeight * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
+            const int blockHeight = paintSize.height() / jobs;
+            const int jobsWithExtra = paintSize.height() % jobs;
+
+            int currentY = 0;
+            for (int job = 0; job < jobs; job++) {
+                ApplyParameters& params = parallelJobs.parameter(job);
+
+                int startY = !job ? 0 : currentY - extraHeight;
+                currentY += job < jobsWithExtra ? blockHeight + 1 : blockHeight;
+                int endY = job == jobs - 1 ? currentY : currentY + extraHeight;
+
+                int blockSize = (endY - startY) * scanline;
+                if (!job) {
+                    params.ioPixelArray = &ioBuffer;
+                    params.tmpPixelArray = &tmpPixelArray;
+                } else {
+                    params.ioPixelArray = Uint8ClampedArray::createUninitialized(blockSize);
+                    params.tmpPixelArray = Uint8ClampedArray::createUninitialized(blockSize);
+                    memcpy(params.ioPixelArray->data(), ioBuffer.data() + startY * scanline, blockSize);
+                }
+
+                params.width = paintSize.width();
+                params.height = endY - startY;
+                params.kernelSizeX = kernelSizeX;
+                params.kernelSizeY = kernelSizeY;
+                params.isAlphaImage = isAlphaImage;
+                params.edgeMode = edgeMode;
+            }
+
+            parallelJobs.execute();
+
+            // Copy together the parts of the image.
+            currentY = 0;
+            for (int job = 1; job < jobs; job++) {
+                ApplyParameters& params = parallelJobs.parameter(job);
+                int sourceOffset;
+                int destinationOffset;
+                int size;
+                int adjustedBlockHeight = job < jobsWithExtra ? blockHeight + 1 : blockHeight;
+
+                currentY += adjustedBlockHeight;
+                sourceOffset = extraHeight * scanline;
+                destinationOffset = currentY * scanline;
+                size = adjustedBlockHeight * scanline;
+
+                memcpy(ioBuffer.data() + destinationOffset, params.ioPixelArray->data() + sourceOffset, size);
+            }
+            return;
+        }
+        // Fallback to single threaded mode.
+    }
+#endif
+
+    // The selection here eventually should happen dynamically on some platforms.
+    boxBlurGeneric(ioBuffer, tmpPixelArray, kernelSizeX, kernelSizeY, paintSize, isAlphaImage, edgeMode);
+}
+
+bool FEGaussianBlurSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
+    if (!destinationPixelBuffer)
+        return false;
+
+    m_effect.setIsAlphaImage(in->isAlphaImage());
+
+    auto effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
+    in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
+    if (!m_effect.stdDeviationX() && !m_effect.stdDeviationY())
+        return true;
+
+    auto kernelSize = m_effect.calculateKernelSize(filter, { m_effect.stdDeviationX(), m_effect.stdDeviationY() });
+
+    IntSize paintSize = m_effect.absolutePaintRect().size();
+    auto tmpImageData = Uint8ClampedArray::tryCreateUninitialized(paintSize.area() * 4);
+    if (!tmpImageData)
+        return false;
+
+    auto& destinationPixelArray = destinationPixelBuffer->data();
+    applyPlatform(destinationPixelArray, *tmpImageData, kernelSize.width(), kernelSize.height(), paintSize, m_effect.isAlphaImage(), m_effect.edgeMode());
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEGaussianBlurSoftwareApplierh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.h (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.h                          (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEGaussianBlurSoftwareApplier.h     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2015-2021 Apple, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+#include <JavaScriptCore/Forward.h>
+
+namespace WebCore {
+
+class FEGaussianBlur;
+enum class EdgeModeType;
+
+class FEGaussianBlurSoftwareApplier : public FilterEffectConcreteApplier<FEGaussianBlur> {
+    using Base = FilterEffectConcreteApplier<FEGaussianBlur>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    struct ApplyParameters {
+        RefPtr<Uint8ClampedArray> ioPixelArray;
+        RefPtr<Uint8ClampedArray> tmpPixelArray;
+        int width;
+        int height;
+        unsigned kernelSizeX;
+        unsigned kernelSizeY;
+        bool isAlphaImage;
+        EdgeModeType edgeMode;
+    };
+
+    static inline void kernelPosition(int blurIteration, unsigned& radius, int& deltaLeft, int& deltaRight);
+
+    static inline void boxBlurAlphaOnly(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int& dxLeft, int& dxRight, int& stride, int& strideLine, int& effectWidth, int& effectHeight, const int& maxKernelSize);
+    static inline void boxBlur(const Uint8ClampedArray& srcPixelArray, Uint8ClampedArray& dstPixelArray, unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage, EdgeModeType);
+
+    static inline void boxBlurAccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSize, int stride, int effectWidth, int effectHeight);
+    static inline void boxBlurUnaccelerated(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tempBuffer, unsigned kernelSizeX, unsigned kernelSizeY, int stride, IntSize& paintSize, bool isAlphaImage, EdgeModeType);
+
+    static inline void boxBlurGeneric(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType);
+    static inline void boxBlurWorker(ApplyParameters*);
+
+    static inline void applyPlatform(Uint8ClampedArray& ioBuffer, Uint8ClampedArray& tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize, bool isAlphaImage, EdgeModeType);
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFELightingSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFELightingcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.cpp                            (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.cpp       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,441 @@
</span><ins>+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ * Copyright (C) 2018-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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED 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 "FELightingSoftwareApplier.h"
+
+#include "FELighting.h"
+#include "ImageBuffer.h"
+#include "PixelBuffer.h"
+#include <wtf/ParallelJobs.h>
+
+namespace WebCore {
+
+inline IntSize FELightingSoftwareApplier::LightingData::topLeftNormal(int offset) const
+{
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    offset += widthMultipliedByPixelSize;
+    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int bottomRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    return {
+        -2 * center + 2 * right - bottom + bottomRight,
+        -2 * center - right + 2 * bottom + bottomRight
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::topRowNormal(int offset) const
+{
+    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    offset += widthMultipliedByPixelSize;
+    int bottomLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int bottomRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    return {
+        -2 * left + 2 * right - bottomLeft + bottomRight,
+        -left - 2 * center - right + bottomLeft + 2 * bottom + bottomRight
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::topRightNormal(int offset) const
+{
+    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    offset += widthMultipliedByPixelSize;
+    int bottomLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    return {
+        -2 * left + 2 * center - bottomLeft + bottom,
+        -left - 2 * center + bottomLeft + 2 * bottom
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::leftColumnNormal(int offset) const
+{
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    offset -= widthMultipliedByPixelSize;
+    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int topRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    offset += 2 * widthMultipliedByPixelSize;
+    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int bottomRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    return {
+        -top + topRight - 2 * center + 2 * right - bottom + bottomRight,
+        -2 * top - topRight + 2 * bottom + bottomRight
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::interiorNormal(int offset, AlphaWindow& alphaWindow) const
+{
+    int rightAlphaOffset = offset + cPixelSize + cAlphaChannelOffset;
+    
+    int right = static_cast<int>(pixels->item(rightAlphaOffset));
+    int topRight = static_cast<int>(pixels->item(rightAlphaOffset - widthMultipliedByPixelSize));
+    int bottomRight = static_cast<int>(pixels->item(rightAlphaOffset + widthMultipliedByPixelSize));
+
+    int left = alphaWindow.left();
+    int topLeft = alphaWindow.topLeft();
+    int top = alphaWindow.top();
+
+    int bottomLeft = alphaWindow.bottomLeft();
+    int bottom = alphaWindow.bottom();
+
+    // The alphaWindow has been shifted, and here we fill in the right column.
+    alphaWindow.alpha[0][2] = topRight;
+    alphaWindow.alpha[1][2] = right;
+    alphaWindow.alpha[2][2] = bottomRight;
+    
+    // Check that the alphaWindow is working with some spot-checks.
+    ASSERT(alphaWindow.topLeft() == pixels->item(offset - cPixelSize - widthMultipliedByPixelSize + cAlphaChannelOffset)); // topLeft
+    ASSERT(alphaWindow.top() == pixels->item(offset - widthMultipliedByPixelSize + cAlphaChannelOffset)); // top
+
+    return {
+        -topLeft + topRight - 2 * left + 2 * right - bottomLeft + bottomRight,
+        -topLeft - 2 * top - topRight + bottomLeft + 2 * bottom + bottomRight
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::rightColumnNormal(int offset) const
+{
+    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    offset -= widthMultipliedByPixelSize;
+    int topLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    offset += 2 * widthMultipliedByPixelSize;
+    int bottomLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int bottom = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    return {
+        -topLeft + top - 2 * left + 2 * center - bottomLeft + bottom,
+        -topLeft - 2 * top + bottomLeft + 2 * bottom
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::bottomLeftNormal(int offset) const
+{
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    offset -= widthMultipliedByPixelSize;
+    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int topRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    return {
+        -top + topRight - 2 * center + 2 * right,
+        -2 * top - topRight + 2 * center + right
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::bottomRowNormal(int offset) const
+{
+    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int right = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    offset -= widthMultipliedByPixelSize;
+    int topLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    int topRight = static_cast<int>(pixels->item(offset + cPixelSize + cAlphaChannelOffset));
+    return {
+        -topLeft + topRight - 2 * left + 2 * right,
+        -topLeft - 2 * top - topRight + left + 2 * center + right
+    };
+}
+
+inline IntSize FELightingSoftwareApplier::LightingData::bottomRightNormal(int offset) const
+{
+    int left = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int center = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    offset -= widthMultipliedByPixelSize;
+    int topLeft = static_cast<int>(pixels->item(offset - cPixelSize + cAlphaChannelOffset));
+    int top = static_cast<int>(pixels->item(offset + cAlphaChannelOffset));
+    return {
+        -topLeft + top - 2 * left + 2 * center,
+        -topLeft - 2 * top + left + 2 * center
+    };
+}
+
+void FELightingSoftwareApplier::setPixelInternal(int offset, const LightingData& data, const LightSource::PaintingData& paintingData, int x, int y, float factorX, float factorY, IntSize normal2DVector, float alpha)
+{
+    float z = alpha * data.surfaceScale;
+    LightSource::ComputedLightingData lightingData = data.lightSource->computePixelLightingData(paintingData, x, y, z);
+
+    float lightStrength;
+    if (normal2DVector.isZero()) {
+        // Normal vector is (0, 0, 1). This is a quite frequent case.
+        if (data.effect->filterType() == FilterEffect::Type::FEDiffuseLighting)
+            lightStrength = data.diffuseConstant * lightingData.lightVector.z() / lightingData.lightVectorLength;
+        else {
+            FloatPoint3D halfwayVector = {
+                lightingData.lightVector.x(),
+                lightingData.lightVector.y(),
+                lightingData.lightVector.z() + lightingData.lightVectorLength
+            };
+            float halfwayVectorLength = halfwayVector.length();
+            if (data.specularExponent == 1)
+                lightStrength = data.specularConstant * halfwayVector.z() / halfwayVectorLength;
+            else
+                lightStrength = data.specularConstant * powf(halfwayVector.z() / halfwayVectorLength, data.specularExponent);
+        }
+    } else {
+        FloatPoint3D normalVector = {
+            factorX * normal2DVector.width() * data.surfaceScale,
+            factorY * normal2DVector.height() * data.surfaceScale,
+            1.0f
+        };
+        float normalVectorLength = normalVector.length();
+
+        if (data.effect->filterType() == FilterEffect::Type::FEDiffuseLighting)
+            lightStrength = data.diffuseConstant * (normalVector * lightingData.lightVector) / (normalVectorLength * lightingData.lightVectorLength);
+        else {
+            FloatPoint3D halfwayVector = {
+                lightingData.lightVector.x(),
+                lightingData.lightVector.y(),
+                lightingData.lightVector.z() + lightingData.lightVectorLength
+            };
+            float halfwayVectorLength = halfwayVector.length();
+            if (data.specularExponent == 1)
+                lightStrength = data.specularConstant * (normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength);
+            else
+                lightStrength = data.specularConstant * powf((normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength), data.specularExponent);
+        }
+    }
+
+    if (lightStrength > 1)
+        lightStrength = 1;
+    if (lightStrength < 0)
+        lightStrength = 0;
+
+    uint8_t pixelValue[3] = {
+        static_cast<uint8_t>(lightStrength * lightingData.colorVector.x() * 255.0f),
+        static_cast<uint8_t>(lightStrength * lightingData.colorVector.y() * 255.0f),
+        static_cast<uint8_t>(lightStrength * lightingData.colorVector.z() * 255.0f)
+    };
+    
+    data.pixels->setRange(pixelValue, 3, offset);
+}
+
+void FELightingSoftwareApplier::setPixel(int offset, const LightingData& data, const LightSource::PaintingData& paintingData, int x, int y, float factorX, float factorY, IntSize normal2DVector)
+{
+    setPixelInternal(offset, data, paintingData, x, y, factorX, factorY, normal2DVector, data.pixels->item(offset + cAlphaChannelOffset));
+}
+
+// This appears to read from and write to the same pixel buffer, but it only reads the alpha channel, and writes the non-alpha channels.
+void FELightingSoftwareApplier::applyPlatformGenericPaint(const LightingData& data, const LightSource::PaintingData& paintingData, int startY, int endY)
+{
+    // Make sure startY is > 0 since we read from the previous row in the loop.
+    ASSERT(startY);
+    ASSERT(endY > startY);
+
+    for (int y = startY; y < endY; ++y) {
+        int rowStartOffset = y * data.widthMultipliedByPixelSize;
+        int previousRowStart = rowStartOffset - data.widthMultipliedByPixelSize;
+        int nextRowStart = rowStartOffset + data.widthMultipliedByPixelSize;
+
+        // alphaWindow is a local cache of alpha values.
+        // Fill the two right columns putting the left edge value in the center column.
+        // For each pixel, we shift each row left then fill the right column.
+        AlphaWindow alphaWindow;
+        alphaWindow.setTop(data.pixels->item(previousRowStart + cAlphaChannelOffset));
+        alphaWindow.setTopRight(data.pixels->item(previousRowStart + cPixelSize + cAlphaChannelOffset));
+
+        alphaWindow.setCenter(data.pixels->item(rowStartOffset + cAlphaChannelOffset));
+        alphaWindow.setRight(data.pixels->item(rowStartOffset + cPixelSize + cAlphaChannelOffset));
+
+        alphaWindow.setBottom(data.pixels->item(nextRowStart + cAlphaChannelOffset));
+        alphaWindow.setBottomRight(data.pixels->item(nextRowStart + cPixelSize + cAlphaChannelOffset));
+
+        int offset = rowStartOffset + cPixelSize;
+        for (int x = 1; x < data.width - 1; ++x, offset += cPixelSize) {
+            alphaWindow.shift();
+            setPixelInternal(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, data.interiorNormal(offset, alphaWindow), alphaWindow.center());
+        }
+    }
+}
+
+void FELightingSoftwareApplier::applyPlatformGenericWorker(ApplyParameters* parameters)
+{
+    applyPlatformGenericPaint(parameters->data, parameters->paintingData, parameters->yStart, parameters->yEnd);
+}
+
+#if !(CPU(ARM_NEON) && CPU(ARM_TRADITIONAL) && COMPILER(GCC_COMPATIBLE))
+void FELightingSoftwareApplier::applyPlatformGeneric(const LightingData& data, const LightSource::PaintingData& paintingData)
+{
+    unsigned rowsToProcess = data.height - 2;
+    unsigned maxNumThreads = rowsToProcess / 8;
+    
+    static constexpr int minimalRectDimension = 100 * 100; // Empirical data limit for parallel jobs
+    unsigned optimalThreadNumber = std::min<unsigned>(((data.width - 2) * rowsToProcess) / minimalRectDimension, maxNumThreads);
+
+    if (optimalThreadNumber > 1) {
+        // Initialize parallel jobs
+        ParallelJobs<ApplyParameters> parallelJobs(&applyPlatformGenericWorker, optimalThreadNumber);
+
+        // Fill the parameter array
+        int job = parallelJobs.numberOfJobs();
+        if (job > 1) {
+            // Split the job into "yStep"-sized jobs but there a few jobs that need to be slightly larger since
+            // yStep * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
+            const int yStep = rowsToProcess / job;
+            const int jobsWithExtra = rowsToProcess % job;
+
+            int yStart = 1;
+            for (--job; job >= 0; --job) {
+                ApplyParameters& params = parallelJobs.parameter(job);
+                params.data = data;
+                params.paintingData = paintingData;
+                params.yStart = yStart;
+                yStart += job < jobsWithExtra ? yStep + 1 : yStep;
+                params.yEnd = yStart;
+            }
+            parallelJobs.execute();
+            return;
+        }
+        // Fallback to single threaded mode.
+    }
+
+    applyPlatformGenericPaint(data, paintingData, 1, data.height - 1);
+}
+#endif
+
+void FELightingSoftwareApplier::applyPlatform(const LightingData& data)
+{
+    LightSource::PaintingData paintingData;
+
+    auto [r, g, b, a] = data.lightingColor.toColorComponentsInColorSpace(*data.operatingColorSpace);
+    paintingData.initialLightingData.colorVector = FloatPoint3D(r, g, b);
+
+    data.lightSource->initPaintingData(*data.effect, paintingData);
+
+    // Top left.
+    int offset = 0;
+    setPixel(offset, data, paintingData, 0, 0, cFactor2div3, cFactor2div3, data.topLeftNormal(offset));
+
+    // Top right.
+    offset = data.widthMultipliedByPixelSize - cPixelSize;
+    setPixel(offset, data, paintingData, data.width - 1, 0, cFactor2div3, cFactor2div3, data.topRightNormal(offset));
+
+    // Bottom left.
+    offset = (data.height - 1) * data.widthMultipliedByPixelSize;
+    setPixel(offset, data, paintingData, 0, data.height - 1, cFactor2div3, cFactor2div3, data.bottomLeftNormal(offset));
+
+    // Bottom right.
+    offset = data.height * data.widthMultipliedByPixelSize - cPixelSize;
+    setPixel(offset, data, paintingData, data.width - 1, data.height - 1, cFactor2div3, cFactor2div3, data.bottomRightNormal(offset));
+
+    if (data.width >= 3) {
+        // Top row.
+        offset = cPixelSize;
+        for (int x = 1; x < data.width - 1; ++x, offset += cPixelSize)
+            setPixel(offset, data, paintingData, x, 0, cFactor1div3, cFactor1div2, data.topRowNormal(offset));
+
+        // Bottom row.
+        offset = (data.height - 1) * data.widthMultipliedByPixelSize + cPixelSize;
+        for (int x = 1; x < data.width - 1; ++x, offset += cPixelSize)
+            setPixel(offset, data, paintingData, x, data.height - 1, cFactor1div3, cFactor1div2, data.bottomRowNormal(offset));
+    }
+
+    if (data.height >= 3) {
+        // Left column.
+        offset = data.widthMultipliedByPixelSize;
+        for (int y = 1; y < data.height - 1; ++y, offset += data.widthMultipliedByPixelSize)
+            setPixel(offset, data, paintingData, 0, y, cFactor1div2, cFactor1div3, data.leftColumnNormal(offset));
+
+        // Right column.
+        offset = 2 * data.widthMultipliedByPixelSize - cPixelSize;
+        for (int y = 1; y < data.height - 1; ++y, offset += data.widthMultipliedByPixelSize)
+            setPixel(offset, data, paintingData, data.width - 1, y, cFactor1div2, cFactor1div3, data.rightColumnNormal(offset));
+    }
+
+    if (data.width >= 3 && data.height >= 3) {
+        // Interior pixels.
+        applyPlatformGeneric(data, paintingData);
+    }
+
+    int lastPixel = data.widthMultipliedByPixelSize * data.height;
+    if (data.effect->filterType() == FilterEffect::Type::FEDiffuseLighting) {
+        for (int i = cAlphaChannelOffset; i < lastPixel; i += cPixelSize)
+            data.pixels->set(i, cOpaqueAlpha);
+    } else {
+        for (int i = 0; i < lastPixel; i += cPixelSize) {
+            uint8_t a1 = data.pixels->item(i);
+            uint8_t a2 = data.pixels->item(i + 1);
+            uint8_t a3 = data.pixels->item(i + 2);
+            // alpha set to set to max(a1, a2, a3)
+            data.pixels->set(i + 3, a1 >= a2 ? (a1 >= a3 ? a1 : a3) : (a2 >= a3 ? a2 : a3));
+        }
+    }
+}
+
+bool FELightingSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
+    if (!destinationPixelBuffer)
+        return false;
+
+    auto& destinationPixelArray = destinationPixelBuffer->data();
+
+    m_effect.setIsAlphaImage(false);
+
+    auto effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
+    in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
+
+    // FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3
+    // standard has no test case for them, and other browsers (like Firefox) has strange
+    // output for various kernelUnitLengths, and I am not sure they are reliable.
+    // Anyway, feConvolveMatrix should also use the implementation
+
+    IntSize size = IntSize(m_effect.absolutePaintRect().size());
+
+    // FIXME: do something if width or height (or both) is 1 pixel.
+    // The W3 spec does not define this case. Now the filter just returns.
+    if (size.width() <= 2 || size.height() <= 2)
+        return true;
+
+    LightingData data;
+    data.effect = &m_effect;
+    data.filterType = m_effect.filterType();
+    data.lightingColor = m_effect.lightingColor();
+    data.surfaceScale = m_effect.surfaceScale() / 255.0f;
+    data.diffuseConstant = m_effect.diffuseConstant();
+    data.specularConstant = m_effect.specularConstant();
+    data.specularExponent = m_effect.specularExponent();
+    data.lightSource = &m_effect.lightSource();
+    data.operatingColorSpace = &m_effect.operatingColorSpace();
+
+    data.pixels = &destinationPixelArray;
+    data.widthMultipliedByPixelSize = size.width() * cPixelSize;
+    data.width = size.width();
+    data.height = size.height();
+
+    applyPlatform(data);
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFELightingSoftwareApplierh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.h (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.h                              (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FELightingSoftwareApplier.h 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,135 @@
</span><ins>+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ * Copyright (C) 2018-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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED 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 "Color.h"
+#include "FilterEffectApplier.h"
+#include "LightSource.h"
+
+namespace WebCore {
+
+class FELighting;
+
+class FELightingSoftwareApplier : public FilterEffectConcreteApplier<FELighting> {
+    using Base = FilterEffectConcreteApplier<FELighting>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    static constexpr int cPixelSize = 4;
+    static constexpr int cAlphaChannelOffset = 3;
+    static constexpr uint8_t cOpaqueAlpha = static_cast<uint8_t>(0xFF);
+
+    // These factors and the normal coefficients come from the table under https://www.w3.org/TR/SVG/filters.html#feDiffuseLightingElement.
+    static constexpr float cFactor1div2 = -1 / 2.f;
+    static constexpr float cFactor1div3 = -1 / 3.f;
+    static constexpr float cFactor1div4 = -1 / 4.f;
+    static constexpr float cFactor2div3 = -2 / 3.f;
+
+    struct AlphaWindow {
+        uint8_t alpha[3][3] { };
+    
+        // The implementations are lined up to make comparing indices easier.
+        uint8_t topLeft() const             { return alpha[0][0]; }
+        uint8_t left() const                { return alpha[1][0]; }
+        uint8_t bottomLeft() const          { return alpha[2][0]; }
+
+        uint8_t top() const                 { return alpha[0][1]; }
+        uint8_t center() const              { return alpha[1][1]; }
+        uint8_t bottom() const              { return alpha[2][1]; }
+
+        void setTop(uint8_t value)          { alpha[0][1] = value; }
+        void setCenter(uint8_t value)       { alpha[1][1] = value; }
+        void setBottom(uint8_t value)       { alpha[2][1] = value; }
+
+        void setTopRight(uint8_t value)     { alpha[0][2] = value; }
+        void setRight(uint8_t value)        { alpha[1][2] = value; }
+        void setBottomRight(uint8_t value)  { alpha[2][2] = value; }
+
+        static void shiftRow(uint8_t alpha[3])
+        {
+            alpha[0] = alpha[1];
+            alpha[1] = alpha[2];
+        }
+    
+        void shift()
+        {
+            shiftRow(alpha[0]);
+            shiftRow(alpha[1]);
+            shiftRow(alpha[2]);
+        }
+    };
+
+    struct LightingData {
+        // This structure contains only read-only (SMP safe) data
+        FELighting* effect;
+        FilterEffect::Type filterType;
+        Color lightingColor;
+        float surfaceScale;
+        float diffuseConstant;
+        float specularConstant;
+        float specularExponent;
+        const LightSource* lightSource;
+        const DestinationColorSpace* operatingColorSpace;
+
+        Uint8ClampedArray* pixels;
+        int widthMultipliedByPixelSize;
+        int width;
+        int height;
+
+        inline IntSize topLeftNormal(int offset) const;
+        inline IntSize topRowNormal(int offset) const;
+        inline IntSize topRightNormal(int offset) const;
+        inline IntSize leftColumnNormal(int offset) const;
+        inline IntSize interiorNormal(int offset, AlphaWindow&) const;
+        inline IntSize rightColumnNormal(int offset) const;
+        inline IntSize bottomLeftNormal(int offset) const;
+        inline IntSize bottomRowNormal(int offset) const;
+        inline IntSize bottomRightNormal(int offset) const;
+    };
+
+    struct ApplyParameters {
+        LightingData data;
+        LightSource::PaintingData paintingData;
+        int yStart;
+        int yEnd;
+    };
+
+    static void setPixelInternal(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normal2DVector, float alpha);
+    static void setPixel(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normal2DVector);
+
+    static void applyPlatformGenericPaint(const LightingData&, const LightSource::PaintingData&, int startY, int endY);
+    static void applyPlatformGenericWorker(ApplyParameters*);
+    static void applyPlatformGeneric(const LightingData&, const LightSource::PaintingData&);
+    static void applyPlatform(const LightingData&);
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMergeSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergecpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.cpp                               (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.cpp  2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) Apple Inc. 2021 All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEMergeSoftwareApplier.h"
+
+#include "FEMerge.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+
+namespace WebCore {
+
+bool FEMergeSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    ASSERT(inputEffects.size() > 0);
+
+    auto resultImage = m_effect.imageBufferResult();
+    if (!resultImage)
+        return false;
+
+    auto& filterContext = resultImage->context();
+
+    for (auto& in : inputEffects) {
+        auto inBuffer = in->imageBufferResult();
+        if (!inBuffer)
+            continue;
+        filterContext.drawImageBuffer(*inBuffer, m_effect.drawingRegionOfInputImage(in->absolutePaintRect()));
+    }
+
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMergeSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.h                         (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEMergeSoftwareApplier.h    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) Apple Inc. 2021 All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEMerge;
+
+class FEMergeSoftwareApplier : public FilterEffectConcreteApplier<FEMerge> {
+    using Base = FilterEffectConcreteApplier<FEMerge>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMorphologySoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMorphologycpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.cpp                          (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.cpp     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,195 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) Apple Inc. 2017-2021 All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEMorphologySoftwareApplier.h"
+
+#include "FEMorphology.h"
+#include "Filter.h"
+#include "PixelBuffer.h"
+#include <wtf/ParallelJobs.h>
+
+namespace WebCore {
+
+inline ColorComponents<uint8_t, 4> FEMorphologySoftwareApplier::minOrMax(const ColorComponents<uint8_t, 4>& a, const ColorComponents<uint8_t, 4>& b, MorphologyOperatorType type)
+{
+    if (type == MorphologyOperatorType::Erode)
+        return perComponentMin(a, b);
+
+    return perComponentMax(a, b);
+}
+
+inline ColorComponents<uint8_t, 4> FEMorphologySoftwareApplier::columnExtremum(const Uint8ClampedArray& srcPixelArray, int x, int yStart, int yEnd, int width, MorphologyOperatorType type)
+{
+    auto extremum = makeColorComponentsfromPixelValue(PackedColor::RGBA { *reinterpret_cast<const unsigned*>(srcPixelArray.data() + pixelArrayIndex(x, yStart, width)) });
+
+    for (int y = yStart + 1; y < yEnd; ++y) {
+        auto pixel = makeColorComponentsfromPixelValue(PackedColor::RGBA { *reinterpret_cast<const unsigned*>(srcPixelArray.data() + pixelArrayIndex(x, y, width)) });
+        extremum = minOrMax(extremum, pixel, type);
+    }
+    return extremum;
+}
+
+inline ColorComponents<uint8_t, 4> FEMorphologySoftwareApplier::kernelExtremum(const ColumnExtrema& kernel, MorphologyOperatorType type)
+{
+    auto extremum = kernel[0];
+    for (size_t i = 1; i < kernel.size(); ++i)
+        extremum = minOrMax(extremum, kernel[i], type);
+
+    return extremum;
+}
+
+void FEMorphologySoftwareApplier::applyPlatformGeneric(const PaintingData& paintingData, int startY, int endY)
+{
+    ASSERT(endY > startY);
+
+    const auto& srcPixelArray = *paintingData.srcPixelArray;
+    auto& dstPixelArray = *paintingData.dstPixelArray;
+
+    const int radiusX = paintingData.radiusX;
+    const int radiusY = paintingData.radiusY;
+    const int width = paintingData.width;
+    const int height = paintingData.height;
+
+    ASSERT(radiusX <= width || radiusY <= height);
+    ASSERT(startY >= 0 && endY <= height && startY < endY);
+
+    ColumnExtrema extrema;
+    extrema.reserveInitialCapacity(2 * radiusX + 1);
+
+    for (int y = startY; y < endY; ++y) {
+        int yRadiusStart = std::max(0, y - radiusY);
+        int yRadiusEnd = std::min(height, y + radiusY + 1);
+
+        extrema.shrink(0);
+
+        // We start at the left edge, so compute extreme for the radiusX columns.
+        for (int x = 0; x < radiusX; ++x)
+            extrema.append(columnExtremum(srcPixelArray, x, yRadiusStart, yRadiusEnd, width, paintingData.type));
+
+        // Kernel is filled, get extrema of next column
+        for (int x = 0; x < width; ++x) {
+            if (x < width - radiusX)
+                extrema.append(columnExtremum(srcPixelArray, x + radiusX, yRadiusStart, yRadiusEnd, width, paintingData.type));
+
+            if (x > radiusX)
+                extrema.remove(0);
+
+            unsigned* destPixel = reinterpret_cast<unsigned*>(dstPixelArray.data() + pixelArrayIndex(x, y, width));
+            *destPixel = makePixelValueFromColorComponents(kernelExtremum(extrema, paintingData.type)).value;
+        }
+    }
+}
+
+void FEMorphologySoftwareApplier::applyPlatformWorker(ApplyParameters* params)
+{
+    applyPlatformGeneric(*params->paintingData, params->startY, params->endY);
+}
+
+void FEMorphologySoftwareApplier::applyPlatform(const PaintingData& paintingData)
+{
+    // Empirically, runtime is approximately linear over reasonable kernel sizes with a slope of about 0.65.
+    float kernelFactor = sqrt(paintingData.radiusX * paintingData.radiusY) * 0.65;
+
+    static const int minimalArea = (160 * 160); // Empirical data limit for parallel jobs
+    
+    unsigned maxNumThreads = paintingData.height / 8;
+    unsigned optimalThreadNumber = std::min<unsigned>((paintingData.width * paintingData.height * kernelFactor) / minimalArea, maxNumThreads);
+    if (optimalThreadNumber > 1) {
+        ParallelJobs<ApplyParameters> parallelJobs(&applyPlatformWorker, optimalThreadNumber);
+        auto numOfThreads = parallelJobs.numberOfJobs();
+        if (numOfThreads > 1) {
+            // Split the job into "jobSize"-sized jobs but there a few jobs that need to be slightly larger since
+            // jobSize * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
+            int jobSize = paintingData.height / numOfThreads;
+            int jobsWithExtra = paintingData.height % numOfThreads;
+            int currentY = 0;
+            for (int job = numOfThreads - 1; job >= 0; --job) {
+                ApplyParameters& param = parallelJobs.parameter(job);
+                param.startY = currentY;
+                currentY += job < jobsWithExtra ? jobSize + 1 : jobSize;
+                param.endY = currentY;
+                param.paintingData = &paintingData;
+            }
+            parallelJobs.execute();
+            return;
+        }
+        // Fallback to single thread model
+    }
+
+    applyPlatformGeneric(paintingData, 0, paintingData.height);
+}
+
+bool FEMorphologySoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Premultiplied);
+    if (!destinationPixelBuffer)
+        return false;
+
+    m_effect.setIsAlphaImage(in->isAlphaImage());
+
+    auto isDegenerate = [](int radiusX, int radiusY) -> bool {
+        return radiusX < 0 || radiusY < 0 || (!radiusX && !radiusY);
+    };
+
+    IntRect effectDrawingRect = m_effect.requestedRegionOfInputPixelBuffer(in->absolutePaintRect());
+    IntSize radius = flooredIntSize(FloatSize(m_effect.radiusX(), m_effect.radiusY()));
+
+    if (isDegenerate(radius.width(), radius.height())) {
+        in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
+        return true;
+    }
+
+    radius = flooredIntSize(filter.scaledByFilterScale({ m_effect.radiusX(), m_effect.radiusY() }));
+    int radiusX = std::min(effectDrawingRect.width() - 1, radius.width());
+    int radiusY = std::min(effectDrawingRect.height() - 1, radius.height());
+
+    if (isDegenerate(radiusX, radiusY)) {
+        in->copyPixelBufferResult(*destinationPixelBuffer, effectDrawingRect);
+        return true;
+    }
+
+    auto sourcePixelBuffer = in->getPixelBufferResult(AlphaPremultiplication::Premultiplied, effectDrawingRect, m_effect.operatingColorSpace());
+    if (!sourcePixelBuffer)
+        return false;
+
+    auto& sourcePixelArray = sourcePixelBuffer->data();
+    auto& destinationPixelArray = destinationPixelBuffer->data();
+
+    PaintingData paintingData;
+    paintingData.type = m_effect.morphologyOperator();
+    paintingData.srcPixelArray = &sourcePixelArray;
+    paintingData.dstPixelArray = &destinationPixelArray;
+    paintingData.width = ceilf(effectDrawingRect.width());
+    paintingData.height = ceilf(effectDrawingRect.height());
+    paintingData.radiusX = ceilf(radiusX);
+    paintingData.radiusY = ceilf(radiusY);
+
+    applyPlatform(paintingData);
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEMorphologySoftwareApplierh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.h (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.h                            (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEMorphologySoftwareApplier.h       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,75 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) Apple Inc. 2021 All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "ColorComponents.h"
+#include "ColorTypes.h"
+#include "FilterEffectApplier.h"
+#include <JavaScriptCore/Forward.h>
+
+namespace WebCore {
+
+class FEMorphology;
+enum class MorphologyOperatorType;
+
+class FEMorphologySoftwareApplier : public FilterEffectConcreteApplier<FEMorphology> {
+    using Base = FilterEffectConcreteApplier<FEMorphology>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    using ColumnExtrema = Vector<ColorComponents<uint8_t, 4>, 16>;
+
+    struct PaintingData {
+        MorphologyOperatorType type;
+        int radiusX;
+        int radiusY;
+        const Uint8ClampedArray* srcPixelArray;
+        Uint8ClampedArray* dstPixelArray;
+        int width;
+        int height;
+    };
+
+    struct ApplyParameters {
+        const PaintingData* paintingData;
+        int startY;
+        int endY;
+    };
+
+    static inline int pixelArrayIndex(int x, int y, int width) { return (y * width + x) * 4; }
+    static inline PackedColor::RGBA makePixelValueFromColorComponents(const ColorComponents<uint8_t, 4>& components) { return PackedColor::RGBA { makeFromComponents<SRGBA<uint8_t>>(components) }; }
+
+    static inline ColorComponents<uint8_t, 4> makeColorComponentsfromPixelValue(PackedColor::RGBA pixel) { return asColorComponents(asSRGBA(pixel)); }
+    static inline ColorComponents<uint8_t, 4> minOrMax(const ColorComponents<uint8_t, 4>& a, const ColorComponents<uint8_t, 4>& b, MorphologyOperatorType);
+    static inline ColorComponents<uint8_t, 4> columnExtremum(const Uint8ClampedArray& srcPixelArray, int x, int yStart, int yEnd, int width, MorphologyOperatorType);
+    static inline ColorComponents<uint8_t, 4> kernelExtremum(const ColumnExtrema& kernel, MorphologyOperatorType);
+
+    static void applyPlatformGeneric(const PaintingData&, int startY, int endY);
+    static void applyPlatformWorker(ApplyParameters*);
+    static void applyPlatform(const PaintingData&);
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEOffsetSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEOffsetcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.cpp                              (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.cpp 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FEOffsetSoftwareApplier.h"
+
+#include "FEOffset.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+
+namespace WebCore {
+
+bool FEOffsetSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto resultImage = m_effect.imageBufferResult();
+    auto inBuffer = in->imageBufferResult();
+    if (!resultImage || !inBuffer)
+        return false;
+
+    m_effect.setIsAlphaImage(in->isAlphaImage());
+
+    FloatRect drawingRegion = m_effect.drawingRegionOfInputImage(in->absolutePaintRect());
+    drawingRegion.move(filter.scaledByFilterScale({ m_effect.dx(), m_effect.dy() }));
+    resultImage->context().drawImageBuffer(*inBuffer, drawingRegion);
+
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFEOffsetSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FEOffsetSoftwareApplier.h   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FEOffset;
+
+class FEOffsetSoftwareApplier : public FilterEffectConcreteApplier<FEOffset> {
+    using Base = FilterEffectConcreteApplier<FEOffset>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFETileSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFETilecpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FETile.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.cpp   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FETileSoftwareApplier.h"
+
+#include "AffineTransform.h"
+#include "FETile.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "Pattern.h"
+#include "SVGRenderingContext.h"
+
+namespace WebCore {
+
+bool FETileSoftwareApplier::apply(const Filter& filter, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto resultImage = m_effect.imageBufferResult();
+    auto inBuffer = in->imageBufferResult();
+    if (!resultImage || !inBuffer)
+        return false;
+
+    m_effect.setIsAlphaImage(in->isAlphaImage());
+
+    // Source input needs more attention. It has the size of the filterRegion but gives the
+    // size of the cutted sourceImage back. This is part of the specification and optimization.
+    FloatRect tileRect = in->maxEffectRect();
+    FloatPoint inMaxEffectLocation = tileRect.location();
+    FloatPoint maxEffectLocation = m_effect.maxEffectRect().location();
+    if (in->filterType() == FilterEffect::Type::SourceGraphic || in->filterType() == FilterEffect::Type::SourceAlpha) {
+        tileRect = filter.filterRegion();
+        tileRect.scale(filter.filterScale());
+    }
+
+    // FIXME: remove this non-paltform call.
+    auto tileImage = SVGRenderingContext::createImageBuffer(tileRect, tileRect, DestinationColorSpace::SRGB(), filter.renderingMode());
+    if (!tileImage)
+        return false;
+
+    GraphicsContext& tileImageContext = tileImage->context();
+    tileImageContext.translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
+    tileImageContext.drawImageBuffer(*inBuffer, in->absolutePaintRect().location());
+
+    auto tileImageCopy = ImageBuffer::sinkIntoNativeImage(WTFMove(tileImage));
+    if (!tileImageCopy)
+        return false;
+
+    AffineTransform patternTransform;
+    patternTransform.translate(inMaxEffectLocation - maxEffectLocation);
+
+    auto pattern = Pattern::create(tileImageCopy.releaseNonNull(), { true, true, patternTransform });
+
+    GraphicsContext& filterContext = resultImage->context();
+    filterContext.setFillPattern(WTFMove(pattern));
+    filterContext.fillRect(FloatRect(FloatPoint(), m_effect.absolutePaintRect().size()));
+
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFETileSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.h                          (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.h     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class FETile;
+
+class FETileSoftwareApplier : public FilterEffectConcreteApplier<FETile> {
+    using Base = FilterEffectConcreteApplier<FETile>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFETurbulenceSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFETurbulencecpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.cpp                          (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.cpp     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,371 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
+ * Copyright (C) 2011 Gabor Loki <loki@webkit.org>
+ * Copyright (C) 2017-2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FETurbulenceSoftwareApplier.h"
+
+#include "FETurbulence.h"
+#include "Filter.h"
+#include "PixelBuffer.h"
+#include <wtf/MathExtras.h>
+#include <wtf/ParallelJobs.h>
+
+namespace WebCore {
+
+// The turbulence calculation code is an adapted version of what appears in the SVG 1.1 specification:
+// http://www.w3.org/TR/SVG11/filters.html#feTurbulence
+
+FETurbulenceSoftwareApplier::PaintingData FETurbulenceSoftwareApplier::initPaintingData(TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, long seed, bool stitchTiles, const IntSize& paintingSize)
+{
+    PaintingData paintingData { type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles, paintingSize, { }, { } };
+
+    // The seed value clamp to the range [1, s_randMaximum - 1].
+    if (paintingData.seed <= 0)
+        paintingData.seed = -(paintingData.seed % (s_randMaximum - 1)) + 1;
+    if (paintingData.seed > s_randMaximum - 1)
+        paintingData.seed = s_randMaximum - 1;
+
+    float* gradient;
+    for (int channel = 0; channel < 4; ++channel) {
+        for (int i = 0; i < s_blockSize; ++i) {
+            paintingData.latticeSelector[i] = i;
+            gradient = paintingData.gradient[channel][i];
+            do {
+                gradient[0] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+                gradient[1] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+            } while (!gradient[0] && !gradient[1]);
+            float normalizationFactor = std::hypot(gradient[0], gradient[1]);
+            gradient[0] /= normalizationFactor;
+            gradient[1] /= normalizationFactor;
+        }
+    }
+
+    for (int i = s_blockSize - 1; i > 0; --i) {
+        int k = paintingData.latticeSelector[i];
+        int j = paintingData.random() % s_blockSize;
+        ASSERT(j >= 0);
+        ASSERT(j < 2 * s_blockSize + 2);
+        paintingData.latticeSelector[i] = paintingData.latticeSelector[j];
+        paintingData.latticeSelector[j] = k;
+    }
+
+    for (int i = 0; i < s_blockSize + 2; ++i) {
+        paintingData.latticeSelector[s_blockSize + i] = paintingData.latticeSelector[i];
+        for (int channel = 0; channel < 4; ++channel) {
+            paintingData.gradient[channel][s_blockSize + i][0] = paintingData.gradient[channel][i][0];
+            paintingData.gradient[channel][s_blockSize + i][1] = paintingData.gradient[channel][i][1];
+        }
+    }
+
+    return paintingData;
+}
+
+FETurbulenceSoftwareApplier::StitchData FETurbulenceSoftwareApplier::computeStitching(IntSize tileSize, float& baseFrequencyX, float& baseFrequencyY, bool stitchTiles)
+{
+    if (!stitchTiles)
+        return { };
+
+    float tileWidth = tileSize.width();
+    float tileHeight = tileSize.height();
+    ASSERT(tileWidth > 0 && tileHeight > 0);
+
+    // When stitching tiled turbulence, the frequencies must be adjusted
+    // so that the tile borders will be continuous.
+    if (baseFrequencyX) {
+        float lowFrequency = floorf(tileWidth * baseFrequencyX) / tileWidth;
+        float highFrequency = ceilf(tileWidth * baseFrequencyX) / tileWidth;
+        // BaseFrequency should be non-negative according to the standard.
+        if (baseFrequencyX / lowFrequency < highFrequency / baseFrequencyX)
+            baseFrequencyX = lowFrequency;
+        else
+            baseFrequencyX = highFrequency;
+    }
+    if (baseFrequencyY) {
+        float lowFrequency = floorf(tileHeight * baseFrequencyY) / tileHeight;
+        float highFrequency = ceilf(tileHeight * baseFrequencyY) / tileHeight;
+        if (baseFrequencyY / lowFrequency < highFrequency / baseFrequencyY)
+            baseFrequencyY = lowFrequency;
+        else
+            baseFrequencyY = highFrequency;
+    }
+
+    StitchData stitchData;
+    stitchData.width = roundf(tileWidth * baseFrequencyX);
+    stitchData.wrapX = s_perlinNoise + stitchData.width;
+    stitchData.height = roundf(tileHeight * baseFrequencyY);
+    stitchData.wrapY = s_perlinNoise + stitchData.height;
+
+    return stitchData;
+}
+
+// This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
+ColorComponents<float, 4> FETurbulenceSoftwareApplier::noise2D(const PaintingData& paintingData, const StitchData& stitchData, const FloatPoint& noiseVector)
+{
+    struct NoisePosition {
+        int index; // bx0, by0 in the spec text.
+        int nextIndex; // bx1, by1 in the spec text.
+        float fraction; // rx0, ry0 in the spec text.
+
+        NoisePosition(float component)
+        {
+            //  t = vec[0] + PerlinN;
+            //  bx0 = (int)t;
+            //  bx1 = bx0+1;
+            //  rx0 = t - (int)t;
+            float position = component + s_perlinNoise;
+            index = static_cast<int>(position);
+            nextIndex = index + 1;
+            fraction = position - index;
+        }
+        
+        void stitch(int size, int wrapSize)
+        {
+            // if (bx0 >= pStitchInfo->nWrapX)
+            //   bx0 -= pStitchInfo->nWidth;
+            if (index >= wrapSize)
+                index -= size;
+
+            // if (bx1 >= pStitchInfo->nWrapX)
+            //   bx1 -= pStitchInfo->nWidth;
+            if (nextIndex >= wrapSize)
+                nextIndex -= size;
+        }
+    };
+
+    NoisePosition noiseX(noiseVector.x());
+    NoisePosition noiseY(noiseVector.y());
+
+    // If stitching, adjust lattice points accordingly.
+    if (paintingData.stitchTiles) {
+        noiseX.stitch(stitchData.width, stitchData.wrapX);
+        noiseY.stitch(stitchData.height, stitchData.wrapY);
+    }
+
+    // bx0 &= BM;
+    // bx1 &= BM;
+    // by0 &= BM;
+    // by1 &= BM;
+    noiseX.index &= s_blockMask;
+    noiseX.nextIndex &= s_blockMask;
+    noiseY.index &= s_blockMask;
+    noiseY.nextIndex &= s_blockMask;
+
+    // i = uLatticeSelector[bx0];
+    // j = uLatticeSelector[bx1];
+    int latticeIndex = paintingData.latticeSelector[noiseX.index];
+    int nextLatticeIndex = paintingData.latticeSelector[noiseX.nextIndex];
+
+    // sx = double(s_curve(rx0));
+    // sy = double(s_curve(ry0));
+    float sx = smoothCurve(noiseX.fraction);
+    float sy = smoothCurve(noiseY.fraction);
+
+    auto noiseForChannel = [&](int channel) {
+        // b00 = uLatticeSelector[i + by0]
+        int b00 = paintingData.latticeSelector[latticeIndex + noiseY.index];
+        // q = fGradient[nColorChannel][b00]; u = rx0 * q[0] + ry0 * q[1];
+        const float* q = paintingData.gradient[channel][b00];
+        float u = noiseX.fraction * q[0] + noiseY.fraction * q[1];
+
+        // b10 = uLatticeSelector[j + by0];
+        int b10 = paintingData.latticeSelector[nextLatticeIndex + noiseY.index];
+        // rx1 = rx0 - 1.0f;
+        // q = fGradient[nColorChannel][b10]; v = rx1 * q[0] + ry0 * q[1];
+        q = paintingData.gradient[channel][b10];
+        float v = (noiseX.fraction - 1) * q[0] + noiseY.fraction * q[1];
+        // a = lerp(sx, u, v);
+        float a = linearInterpolation(sx, u, v);
+
+        // b01 = uLatticeSelector[i + by1];
+        int b01 = paintingData.latticeSelector[latticeIndex + noiseY.nextIndex];
+        // ry1 = ry0 - 1.0f;
+        // q = fGradient[nColorChannel][b01]; u = rx0 * q[0] + ry1 * q[1];
+        q = paintingData.gradient[channel][b01];
+        u = noiseX.fraction * q[0] + (noiseY.fraction - 1) * q[1];
+
+        // b11 = uLatticeSelector[j + by1];
+        int b11 = paintingData.latticeSelector[nextLatticeIndex + noiseY.nextIndex];
+        // q = fGradient[nColorChannel][b11]; v = rx1 * q[0] + ry1 * q[1];
+        q = paintingData.gradient[channel][b11];
+        v = (noiseX.fraction - 1) * q[0] + (noiseY.fraction - 1) * q[1];
+        // b = lerp(sx, u, v);
+        float b = linearInterpolation(sx, u, v);
+
+        // return lerp(sy, a, b);
+        return linearInterpolation(sy, a, b);
+    };
+
+    return {
+        noiseForChannel(0),
+        noiseForChannel(1),
+        noiseForChannel(2),
+        noiseForChannel(3)
+    };
+}
+
+// https://www.w3.org/TR/SVG/filters.html#feTurbulenceElement describes this conversion to color components.
+// FIXME: This should use colorConvert<SRGBA<uint8>>(SRGBA<float>) to get the same behavior.
+ColorComponents<uint8_t, 4> FETurbulenceSoftwareApplier::toIntBasedColorComponents(const ColorComponents<float, 4>& floatComponents)
+{
+    return {
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[0] * 255), 0, 255),
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[1] * 255), 0, 255),
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[2] * 255), 0, 255),
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[3] * 255), 0, 255),
+    };
+}
+
+ColorComponents<uint8_t, 4> FETurbulenceSoftwareApplier::calculateTurbulenceValueForPoint(const PaintingData& paintingData, StitchData stitchData, const FloatPoint& point)
+{
+    ColorComponents<float, 4> turbulenceFunctionResult;
+    FloatPoint noiseVector(point.x() * paintingData.baseFrequencyX, point.y() * paintingData.baseFrequencyY);
+    float ratio = 1;
+    for (int octave = 0; octave < paintingData.numOctaves; ++octave) {
+        if (paintingData.type == TurbulenceType::FractalNoise)
+            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector) / ratio;
+        else
+            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector).abs() / ratio;
+
+        noiseVector.setX(noiseVector.x() * 2);
+        noiseVector.setY(noiseVector.y() * 2);
+        ratio *= 2;
+
+        if (paintingData.stitchTiles) {
+            // Update stitch values. Subtracting s_perlinNoise before the multiplication and
+            // adding it afterward simplifies to subtracting it once.
+            stitchData.width *= 2;
+            stitchData.wrapX = 2 * stitchData.wrapX - s_perlinNoise;
+            stitchData.height *= 2;
+            stitchData.wrapY = 2 * stitchData.wrapY - s_perlinNoise;
+        }
+    }
+
+    // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult * 255) + 255) / 2 by fractalNoise
+    // and (turbulenceFunctionResult * 255) by turbulence.
+    if (paintingData.type == TurbulenceType::FractalNoise)
+        turbulenceFunctionResult = turbulenceFunctionResult * 0.5f + 0.5f;
+
+    return toIntBasedColorComponents(turbulenceFunctionResult);
+}
+
+void FETurbulenceSoftwareApplier::applyPlatformGeneric(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, const PaintingData& paintingData, StitchData stitchData, int startY, int endY)
+{
+    ASSERT(endY > startY);
+
+    FloatPoint point(0, filterRegion.y() + startY);
+    int indexOfPixelChannel = startY * (filterRegion.width() << 2);
+    FloatSize inverseScale = { 1 / filterScale.width(), 1 / filterScale.height() };
+
+    for (int y = startY; y < endY; ++y) {
+        point.setY(point.y() + 1);
+        point.setX(filterRegion.x());
+        for (int x = 0; x < filterRegion.width(); ++x) {
+            point.setX(point.x() + 1);
+            FloatPoint localPoint = point.scaled(inverseScale.width(), inverseScale.height());
+            auto values = calculateTurbulenceValueForPoint(paintingData, stitchData, localPoint);
+            pixelArray.setRange(values.components.data(), 4, indexOfPixelChannel);
+            indexOfPixelChannel += 4;
+        }
+    }
+}
+
+void FETurbulenceSoftwareApplier::applyPlatformWorker(ApplyParameters* parameters)
+{
+    applyPlatformGeneric(parameters->filterRegion, parameters->filterScale, *parameters->pixelArray, *parameters->paintingData, parameters->stitchData, parameters->startY, parameters->endY);
+}
+
+void FETurbulenceSoftwareApplier::applyPlatform(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, PaintingData& paintingData, StitchData& stitchData)
+{
+    int height = filterRegion.height();
+    unsigned area = filterRegion.area();
+
+    static const int minimalRectDimension = (100 * 100); // Empirical data limit for parallel jobs.
+    unsigned maxNumThreads = filterRegion.height() / 8;
+    unsigned optimalThreadNumber = std::min<unsigned>(area / minimalRectDimension, maxNumThreads);
+
+    if (optimalThreadNumber > 1) {
+        ParallelJobs<ApplyParameters> parallelJobs(&applyPlatformWorker, optimalThreadNumber);
+
+        // Fill the parameter array
+        auto numJobs = parallelJobs.numberOfJobs();
+        if (numJobs > 1) {
+            // Split the job into "stepY"-sized jobs, distributing the extra rows into the first "jobsWithExtra" jobs.
+            unsigned stepY = height / numJobs;
+            unsigned jobsWithExtra = height % numJobs;
+            unsigned startY = 0;
+
+            for (unsigned i = 0; i < numJobs; ++i) {
+                ApplyParameters& params = parallelJobs.parameter(i);
+                params.filterRegion = filterRegion;
+                params.filterScale = filterScale;
+                params.pixelArray = &pixelArray;
+                params.paintingData = &paintingData;
+                params.stitchData = stitchData;
+                params.startY = startY;
+
+                unsigned jobHeight = (i < jobsWithExtra) ? stepY + 1 : stepY;
+                params.endY = params.startY + jobHeight;
+                startY += jobHeight;
+            }
+
+            parallelJobs.execute();
+            return;
+        }
+    }
+
+    // Fallback to single threaded mode if there is no room for a new thread or the paint area is too small.
+    applyPlatformGeneric(filterRegion, filterScale, pixelArray, paintingData, stitchData, 0, height);
+}
+
+bool FETurbulenceSoftwareApplier::apply(const Filter& filter, const FilterEffectVector&)
+{
+    auto destinationPixelBuffer = m_effect.pixelBufferResult(AlphaPremultiplication::Unpremultiplied);
+    if (!destinationPixelBuffer)
+        return false;
+
+    IntSize resultSize(m_effect.absolutePaintRect().size());
+    if (resultSize.area().hasOverflowed())
+        return false;
+
+    auto& destinationPixelArray = destinationPixelBuffer->data();
+
+    if (resultSize.isEmpty()) {
+        destinationPixelArray.zeroFill();
+        return true;
+    }
+
+    auto tileSize = roundedIntSize(m_effect.filterPrimitiveSubregion().size());
+
+    float baseFrequencyX = m_effect.baseFrequencyX();
+    float baseFrequencyY = m_effect.baseFrequencyY();
+    auto stitchData = computeStitching(tileSize, baseFrequencyX, baseFrequencyY, m_effect.stitchTiles());
+
+    auto paintingData = initPaintingData(m_effect.type(), baseFrequencyX, baseFrequencyY, m_effect.numOctaves(), m_effect.seed(), m_effect.stitchTiles(), tileSize);
+
+    applyPlatform(m_effect.absolutePaintRect(), filter.filterScale(), destinationPixelArray, paintingData, stitchData);
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareFETurbulenceSoftwareApplierh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.h (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.h                            (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FETurbulenceSoftwareApplier.h       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,117 @@
</span><ins>+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
+ * Copyright (C) 2017-2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "ColorComponents.h"
+#include "FilterEffectApplier.h"
+#include "FloatPoint.h"
+#include "IntRect.h"
+#include <JavaScriptCore/Forward.h>
+
+namespace WebCore {
+
+class FETurbulence;
+enum class TurbulenceType;
+
+class FETurbulenceSoftwareApplier : public FilterEffectConcreteApplier<FETurbulence> {
+    using Base = FilterEffectConcreteApplier<FETurbulence>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+
+private:
+    // Produces results in the range [1, 2**31 - 2]. Algorithm is:
+    // r = (a * r) mod m where a = s_randAmplitude = 16807 and
+    // m = s_randMaximum = 2**31 - 1 = 2147483647, r = seed.
+    // See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
+    // To test: the algorithm should produce the result 1043618065
+    // as the 10,000th generated number if the original seed is 1.
+    static const int s_perlinNoise = 4096;
+    static const long s_randMaximum = 2147483647; // 2**31 - 1
+    static const int s_randAmplitude = 16807; // 7**5; primitive root of m
+    static const int s_randQ = 127773; // m / a
+    static const int s_randR = 2836; // m % a
+
+    static const int s_blockSize = 256;
+    static const int s_blockMask = s_blockSize - 1;
+
+    struct PaintingData {
+        // Compute pseudo random number.
+        long random()
+        {
+            long result = s_randAmplitude * (seed % s_randQ) - s_randR * (seed / s_randQ);
+            if (result <= 0)
+                result += s_randMaximum;
+            seed = result;
+            return result;
+        }
+
+        TurbulenceType type;
+        float baseFrequencyX;
+        float baseFrequencyY;
+        int numOctaves;
+        long seed;
+        bool stitchTiles;
+        IntSize paintingSize;
+
+        int latticeSelector[2 * s_blockSize + 2];
+        float gradient[4][2 * s_blockSize + 2][2];
+    };
+
+    struct StitchData {
+        int width { 0 }; // How much to subtract to wrap for stitching.
+        int wrapX { 0 }; // Minimum value to wrap.
+        int height { 0 };
+        int wrapY { 0 };
+    };
+
+    struct ApplyParameters {
+        IntRect filterRegion;
+        FloatSize filterScale;
+        Uint8ClampedArray* pixelArray;
+        PaintingData* paintingData;
+        StitchData stitchData;
+        int startY;
+        int endY;
+    };
+
+    static inline float smoothCurve(float t) { return t * t * (3 - 2 * t); }
+    static inline float linearInterpolation(float t, float a, float b) { return a + t * (b - a); }
+
+    static PaintingData initPaintingData(TurbulenceType, float baseFrequencyX, float baseFrequencyY, int numOctaves, long seed, bool stitchTiles, const IntSize& paintingSize);
+    static StitchData computeStitching(IntSize tileSize, float& baseFrequencyX, float& baseFrequencyY, bool stitchTiles);
+
+    static ColorComponents<float, 4> noise2D(const PaintingData&, const StitchData&, const FloatPoint& noiseVector);
+    static ColorComponents<uint8_t, 4> toIntBasedColorComponents(const ColorComponents<float, 4>& floatComponents);
+    static ColorComponents<uint8_t, 4> calculateTurbulenceValueForPoint(const PaintingData&, StitchData, const FloatPoint&);
+
+    static void applyPlatformGeneric(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, const PaintingData&, StitchData, int startY, int endY);
+    static void applyPlatformWorker(ApplyParameters*);
+    static void applyPlatform(const IntRect& filterRegion, const FloatSize& filterScale, Uint8ClampedArray& pixelArray, PaintingData&, StitchData&);
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceAlphaSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersSourceAlphacpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp                           (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "SourceAlphaSoftwareApplier.h"
+
+#include "Color.h"
+#include "GraphicsContext.h"
+#include "SourceAlpha.h"
+
+namespace WebCore {
+
+bool SourceAlphaSoftwareApplier::apply(const Filter&, const FilterEffectVector& inputEffects)
+{
+    FilterEffect* in = inputEffects[0].get();
+
+    auto resultImage = m_effect.imageBufferResult();
+    if (!resultImage)
+        return false;
+    
+    auto imageBuffer = in->imageBufferResult();
+    if (!imageBuffer)
+        return false;
+
+    FloatRect imageRect(FloatPoint(), m_effect.absolutePaintRect().size());
+    GraphicsContext& filterContext = resultImage->context();
+
+    filterContext.fillRect(imageRect, Color::black);
+    filterContext.drawImageBuffer(*imageBuffer, IntPoint(), CompositeOperator::DestinationIn);
+
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceAlphaSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersFEMergeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/FEMerge.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.h                             (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.h        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class SourceAlpha;
+
+class SourceAlphaSoftwareApplier : public FilterEffectConcreteApplier<SourceAlpha> {
+    using Base = FilterEffectConcreteApplier<SourceAlpha>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceGraphicSoftwareAppliercppfromrev286151trunkSourceWebCoreplatformgraphicsfiltersSourceAlphah"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp                         (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp    2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "SourceGraphicSoftwareApplier.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "SourceGraphic.h"
+
+namespace WebCore {
+
+bool SourceGraphicSoftwareApplier::apply(const Filter& filter, const FilterEffectVector&)
+{
+    auto resultImage = m_effect.imageBufferResult();
+    auto sourceImage = filter.sourceImage();
+    if (!resultImage || !sourceImage)
+        return false;
+
+    resultImage->context().drawImageBuffer(*sourceImage, IntPoint());
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfilterssoftwareSourceGraphicSoftwareApplierhfromrev286151trunkSourceWebCoreplatformgraphicsfiltersSourceGraphich"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.h (from rev 286151, trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.h) (0 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.h                           (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.h      2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FilterEffectApplier.h"
+
+namespace WebCore {
+
+class SourceGraphic;
+
+class SourceGraphicSoftwareApplier : public FilterEffectConcreteApplier<SourceGraphic> {
+    using Base = FilterEffectConcreteApplier<SourceGraphic>;
+
+public:
+    using Base::Base;
+
+    bool apply(const Filter&, const FilterEffectVector& inputEffects) override;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingCSSFiltercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/CSSFilter.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/CSSFilter.cpp     2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/rendering/CSSFilter.cpp        2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx"> static RefPtr<FilterEffect> createBlurEffect(const BlurFilterOperation& blurOperation, FilterConsumer consumer)
</span><span class="cx"> {
</span><span class="cx">     float stdDeviation = floatValueForLength(blurOperation.stdDeviation(), 0);
</span><del>-    return FEGaussianBlur::create(stdDeviation, stdDeviation, consumer == FilterConsumer::FilterProperty ? EDGEMODE_NONE : EDGEMODE_DUPLICATE);
</del><ins>+    return FEGaussianBlur::create(stdDeviation, stdDeviation, consumer == FilterConsumer::FilterProperty ? EdgeModeType::None : EdgeModeType::Duplicate);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static RefPtr<FilterEffect> createBrightnessEffect(const BasicComponentTransferFilterOperation& componentTransferOperation)
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEConvolveMatrixElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp  2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp     2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -79,7 +79,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (name == SVGNames::edgeModeAttr) {
</span><span class="cx">         EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value);
</span><del>-        if (propertyValue > 0)
</del><ins>+        if (propertyValue != EdgeModeType::Unknown)
</ins><span class="cx">             m_edgeMode->setBaseValInternal<EdgeModeType>(propertyValue);
</span><span class="cx">         else
</span><span class="cx">             document().accessSVGExtensions().reportWarning("feConvolveMatrix: problem parsing edgeMode=\"" + value + "\". Filtered element will not be displayed.");
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEConvolveMatrixElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.h    2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.h       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -27,19 +27,19 @@
</span><span class="cx"> 
</span><span class="cx"> template<>
</span><span class="cx"> struct SVGPropertyTraits<EdgeModeType> {
</span><del>-    static unsigned highestEnumValue() { return EDGEMODE_NONE; }
-    static EdgeModeType initialValue() { return EDGEMODE_NONE; }
</del><ins>+    static unsigned highestEnumValue() { return static_cast<unsigned>(EdgeModeType::None); }
+    static EdgeModeType initialValue() { return EdgeModeType::None; }
</ins><span class="cx"> 
</span><span class="cx">     static String toString(EdgeModeType type)
</span><span class="cx">     {
</span><span class="cx">         switch (type) {
</span><del>-        case EDGEMODE_UNKNOWN:
</del><ins>+        case EdgeModeType::Unknown:
</ins><span class="cx">             return emptyString();
</span><del>-        case EDGEMODE_DUPLICATE:
</del><ins>+        case EdgeModeType::Duplicate:
</ins><span class="cx">             return "duplicate"_s;
</span><del>-        case EDGEMODE_WRAP:
</del><ins>+        case EdgeModeType::Wrap:
</ins><span class="cx">             return "wrap"_s;
</span><del>-        case EDGEMODE_NONE:
</del><ins>+        case EdgeModeType::None:
</ins><span class="cx">             return "none"_s;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -50,12 +50,12 @@
</span><span class="cx">     static EdgeModeType fromString(const String& value)
</span><span class="cx">     {
</span><span class="cx">         if (value == "duplicate")
</span><del>-            return EDGEMODE_DUPLICATE;
</del><ins>+            return EdgeModeType::Duplicate;
</ins><span class="cx">         if (value == "wrap")
</span><del>-            return EDGEMODE_WRAP;
</del><ins>+            return EdgeModeType::Wrap;
</ins><span class="cx">         if (value == "none")
</span><del>-            return EDGEMODE_NONE;
-        return EDGEMODE_UNKNOWN;
</del><ins>+            return EdgeModeType::None;
+        return EdgeModeType::Unknown;
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx">     Ref<SVGAnimatedNumber> m_bias { SVGAnimatedNumber::create(this) };
</span><span class="cx">     Ref<SVGAnimatedInteger> m_targetX { SVGAnimatedInteger::create(this) };
</span><span class="cx">     Ref<SVGAnimatedInteger> m_targetY { SVGAnimatedInteger::create(this) };
</span><del>-    Ref<SVGAnimatedEnumeration> m_edgeMode { SVGAnimatedEnumeration::create(this, EDGEMODE_DUPLICATE) };
</del><ins>+    Ref<SVGAnimatedEnumeration> m_edgeMode { SVGAnimatedEnumeration::create(this, EdgeModeType::Duplicate) };
</ins><span class="cx">     Ref<SVGAnimatedNumber> m_kernelUnitLengthX { SVGAnimatedNumber::create(this) };
</span><span class="cx">     Ref<SVGAnimatedNumber> m_kernelUnitLengthY { SVGAnimatedNumber::create(this) };
</span><span class="cx">     Ref<SVGAnimatedBoolean> m_preserveAlpha { SVGAnimatedBoolean::create(this) };
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEGaussianBlurElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp    2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp       2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (name == SVGNames::edgeModeAttr) {
</span><span class="cx">         auto propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value);
</span><del>-        if (propertyValue > 0)
</del><ins>+        if (propertyValue != EdgeModeType::Unknown)
</ins><span class="cx">             m_edgeMode->setBaseValInternal<EdgeModeType>(propertyValue);
</span><span class="cx">         else
</span><span class="cx">             document().accessSVGExtensions().reportWarning("feGaussianBlur: problem parsing edgeMode=\"" + value + "\". Filtered element will not be displayed.");
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEGaussianBlurElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h      2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx">     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
</span><span class="cx">     Ref<SVGAnimatedNumber> m_stdDeviationX { SVGAnimatedNumber::create(this) };
</span><span class="cx">     Ref<SVGAnimatedNumber> m_stdDeviationY { SVGAnimatedNumber::create(this) };
</span><del>-    Ref<SVGAnimatedEnumeration> m_edgeMode { SVGAnimatedEnumeration::create(this, EDGEMODE_NONE) };
</del><ins>+    Ref<SVGAnimatedEnumeration> m_edgeMode { SVGAnimatedEnumeration::create(this, EdgeModeType::None) };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEMorphologyElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEMorphologyElement.cpp (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEMorphologyElement.cpp      2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/svg/SVGFEMorphologyElement.cpp 2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (name == SVGNames::operatorAttr) {
</span><span class="cx">         MorphologyOperatorType propertyValue = SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
</span><del>-        if (propertyValue > 0)
</del><ins>+        if (propertyValue != MorphologyOperatorType::Unknown)
</ins><span class="cx">             m_svgOperator->setBaseValInternal<MorphologyOperatorType>(propertyValue);
</span><span class="cx">         return;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEMorphologyElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEMorphologyElement.h (286151 => 286152)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEMorphologyElement.h        2021-11-24 18:29:11 UTC (rev 286151)
+++ trunk/Source/WebCore/svg/SVGFEMorphologyElement.h   2021-11-24 19:41:26 UTC (rev 286152)
</span><span class="lines">@@ -27,16 +27,16 @@
</span><span class="cx"> 
</span><span class="cx"> template<>
</span><span class="cx"> struct SVGPropertyTraits<MorphologyOperatorType> {
</span><del>-    static unsigned highestEnumValue() { return FEMORPHOLOGY_OPERATOR_DILATE; }
</del><ins>+    static unsigned highestEnumValue() { return static_cast<unsigned>(MorphologyOperatorType::Dilate); }
</ins><span class="cx"> 
</span><span class="cx">     static String toString(MorphologyOperatorType type)
</span><span class="cx">     {
</span><span class="cx">         switch (type) {
</span><del>-        case FEMORPHOLOGY_OPERATOR_UNKNOWN:
</del><ins>+        case MorphologyOperatorType::Unknown:
</ins><span class="cx">             return emptyString();
</span><del>-        case FEMORPHOLOGY_OPERATOR_ERODE:
</del><ins>+        case MorphologyOperatorType::Erode:
</ins><span class="cx">             return "erode"_s;
</span><del>-        case FEMORPHOLOGY_OPERATOR_DILATE:
</del><ins>+        case MorphologyOperatorType::Dilate:
</ins><span class="cx">             return "dilate"_s;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -47,10 +47,10 @@
</span><span class="cx">     static MorphologyOperatorType fromString(const String& value)
</span><span class="cx">     {
</span><span class="cx">         if (value == "erode")
</span><del>-            return FEMORPHOLOGY_OPERATOR_ERODE;
</del><ins>+            return MorphologyOperatorType::Erode;
</ins><span class="cx">         if (value == "dilate")
</span><del>-            return FEMORPHOLOGY_OPERATOR_DILATE;
-        return FEMORPHOLOGY_OPERATOR_UNKNOWN;
</del><ins>+            return MorphologyOperatorType::Dilate;
+        return MorphologyOperatorType::Unknown;
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx"> 
</span><span class="cx">     PropertyRegistry m_propertyRegistry { *this };
</span><span class="cx">     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
</span><del>-    Ref<SVGAnimatedEnumeration> m_svgOperator { SVGAnimatedEnumeration::create(this, FEMORPHOLOGY_OPERATOR_ERODE) };
</del><ins>+    Ref<SVGAnimatedEnumeration> m_svgOperator { SVGAnimatedEnumeration::create(this, MorphologyOperatorType::Erode) };
</ins><span class="cx">     Ref<SVGAnimatedNumber> m_radiusX { SVGAnimatedNumber::create(this) };
</span><span class="cx">     Ref<SVGAnimatedNumber> m_radiusY { SVGAnimatedNumber::create(this) };
</span><span class="cx"> };
</span></span></pre>
</div>
</div>

</body>
</html>