Changeset 225009 in webkit


Ignore:
Timestamp:
Nov 17, 2017, 6:32:00 PM (8 years ago)
Author:
Simon Fraser
Message:

FETurbulence: compute all 4 channels at once
https://bugs.webkit.org/show_bug.cgi?id=179833

Reviewed by Sam Weinig.

Introduce some new helper classes for storing float color components, and use
them in calculateTurbulenceValueForPoint() and noise2D() for all the channels in one
pass. This makes FETurbulence about twice as fast.

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/ColorUtilities.cpp: Added.

(WebCore::ColorComponents::ColorComponents):

  • platform/graphics/ColorUtilities.h: Added.

(WebCore::FloatComponents::FloatComponents):
(WebCore::FloatComponents::operator +=):
(WebCore::FloatComponents::operator + const):
(WebCore::FloatComponents::operator / const):
(WebCore::FloatComponents::operator * const):
(WebCore::FloatComponents::abs const):
(WebCore::clampedColorComponent):

  • platform/graphics/filters/FETurbulence.cpp:

(WebCore::FETurbulence::noise2D):
(WebCore::FETurbulence::calculateTurbulenceValueForPoint):
(WebCore::FETurbulence::fillRegion):
(WebCore::FETurbulence::platformApplySoftware):

  • platform/graphics/filters/FETurbulence.h:
Location:
trunk/Source/WebCore
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r225008 r225009  
     12017-11-17  Simon Fraser  <simon.fraser@apple.com>
     2
     3        FETurbulence: compute all 4 channels at once
     4        https://bugs.webkit.org/show_bug.cgi?id=179833
     5
     6        Reviewed by Sam Weinig.
     7
     8        Introduce some new helper classes for storing float color components, and use
     9        them in calculateTurbulenceValueForPoint() and noise2D() for all the channels in one
     10        pass. This makes FETurbulence about twice as fast.
     11
     12        * Sources.txt:
     13        * WebCore.xcodeproj/project.pbxproj:
     14        * platform/graphics/ColorUtilities.cpp: Added.
     15        (WebCore::ColorComponents::ColorComponents):
     16        * platform/graphics/ColorUtilities.h: Added.
     17        (WebCore::FloatComponents::FloatComponents):
     18        (WebCore::FloatComponents::operator +=):
     19        (WebCore::FloatComponents::operator + const):
     20        (WebCore::FloatComponents::operator / const):
     21        (WebCore::FloatComponents::operator * const):
     22        (WebCore::FloatComponents::abs const):
     23        (WebCore::clampedColorComponent):
     24        * platform/graphics/filters/FETurbulence.cpp:
     25        (WebCore::FETurbulence::noise2D):
     26        (WebCore::FETurbulence::calculateTurbulenceValueForPoint):
     27        (WebCore::FETurbulence::fillRegion):
     28        (WebCore::FETurbulence::platformApplySoftware):
     29        * platform/graphics/filters/FETurbulence.h:
     30
    1312017-11-17  Chris Dumez  <cdumez@apple.com>
    232
  • trunk/Source/WebCore/Sources.txt

    r224929 r225009  
    14821482platform/graphics/BitmapImage.cpp
    14831483platform/graphics/Color.cpp
     1484platform/graphics/ColorUtilities.cpp
    14841485platform/graphics/ComplexTextController.cpp
    14851486platform/graphics/CrossfadeGeneratedImage.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r224957 r225009  
    54995499                0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListReplayer.cpp; path = displaylists/DisplayListReplayer.cpp; sourceTree = "<group>"; };
    55005500                0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListReplayer.h; path = displaylists/DisplayListReplayer.h; sourceTree = "<group>"; };
     5501                0FE6C76B1FBFB7A60025C053 /* ColorUtilities.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ColorUtilities.cpp; sourceTree = "<group>"; };
     5502                0FE6C76C1FBFB7A60025C053 /* ColorUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ColorUtilities.h; sourceTree = "<group>"; };
    55015503                0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarThemeMock.cpp; sourceTree = "<group>"; };
    55025504                0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeMock.h; sourceTree = "<group>"; };
     
    2259422596                                3103B7DE1DB01556008BB890 /* ColorHash.h */,
    2259522597                                9382DF5710A8D5C900925652 /* ColorSpace.h */,
     22598                                0FE6C76B1FBFB7A60025C053 /* ColorUtilities.cpp */,
     22599                                0FE6C76C1FBFB7A60025C053 /* ColorUtilities.h */,
    2259622600                                C2F4E7881E45AEDF006D7105 /* ComplexTextController.cpp */,
    2259722601                                C2F4E7891E45AEDF006D7105 /* ComplexTextController.h */,
  • trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp

    r224996 r225009  
    66 * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
    77 * Copyright (C) 2011 Gabor Loki <loki@webkit.org>
     8 * Copyright (C) 2017 Apple Inc.
    89 *
    910 * This library is free software; you can redistribute it and/or
     
    187188}
    188189
    189 float FETurbulence::noise2D(int channel, const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& noiseVector)
     190FloatComponents FETurbulence::noise2D(const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& noiseVector)
    190191{
    191192    struct Noise {
     
    217218    float sx = smoothCurve(noiseX.noisePositionFractionValue);
    218219    float sy = smoothCurve(noiseY.noisePositionFractionValue);
    219     float a, b, u, v;
    220 
    221     // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
    222     int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
    223     const float* q = paintingData.gradient[channel][temp];
    224     u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
    225     temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
    226     q = paintingData.gradient[channel][temp];
    227     v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
    228     a = linearInterpolation(sx, u, v);
    229     temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
    230     q = paintingData.gradient[channel][temp];
    231     u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
    232     temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
    233     q = paintingData.gradient[channel][temp];
    234     v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
    235     b = linearInterpolation(sx, u, v);
    236     return linearInterpolation(sy, a, b);
    237 }
    238 
    239 unsigned char FETurbulence::calculateTurbulenceValueForPoint(int channel, const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& point)
     220
     221    auto noiseForChannel = [&](int channel) {
     222        // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
     223        int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
     224        const float* q = paintingData.gradient[channel][temp];
     225
     226        float u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
     227        temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
     228        q = paintingData.gradient[channel][temp];
     229        float v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
     230        float a = linearInterpolation(sx, u, v);
     231        temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
     232        q = paintingData.gradient[channel][temp];
     233        u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
     234        temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
     235        q = paintingData.gradient[channel][temp];
     236        v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
     237        float b = linearInterpolation(sx, u, v);
     238
     239        return linearInterpolation(sy, a, b);
     240    };
     241
     242    return {
     243        noiseForChannel(0),
     244        noiseForChannel(1),
     245        noiseForChannel(2),
     246        noiseForChannel(3)
     247    };
     248}
     249
     250ColorComponents FETurbulence::calculateTurbulenceValueForPoint(const PaintingData& paintingData, StitchData& stitchData, const FloatPoint& point)
    240251{
    241252    float tileWidth = paintingData.filterSize.width();
     
    244255    float baseFrequencyX = m_baseFrequencyX;
    245256    float baseFrequencyY = m_baseFrequencyY;
     257
    246258    // Adjust the base frequencies if necessary for stitching.
    247259    if (m_stitchTiles) {
     
    272284    }
    273285
    274     float turbulenceFunctionResult = 0;
     286    FloatComponents turbulenceFunctionResult;
    275287    FloatPoint noiseVector(point.x() * baseFrequencyX, point.y() * baseFrequencyY);
    276288    float ratio = 1;
    277289    for (int octave = 0; octave < m_numOctaves; ++octave) {
    278290        if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
    279             turbulenceFunctionResult += noise2D(channel, paintingData, stitchData, noiseVector) / ratio;
     291            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector) / ratio;
    280292        else
    281             turbulenceFunctionResult += fabsf(noise2D(channel, paintingData, stitchData, noiseVector)) / ratio;
     293            turbulenceFunctionResult += noise2D(paintingData, stitchData, noiseVector).abs() / ratio;
     294
    282295        noiseVector.setX(noiseVector.x() * 2);
    283296        noiseVector.setY(noiseVector.y() * 2);
    284297        ratio *= 2;
     298
    285299        if (m_stitchTiles) {
    286300            // Update stitch values. Subtracting s_perlinNoiseoise before the multiplication and
     
    297311    if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
    298312        turbulenceFunctionResult = turbulenceFunctionResult * 0.5f + 0.5f;
    299     // Clamp result
    300     turbulenceFunctionResult = std::max(std::min(turbulenceFunctionResult, 1.f), 0.f);
    301     return static_cast<unsigned char>(turbulenceFunctionResult * 255);
     313
     314    return turbulenceFunctionResult;
    302315}
    303316
     
    316329            point.setX(point.x() + 1);
    317330            FloatPoint localPoint = inverseTransfrom.mapPoint(point);
    318             for (int channel = 0; channel < 4; ++channel, ++indexOfPixelChannel)
    319                 pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(channel, paintingData, stitchData, localPoint));
     331            ColorComponents values = calculateTurbulenceValueForPoint(paintingData, stitchData, localPoint);
     332            pixelArray->set(indexOfPixelChannel++, values.components[0]);
     333            pixelArray->set(indexOfPixelChannel++, values.components[1]);
     334            pixelArray->set(indexOfPixelChannel++, values.components[2]);
     335            pixelArray->set(indexOfPixelChannel++, values.components[3]);
    320336        }
    321337    }
     
    356372            int startY = 0;
    357373            for (; i > 0; --i) {
    358                 FillRegionParameters& params = parallelJobs.parameter(i-1);
     374                FillRegionParameters& params = parallelJobs.parameter(i - 1);
    359375                params.filter = this;
    360376                params.pixelArray = pixelArray;
  • trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h

    r225005 r225009  
    55 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
    66 * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
     7 * Copyright (C) 2017 Apple Inc.
    78 *
    89 * This library is free software; you can redistribute it and/or
     
    2223 */
    2324
    24 #ifndef FETurbulence_h
    25 #define FETurbulence_h
     25#pragma once
    2626
     27#include "ColorUtilities.h"
    2728#include "FilterEffect.h"
    2829#include "Filter.h"
     
    119120
    120121    void initPaint(PaintingData&);
    121     float noise2D(int channel, const PaintingData&, StitchData&, const FloatPoint&);
    122     unsigned char calculateTurbulenceValueForPoint(int channel, const PaintingData&, StitchData&, const FloatPoint&);
     122    FloatComponents noise2D(const PaintingData&, StitchData&, const FloatPoint&);
     123    ColorComponents calculateTurbulenceValueForPoint(const PaintingData&, StitchData&, const FloatPoint&);
    123124    void fillRegion(Uint8ClampedArray*, const PaintingData&, int, int);
    124125
     
    133134} // namespace WebCore
    134135
    135 #endif // FETurbulence_h
Note: See TracChangeset for help on using the changeset viewer.