Changeset 86759 in webkit


Ignore:
Timestamp:
May 18, 2011 7:27:28 AM (13 years ago)
Author:
loki@webkit.org
Message:

2011-05-18 Gabor Loki <loki@webkit.org>

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):
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r86758 r86759  
     12011-05-18  Gabor Loki  <loki@webkit.org>
     2
     3        Reviewed by Nikolas Zimmermann.
     4
     5        Apply the ParallelJobs support to FELighting
     6        https://bugs.webkit.org/show_bug.cgi?id=61048
     7
     8        The lighting filter of SVG can consume lots of resources if it is
     9        applied to a large area. The computation can be distributed to multiple
     10        cores if the architecture supports.
     11        The average performance progression is 10-20% on dual-core machines.
     12
     13        Developed in cooperation with Zoltan Herczeg.
     14
     15        * platform/graphics/filters/FELighting.cpp:
     16        (WebCore::FELighting::platformApplyGenericPaint):
     17        (WebCore::FELighting::platformApplyGenericWorker):
     18        (WebCore::FELighting::platformApplyGeneric):
     19        * platform/graphics/filters/FELighting.h:
     20        * platform/graphics/filters/arm/FELightingNEON.cpp:
     21        (WebCore::FELighting::platformApplyNeonWorker):
     22        * platform/graphics/filters/arm/FELightingNEON.h:
     23        (WebCore::FELighting::platformApplyNeon):
     24
    1252011-05-18  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
    226
  • trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp

    r85180 r86759  
    3131
    3232#include "FELightingNEON.h"
     33#include <wtf/ParallelJobs.h>
    3334
    3435namespace WebCore {
     
    228229}
    229230
    230 inline void FELighting::platformApplyGeneric(LightingData& data, LightSource::PaintingData& paintingData)
     231inline void FELighting::platformApplyGenericPaint(LightingData& data, LightSource::PaintingData& paintingData, int startY, int endY)
    231232{
    232233    IntPoint normalVector;
    233234    int offset = 0;
    234235
    235     for (int y = 1; y < data.heightDecreasedByOne; ++y) {
     236    for (int y = startY; y < endY; ++y) {
    236237        offset = y * data.widthMultipliedByPixelSize + cPixelSize;
    237238        for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
     
    240241        }
    241242    }
     243}
     244
     245#if ENABLE(PARALLEL_JOBS)
     246void FELighting::platformApplyGenericWorker(PlatformApplyGenericParameters* parameters)
     247{
     248    parameters->filter->platformApplyGenericPaint(parameters->data, parameters->paintingData, parameters->yStart, parameters->yEnd);
     249}
     250#endif // ENABLE(PARALLEL_JOBS)
     251
     252inline void FELighting::platformApplyGeneric(LightingData& data, LightSource::PaintingData& paintingData)
     253{
     254#if ENABLE(PARALLEL_JOBS)
     255    int optimalThreadNumber = ((data.widthDecreasedByOne - 1) * (data.heightDecreasedByOne - 1)) / s_minimalRectDimension;
     256    if (optimalThreadNumber > 1) {
     257        // Initialize parallel jobs
     258        ParallelJobs<PlatformApplyGenericParameters> parallelJobs(&platformApplyGenericWorker, optimalThreadNumber);
     259
     260        // Fill the parameter array
     261        int job = parallelJobs.numberOfJobs();
     262        if (job > 1) {
     263            int yStart = 1;
     264            int yStep = (data.widthDecreasedByOne - 1) / job;
     265            for (--job; job >= 0; --job) {
     266                PlatformApplyGenericParameters& params = parallelJobs.parameter(job);
     267                params.filter = this;
     268                params.data = data;
     269                params.paintingData = paintingData;
     270                params.yStart = yStart;
     271                if (job > 0) {
     272                    params.yEnd = yStart + yStep;
     273                    yStart += yStep;
     274                } else
     275                    params.yEnd = data.heightDecreasedByOne;
     276            }
     277            parallelJobs.execute();
     278            return;
     279        }
     280    }
     281#endif
     282    platformApplyGenericPaint(data, paintingData, 1, data.heightDecreasedByOne);
    242283}
    243284
  • trunk/Source/WebCore/platform/graphics/filters/FELighting.h

    r85926 r86759  
    4242namespace WebCore {
    4343
     44struct FELightingPaintingDataForNeon;
     45
    4446class FELighting : public FilterEffect {
    4547public:
     
    4951
    5052protected:
     53#if ENABLE(PARALLEL_JOBS)
     54    static const int s_minimalRectDimension = 100 * 100; // Empirical data limit for parallel jobs
     55#endif
     56
    5157    enum LightingType {
    5258        DiffuseLighting,
     
    7379    };
    7480
     81#if ENABLE(PARALLEL_JOBS)
     82    template<typename Type>
     83    friend class ParallelJobs;
     84
     85    struct PlatformApplyGenericParameters {
     86        FELighting* filter;
     87        LightingData data;
     88        LightSource::PaintingData paintingData;
     89        int yStart;
     90        int yEnd;
     91    };
     92
     93    static void platformApplyGenericWorker(PlatformApplyGenericParameters*);
     94    static void platformApplyNeonWorker(FELightingPaintingDataForNeon*);
     95#endif
     96
    7597    FELighting(Filter*, LightingType, const Color&, float, float, float, float, float, float, PassRefPtr<LightSource>);
    7698
     
    85107    inline void platformApply(LightingData&, LightSource::PaintingData&);
    86108
     109    inline void platformApplyGenericPaint(LightingData&, LightSource::PaintingData&, int startX, int startY);
    87110    inline void platformApplyGeneric(LightingData&, LightSource::PaintingData&);
     111
    88112    static int getPowerCoefficients(float exponent);
    89113    inline void platformApplyNeon(LightingData&, LightSource::PaintingData&);
  • trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp

    r85180 r86759  
    5151}
    5252
     53#if ENABLE(PARALLEL_JOBS)
     54void FELighting::platformApplyNeonWorker(FELightingPaintingDataForNeon* parameters)
     55{
     56    neonDrawLighting(parameters);
     57}
     58#endif
     59
    5360#define ASSTRING(str) #str
    5461#define TOSTRING(value) ASSTRING(value)
    5562
    5663#define PIXELS_OFFSET TOSTRING(0)
    57 #define WIDTH_OFFSET TOSTRING(4)
    58 #define HEIGHT_OFFSET TOSTRING(8)
    59 #define FLAGS_OFFSET TOSTRING(12)
    60 #define SPECULAR_EXPONENT_OFFSET TOSTRING(16)
    61 #define CONE_EXPONENT_OFFSET TOSTRING(20)
    62 #define FLOAT_ARGUMENTS_OFFSET TOSTRING(24)
    63 #define PAINTING_CONSTANTS_OFFSET TOSTRING(28)
     64#define YSTART_OFFSET TOSTRING(4)
     65#define WIDTH_OFFSET TOSTRING(8)
     66#define HEIGHT_OFFSET TOSTRING(12)
     67#define FLAGS_OFFSET TOSTRING(16)
     68#define SPECULAR_EXPONENT_OFFSET TOSTRING(20)
     69#define CONE_EXPONENT_OFFSET TOSTRING(24)
     70#define FLOAT_ARGUMENTS_OFFSET TOSTRING(28)
     71#define PAINTING_CONSTANTS_OFFSET TOSTRING(32)
    6472#define NL "\n"
    6573
     
    222230    "ldr r1, [" PAINTING_DATA_R ", #" PAINTING_CONSTANTS_OFFSET "]" NL
    223231    "ldr " PIXELS_R ", [" PAINTING_DATA_R ", #" PIXELS_OFFSET "]" NL
     232    "vldr.f32 " POSITION_Y_S ", [" PAINTING_DATA_R ", #" YSTART_OFFSET "]"  NL
    224233    "ldr " WIDTH_R ", [" PAINTING_DATA_R ", #" WIDTH_OFFSET "]" NL
    225234    "ldr " HEIGHT_R ", [" PAINTING_DATA_R ", #" HEIGHT_OFFSET "]" NL
     
    242251    "mov r0, #0" NL
    243252    "vmov.f32 " CONST_ZERO_S ", r0" NL
    244     "vmov.f32 " POSITION_Y_S ", " CONST_ONE_S NL
    245253    "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
    246254    "vmov.f32 " SPOT_COLOR_Q ", " COLOR_Q NL
  • trunk/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h

    r85180 r86759  
    3434#include "FELighting.h"
    3535#include <wtf/Alignment.h>
     36#include <wtf/ParallelJobs.h>
    3637
    3738namespace WebCore {
     
    7778struct FELightingPaintingDataForNeon {
    7879    unsigned char* pixels;
     80    float yStart;
    7981    int widthDecreasedByTwo;
    80     int heightDecreasedByTwo;
     82    int absoluteHeight;
    8183    // Combination of FLAG constants above.
    8284    int flags;
     
    99101    FELightingPaintingDataForNeon neonData = {
    100102        data.pixels->data(),
     103        1,
    101104        data.widthDecreasedByOne - 1,
    102105        data.heightDecreasedByOne - 1,
     
    165168        neonData.flags |= FLAG_DIFFUSE_CONST_IS_1;
    166169
     170#if ENABLE(PARALLEL_JOBS)
     171    int optimalThreadNumber = ((data.widthDecreasedByOne - 1) * (data.heightDecreasedByOne - 1)) / s_minimalRectDimension;
     172    if (optimalThreadNumber > 1) {
     173        // Initialize parallel jobs
     174        ParallelJobs<FELightingPaintingDataForNeon> parallelJobs(&WebCore::FELighting::platformApplyNeonWorker, optimalThreadNumber);
     175
     176        // Fill the parameter array
     177        int job = parallelJobs.numberOfJobs();
     178        if (job > 1) {
     179            int yStart = 1;
     180            int yStep = (data.heightDecreasedByOne - 1) / job;
     181            for (--job; job >= 0; --job) {
     182                FELightingPaintingDataForNeon& params = parallelJobs.parameter(job);
     183                params = neonData;
     184                params.yStart = yStart;
     185                params.pixels += (yStart - 1) * (data.widthDecreasedByOne + 1) * 4;
     186                if (job > 0) {
     187                    params.absoluteHeight = yStep;
     188                    yStart += yStep;
     189                } else
     190                    params.absoluteHeight = data.heightDecreasedByOne - yStart;
     191            }
     192            parallelJobs.execute();
     193            return;
     194        }
     195    }
     196#endif
     197
    167198    neonDrawLighting(&neonData);
    168199}
Note: See TracChangeset for help on using the changeset viewer.