Title: [214916] trunk/Source/WebCore
Revision
214916
Author
[email protected]
Date
2017-04-04 17:23:46 -0700 (Tue, 04 Apr 2017)

Log Message

Do some minor FEColorMatrix code cleanup and optimization
https://bugs.webkit.org/show_bug.cgi?id=170474

Reviewed by Dean Jackson.

Don't switch inside of a pixel processing loop; repeat the loop inside switch (filterType).

Change matrix() and saturateAndHueRotate() to dereference the source pixels once, instead
of multiple times, which is faster.

This kind of code benefits from aligning things with spaces for readability, so do so,
violating webkit style.

Add some off-by-default performance logging code.

Increases pixel processing performance from about 86ms per megapixel to 65ms per megapixel.

* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::matrix):
(WebCore::saturateAndHueRotate):
(WebCore::effectType):
(WebCore::FEColorMatrix::platformApplySoftware):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (214915 => 214916)


--- trunk/Source/WebCore/ChangeLog	2017-04-05 00:05:27 UTC (rev 214915)
+++ trunk/Source/WebCore/ChangeLog	2017-04-05 00:23:46 UTC (rev 214916)
@@ -1,3 +1,28 @@
+2017-04-04  Simon Fraser  <[email protected]>
+
+        Do some minor FEColorMatrix code cleanup and optimization
+        https://bugs.webkit.org/show_bug.cgi?id=170474
+
+        Reviewed by Dean Jackson.
+
+        Don't switch inside of a pixel processing loop; repeat the loop inside switch (filterType).
+        
+        Change matrix() and saturateAndHueRotate() to dereference the source pixels once, instead
+        of multiple times, which is faster.
+        
+        This kind of code benefits from aligning things with spaces for readability, so do so,
+        violating webkit style.
+        
+        Add some off-by-default performance logging code.
+
+        Increases pixel processing performance from about 86ms per megapixel to 65ms per megapixel.
+
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::matrix):
+        (WebCore::saturateAndHueRotate):
+        (WebCore::effectType):
+        (WebCore::FEColorMatrix::platformApplySoftware):
+
 2017-04-04  Brent Fulgham  <[email protected]>
 
         Do not assert when CharacterData representing an Attr fires events

Modified: trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp (214915 => 214916)


--- trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2017-04-05 00:05:27 UTC (rev 214915)
+++ trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2017-04-05 00:23:46 UTC (rev 214916)
@@ -30,6 +30,8 @@
 #include <runtime/Uint8ClampedArray.h>
 #include <wtf/MathExtras.h>
 
+#define PRINT_FILTER_PERFORMANCE 0
+
 namespace WebCore {
 
 FEColorMatrix::FEColorMatrix(Filter& filter, ColorMatrixType type, const Vector<float>& values)
@@ -72,26 +74,26 @@
 
 inline void matrix(float& red, float& green, float& blue, float& alpha, const Vector<float>& values)
 {
-    float r = values[0] * red + values[1] * green + values[2] * blue + values[3] * alpha + values[4] * 255;
-    float g = values[5] * red + values[6] * green + values[7] * blue + values[8] * alpha + values[9] * 255;
-    float b = values[10] * red + values[11] * green + values[12] * blue + values[13] * alpha + values[14] * 255;
-    float a = values[15] * red + values[16] * green + values[17] * blue + values[18] * alpha + values[19] * 255;
+    float r = red;
+    float g = green;
+    float b = blue;
+    float a = alpha;
 
-    red = r;
-    green = g;
-    blue = b;
-    alpha = a;
+    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 saturateAndHueRotate(float& red, float& green, float& blue, const float* components)
 {
-    float r = red * components[0] + green * components[1] + blue * components[2];
-    float g = red * components[3] + green * components[4] + blue * components[5];
-    float b = red * components[6] + green * components[7] + blue * components[8];
+    float r = red;
+    float g = green;
+    float b = blue;
 
-    red = r;
-    green = g;
-    blue = b;
+    red     = r * components[0] + g * components[1] + b * components[2];
+    green   = r * components[3] + g * components[4] + b * components[5];
+    blue    = r * components[6] + g * components[7] + b * components[8];
 }
 
 inline void luminance(float& red, float& green, float& blue, float& alpha)
@@ -105,7 +107,6 @@
 template<ColorMatrixType filterType>
 void effectType(Uint8ClampedArray* pixelArray, const Vector<float>& values)
 {
-    unsigned pixelArrayLength = pixelArray->length();
     float components[9];
 
     if (filterType == FECOLORMATRIX_TYPE_SATURATE)
@@ -113,29 +114,51 @@
     else if (filterType == FECOLORMATRIX_TYPE_HUEROTATE)
         FEColorMatrix::calculateHueRotateComponents(components, values[0]);
 
-    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);
+    unsigned pixelArrayLength = pixelArray->length();
 
-        switch (filterType) {
-            case FECOLORMATRIX_TYPE_MATRIX:
-                matrix(red, green, blue, alpha, values);
-                break;
-            case FECOLORMATRIX_TYPE_SATURATE:
-            case FECOLORMATRIX_TYPE_HUEROTATE:
-                saturateAndHueRotate(red, green, blue, components);
-                break;
-            case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
-                luminance(red, green, blue, alpha);
-                break;
+    switch (filterType) {
+    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, values);
+            pixelArray->set(pixelByteOffset, red);
+            pixelArray->set(pixelByteOffset + 1, green);
+            pixelArray->set(pixelByteOffset + 2, blue);
+            pixelArray->set(pixelByteOffset + 3, alpha);
         }
+        break;
 
-        pixelArray->set(pixelByteOffset, red);
-        pixelArray->set(pixelByteOffset + 1, green);
-        pixelArray->set(pixelByteOffset + 2, blue);
-        pixelArray->set(pixelByteOffset + 3, alpha);
+    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, components);
+            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;
     }
 }
 
@@ -147,6 +170,10 @@
     if (!resultImage)
         return;
 
+#if PRINT_FILTER_PERFORMANCE
+    MonotonicTime startTime = MonotonicTime::now();
+#endif
+
     ImageBuffer* inBuffer = in->asImageBuffer();
     if (inBuffer)
         resultImage->context().drawImageBuffer(*inBuffer, drawingRegionOfInputImage(in->absolutePaintRect()));
@@ -174,6 +201,20 @@
     }
 
     resultImage->putByteArray(Unmultiplied, pixelArray.get(), imageRect.size(), imageRect, IntPoint());
+
+#if PRINT_FILTER_PERFORMANCE
+    MonotonicTime endTime = MonotonicTime::now();
+    Seconds duration = endTime - startTime;
+    unsigned pixelCount = imageRect.width() * imageRect.height();
+    
+    static double totalMegapixels;
+    totalMegapixels += (double)pixelCount / 1048576.0;
+    
+    static Seconds totalTime;
+    totalTime += duration;
+    
+    WTFLogAlways("FEColorMatrix::platformApplySoftware (%dx%d) took %.4fms (ave %.4fms/mp)", imageRect.width(), imageRect.height(), duration.milliseconds(), totalTime.milliseconds() / totalMegapixels);
+#endif
 }
 
 void FEColorMatrix::dump()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to