Changeset 84911 in webkit
- Timestamp:
- Apr 26, 2011 7:40:47 AM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 6 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r84900 r84911 1 2011-04-26 Gabor Loki <loki@webkit.org> 2 3 Reviewed by Csaba Osztrogonác. 4 5 Speeding up SVG filters with multicore (SMP) support 6 https://bugs.webkit.org/show_bug.cgi?id=43903 7 8 Some SVG filters execute a huge number of pixel manipulations, which 9 cannot be sped up by graphics accelerators, since their algorithm is 10 too complex. Using the power of Symmetric Multi Processing (SMP) we 11 can split up a task to smaller (data independent) tasks, which can be 12 executed independently. 13 14 The ParallelJobs framework provides a simple way for distributed 15 programming. The framework is based on WebKit's threading infrastructure, 16 Open Multi-Processing's (OpenMP) API, and libdispatch API. 17 18 * GNUmakefile.list.am: 19 * JavaScriptCore.vcproj/WTF/WTF.vcproj: 20 * JavaScriptCore.xcodeproj/project.pbxproj: 21 * wtf/CMakeLists.txt: 22 * wtf/ParallelJobs.h: Added. 23 (WTF::ParallelJobs::ParallelJobs): 24 (WTF::ParallelJobs::numberOfJobs): 25 (WTF::ParallelJobs::parameterForJob): 26 (WTF::ParallelJobs::executeJobs): 27 * wtf/ParallelJobsGeneric.cpp: Added. 28 (WTF::ParallelEnvironment::ThreadPrivate::tryLockFor): 29 (WTF::ParallelEnvironment::ThreadPrivate::executeJob): 30 (WTF::ParallelEnvironment::ThreadPrivate::waitForFinish): 31 (WTF::ParallelEnvironment::ThreadPrivate::workerThread): 32 * wtf/ParallelJobsGeneric.h: Added. 33 (WTF::ParallelEnvironment::ParallelEnvironment): 34 (WTF::ParallelEnvironment::numberOfJobs): 35 (WTF::ParallelEnvironment::parameterForJob): 36 (WTF::ParallelEnvironment::executeJobs): 37 (WTF::ParallelEnvironment::ThreadPrivate::ThreadPrivate): 38 (WTF::ParallelEnvironment::ThreadPrivate::create): 39 * wtf/ParallelJobsLibdispatch.h: Added. 40 (WTF::ParallelEnvironment::ParallelEnvironment): 41 (WTF::ParallelEnvironment::numberOfJobs): 42 (WTF::ParallelEnvironment::parameterForJob): 43 (WTF::ParallelEnvironment::executeJobs): 44 * wtf/ParallelJobsOpenMP.h: Added. 45 (WTF::ParallelEnvironment::ParallelEnvironment): 46 (WTF::ParallelEnvironment::numberOfJobs): 47 (WTF::ParallelEnvironment::parameterForJob): 48 (WTF::ParallelEnvironment::executeJobs): 49 * wtf/Platform.h: 50 * wtf/wtf.pri: 51 1 52 2011-04-26 Mihai Parparita <mihaip@chromium.org> 2 53 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r83506 r84911 479 479 Source/JavaScriptCore/wtf/PassOwnPtr.h \ 480 480 Source/JavaScriptCore/wtf/PassRefPtr.h \ 481 Source/JavaScriptCore/wtf/ParallelJobs.h \ 482 Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp \ 483 Source/JavaScriptCore/wtf/ParallelJobsGeneric.h \ 484 Source/JavaScriptCore/wtf/ParallelJobsLibdispatch.h \ 485 Source/JavaScriptCore/wtf/ParallelJobsOpenMP.h \ 481 486 Source/JavaScriptCore/wtf/Platform.h \ 482 487 Source/JavaScriptCore/wtf/PossiblyNull.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
r84290 r84911 846 846 </File> 847 847 <File 848 RelativePath="..\..\wtf\ParallelJobs.h" 849 > 850 </File> 851 <File 852 RelativePath="..\..\wtf\ParallelJobsGeneric.cpp" 853 > 854 </File> 855 <File 856 RelativePath="..\..\wtf\ParallelJobsGeneric.h" 857 > 858 </File> 859 <File 860 RelativePath="..\..\wtf\ParallelJobsLibdispatch.h" 861 > 862 </File> 863 <File 864 RelativePath="..\..\wtf\ParallelJobsOpenMP.h" 865 > 866 </File> 867 <File 848 868 RelativePath="..\..\wtf\Platform.h" 849 869 > -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r84900 r84911 225 225 76FB9F0F12E851860051A2EB /* SHA1.h in Headers */ = {isa = PBXBuildFile; fileRef = 76FB9F0E12E851860051A2EB /* SHA1.h */; settings = {ATTRIBUTES = (Private, ); }; }; 226 226 76FB9F1112E851960051A2EB /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76FB9F1012E851960051A2EB /* SHA1.cpp */; }; 227 7934BB7B1361979300CB99A1 /* ParallelJobs.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB761361979300CB99A1 /* ParallelJobs.h */; settings = {ATTRIBUTES = (Private, ); }; }; 228 7934BB7C1361979400CB99A1 /* ParallelJobsGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7934BB771361979300CB99A1 /* ParallelJobsGeneric.cpp */; }; 229 7934BB7D1361979400CB99A1 /* ParallelJobsGeneric.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB781361979300CB99A1 /* ParallelJobsGeneric.h */; settings = {ATTRIBUTES = (Private, ); }; }; 230 7934BB7E1361979400CB99A1 /* ParallelJobsLibdispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB791361979300CB99A1 /* ParallelJobsLibdispatch.h */; settings = {ATTRIBUTES = (Private, ); }; }; 231 7934BB7F1361979400CB99A1 /* ParallelJobsOpenMP.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB7A1361979300CB99A1 /* ParallelJobsOpenMP.h */; settings = {ATTRIBUTES = (Private, ); }; }; 227 232 7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; }; 228 233 7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */; }; … … 891 896 76FB9F0E12E851860051A2EB /* SHA1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHA1.h; sourceTree = "<group>"; }; 892 897 76FB9F1012E851960051A2EB /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SHA1.cpp; sourceTree = "<group>"; }; 898 7934BB761361979300CB99A1 /* ParallelJobs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParallelJobs.h; sourceTree = "<group>"; }; 899 7934BB771361979300CB99A1 /* ParallelJobsGeneric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParallelJobsGeneric.cpp; sourceTree = "<group>"; }; 900 7934BB781361979300CB99A1 /* ParallelJobsGeneric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParallelJobsGeneric.h; sourceTree = "<group>"; }; 901 7934BB791361979300CB99A1 /* ParallelJobsLibdispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParallelJobsLibdispatch.h; sourceTree = "<group>"; }; 902 7934BB7A1361979300CB99A1 /* ParallelJobsOpenMP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParallelJobsOpenMP.h; sourceTree = "<group>"; }; 893 903 7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeChainMark.h; sourceTree = "<group>"; }; 894 904 7E4EE7080EBB7963005934AA /* StructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureChain.h; sourceTree = "<group>"; }; … … 1690 1700 44DD48520FAEA85000D6B4EB /* PassOwnPtr.h */, 1691 1701 6580F795094070560082C219 /* PassRefPtr.h */, 1702 7934BB761361979300CB99A1 /* ParallelJobs.h */, 1703 7934BB771361979300CB99A1 /* ParallelJobsGeneric.cpp */, 1704 7934BB781361979300CB99A1 /* ParallelJobsGeneric.h */, 1705 7934BB791361979300CB99A1 /* ParallelJobsLibdispatch.h */, 1706 7934BB7A1361979300CB99A1 /* ParallelJobsOpenMP.h */, 1692 1707 65D6D87E09B5A32E0002E4D7 /* Platform.h */, 1693 1708 A7D649A91015224E009B2E1B /* PossiblyNull.h */, … … 2553 2568 86AE64A9135E5E1C00963012 /* MacroAssemblerSH4.h in Headers */, 2554 2569 86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */, 2570 7934BB7B1361979300CB99A1 /* ParallelJobs.h in Headers */, 2571 7934BB7D1361979400CB99A1 /* ParallelJobsGeneric.h in Headers */, 2572 7934BB7E1361979400CB99A1 /* ParallelJobsLibdispatch.h in Headers */, 2573 7934BB7F1361979400CB99A1 /* ParallelJobsOpenMP.h in Headers */, 2555 2574 ); 2556 2575 runOnlyForDeploymentPostprocessing = 0; … … 2999 3018 142D6F1313539A4100B02E86 /* MarkStackPosix.cpp in Sources */, 3000 3019 86AE64A8135E5E1C00963012 /* MacroAssemblerSH4.cpp in Sources */, 3020 7934BB7C1361979400CB99A1 /* ParallelJobsGeneric.cpp in Sources */, 3001 3021 ); 3002 3022 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/JavaScriptCore/wtf/CMakeLists.txt
r84290 r84911 59 59 PassOwnPtr.h 60 60 PassRefPtr.h 61 ParallelJobs.h 62 ParallelJobsGeneric.h 63 ParallelJobsLibdispatch.h 64 ParallelJobsOpenMP.h 61 65 Platform.h 62 66 PossiblyNull.h … … 120 124 MD5.cpp 121 125 OSRandomSource.cpp 126 ParallelJobsGeneric.cpp 122 127 RandomNumber.cpp 123 128 RefCountedLeakCounter.cpp -
trunk/Source/JavaScriptCore/wtf/Platform.h
r84550 r84911 1197 1197 #endif 1198 1198 1199 #if !defined(ENABLE_THREADING_OPENMP) && defined(_OPENMP) 1200 #define ENABLE_THREADING_OPENMP 1 1201 #endif 1202 1203 #if !defined(ENABLE_PARALLEL_JOBS) && !ENABLE(SINGLE_THREADED) && (ENABLE(THREADING_GENERIC) || ENABLE(THREADING_LIBDISPATCH) || ENABLE(THREADING_OPENMP)) 1204 #define ENABLE_PARALLEL_JOBS 1 1205 #endif 1206 1199 1207 #if ENABLE(GLIB_SUPPORT) 1200 1208 #include "GTypedefs.h" -
trunk/Source/JavaScriptCore/wtf/wtf.pri
r80446 r84911 22 22 wtf/PageAllocationAligned.cpp \ 23 23 wtf/PageBlock.cpp \ 24 wtf/ParallelJobsGeneric.cpp \ 24 25 wtf/RandomNumber.cpp \ 25 26 wtf/RefCountedLeakCounter.cpp \ -
trunk/Source/WebCore/ChangeLog
r84910 r84911 1 2011-04-26 Gabor Loki <loki@webkit.org> 2 3 Reviewed by Csaba Osztrogonác. 4 5 Speeding up SVG filters with multicore (SMP) support 6 https://bugs.webkit.org/show_bug.cgi?id=43903 7 8 Some SVG filters execute a huge number of pixel manipulations, which 9 cannot be sped up by graphics accelerators, since their algorithm is 10 too complex. Using the power of Symmetric Multi Processing (SMP) we 11 can split up a task to smaller (data independent) tasks, which can be 12 executed independently. 13 14 The ParallelJobs framework provides a simple way for distributed 15 programming. The framework is based on WebKit's threading infrastructure, 16 Open Multi-Processing's (OpenMP) API, and libdispatch API. 17 18 * ForwardingHeaders/wtf/ParallelJobs.h: Added. 19 * platform/graphics/filters/FETurbulence.cpp: 20 (WebCore::FETurbulence::PaintingData::PaintingData): 21 (WebCore::FETurbulence::noise2D): 22 (WebCore::FETurbulence::calculateTurbulenceValueForPoint): 23 (WebCore::FETurbulence::fillRegion): 24 (WebCore::FETurbulence::fillRegionWorker): 25 (WebCore::FETurbulence::apply): 26 * platform/graphics/filters/FETurbulence.h: 27 1 28 2011-04-26 Pavel Feldman <pfeldman@google.com> 2 29 -
trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp
r79851 r84911 5 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 6 * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu> 7 * Copyright (C) 2011 Gabor Loki <loki@webkit.org> 7 8 * 8 9 * This library is free software; you can redistribute it and/or … … 33 34 #include <wtf/ByteArray.h> 34 35 #include <wtf/MathExtras.h> 36 #include <wtf/ParallelJobs.h> 35 37 36 38 namespace WebCore { … … 153 155 , wrapX(0) 154 156 , wrapY(0) 155 , channel(0)156 157 , filterSize(paintingSize) 157 158 { … … 225 226 } 226 227 227 float FETurbulence::noise2D( PaintingData& paintingData, const FloatPoint& noiseVector)228 float FETurbulence::noise2D(int channel, PaintingData& paintingData, const FloatPoint& noiseVector) 228 229 { 229 230 struct Noise { … … 260 261 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement. 261 262 int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue]; 262 q = paintingData.gradient[ paintingData.channel][temp];263 q = paintingData.gradient[channel][temp]; 263 264 u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1]; 264 265 temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue]; 265 q = paintingData.gradient[ paintingData.channel][temp];266 q = paintingData.gradient[channel][temp]; 266 267 v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1]; 267 268 a = linearInterpolation(sx, u, v); 268 269 temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1]; 269 q = paintingData.gradient[ paintingData.channel][temp];270 q = paintingData.gradient[channel][temp]; 270 271 u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1]; 271 272 temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1]; 272 q = paintingData.gradient[ paintingData.channel][temp];273 q = paintingData.gradient[channel][temp]; 273 274 v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1]; 274 275 b = linearInterpolation(sx, u, v); … … 276 277 } 277 278 278 unsigned char FETurbulence::calculateTurbulenceValueForPoint( PaintingData& paintingData, const FloatPoint& point)279 unsigned char FETurbulence::calculateTurbulenceValueForPoint(int channel, PaintingData& paintingData, const FloatPoint& point) 279 280 { 280 281 float tileWidth = paintingData.filterSize.width(); … … 314 315 for (int octave = 0; octave < m_numOctaves; ++octave) { 315 316 if (m_type == FETURBULENCE_TYPE_FRACTALNOISE) 316 turbulenceFunctionResult += noise2D( paintingData, noiseVector) / ratio;317 turbulenceFunctionResult += noise2D(channel, paintingData, noiseVector) / ratio; 317 318 else 318 turbulenceFunctionResult += fabsf(noise2D( paintingData, noiseVector)) / ratio;319 turbulenceFunctionResult += fabsf(noise2D(channel, paintingData, noiseVector)) / ratio; 319 320 noiseVector.setX(noiseVector.x() * 2); 320 321 noiseVector.setY(noiseVector.y() * 2); … … 339 340 } 340 341 342 inline void FETurbulence::fillRegion(ByteArray* pixelArray, PaintingData& paintingData, int startY, int endY) 343 { 344 IntRect filterRegion = absolutePaintRect(); 345 IntPoint point(0, filterRegion.y() + startY); 346 int indexOfPixelChannel = startY * (filterRegion.width() << 2); 347 int channel; 348 349 for (int y = startY; y < endY; ++y) { 350 point.setY(point.y() + 1); 351 point.setX(filterRegion.x()); 352 for (int x = 0; x < filterRegion.width(); ++x) { 353 point.setX(point.x() + 1); 354 for (channel = 0; channel < 4; ++channel, ++indexOfPixelChannel) 355 pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(channel, paintingData, filter()->mapAbsolutePointToLocalPoint(point))); 356 } 357 } 358 } 359 360 #if ENABLE(PARALLEL_JOBS) 361 void FETurbulence::fillRegionWorker(FillRegionParameters* parameters) 362 { 363 parameters->filter->fillRegion(parameters->pixelArray, *parameters->paintingData, parameters->startY, parameters->endY); 364 } 365 #endif // ENABLE(PARALLEL_JOBS) 366 341 367 void FETurbulence::apply() 342 368 { … … 353 379 initPaint(paintingData); 354 380 355 FloatRect filterRegion = absolutePaintRect(); 356 FloatPoint point; 357 point.setY(filterRegion.y()); 358 int indexOfPixelChannel = 0; 359 for (int y = 0; y < absolutePaintRect().height(); ++y) { 360 point.setY(point.y() + 1); 361 point.setX(filterRegion.x()); 362 for (int x = 0; x < absolutePaintRect().width(); ++x) { 363 point.setX(point.x() + 1); 364 for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel) 365 pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, filter()->mapAbsolutePointToLocalPoint(point))); 366 } 367 } 381 #if ENABLE(PARALLEL_JOBS) 382 383 int optimalThreadNumber = (absolutePaintRect().width() * absolutePaintRect().height()) / s_minimalRectDimension; 384 if (optimalThreadNumber > 1) { 385 // Initialize parallel jobs 386 ParallelJobs<FillRegionParameters> parallelJobs(&WebCore::FETurbulence::fillRegionWorker, optimalThreadNumber); 387 388 // Fill the parameter array 389 int i = parallelJobs.numberOfJobs(); 390 if (i > 1) { 391 int startY = 0; 392 int stepY = absolutePaintRect().height() / i; 393 for (; i > 0; --i) { 394 FillRegionParameters& params = parallelJobs.parameter(i-1); 395 params.filter = this; 396 params.pixelArray = pixelArray; 397 params.paintingData = &paintingData; 398 params.startY = startY; 399 if (i != 1) { 400 params.endY = startY + stepY; 401 startY = startY + stepY; 402 } else 403 params.endY = absolutePaintRect().height(); 404 } 405 406 // Execute parallel jobs 407 parallelJobs.execute(); 408 409 return; 410 } 411 } 412 // Fallback to sequential mode if there is no room for a new thread or the paint area is too small 413 414 #endif // ENABLE(PARALLEL_JOBS) 415 416 fillRegion(pixelArray, paintingData, 0, absolutePaintRect().height()); 368 417 } 369 418 -
trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h
r79851 r84911 59 59 bool setStitchTiles(bool); 60 60 61 #if ENABLE(PARALLEL_JOBS) 62 static void fillRegionWorker(void*); 63 #endif 64 61 65 virtual void apply(); 62 66 virtual void dump(); … … 69 73 static const int s_blockSize = 256; 70 74 static const int s_blockMask = s_blockSize - 1; 75 #if ENABLE(PARALLEL_JOBS) 76 static const int s_minimalRectDimension = (100 * 100); // Empirical data limit for parallel jobs 77 #endif 71 78 72 79 struct PaintingData { … … 78 85 int wrapX; // Minimum value to wrap. 79 86 int wrapY; 80 int channel;81 87 IntSize filterSize; 82 88 … … 85 91 }; 86 92 93 #if ENABLE(PARALLEL_JOBS) 94 template<typename Type> 95 friend class ParallelJobs; 96 97 struct FillRegionParameters { 98 FETurbulence* filter; 99 ByteArray* pixelArray; 100 PaintingData* paintingData; 101 int startY; 102 int endY; 103 }; 104 105 static void fillRegionWorker(FillRegionParameters*); 106 #endif 107 87 108 FETurbulence(Filter*, TurbulenceType, float, float, int, float, bool); 88 109 89 110 inline void initPaint(PaintingData&); 90 float noise2D(PaintingData&, const FloatPoint&); 91 unsigned char calculateTurbulenceValueForPoint(PaintingData&, const FloatPoint&); 111 float noise2D(int channel, PaintingData&, const FloatPoint&); 112 unsigned char calculateTurbulenceValueForPoint(int channel, PaintingData&, const FloatPoint&); 113 inline void fillRegion(ByteArray*, PaintingData&, int, int); 92 114 93 115 TurbulenceType m_type;
Note: See TracChangeset
for help on using the changeset viewer.