Title: [225009] trunk/Source/WebCore
Revision
225009
Author
[email protected]
Date
2017-11-17 18:32:00 -0800 (Fri, 17 Nov 2017)

Log Message

FETurbulence: compute all 4 channels at once
https://bugs.webkit.org/show_bug.cgi?id=179833

Reviewed by Sam Weinig.

Introduce some new helper classes for storing float color components, and use
them in calculateTurbulenceValueForPoint() and noise2D() for all the channels in one
pass. This makes FETurbulence about twice as fast.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/ColorUtilities.cpp: Added.
(WebCore::ColorComponents::ColorComponents):
* platform/graphics/ColorUtilities.h: Added.
(WebCore::FloatComponents::FloatComponents):
(WebCore::FloatComponents::operator +=):
(WebCore::FloatComponents::operator + const):
(WebCore::FloatComponents::operator / const):
(WebCore::FloatComponents::operator * const):
(WebCore::FloatComponents::abs const):
(WebCore::clampedColorComponent):
* platform/graphics/filters/FETurbulence.cpp:
(WebCore::FETurbulence::noise2D):
(WebCore::FETurbulence::calculateTurbulenceValueForPoint):
(WebCore::FETurbulence::fillRegion):
(WebCore::FETurbulence::platformApplySoftware):
* platform/graphics/filters/FETurbulence.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (225008 => 225009)


--- trunk/Source/WebCore/ChangeLog	2017-11-18 02:27:13 UTC (rev 225008)
+++ trunk/Source/WebCore/ChangeLog	2017-11-18 02:32:00 UTC (rev 225009)
@@ -1,3 +1,33 @@
+2017-11-17  Simon Fraser  <[email protected]>
+
+        FETurbulence: compute all 4 channels at once
+        https://bugs.webkit.org/show_bug.cgi?id=179833
+
+        Reviewed by Sam Weinig.
+
+        Introduce some new helper classes for storing float color components, and use
+        them in calculateTurbulenceValueForPoint() and noise2D() for all the channels in one
+        pass. This makes FETurbulence about twice as fast.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/ColorUtilities.cpp: Added.
+        (WebCore::ColorComponents::ColorComponents):
+        * platform/graphics/ColorUtilities.h: Added.
+        (WebCore::FloatComponents::FloatComponents):
+        (WebCore::FloatComponents::operator +=):
+        (WebCore::FloatComponents::operator + const):
+        (WebCore::FloatComponents::operator / const):
+        (WebCore::FloatComponents::operator * const):
+        (WebCore::FloatComponents::abs const):
+        (WebCore::clampedColorComponent):
+        * platform/graphics/filters/FETurbulence.cpp:
+        (WebCore::FETurbulence::noise2D):
+        (WebCore::FETurbulence::calculateTurbulenceValueForPoint):
+        (WebCore::FETurbulence::fillRegion):
+        (WebCore::FETurbulence::platformApplySoftware):
+        * platform/graphics/filters/FETurbulence.h:
+
 2017-11-17  Chris Dumez  <[email protected]>
 
         Use a strongly typed identifier for SWServer::Connection

Modified: trunk/Source/WebCore/Sources.txt (225008 => 225009)


--- trunk/Source/WebCore/Sources.txt	2017-11-18 02:27:13 UTC (rev 225008)
+++ trunk/Source/WebCore/Sources.txt	2017-11-18 02:32:00 UTC (rev 225009)
@@ -1481,6 +1481,7 @@
 
 platform/graphics/BitmapImage.cpp
 platform/graphics/Color.cpp
+platform/graphics/ColorUtilities.cpp
 platform/graphics/ComplexTextController.cpp
 platform/graphics/CrossfadeGeneratedImage.cpp
 platform/graphics/DisplayRefreshMonitor.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (225008 => 225009)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-11-18 02:27:13 UTC (rev 225008)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-11-18 02:32:00 UTC (rev 225009)
@@ -5498,6 +5498,8 @@
 		0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListRecorder.h; path = displaylists/DisplayListRecorder.h; sourceTree = "<group>"; };
 		0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListReplayer.cpp; path = displaylists/DisplayListReplayer.cpp; sourceTree = "<group>"; };
 		0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListReplayer.h; path = displaylists/DisplayListReplayer.h; sourceTree = "<group>"; };
+		0FE6C76B1FBFB7A60025C053 /* ColorUtilities.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ColorUtilities.cpp; sourceTree = "<group>"; };
+		0FE6C76C1FBFB7A60025C053 /* ColorUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ColorUtilities.h; sourceTree = "<group>"; };
 		0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarThemeMock.cpp; sourceTree = "<group>"; };
 		0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeMock.h; sourceTree = "<group>"; };
 		0FE71415142189FC00DB33BA /* ScrollbarTheme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarTheme.cpp; sourceTree = "<group>"; };
@@ -22593,6 +22595,8 @@
 				B27535390B053814002CE64F /* Color.h */,
 				3103B7DE1DB01556008BB890 /* ColorHash.h */,
 				9382DF5710A8D5C900925652 /* ColorSpace.h */,
+				0FE6C76B1FBFB7A60025C053 /* ColorUtilities.cpp */,
+				0FE6C76C1FBFB7A60025C053 /* ColorUtilities.h */,
 				C2F4E7881E45AEDF006D7105 /* ComplexTextController.cpp */,
 				C2F4E7891E45AEDF006D7105 /* ComplexTextController.h */,
 				2D2FC0541460CD6F00263633 /* CrossfadeGeneratedImage.cpp */,

Added: trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp (0 => 225009)


--- trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp	2017-11-18 02:32:00 UTC (rev 225009)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 "ColorUtilities.h"
+
+namespace WebCore {
+
+ColorComponents::ColorComponents(const FloatComponents& floatComponents)
+{
+    components[0] = clampedColorComponent(floatComponents.components[0]);
+    components[1] = clampedColorComponent(floatComponents.components[1]);
+    components[2] = clampedColorComponent(floatComponents.components[2]);
+    components[3] = clampedColorComponent(floatComponents.components[3]);
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/platform/graphics/ColorUtilities.h (0 => 225009)


--- trunk/Source/WebCore/platform/graphics/ColorUtilities.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.h	2017-11-18 02:32:00 UTC (rev 225009)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 <algorithm>
+#include <math.h>
+
+namespace WebCore {
+
+struct FloatComponents {
+    FloatComponents(float a = 0, float b = 0, float c = 0, float d = 0)
+    {
+        components[0] = a;
+        components[1] = b;
+        components[2] = c;
+        components[3] = d;
+    }
+
+    FloatComponents& operator+=(const FloatComponents& rhs)
+    {
+        components[0] += rhs.components[0];
+        components[1] += rhs.components[1];
+        components[2] += rhs.components[2];
+        components[3] += rhs.components[3];
+        return *this;
+    }
+
+    FloatComponents operator+(float rhs) const
+    {
+        FloatComponents result;
+        result.components[0] = components[0] + rhs;
+        result.components[1] = components[1] + rhs;
+        result.components[2] = components[2] + rhs;
+        result.components[3] = components[3] + rhs;
+        return result;
+    }
+
+    FloatComponents operator/(float denominator) const
+    {
+        FloatComponents result;
+        result.components[0] = components[0] / denominator;
+        result.components[1] = components[1] / denominator;
+        result.components[2] = components[2] / denominator;
+        result.components[3] = components[3] / denominator;
+        return result;
+    }
+
+    FloatComponents operator*(float factor) const
+    {
+        FloatComponents result;
+        result.components[0] = components[0] * factor;
+        result.components[1] = components[1] * factor;
+        result.components[2] = components[2] * factor;
+        result.components[3] = components[3] * factor;
+        return result;
+    }
+
+    FloatComponents abs() const
+    {
+        FloatComponents result;
+        result.components[0] = fabs(components[0]);
+        result.components[1] = fabs(components[1]);
+        result.components[2] = fabs(components[2]);
+        result.components[3] = fabs(components[3]);
+        return result;
+    }
+
+    float components[4];
+};
+
+struct ColorComponents {
+    ColorComponents() = default;
+    ColorComponents(const FloatComponents&);
+    uint8_t components[4] { };
+};
+
+inline uint8_t clampedColorComponent(float f)
+{
+    // See also colorFloatToRGBAByte().
+    return std::max(0, std::min(static_cast<int>(lroundf(255.0f * f)), 255));
+}
+
+} // namespace WebCore
+

Modified: trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp (225008 => 225009)


--- trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp	2017-11-18 02:27:13 UTC (rev 225008)
+++ trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp	2017-11-18 02:32:00 UTC (rev 225009)
@@ -5,6 +5,7 @@
  * Copyright (C) 2009 Dirk Schulze <[email protected]>
  * Copyright (C) 2010 Renata Hodovan <[email protected]>
  * Copyright (C) 2011 Gabor Loki <[email protected]>
+ * Copyright (C) 2017 Apple Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -186,7 +187,7 @@
         noiseValue -= newValue - 1;
 }
 
-float FETurbulence::noise2D(int channel, const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& noiseVector)
+FloatComponents FETurbulence::noise2D(const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& noiseVector)
 {
     struct Noise {
         int noisePositionIntegerValue;
@@ -216,27 +217,37 @@
 
     float sx = smoothCurve(noiseX.noisePositionFractionValue);
     float sy = smoothCurve(noiseY.noisePositionFractionValue);
-    float a, b, u, v;
 
-    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
-    int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
-    const float* q = paintingData.gradient[channel][temp];
-    u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
-    temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
-    q = paintingData.gradient[channel][temp];
-    v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
-    a = linearInterpolation(sx, u, v);
-    temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
-    q = paintingData.gradient[channel][temp];
-    u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
-    temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
-    q = paintingData.gradient[channel][temp];
-    v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
-    b = linearInterpolation(sx, u, v);
-    return linearInterpolation(sy, a, b);
+    auto noiseForChannel = [&](int channel) {
+        // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
+        int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
+        const float* q = paintingData.gradient[channel][temp];
+
+        float u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
+        temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
+        q = paintingData.gradient[channel][temp];
+        float v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
+        float a = linearInterpolation(sx, u, v);
+        temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
+        q = paintingData.gradient[channel][temp];
+        u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+        temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
+        q = paintingData.gradient[channel][temp];
+        v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+        float b = linearInterpolation(sx, u, v);
+
+        return linearInterpolation(sy, a, b);
+    };
+
+    return {
+        noiseForChannel(0),
+        noiseForChannel(1),
+        noiseForChannel(2),
+        noiseForChannel(3)
+    };
 }
 
-unsigned char FETurbulence::calculateTurbulenceValueForPoint(int channel, const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& point)
+ColorComponents FETurbulence::calculateTurbulenceValueForPoint(const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& point)
 {
     float tileWidth = paintingData.filterSize.width();
     float tileHeight = paintingData.filterSize.height();
@@ -243,6 +254,7 @@
     ASSERT(tileWidth > 0 && tileHeight > 0);
     float baseFrequencyX = m_baseFrequencyX;
     float baseFrequencyY = m_baseFrequencyY;
+
     // Adjust the base frequencies if necessary for stitching.
     if (m_stitchTiles) {
         // When stitching tiled turbulence, the frequencies must be adjusted
@@ -271,17 +283,19 @@
         stitchData.wrapY = s_perlinNoise + stitchData.height;
     }
 
-    float turbulenceFunctionResult = 0;
+    FloatComponents turbulenceFunctionResult;
     FloatPoint noiseVector(point.x() * baseFrequencyX, point.y() * baseFrequencyY);
     float ratio = 1;
     for (int octave = 0; octave < m_numOctaves; ++octave) {
         if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
-            turbulenceFunctionResult += noise2D(channel, paintingData, stitchData, noiseVector) / ratio;
+            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector) / ratio;
         else
-            turbulenceFunctionResult += fabsf(noise2D(channel, paintingData, stitchData, noiseVector)) / ratio;
+            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector).abs() / ratio;
+
         noiseVector.setX(noiseVector.x() * 2);
         noiseVector.setY(noiseVector.y() * 2);
         ratio *= 2;
+
         if (m_stitchTiles) {
             // Update stitch values. Subtracting s_perlinNoiseoise before the multiplication and
             // adding it afterward simplifies to subtracting it once.
@@ -296,9 +310,8 @@
     // and (turbulenceFunctionResult * 255) by turbulence.
     if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
         turbulenceFunctionResult = turbulenceFunctionResult * 0.5f + 0.5f;
-    // Clamp result
-    turbulenceFunctionResult = std::max(std::min(turbulenceFunctionResult, 1.f), 0.f);
-    return static_cast<unsigned char>(turbulenceFunctionResult * 255);
+
+    return turbulenceFunctionResult;
 }
 
 void FETurbulence::fillRegion(Uint8ClampedArray* pixelArray, const PaintingData& paintingData, int startY, int endY)
@@ -315,8 +328,11 @@
         for (int x = 0; x < filterRegion.width(); ++x) {
             point.setX(point.x() + 1);
             FloatPoint localPoint = inverseTransfrom.mapPoint(point);
-            for (int channel = 0; channel < 4; ++channel, ++indexOfPixelChannel)
-                pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(channel, paintingData, stitchData, localPoint));
+            ColorComponents values = calculateTurbulenceValueForPoint(paintingData, stitchData, localPoint);
+            pixelArray->set(indexOfPixelChannel++, values.components[0]);
+            pixelArray->set(indexOfPixelChannel++, values.components[1]);
+            pixelArray->set(indexOfPixelChannel++, values.components[2]);
+            pixelArray->set(indexOfPixelChannel++, values.components[3]);
         }
     }
 }
@@ -355,7 +371,7 @@
 
             int startY = 0;
             for (; i > 0; --i) {
-                FillRegionParameters& params = parallelJobs.parameter(i-1);
+                FillRegionParameters& params = parallelJobs.parameter(i - 1);
                 params.filter = this;
                 params.pixelArray = pixelArray;
                 params.paintingData = &paintingData;

Modified: trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h (225008 => 225009)


--- trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h	2017-11-18 02:27:13 UTC (rev 225008)
+++ trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h	2017-11-18 02:32:00 UTC (rev 225009)
@@ -4,6 +4,7 @@
  * Copyright (C) 2005 Eric Seidel <[email protected]>
  * Copyright (C) 2009 Dirk Schulze <[email protected]>
  * Copyright (C) 2010 Renata Hodovan <[email protected]>
+ * Copyright (C) 2017 Apple Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -21,9 +22,9 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#ifndef FETurbulence_h
-#define FETurbulence_h
+#pragma once
 
+#include "ColorUtilities.h"
 #include "FilterEffect.h"
 #include "Filter.h"
 
@@ -118,8 +119,8 @@
     FETurbulence(Filter&, TurbulenceType, float, float, int, float, bool);
 
     void initPaint(PaintingData&);
-    float noise2D(int channel, const PaintingData&, StitchData&, const FloatPoint&);
-    unsigned char calculateTurbulenceValueForPoint(int channel, const PaintingData&, StitchData&, const FloatPoint&);
+    FloatComponents noise2D(const PaintingData&, StitchData&, const FloatPoint&);
+    ColorComponents calculateTurbulenceValueForPoint(const PaintingData&, StitchData&, const FloatPoint&);
     void fillRegion(Uint8ClampedArray*, const PaintingData&, int, int);
 
     TurbulenceType m_type;
@@ -132,4 +133,3 @@
 
 } // namespace WebCore
 
-#endif // FETurbulence_h
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to