Title: [86759] trunk/Source/WebCore
Revision
86759
Author
[email protected]
Date
2011-05-18 07:27:28 -0700 (Wed, 18 May 2011)

Log Message

2011-05-18  Gabor Loki  <[email protected]>

        Reviewed by Nikolas Zimmermann.

        Apply the ParallelJobs support to FELighting
        https://bugs.webkit.org/show_bug.cgi?id=61048

        The lighting filter of SVG can consume lots of resources if it is
        applied to a large area. The computation can be distributed to multiple
        cores if the architecture supports.
        The average performance progression is 10-20% on dual-core machines.

        Developed in cooperation with Zoltan Herczeg.

        * platform/graphics/filters/FELighting.cpp:
        (WebCore::FELighting::platformApplyGenericPaint):
        (WebCore::FELighting::platformApplyGenericWorker):
        (WebCore::FELighting::platformApplyGeneric):
        * platform/graphics/filters/FELighting.h:
        * platform/graphics/filters/arm/FELightingNEON.cpp:
        (WebCore::FELighting::platformApplyNeonWorker):
        * platform/graphics/filters/arm/FELightingNEON.h:
        (WebCore::FELighting::platformApplyNeon):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (86758 => 86759)


--- trunk/Source/WebCore/ChangeLog	2011-05-18 14:12:56 UTC (rev 86758)
+++ trunk/Source/WebCore/ChangeLog	2011-05-18 14:27:28 UTC (rev 86759)
@@ -1,3 +1,27 @@
+2011-05-18  Gabor Loki  <[email protected]>
+
+        Reviewed by Nikolas Zimmermann.
+
+        Apply the ParallelJobs support to FELighting
+        https://bugs.webkit.org/show_bug.cgi?id=61048
+
+        The lighting filter of SVG can consume lots of resources if it is
+        applied to a large area. The computation can be distributed to multiple
+        cores if the architecture supports.
+        The average performance progression is 10-20% on dual-core machines.
+
+        Developed in cooperation with Zoltan Herczeg.
+
+        * platform/graphics/filters/FELighting.cpp:
+        (WebCore::FELighting::platformApplyGenericPaint):
+        (WebCore::FELighting::platformApplyGenericWorker):
+        (WebCore::FELighting::platformApplyGeneric):
+        * platform/graphics/filters/FELighting.h:
+        * platform/graphics/filters/arm/FELightingNEON.cpp:
+        (WebCore::FELighting::platformApplyNeonWorker):
+        * platform/graphics/filters/arm/FELightingNEON.h:
+        (WebCore::FELighting::platformApplyNeon):
+
 2011-05-18  Caio Marcelo de Oliveira Filho  <[email protected]>
 
         Reviewed by Andreas Kling.

Modified: trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp (86758 => 86759)


--- trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp	2011-05-18 14:12:56 UTC (rev 86758)
+++ trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp	2011-05-18 14:27:28 UTC (rev 86759)
@@ -30,6 +30,7 @@
 #include "FELighting.h"
 
 #include "FELightingNEON.h"
+#include <wtf/ParallelJobs.h>
 
 namespace WebCore {
 
@@ -227,12 +228,12 @@
     inlineSetPixel(offset, data, paintingData, lightX, lightY, factorX, factorY, normalVector);
 }
 
-inline void FELighting::platformApplyGeneric(LightingData& data, LightSource::PaintingData& paintingData)
+inline void FELighting::platformApplyGenericPaint(LightingData& data, LightSource::PaintingData& paintingData, int startY, int endY)
 {
     IntPoint normalVector;
     int offset = 0;
 
-    for (int y = 1; y < data.heightDecreasedByOne; ++y) {
+    for (int y = startY; y < endY; ++y) {
         offset = y * data.widthMultipliedByPixelSize + cPixelSize;
         for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
             data.interior(offset, normalVector);
@@ -241,6 +242,46 @@
     }
 }
 
+#if ENABLE(PARALLEL_JOBS)
+void FELighting::platformApplyGenericWorker(PlatformApplyGenericParameters* parameters)
+{
+    parameters->filter->platformApplyGenericPaint(parameters->data, parameters->paintingData, parameters->yStart, parameters->yEnd);
+}
+#endif // ENABLE(PARALLEL_JOBS)
+
+inline void FELighting::platformApplyGeneric(LightingData& data, LightSource::PaintingData& paintingData)
+{
+#if ENABLE(PARALLEL_JOBS)
+    int optimalThreadNumber = ((data.widthDecreasedByOne - 1) * (data.heightDecreasedByOne - 1)) / s_minimalRectDimension;
+    if (optimalThreadNumber > 1) {
+        // Initialize parallel jobs
+        ParallelJobs<PlatformApplyGenericParameters> parallelJobs(&platformApplyGenericWorker, optimalThreadNumber);
+
+        // Fill the parameter array
+        int job = parallelJobs.numberOfJobs();
+        if (job > 1) {
+            int yStart = 1;
+            int yStep = (data.widthDecreasedByOne - 1) / job;
+            for (--job; job >= 0; --job) {
+                PlatformApplyGenericParameters& params = parallelJobs.parameter(job);
+                params.filter = this;
+                params.data = ""
+                params.paintingData = paintingData;
+                params.yStart = yStart;
+                if (job > 0) {
+                    params.yEnd = yStart + yStep;
+                    yStart += yStep;
+                } else
+                    params.yEnd = data.heightDecreasedByOne;
+            }
+            parallelJobs.execute();
+            return;
+        }
+    }
+#endif
+    platformApplyGenericPaint(data, paintingData, 1, data.heightDecreasedByOne);
+}
+
 inline void FELighting::platformApply(LightingData& data, LightSource::PaintingData& paintingData)
 {
     // The selection here eventually should happen dynamically on some platforms.

Modified: trunk/Source/WebCore/platform/graphics/filters/FELighting.h (86758 => 86759)


--- trunk/Source/WebCore/platform/graphics/filters/FELighting.h	2011-05-18 14:12:56 UTC (rev 86758)
+++ trunk/Source/WebCore/platform/graphics/filters/FELighting.h	2011-05-18 14:27:28 UTC (rev 86759)
@@ -41,6 +41,8 @@
 
 namespace WebCore {
 
+struct FELightingPaintingDataForNeon;
+
 class FELighting : public FilterEffect {
 public:
     virtual void apply();
@@ -48,6 +50,10 @@
     virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
 protected:
+#if ENABLE(PARALLEL_JOBS)
+    static const int s_minimalRectDimension = 100 * 100; // Empirical data limit for parallel jobs
+#endif
+
     enum LightingType {
         DiffuseLighting,
         SpecularLighting
@@ -72,6 +78,22 @@
         inline void bottomRight(int offset, IntPoint& normalVector);
     };
 
+#if ENABLE(PARALLEL_JOBS)
+    template<typename Type>
+    friend class ParallelJobs;
+
+    struct PlatformApplyGenericParameters {
+        FELighting* filter;
+        LightingData data;
+        LightSource::PaintingData paintingData;
+        int yStart;
+        int yEnd;
+    };
+
+    static void platformApplyGenericWorker(PlatformApplyGenericParameters*);
+    static void platformApplyNeonWorker(FELightingPaintingDataForNeon*);
+#endif
+
     FELighting(Filter*, LightingType, const Color&, float, float, float, float, float, float, PassRefPtr<LightSource>);
 
     bool drawLighting(ByteArray*, int, int);
@@ -84,7 +106,9 @@
 
     inline void platformApply(LightingData&, LightSource::PaintingData&);
 
+    inline void platformApplyGenericPaint(LightingData&, LightSource::PaintingData&, int startX, int startY);
     inline void platformApplyGeneric(LightingData&, LightSource::PaintingData&);
+
     static int getPowerCoefficients(float exponent);
     inline void platformApplyNeon(LightingData&, LightSource::PaintingData&);
 

Modified: trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp (86758 => 86759)


--- trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp	2011-05-18 14:12:56 UTC (rev 86758)
+++ trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp	2011-05-18 14:27:28 UTC (rev 86759)
@@ -50,17 +50,25 @@
     return s_FELightingConstantsForNeon;
 }
 
+#if ENABLE(PARALLEL_JOBS)
+void FELighting::platformApplyNeonWorker(FELightingPaintingDataForNeon* parameters)
+{
+    neonDrawLighting(parameters);
+}
+#endif
+
 #define ASSTRING(str) #str
 #define TOSTRING(value) ASSTRING(value)
 
 #define PIXELS_OFFSET TOSTRING(0)
-#define WIDTH_OFFSET TOSTRING(4)
-#define HEIGHT_OFFSET TOSTRING(8)
-#define FLAGS_OFFSET TOSTRING(12)
-#define SPECULAR_EXPONENT_OFFSET TOSTRING(16)
-#define CONE_EXPONENT_OFFSET TOSTRING(20)
-#define FLOAT_ARGUMENTS_OFFSET TOSTRING(24)
-#define PAINTING_CONSTANTS_OFFSET TOSTRING(28)
+#define YSTART_OFFSET TOSTRING(4)
+#define WIDTH_OFFSET TOSTRING(8)
+#define HEIGHT_OFFSET TOSTRING(12)
+#define FLAGS_OFFSET TOSTRING(16)
+#define SPECULAR_EXPONENT_OFFSET TOSTRING(20)
+#define CONE_EXPONENT_OFFSET TOSTRING(24)
+#define FLOAT_ARGUMENTS_OFFSET TOSTRING(28)
+#define PAINTING_CONSTANTS_OFFSET TOSTRING(32)
 #define NL "\n"
 
 // Register allocation
@@ -221,6 +229,7 @@
     "ldr r0, [" PAINTING_DATA_R ", #" FLOAT_ARGUMENTS_OFFSET "]" NL
     "ldr r1, [" PAINTING_DATA_R ", #" PAINTING_CONSTANTS_OFFSET "]" NL
     "ldr " PIXELS_R ", [" PAINTING_DATA_R ", #" PIXELS_OFFSET "]" NL
+    "vldr.f32 " POSITION_Y_S ", [" PAINTING_DATA_R ", #" YSTART_OFFSET "]"  NL
     "ldr " WIDTH_R ", [" PAINTING_DATA_R ", #" WIDTH_OFFSET "]" NL
     "ldr " HEIGHT_R ", [" PAINTING_DATA_R ", #" HEIGHT_OFFSET "]" NL
     "ldr " FLAGS_R ", [" PAINTING_DATA_R ", #" FLAGS_OFFSET "]" NL
@@ -241,7 +250,6 @@
     "add " PIXELS_R ", " PIXELS_R ", #3" NL
     "mov r0, #0" NL
     "vmov.f32 " CONST_ZERO_S ", r0" NL
-    "vmov.f32 " POSITION_Y_S ", " CONST_ONE_S NL
     "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
     "vmov.f32 " SPOT_COLOR_Q ", " COLOR_Q NL
     "mov " RESET_WIDTH_R ", " WIDTH_R NL

Modified: trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h (86758 => 86759)


--- trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h	2011-05-18 14:12:56 UTC (rev 86758)
+++ trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h	2011-05-18 14:27:28 UTC (rev 86759)
@@ -33,6 +33,7 @@
 
 #include "FELighting.h"
 #include <wtf/Alignment.h>
+#include <wtf/ParallelJobs.h>
 
 namespace WebCore {
 
@@ -76,8 +77,9 @@
 
 struct FELightingPaintingDataForNeon {
     unsigned char* pixels;
+    float yStart;
     int widthDecreasedByTwo;
-    int heightDecreasedByTwo;
+    int absoluteHeight;
     // Combination of FLAG constants above.
     int flags;
     int specularExponent;
@@ -98,6 +100,7 @@
 
     FELightingPaintingDataForNeon neonData = {
         data.pixels->data(),
+        1,
         data.widthDecreasedByOne - 1,
         data.heightDecreasedByOne - 1,
         0,
@@ -164,6 +167,34 @@
     if (floatArguments.diffuseConstant == 1)
         neonData.flags |= FLAG_DIFFUSE_CONST_IS_1;
 
+#if ENABLE(PARALLEL_JOBS)
+    int optimalThreadNumber = ((data.widthDecreasedByOne - 1) * (data.heightDecreasedByOne - 1)) / s_minimalRectDimension;
+    if (optimalThreadNumber > 1) {
+        // Initialize parallel jobs
+        ParallelJobs<FELightingPaintingDataForNeon> parallelJobs(&WebCore::FELighting::platformApplyNeonWorker, optimalThreadNumber);
+
+        // Fill the parameter array
+        int job = parallelJobs.numberOfJobs();
+        if (job > 1) {
+            int yStart = 1;
+            int yStep = (data.heightDecreasedByOne - 1) / job;
+            for (--job; job >= 0; --job) {
+                FELightingPaintingDataForNeon& params = parallelJobs.parameter(job);
+                params = neonData;
+                params.yStart = yStart;
+                params.pixels += (yStart - 1) * (data.widthDecreasedByOne + 1) * 4;
+                if (job > 0) {
+                    params.absoluteHeight = yStep;
+                    yStart += yStep;
+                } else
+                    params.absoluteHeight = data.heightDecreasedByOne - yStart;
+            }
+            parallelJobs.execute();
+            return;
+        }
+    }
+#endif
+
     neonDrawLighting(&neonData);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to