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