Title: [225183] trunk/Source/WebCore
Revision
225183
Author
[email protected]
Date
2017-11-27 11:40:45 -0800 (Mon, 27 Nov 2017)

Log Message

Optimize FEDisplacementMap
https://bugs.webkit.org/show_bug.cgi?id=180023

Reviewed by Sam Weinig.

Make FEDisplacementMap about 3x faster by operating on whole pixels rather than
individual channels. There's no per-channel logic once the srcX and srcY are computed.

Other sundry cleanup.

* platform/graphics/ColorUtilities.h:
(WebCore::byteOffsetOfPixel): Will use this in more places in future.
* platform/graphics/filters/FEDisplacementMap.cpp:
(WebCore::FEDisplacementMap::platformApplySoftware):
* platform/graphics/filters/FEDisplacementMap.h:
(WebCore::FEDisplacementMap::xChannelIndex const):
(WebCore::FEDisplacementMap::yChannelIndex const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (225182 => 225183)


--- trunk/Source/WebCore/ChangeLog	2017-11-27 19:36:05 UTC (rev 225182)
+++ trunk/Source/WebCore/ChangeLog	2017-11-27 19:40:45 UTC (rev 225183)
@@ -1,3 +1,23 @@
+2017-11-27  Simon Fraser  <[email protected]>
+
+        Optimize FEDisplacementMap
+        https://bugs.webkit.org/show_bug.cgi?id=180023
+
+        Reviewed by Sam Weinig.
+
+        Make FEDisplacementMap about 3x faster by operating on whole pixels rather than
+        individual channels. There's no per-channel logic once the srcX and srcY are computed.
+        
+        Other sundry cleanup.
+
+        * platform/graphics/ColorUtilities.h:
+        (WebCore::byteOffsetOfPixel): Will use this in more places in future.
+        * platform/graphics/filters/FEDisplacementMap.cpp:
+        (WebCore::FEDisplacementMap::platformApplySoftware):
+        * platform/graphics/filters/FEDisplacementMap.h:
+        (WebCore::FEDisplacementMap::xChannelIndex const):
+        (WebCore::FEDisplacementMap::yChannelIndex const):
+
 2017-11-27  Tim Horton  <[email protected]>
 
         One too many zeroes in macOS version number in FeatureDefines

Modified: trunk/Source/WebCore/platform/graphics/ColorUtilities.h (225182 => 225183)


--- trunk/Source/WebCore/platform/graphics/ColorUtilities.h	2017-11-27 19:36:05 UTC (rev 225182)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.h	2017-11-27 19:40:45 UTC (rev 225183)
@@ -141,5 +141,11 @@
     return std::max(0, std::min(static_cast<int>(lroundf(255.0f * f)), 255));
 }
 
+inline unsigned byteOffsetOfPixel(unsigned x, unsigned y, unsigned rowBytes)
+{
+    const unsigned bytesPerPixel = 4;
+    return x * bytesPerPixel + y * rowBytes;
+}
+
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp (225182 => 225183)


--- trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp	2017-11-27 19:36:05 UTC (rev 225182)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp	2017-11-27 19:40:45 UTC (rev 225183)
@@ -24,12 +24,12 @@
 #include "config.h"
 #include "FEDisplacementMap.h"
 
+#include "ColorUtilities.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
+#include <runtime/Uint8ClampedArray.h>
 #include <wtf/text/TextStream.h>
 
-#include <runtime/Uint8ClampedArray.h>
-
 namespace WebCore {
 
 FEDisplacementMap::FEDisplacementMap(Filter& filter, ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float scale)
@@ -99,15 +99,16 @@
         return;
 
     IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
-    auto srcPixelArrayA = in->premultipliedResult(effectADrawingRect);
+    auto inputImage = in->premultipliedResult(effectADrawingRect);
 
     IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
-    auto srcPixelArrayB = in2->unmultipliedResult(effectBDrawingRect);
+    // The calculations using the pixel values from ‘in2’ are performed using non-premultiplied color values.
+    auto displacementImage = in2->unmultipliedResult(effectBDrawingRect);
     
-    if (!srcPixelArrayA || !srcPixelArrayB)
+    if (!inputImage || !displacementImage)
         return;
 
-    ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
+    ASSERT(inputImage->length() == displacementImage->length());
 
     Filter& filter = this->filter();
     IntSize paintSize = absolutePaintRect().size();
@@ -117,21 +118,28 @@
     float scaleForColorY = scaleY / 255.0;
     float scaledOffsetX = 0.5 - scaleX * 0.5;
     float scaledOffsetY = 0.5 - scaleY * 0.5;
-    int stride = paintSize.width() * 4;
+    
+    int displacementChannelX = xChannelIndex();
+    int displacementChannelY = yChannelIndex();
+
+    int rowBytes = paintSize.width() * 4;
+
     for (int y = 0; y < paintSize.height(); ++y) {
-        int line = y * stride;
+        int lineStartOffset = y * rowBytes;
+
         for (int x = 0; x < paintSize.width(); ++x) {
-            int dstIndex = line + x * 4;
-            int srcX = x + static_cast<int>(scaleForColorX * srcPixelArrayB->item(dstIndex + m_xChannelSelector - 1) + scaledOffsetX);
-            int srcY = y + static_cast<int>(scaleForColorY * srcPixelArrayB->item(dstIndex + m_yChannelSelector - 1) + scaledOffsetY);
-            for (unsigned channel = 0; channel < 4; ++channel) {
-                if (srcX < 0 || srcX >= paintSize.width() || srcY < 0 || srcY >= paintSize.height())
-                    dstPixelArray->set(dstIndex + channel, static_cast<unsigned char>(0));
-                else {
-                    unsigned char pixelValue = srcPixelArrayA->item(srcY * stride + srcX * 4 + channel);
-                    dstPixelArray->set(dstIndex + channel, pixelValue);
-                }
+            int dstIndex = lineStartOffset + x * 4;
+            
+            int srcX = x + static_cast<int>(scaleForColorX * displacementImage->item(dstIndex + displacementChannelX) + scaledOffsetX);
+            int srcY = y + static_cast<int>(scaleForColorY * displacementImage->item(dstIndex + displacementChannelY) + scaledOffsetY);
+
+            unsigned* dstPixelPtr = reinterpret_cast<unsigned*>(dstPixelArray->data() + dstIndex);
+            if (srcX < 0 || srcX >= paintSize.width() || srcY < 0 || srcY >= paintSize.height()) {
+                *dstPixelPtr = 0;
+                continue;
             }
+
+            *dstPixelPtr = *reinterpret_cast<unsigned*>(inputImage->data() + byteOffsetOfPixel(srcX, srcY, rowBytes));
         }
     }
 }

Modified: trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h (225182 => 225183)


--- trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h	2017-11-27 19:36:05 UTC (rev 225182)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h	2017-11-27 19:40:45 UTC (rev 225183)
@@ -61,6 +61,9 @@
     void determineAbsolutePaintRect() override { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
     WTF::TextStream& externalRepresentation(WTF::TextStream&, int indention) const override;
+    
+    int xChannelIndex() const { return m_xChannelSelector - 1; }
+    int yChannelIndex() const { return m_yChannelSelector - 1; }
 
     ChannelSelectorType m_xChannelSelector;
     ChannelSelectorType m_yChannelSelector;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to