COMMIT_MESSAGE

 1parallel-filters
 2
 3Signed-off-by: Zoltan Herczeg <zherczeg@inf.u-szeged.hu>

WebCore/platform/graphics/filters/FELighting.cpp

@@void FELighting::setPixel(int offset, LightingData& data, LightSource::PaintingD
229229 inlineSetPixel(offset, data, paintingData, lightX, lightY, factorX, factorY, normalVector);
230230}
231231
 232inline void FELighting::setInteriorPixels(LightingData& data, LightSource::PaintingData& paintingData, int fromY, int toY)
 233{
 234 IntPoint normalVector;
 235 int offset;
 236
 237 for (int y = fromY; y < toY; ++y) {
 238 offset = y * data.widthMultipliedByPixelSize + cPixelSize;
 239 for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
 240 data.interior(offset, normalVector);
 241 inlineSetPixel(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, normalVector);
 242 }
 243 }
 244}
 245
 246#ifdef FILTER_THREAD
 247void* FELighting::paintThread(void* parameter)
 248{
 249 PaintThreadData& data = *reinterpret_cast<PaintThreadData*>(parameter);
 250
 251 data.filter->setInteriorPixels(data.lightingData, data.paintingData, 1, data.endY);
 252 return 0;
 253}
 254#endif
 255
232256bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
233257{
234258 LightSource::PaintingData paintingData;

@@bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
250274 paintingData.colorVector = FloatPoint3D(m_lightingColor.red(), m_lightingColor.green(), m_lightingColor.blue());
251275 m_lightSource->initPaintingData(paintingData);
252276
 277 int startY = 1;
 278#ifdef FILTER_THREAD
 279 PaintThreadData paintThreadData(this, data, paintingData);
 280 if (width >= 3 && height >= 10 && width * height > 4000) {
 281 startY = (height >> 1) + 3;
 282 paintThreadData.endY = startY;
 283 if (!execute(paintThread, &paintThreadData))
 284 startY = 1;
 285 }
 286#endif
 287
253288 // Top/Left corner
254289 IntPoint normalVector;
255290 int offset = 0;

@@bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
301336 }
302337 }
303338
304  if (width >= 3 && height >= 3) {
305  // Interior pixels
306  for (int y = 1; y < data.heightDecreasedByOne; ++y) {
307  offset = y * data.widthMultipliedByPixelSize + cPixelSize;
308  for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
309  data.interior(offset, normalVector);
310  inlineSetPixel(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, normalVector);
311  }
312  }
313  }
 339 if (width >= 3 && height >= 3)
 340 setInteriorPixels(data, paintingData, startY, data.heightDecreasedByOne);
 341
 342#ifdef FILTER_THREAD
 343 if (startY != 1)
 344 waitForFinish();
 345#endif
314346
315347 int lastPixel = data.widthMultipliedByPixelSize * height;
316348 if (m_lightingType == DiffuseLighting) {

WebCore/platform/graphics/filters/FELighting.h

@@protected:
6969 inline void bottomRight(int offset, IntPoint& normalVector);
7070 };
7171
 72#ifdef FILTER_THREAD
 73 struct PaintThreadData {
 74 PaintThreadData(FELighting* filter, LightingData& lightingData, LightSource::PaintingData& paintingData)
 75 : filter(filter)
 76 , lightingData(lightingData)
 77 , paintingData(paintingData)
 78 , endY(0)
 79 {
 80 }
 81
 82 FELighting* filter;
 83 LightingData& lightingData;
 84 // LightSource::PaintingData must be duplicated.
 85 LightSource::PaintingData paintingData;
 86 int endY;
 87 };
 88#endif
 89
7290 FELighting(LightingType, const Color&, float, float, float, float, float, float, PassRefPtr<LightSource>);
7391
7492 bool drawLighting(ByteArray*, int, int);

@@protected:
82100 LightingType m_lightingType;
83101 RefPtr<LightSource> m_lightSource;
84102
 103 inline void setInteriorPixels(LightingData&, LightSource::PaintingData&, int fromY, int toY);
 104
 105#ifdef FILTER_THREAD
 106 static void* paintThread(void* parameter);
 107#endif
 108
85109 Color m_lightingColor;
86110 float m_surfaceScale;
87111 float m_diffuseConstant;

WebCore/platform/graphics/filters/FETurbulence.cpp

2727#include "FETurbulence.h"
2828
2929#include "Filter.h"
30 #include "ImageData.h"
3130
3231#include <wtf/MathExtras.h>
3332

@@void FETurbulence::setStitchTiles(bool stitch)
128127
129128FETurbulence::PaintingData::PaintingData(long paintingSeed, const IntSize& paintingSize)
130129 : seed(paintingSeed)
 130 , filterSize(paintingSize)
131131 , width(0)
132132 , height(0)
133133 , wrapX(0)
134134 , wrapY(0)
135  , channel(0)
136  , filterSize(paintingSize)
137135{
138136}
139137

@@inline void checkNoise(int& noiseValue, int limitValue, int newValue)
204202 noiseValue -= newValue - 1;
205203}
206204
207 float FETurbulence::noise2D(PaintingData& paintingData, const FloatPoint& noiseVector)
 205float FETurbulence::noise2D(int channel, PaintingData& paintingData, const FloatPoint& noiseVector)
208206{
209207 struct Noise {
210208 int noisePositionIntegerValue;

@@float FETurbulence::noise2D(PaintingData& paintingData, const FloatPoint& noiseV
239237
240238 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
241239 int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
242  q = paintingData.gradient[paintingData.channel][temp];
 240 q = paintingData.gradient[channel][temp];
243241 u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
244242 temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
245  q = paintingData.gradient[paintingData.channel][temp];
 243 q = paintingData.gradient[channel][temp];
246244 v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
247245 a = linearInterpolation(sx, u, v);
248246 temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
249  q = paintingData.gradient[paintingData.channel][temp];
 247 q = paintingData.gradient[channel][temp];
250248 u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
251249 temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
252  q = paintingData.gradient[paintingData.channel][temp];
 250 q = paintingData.gradient[channel][temp];
253251 v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
254252 b = linearInterpolation(sx, u, v);
255253 return linearInterpolation(sy, a, b);
256254}
257255
258 unsigned char FETurbulence::calculateTurbulenceValueForPoint(PaintingData& paintingData, const FloatPoint& point)
 256inline unsigned char FETurbulence::calculateTurbulenceValueForPoint(int channel, PaintingData& paintingData, const FloatPoint& point)
259257{
260258 float tileWidth = paintingData.filterSize.width();
261259 ASSERT(tileWidth > 0);

@@unsigned char FETurbulence::calculateTurbulenceValueForPoint(PaintingData& paint
293291 float ratio = 1;
294292 for (int octave = 0; octave < m_numOctaves; ++octave) {
295293 if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
296  turbulenceFunctionResult += noise2D(paintingData, noiseVector) / ratio;
 294 turbulenceFunctionResult += noise2D(channel, paintingData, noiseVector) / ratio;
297295 else
298  turbulenceFunctionResult += fabsf(noise2D(paintingData, noiseVector)) / ratio;
 296 turbulenceFunctionResult += fabsf(noise2D(channel, paintingData, noiseVector)) / ratio;
299297 noiseVector.setX(noiseVector.x() * 2);
300298 noiseVector.setY(noiseVector.y() * 2);
301299 ratio *= 2;

@@unsigned char FETurbulence::calculateTurbulenceValueForPoint(PaintingData& paint
318316 return static_cast<unsigned char>(turbulenceFunctionResult * 255);
319317}
320318
 319inline void FETurbulence::setInteriorPixels(PaintingData& paintingData, ByteArray* pixelArray, int width, int fromY, int toY)
 320{
 321 FloatPoint point;
 322 point.setY(absolutePaintRect().y() + fromY);
 323 int indexOfPixelChannel = fromY * width * 4;
 324 for (int y = fromY; y < toY; ++y) {
 325 point.setY(point.y() + 1);
 326 point.setX(absolutePaintRect().x());
 327 for (int x = 0; x < width; ++x) {
 328 point.setX(point.x() + 1);
 329 for (int channel = 0; channel < 4; ++channel, ++indexOfPixelChannel)
 330 pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(channel, paintingData, point));
 331 }
 332 }
 333}
 334
 335#ifdef FILTER_THREAD
 336void* FETurbulence::paintThread(void* parameter)
 337{
 338 PaintThreadData& data = *reinterpret_cast<PaintThreadData*>(parameter);
 339
 340 data.filter->setInteriorPixels(data.paintingData, data.pixelArray, data.width, 0, data.endY);
 341 return 0;
 342}
 343#endif
 344
321345void FETurbulence::apply(Filter* filter)
322346{
323347 if (!effectContext(filter))

@@void FETurbulence::apply(Filter* filter)
332356 PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size()));
333357 initPaint(paintingData);
334358
335  FloatRect filterRegion = absolutePaintRect();
336  FloatPoint point;
337  point.setY(filterRegion.y());
338  int indexOfPixelChannel = 0;
339  for (int y = 0; y < imageRect.height(); ++y) {
340  point.setY(point.y() + 1);
341  point.setX(filterRegion.x());
342  for (int x = 0; x < imageRect.width(); ++x) {
343  point.setX(point.x() + 1);
344  for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel)
345  pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, filter->mapAbsolutePointToLocalPoint(point)));
346  }
 359 int startY = 0;
 360#ifdef FILTER_THREAD
 361 PaintThreadData paintThreadData(this, pixelArray, paintingData, imageRect.width());
 362 if (imageRect.height() >= 6 && imageRect.width() * imageRect.height() > 4000) {
 363 startY = imageRect.height() >> 1;
 364 paintThreadData.endY = startY;
 365 if (!execute(paintThread, &paintThreadData))
 366 startY = 0;
347367 }
 368#endif
 369 setInteriorPixels(paintingData, pixelArray, imageRect.width(), startY, imageRect.height());
 370#ifdef FILTER_THREAD
 371 if (startY)
 372 waitForFinish();
 373#endif
348374 resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
349375}
350376

WebCore/platform/graphics/filters/FETurbulence.h

2727#if ENABLE(FILTERS)
2828#include "FilterEffect.h"
2929#include "Filter.h"
 30#include "ImageData.h"
3031
3132namespace WebCore {
3233

@@private:
7374 long seed;
7475 int latticeSelector[2 * s_blockSize + 2];
7576 float gradient[4][2 * s_blockSize + 2][2];
 77 IntSize filterSize;
7678 int width; // How much to subtract to wrap for stitching.
7779 int height;
7880 int wrapX; // Minimum value to wrap.
7981 int wrapY;
80  int channel;
81  IntSize filterSize;
8282
8383 PaintingData(long paintingSeed, const IntSize& paintingSize);
8484 inline long random();
8585 };
8686
 87#ifdef FILTER_THREAD
 88 struct PaintThreadData {
 89 PaintThreadData(FETurbulence* filter, ByteArray* pixelArray, PaintingData& paintingData, int width)
 90 : filter(filter)
 91 , pixelArray(pixelArray)
 92 , paintingData(paintingData)
 93 , width(width)
 94 , endY(0)
 95 {
 96 }
 97
 98 FETurbulence* filter;
 99 ByteArray* pixelArray;
 100 PaintingData& paintingData;
 101 int width;
 102 int endY;
 103 };
 104#endif
 105
87106 FETurbulence(TurbulanceType, float, float, int, float, bool);
88107
89108 inline void initPaint(PaintingData&);
90  float noise2D(PaintingData&, const FloatPoint&);
91  unsigned char calculateTurbulenceValueForPoint(PaintingData&, const FloatPoint&);
 109 float noise2D(int channel, PaintingData&, const FloatPoint&);
 110 inline unsigned char calculateTurbulenceValueForPoint(int channel, PaintingData&, const FloatPoint&);
 111 inline void setInteriorPixels(PaintingData&, ByteArray*, int width, int fromY, int toY);
 112
 113#ifdef FILTER_THREAD
 114 static void* paintThread(void* parameter);
 115#endif
92116
93117 TurbulanceType m_type;
94118 float m_baseFrequencyX;

WebCore/platform/graphics/filters/FilterEffect.cpp

2626
2727namespace WebCore {
2828
 29#ifdef FILTER_THREAD
 30ThreadIdentifier FilterEffect::s_threadID;
 31FilterEffect::ThreadShared* FilterEffect::s_threadShared;
 32bool FilterEffect::s_stopThread;
 33#endif
 34
2935FilterEffect::FilterEffect()
3036 : m_alphaImage(false)
3137 , m_hasX(false)

@@FilterEffect::FilterEffect()
3339 , m_hasWidth(false)
3440 , m_hasHeight(false)
3541{
 42#ifdef FILTER_THREAD
 43 if (!s_threadID) {
 44 if (!s_threadShared)
 45 s_threadShared = new ThreadShared;
 46 s_threadID = createThread(filterThread, 0, "Filter common thread");
 47 }
 48#endif
3649}
3750
3851FilterEffect::~FilterEffect()

@@TextStream& FilterEffect::externalRepresentation(TextStream& ts, int) const
88101 return ts;
89102}
90103
 104#ifdef FILTER_THREAD
 105bool FilterEffect::execute(WTF::ThreadFunction function, void* parameter)
 106{
 107 if (!s_threadShared)
 108 return false;
 109
 110 ASSERT(!s_threadShared->m_start && !s_threadShared->m_finish);
 111
 112 MutexLocker lock(s_threadShared->m_mutex);
 113 s_threadShared->m_function = function;
 114 s_threadShared->m_parameter = parameter;
 115 s_threadShared->m_start = true;
 116 s_threadShared->m_cond.signal();
 117 return true;
 118}
 119
 120void FilterEffect::waitForFinish()
 121{
 122 ASSERT(s_threadShared);
 123
 124 while (!s_threadShared->m_finish)
 125 s_threadShared->m_cond.wait(s_threadShared->m_mutex);
 126
 127 s_threadShared->m_finish = false;
 128}
 129
 130void* FilterEffect::filterThread(void*)
 131{
 132 while (!s_stopThread) {
 133 if (s_threadShared->m_start) {
 134 s_threadShared->m_function(s_threadShared->m_parameter);
 135
 136 MutexLocker lock(s_threadShared->m_mutex);
 137 s_threadShared->m_start = false;
 138 s_threadShared->m_finish = true;
 139 s_threadShared->m_cond.signal();
 140 }
 141 s_threadShared->m_cond.wait(s_threadShared->m_mutex);
 142 }
 143 s_stopThread = false;
 144 return 0;
 145}
 146#endif
 147
91148} // namespace WebCore
92149
93150#endif // ENABLE(FILTERS)

WebCore/platform/graphics/filters/FilterEffect.h

3434#include <wtf/RefCounted.h>
3535#include <wtf/RefPtr.h>
3636#include <wtf/Vector.h>
 37#include <wtf/Threading.h>
 38
 39#define FILTER_THREAD
3740
3841namespace WebCore {
3942

@@public:
108111protected:
109112 FilterEffect();
110113
 114#ifdef FILTER_THREAD
 115 static bool execute(WTF::ThreadFunction, void* parameter);
 116 static void waitForFinish();
 117#endif
 118
111119private:
112120 OwnPtr<ImageBuffer> m_effectBuffer;
113121 FilterEffectVector m_inputEffects;

@@private:
121129 IntRect m_maxEffectRect;
122130
123131private:
 132#ifdef FILTER_THREAD
 133 static void* filterThread(void*);
 134
 135 class ThreadShared : public FastAllocBase {
 136 public:
 137 ThreadShared()
 138 : m_start(false)
 139 , m_finish(false)
 140 , m_function(filterThread) // Dummy function.
 141 {
 142 }
 143
 144 mutable Mutex m_mutex;
 145 ThreadCondition m_cond;
 146 bool m_start;
 147 bool m_finish;
 148 WTF::ThreadFunction m_function;
 149 void* m_parameter;
 150 };
 151#endif
 152
124153 // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive.
125154 // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
126155

@@private:
135164 bool m_hasY;
136165 bool m_hasWidth;
137166 bool m_hasHeight;
 167
 168#ifdef FILTER_THREAD
 169 static ThreadIdentifier s_threadID;
 170 static ThreadShared* s_threadShared;
 171 static bool s_stopThread;
 172#endif
138173};
139174
140175} // namespace WebCore