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);
}