Modified: trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp (86930 => 86931)
--- trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp 2011-05-20 08:48:12 UTC (rev 86930)
+++ trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp 2011-05-20 08:53:05 UTC (rev 86931)
@@ -31,6 +31,7 @@
#include "TextStream.h"
#include <wtf/ByteArray.h>
+#include <wtf/ParallelJobs.h>
namespace WebCore {
@@ -237,11 +238,10 @@
// Only for region C
template<bool preserveAlphaValues>
-ALWAYS_INLINE void FEConvolveMatrix::fastSetInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom)
+ALWAYS_INLINE void FEConvolveMatrix::fastSetInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom, int yStart, int yEnd)
{
// edge mode does not affect these pixels
int pixel = (m_targetOffset.y() * paintingData.width + m_targetOffset.x()) * 4;
- int startKernelPixel = 0;
int kernelIncrease = clipRight * 4;
int xIncrease = (m_kernelSize.width() - 1) * 4;
// Contains the sum of rgb(a) components
@@ -250,7 +250,11 @@
// m_divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
ASSERT(m_divisor);
- for (int y = clipBottom + 1; y > 0; --y) {
+ // Skip the first '(clipBottom - yEnd)' lines
+ pixel += (clipBottom - yEnd) * (xIncrease + (clipRight + 1) * (preserveAlphaValues ? 3 : 4));
+ int startKernelPixel = (clipBottom - yEnd) * (xIncrease + (clipRight + 1) * 4);
+
+ for (int y = yEnd + 1; y > yStart; --y) {
for (int x = clipRight + 1; x > 0; --x) {
int kernelValue = m_kernelMatrix.size() - 1;
int kernelPixel = startKernelPixel;
@@ -370,14 +374,14 @@
}
}
-ALWAYS_INLINE void FEConvolveMatrix::setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom)
+ALWAYS_INLINE void FEConvolveMatrix::setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom, int yStart, int yEnd)
{
// Must be implemented here, since it refers another ALWAYS_INLINE
// function, which defined in this C++ source file as well
if (m_preserveAlpha)
- fastSetInteriorPixels<true>(paintingData, clipRight, clipBottom);
+ fastSetInteriorPixels<true>(paintingData, clipRight, clipBottom, yStart, yEnd);
else
- fastSetInteriorPixels<false>(paintingData, clipRight, clipBottom);
+ fastSetInteriorPixels<false>(paintingData, clipRight, clipBottom, yStart, yEnd);
}
ALWAYS_INLINE void FEConvolveMatrix::setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2)
@@ -390,6 +394,13 @@
fastSetOuterPixels<false>(paintingData, x1, y1, x2, y2);
}
+#if ENABLE(PARALLEL_JOBS)
+void FEConvolveMatrix::setInteriorPixelsWorker(InteriorPixelParameters* param)
+{
+ param->filter->setInteriorPixels(*param->paintingData, param->clipRight, param->clipBottom, param->yStart, param->yEnd);
+}
+#endif
+
void FEConvolveMatrix::apply()
{
if (hasResult())
@@ -428,8 +439,35 @@
int clipBottom = paintSize.height() - m_kernelSize.height();
if (clipRight >= 0 && clipBottom >= 0) {
- setInteriorPixels(paintingData, clipRight, clipBottom);
+#if ENABLE(PARALLEL_JOBS)
+ int optimalThreadNumber = (absolutePaintRect().width() * absolutePaintRect().height()) / s_minimalRectDimension;
+ if (optimalThreadNumber > 1) {
+ ParallelJobs<InteriorPixelParameters> parallelJobs(&WebCore::FEConvolveMatrix::setInteriorPixelsWorker, optimalThreadNumber);
+ const int numOfThreads = parallelJobs.numberOfJobs();
+ const int heightPerThread = clipBottom / numOfThreads;
+ int startY = 0;
+
+ for (int job = 0; job < numOfThreads; ++job) {
+ InteriorPixelParameters& param = parallelJobs.parameter(job);
+ param.filter = this;
+ param.paintingData = &paintingData;
+ param.clipRight = clipRight;
+ param.clipBottom = clipBottom;
+ param.yStart = startY;
+ if (i < numOfThreads - 1) {
+ startY += heightPerThread;
+ param.yEnd = startY - 1;
+ } else
+ param.yEnd = clipBottom;
+ }
+
+ parallelJobs.execute();
+ } else
+ // Fallback to the default setInteriorPixels call.
+#endif
+ setInteriorPixels(paintingData, clipRight, clipBottom, 0, clipBottom);
+
clipRight += m_targetOffset.x() + 1;
clipBottom += m_targetOffset.y() + 1;
if (m_targetOffset.y() > 0)
Modified: trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h (86930 => 86931)
--- trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h 2011-05-20 08:48:12 UTC (rev 86930)
+++ trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h 2011-05-20 08:53:05 UTC (rev 86931)
@@ -80,8 +80,6 @@
virtual TextStream& externalRepresentation(TextStream&, int indention) const;
private:
- FEConvolveMatrix(Filter*, const IntSize&, float, float,
- const IntPoint&, EdgeModeType, const FloatPoint&, bool, const Vector<float>&);
struct PaintingData {
ByteArray* srcPixelArray;
@@ -91,8 +89,11 @@
float bias;
};
+ FEConvolveMatrix(Filter*, const IntSize&, float, float,
+ const IntPoint&, EdgeModeType, const FloatPoint&, bool, const Vector<float>&);
+
template<bool preserveAlphaValues>
- ALWAYS_INLINE void fastSetInteriorPixels(PaintingData&, int clipRight, int clipBottom);
+ ALWAYS_INLINE void fastSetInteriorPixels(PaintingData&, int clipRight, int clipBottom, int yStart, int yEnd);
ALWAYS_INLINE int getPixelValue(PaintingData&, int x, int y);
@@ -100,9 +101,28 @@
void fastSetOuterPixels(PaintingData&, int x1, int y1, int x2, int y2);
// Wrapper functions
- ALWAYS_INLINE void setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom);
- ALWAYS_INLINE void setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2);
+ ALWAYS_INLINE void setInteriorPixels(PaintingData&, int clipRight, int clipBottom, int yStart, int yEnd);
+ ALWAYS_INLINE void setOuterPixels(PaintingData&, int x1, int y1, int x2, int y2);
+ // Parallelization parts
+#if ENABLE(PARALLEL_JOBS)
+ static const int s_minimalRectDimension = (100 * 100); // Empirical data limit for parallel jobs
+
+ template<typename Type>
+ friend class ParallelJobs;
+
+ struct InteriorPixelParameters {
+ FEConvolveMatrix* filter;
+ PaintingData* paintingData;
+ int clipBottom;
+ int clipRight;
+ int yStart;
+ int yEnd;
+ };
+
+ static void setInteriorPixelsWorker(InteriorPixelParameters*);
+#endif
+
IntSize m_kernelSize;
float m_divisor;
float m_bias;