| Differences between
and this patch
- a/Source/WebCore/Target.pri +20 lines
Lines 4014-4019 contains(CONFIG, opengl-shims) { a/Source/WebCore/Target.pri_sec1
4014
    DEFINES += QT_OPENGL_SHIMS=1
4014
    DEFINES += QT_OPENGL_SHIMS=1
4015
}
4015
}
4016
4016
4017
contains(DEFINES, ENABLE_OPENCL=1) {
4018
    HEADERS += platform/graphics/filters/OpenCL/OpenCLContext.h
4019
    SOURCES += platform/graphics/filters/OpenCL/OpenCLContext.cpp
4020
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEImage.cpp
4021
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEComposite.cpp
4022
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEBlend.cpp
4023
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEFlood.cpp
4024
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEOffset.cpp
4025
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFESourceGraphic.cpp
4026
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFESourceAlpha.cpp
4027
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFETurbulence.cpp
4028
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEColorMatrix.cpp
4029
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEConvolveMatrix.cpp
4030
    #SOURCES += platform/graphics/filters/OpenCL/OpenCLFEComponentTransfer.cpp
4031
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEMerge.cpp
4032
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFEMorphology.cpp
4033
    SOURCES += platform/graphics/filters/OpenCL/OpenCLFETile.cpp
4034
    DEFINES += OPENCL=1
4035
}
4036
4017
use?(GRAPHICS_SURFACE) {
4037
use?(GRAPHICS_SURFACE) {
4018
    mac {
4038
    mac {
4019
        SOURCES += platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
4039
        SOURCES += platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
- a/Source/WebCore/WebCore.pri +5 lines
Lines 263-268 unix|win32-g++* { a/Source/WebCore/WebCore.pri_sec1
263
    QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui QtNetwork QtWidgets
263
    QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui QtNetwork QtWidgets
264
}
264
}
265
265
266
contains(DEFINES, ENABLE_OPENCL=1){
267
  QMAKE_LFLAGS += -I/usr/include/ -L/usr/lib/
268
  LIBS += -lOpenCL
269
}
270
266
# Disable C++0x mode in WebCore for those who enabled it in their Qt's mkspec
271
# Disable C++0x mode in WebCore for those who enabled it in their Qt's mkspec
267
*-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x
272
*-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x
268
273
- a/Source/WebCore/platform/graphics/filters/FEBlend.h -1 / +3 lines
Lines 52-58 public: a/Source/WebCore/platform/graphics/filters/FEBlend.h_sec1
52
#if USE(SKIA)
52
#if USE(SKIA)
53
    virtual bool platformApplySkia();
53
    virtual bool platformApplySkia();
54
#endif
54
#endif
55
55
#if ENABLE(OPENCL)
56
    virtual bool platformApplyOpenCL();
57
#endif
56
    virtual void platformApplySoftware();
58
    virtual void platformApplySoftware();
57
    virtual void dump();
59
    virtual void dump();
58
60
- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h +3 lines
Lines 49-54 public: a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h_sec1
49
    bool setValues(const Vector<float>&);
49
    bool setValues(const Vector<float>&);
50
50
51
    virtual void platformApplySoftware();
51
    virtual void platformApplySoftware();
52
#if ENABLE(OPENCL)
53
    virtual bool platformApplyOpenCL();
54
#endif
52
#if USE(SKIA)
55
#if USE(SKIA)
53
    virtual bool platformApplySkia();
56
    virtual bool platformApplySkia();
54
#endif
57
#endif
- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp +12 lines
Lines 174-179 void FEComponentTransfer::platformApplySoftware() a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp_sec1
174
    }
174
    }
175
}
175
}
176
176
177
#if ENABLE(OPENCL)
178
bool FEComponentTransfer::platformApplyOpenCL()
179
{
180
    asImageBuffer();
181
    platformApplySoftware();
182
    ImageBuffer* sourceImage = asImageBuffer();
183
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
184
    createOpenCLImageResult(sourceImageData->data());
185
    return true;
186
}
187
#endif
188
177
void FEComponentTransfer::getValues(unsigned char rValues[256], unsigned char gValues[256], unsigned char bValues[256], unsigned char aValues[256])
189
void FEComponentTransfer::getValues(unsigned char rValues[256], unsigned char gValues[256], unsigned char bValues[256], unsigned char aValues[256])
178
{
190
{
179
    for (unsigned i = 0; i < 256; ++i)
191
    for (unsigned i = 0; i < 256; ++i)
- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h +3 lines
Lines 79-84 public: a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h_sec1
79
    void setAlphaFunction(const ComponentTransferFunction&);
79
    void setAlphaFunction(const ComponentTransferFunction&);
80
80
81
    virtual void platformApplySoftware();
81
    virtual void platformApplySoftware();
82
#if ENABLE(OPENCL)
83
    virtual bool platformApplyOpenCL();
84
#endif
82
#if USE(SKIA)
85
#if USE(SKIA)
83
    virtual bool platformApplySkia();
86
    virtual bool platformApplySkia();
84
#endif
87
#endif
- a/Source/WebCore/platform/graphics/filters/FEComposite.h +3 lines
Lines 62-67 public: a/Source/WebCore/platform/graphics/filters/FEComposite.h_sec1
62
    virtual void correctFilterResultIfNeeded() OVERRIDE;
62
    virtual void correctFilterResultIfNeeded() OVERRIDE;
63
63
64
    virtual void platformApplySoftware();
64
    virtual void platformApplySoftware();
65
#if ENABLE(OPENCL)
66
    virtual bool platformApplyOpenCL();
67
#endif
65
    virtual void dump();
68
    virtual void dump();
66
    
69
    
67
    virtual void determineAbsolutePaintRect();
70
    virtual void determineAbsolutePaintRect();
- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h +3 lines
Lines 71-76 public: a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h_sec1
71
    bool setPreserveAlpha(bool);
71
    bool setPreserveAlpha(bool);
72
72
73
    virtual void platformApplySoftware();
73
    virtual void platformApplySoftware();
74
#if ENABLE(OPENCL)
75
    virtual bool platformApplyOpenCL();
76
#endif
74
    virtual void dump();
77
    virtual void dump();
75
78
76
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
79
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
- a/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp +12 lines
Lines 135-140 void FECustomFilter::platformApplySoftware() a/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp_sec1
135
        clearShaderResult();
135
        clearShaderResult();
136
}
136
}
137
137
138
#if ENABLE(OPENCL)
139
bool FECustomFilter::platformApplyOpenCL()
140
{
141
    asImageBuffer();
142
    platformApplySoftware();
143
    ImageBuffer* sourceImage = asImageBuffer();
144
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
145
    createOpenCLImageResult(sourceImageData->data());
146
    return true;
147
}
148
#endif
149
138
void FECustomFilter::clearShaderResult()
150
void FECustomFilter::clearShaderResult()
139
{
151
{
140
    clearResult();
152
    clearResult();
- a/Source/WebCore/platform/graphics/filters/FECustomFilter.h +3 lines
Lines 64-69 public: a/Source/WebCore/platform/graphics/filters/FECustomFilter.h_sec1
64
                   CustomFilterOperation::MeshType);
64
                   CustomFilterOperation::MeshType);
65
65
66
    virtual void platformApplySoftware();
66
    virtual void platformApplySoftware();
67
#if ENABLE(OPENCL)
68
    virtual bool platformApplyOpenCL();
69
#endif
67
    virtual void dump();
70
    virtual void dump();
68
71
69
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
72
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp +12 lines
Lines 133-138 void FEDisplacementMap::platformApplySoftware() a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp_sec1
133
    }
133
    }
134
}
134
}
135
135
136
#if ENABLE(OPENCL)
137
bool FEDisplacementMap::platformApplyOpenCL()
138
{
139
    asImageBuffer();
140
    platformApplySoftware();
141
    ImageBuffer* sourceImage = asImageBuffer();
142
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
143
    createOpenCLImageResult(sourceImageData->data());
144
    return true;
145
}
146
#endif
147
136
void FEDisplacementMap::dump()
148
void FEDisplacementMap::dump()
137
{
149
{
138
}
150
}
- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h +3 lines
Lines 51-56 public: a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h_sec1
51
    bool setScale(float);
51
    bool setScale(float);
52
52
53
    virtual void platformApplySoftware();
53
    virtual void platformApplySoftware();
54
#if ENABLE(OPENCL)
55
    virtual bool platformApplyOpenCL();
56
#endif
54
    virtual void dump();
57
    virtual void dump();
55
58
56
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
59
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
- a/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp +12 lines
Lines 119-124 void FEDropShadow::platformApplySoftware() a/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp_sec1
119
    resultImage->context()->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegion);
119
    resultImage->context()->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegion);
120
}
120
}
121
121
122
#if ENABLE(OPENCL)
123
bool FEDropShadow::platformApplyOpenCL()
124
{
125
    asImageBuffer();
126
    platformApplySoftware();
127
    ImageBuffer* sourceImage = asImageBuffer();
128
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
129
    createOpenCLImageResult(sourceImageData->data());
130
    return true;
131
}
132
#endif
133
122
void FEDropShadow::dump()
134
void FEDropShadow::dump()
123
{
135
{
124
}
136
}
- a/Source/WebCore/platform/graphics/filters/FEDropShadow.h +3 lines
Lines 52-57 public: a/Source/WebCore/platform/graphics/filters/FEDropShadow.h_sec1
52
    static float calculateStdDeviation(float);
52
    static float calculateStdDeviation(float);
53
53
54
    virtual void platformApplySoftware();
54
    virtual void platformApplySoftware();
55
#if ENABLE(OPENCL)
56
    virtual bool platformApplyOpenCL();
57
#endif
55
    virtual void dump();
58
    virtual void dump();
56
59
57
    virtual void determineAbsolutePaintRect();
60
    virtual void determineAbsolutePaintRect();
- a/Source/WebCore/platform/graphics/filters/FEFlood.h +3 lines
Lines 40-45 public: a/Source/WebCore/platform/graphics/filters/FEFlood.h_sec1
40
    bool setFloodOpacity(float);
40
    bool setFloodOpacity(float);
41
41
42
    virtual void platformApplySoftware();
42
    virtual void platformApplySoftware();
43
#if ENABLE(OPENCL)
44
    virtual bool platformApplyOpenCL();
45
#endif
43
    virtual void dump();
46
    virtual void dump();
44
47
45
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
48
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +12 lines
Lines 305-310 void FEGaussianBlur::platformApplySoftware() a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp_sec1
305
    platformApply(srcPixelArray, tmpPixelArray, kernelSizeX, kernelSizeY, paintSize);
305
    platformApply(srcPixelArray, tmpPixelArray, kernelSizeX, kernelSizeY, paintSize);
306
}
306
}
307
307
308
#if ENABLE(OPENCL)
309
bool FEGaussianBlur::platformApplyOpenCL()
310
{
311
    asImageBuffer();
312
    platformApplySoftware();
313
    ImageBuffer* sourceImage = asImageBuffer();
314
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
315
    createOpenCLImageResult(sourceImageData->data());
316
    return true;
317
}
318
#endif
319
308
void FEGaussianBlur::dump()
320
void FEGaussianBlur::dump()
309
{
321
{
310
}
322
}
- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h +3 lines
Lines 41-46 public: a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h_sec1
41
    static float calculateStdDeviation(float);
41
    static float calculateStdDeviation(float);
42
42
43
    virtual void platformApplySoftware();
43
    virtual void platformApplySoftware();
44
#if ENABLE(OPENCL)
45
    virtual bool platformApplyOpenCL();
46
#endif
44
    virtual void dump();
47
    virtual void dump();
45
    
48
    
46
    virtual void determineAbsolutePaintRect();
49
    virtual void determineAbsolutePaintRect();
- a/Source/WebCore/platform/graphics/filters/FELighting.cpp +12 lines
Lines 406-411 void FELighting::platformApplySoftware() a/Source/WebCore/platform/graphics/filters/FELighting.cpp_sec1
406
    drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height());
406
    drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height());
407
}
407
}
408
408
409
#if ENABLE(OPENCL)
410
bool FELighting::platformApplyOpenCL()
411
{
412
    asImageBuffer();
413
    platformApplySoftware();
414
    ImageBuffer* sourceImage = asImageBuffer();
415
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
416
    createOpenCLImageResult(sourceImageData->data());
417
    return true;
418
}
419
#endif
420
409
} // namespace WebCore
421
} // namespace WebCore
410
422
411
#endif // ENABLE(FILTERS)
423
#endif // ENABLE(FILTERS)
- a/Source/WebCore/platform/graphics/filters/FELighting.h +3 lines
Lines 46-51 struct FELightingPaintingDataForNeon; a/Source/WebCore/platform/graphics/filters/FELighting.h_sec1
46
class FELighting : public FilterEffect {
46
class FELighting : public FilterEffect {
47
public:
47
public:
48
    virtual void platformApplySoftware();
48
    virtual void platformApplySoftware();
49
#if ENABLE(OPENCL)
50
    virtual bool platformApplyOpenCL();
51
#endif
49
#if USE(SKIA)
52
#if USE(SKIA)
50
    virtual bool platformApplySkia();
53
    virtual bool platformApplySkia();
51
#endif
54
#endif
- a/Source/WebCore/platform/graphics/filters/FEMerge.h +3 lines
Lines 34-39 public: a/Source/WebCore/platform/graphics/filters/FEMerge.h_sec1
34
    static PassRefPtr<FEMerge> create(Filter*);
34
    static PassRefPtr<FEMerge> create(Filter*);
35
35
36
    virtual void platformApplySoftware();
36
    virtual void platformApplySoftware();
37
#if ENABLE(OPENCL)
38
    virtual bool platformApplyOpenCL();
39
#endif
37
    virtual void dump();
40
    virtual void dump();
38
41
39
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
42
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- a/Source/WebCore/platform/graphics/filters/FEMorphology.h +3 lines
Lines 47-52 public: a/Source/WebCore/platform/graphics/filters/FEMorphology.h_sec1
47
    bool setRadiusY(float);
47
    bool setRadiusY(float);
48
48
49
    virtual void platformApplySoftware();
49
    virtual void platformApplySoftware();
50
#if ENABLE(OPENCL)
51
    virtual bool platformApplyOpenCL();
52
#endif
50
#if USE(SKIA)
53
#if USE(SKIA)
51
    virtual bool platformApplySkia();
54
    virtual bool platformApplySkia();
52
#endif
55
#endif
- a/Source/WebCore/platform/graphics/filters/FEOffset.h +3 lines
Lines 39-44 public: a/Source/WebCore/platform/graphics/filters/FEOffset.h_sec1
39
    void setDy(float);
39
    void setDy(float);
40
40
41
    virtual void platformApplySoftware();
41
    virtual void platformApplySoftware();
42
#if ENABLE(OPENCL)
43
    virtual bool platformApplyOpenCL();
44
#endif
42
    virtual void dump();
45
    virtual void dump();
43
    
46
    
44
    virtual void determineAbsolutePaintRect();
47
    virtual void determineAbsolutePaintRect();
- a/Source/WebCore/platform/graphics/filters/FETile.h +3 lines
Lines 33-38 public: a/Source/WebCore/platform/graphics/filters/FETile.h_sec1
33
    static PassRefPtr<FETile> create(Filter* filter);
33
    static PassRefPtr<FETile> create(Filter* filter);
34
34
35
    virtual void platformApplySoftware();
35
    virtual void platformApplySoftware();
36
#if ENABLE(OPENCL)
37
    virtual bool platformApplyOpenCL();
38
#endif
36
    virtual void dump();
39
    virtual void dump();
37
40
38
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
41
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
- a/Source/WebCore/platform/graphics/filters/FETurbulence.h +3 lines
Lines 61-66 public: a/Source/WebCore/platform/graphics/filters/FETurbulence.h_sec1
61
    static void fillRegionWorker(void*);
61
    static void fillRegionWorker(void*);
62
62
63
    virtual void platformApplySoftware();
63
    virtual void platformApplySoftware();
64
#if ENABLE(OPENCL)
65
    virtual bool platformApplyOpenCL();
66
#endif
64
    virtual void dump();
67
    virtual void dump();
65
    
68
    
66
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
69
    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp +87 lines
Lines 36-42 a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec1
36
namespace WebCore {
36
namespace WebCore {
37
37
38
FilterEffect::FilterEffect(Filter* filter)
38
FilterEffect::FilterEffect(Filter* filter)
39
#if ENABLE(OPENCL)
40
    : m_openclImageResult(0)
41
    , m_alphaImage(false)
42
#else
39
    : m_alphaImage(false)
43
    : m_alphaImage(false)
44
#endif
40
    , m_filter(filter)
45
    , m_filter(filter)
41
    , m_hasX(false)
46
    , m_hasX(false)
42
    , m_hasY(false)
47
    , m_hasY(false)
Lines 51-56 FilterEffect::FilterEffect(Filter* filter) a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec2
51
56
52
FilterEffect::~FilterEffect()
57
FilterEffect::~FilterEffect()
53
{
58
{
59
#if ENABLE(OPENCL)
60
    if (m_openclImageResult)
61
        clReleaseMemObject(m_openclImageResult);
62
#endif
54
}
63
}
55
64
56
inline bool isFilterSizeValid(IntRect rect)
65
inline bool isFilterSizeValid(IntRect rect)
Lines 108-114 void FilterEffect::apply() a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec3
108
            return;
117
            return;
109
118
110
        // Convert input results to the current effect's color space.
119
        // Convert input results to the current effect's color space.
120
#if ENABLE(OPENCL)
121
        in->transformResultColorSpaceOpenCL(m_colorSpace);
122
#else
111
        in->transformResultColorSpace(m_colorSpace);
123
        in->transformResultColorSpace(m_colorSpace);
124
#endif
112
    }
125
    }
113
126
114
    determineAbsolutePaintRect();
127
    determineAbsolutePaintRect();
Lines 123-128 void FilterEffect::apply() a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec4
123
    }
136
    }
124
    
137
    
125
    // Add platform specific apply functions here and return earlier.
138
    // Add platform specific apply functions here and return earlier.
139
#if ENABLE(OPENCL)
140
    if (platformApplyOpenCL())
141
        return;
142
#endif
126
#if USE(SKIA)
143
#if USE(SKIA)
127
    if (platformApplySkia())
144
    if (platformApplySkia())
128
        return;
145
        return;
Lines 187-192 void FilterEffect::clearResult() a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec5
187
        m_unmultipliedImageResult.clear();
204
        m_unmultipliedImageResult.clear();
188
    if (m_premultipliedImageResult)
205
    if (m_premultipliedImageResult)
189
        m_premultipliedImageResult.clear();
206
        m_premultipliedImageResult.clear();
207
#if ENABLE(OPENCL)
208
    if (m_openclImageResult){
209
        clReleaseMemObject(m_openclImageResult);
210
        m_openclImageResult = 0;
211
    }
212
#endif
190
}
213
}
191
214
192
ImageBuffer* FilterEffect::asImageBuffer()
215
ImageBuffer* FilterEffect::asImageBuffer()
Lines 195-200 ImageBuffer* FilterEffect::asImageBuffer() a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec6
195
        return 0;
218
        return 0;
196
    if (m_imageBufferResult)
219
    if (m_imageBufferResult)
197
        return m_imageBufferResult.get();
220
        return m_imageBufferResult.get();
221
#if ENABLE(OPENCL)
222
    if (m_openclImageResult)
223
        return getOpenCLImageResult();
224
#endif
198
    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), 1, m_resultColorSpace, m_filter->renderingMode());
225
    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), 1, m_resultColorSpace, m_filter->renderingMode());
199
    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
226
    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
200
    if (m_premultipliedImageResult)
227
    if (m_premultipliedImageResult)
Lines 204-209 ImageBuffer* FilterEffect::asImageBuffer() a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec7
204
    return m_imageBufferResult.get();
231
    return m_imageBufferResult.get();
205
}
232
}
206
233
234
#if ENABLE(OPENCL)
235
ImageBuffer* FilterEffect::getOpenCLImageResult()
236
{
237
    FilterContextOpenCL* context = FilterContextOpenCL::context();
238
    ASSERT(context);
239
240
    size_t origin[3] = { 0, 0, 0 };
241
    size_t region[3] = { m_absolutePaintRect.width(), m_absolutePaintRect.height(), 1};
242
243
    RefPtr<Uint8ClampedArray> destinationPixelArray = Uint8ClampedArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
244
245
    clEnqueueReadImage(context->commandQueue(), m_openclImageResult, CL_TRUE, origin, region, 0, 0, destinationPixelArray->data(), 0, 0, 0);
246
247
    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size());
248
    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
249
    m_imageBufferResult->putByteArray(Unmultiplied, destinationPixelArray.get(), destinationRect.size(), destinationRect, IntPoint());
250
251
    return m_imageBufferResult.get();
252
}
253
#endif
254
207
PassRefPtr<Uint8ClampedArray> FilterEffect::asUnmultipliedImage(const IntRect& rect)
255
PassRefPtr<Uint8ClampedArray> FilterEffect::asUnmultipliedImage(const IntRect& rect)
208
{
256
{
209
    ASSERT(isFilterSizeValid(rect));
257
    ASSERT(isFilterSizeValid(rect));
Lines 363-368 Uint8ClampedArray* FilterEffect::createPremultipliedImageResult() a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec8
363
    return m_premultipliedImageResult.get();
411
    return m_premultipliedImageResult.get();
364
}
412
}
365
413
414
#if ENABLE(OPENCL)
415
cl_mem FilterEffect::createOpenCLImageResult(unsigned char* source)
416
{
417
    ASSERT(!hasResult());
418
    cl_image_format clImageFormat;
419
    clImageFormat.image_channel_order = CL_RGBA;
420
    clImageFormat.image_channel_data_type = CL_UNORM_INT8;
421
422
    FilterContextOpenCL* context = FilterContextOpenCL::context();
423
    ASSERT(context);
424
    cl_int er;
425
    m_openclImageResult = clCreateImage2D(context->deviceContext(), source ? (CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR) : CL_MEM_READ_WRITE,
426
        &clImageFormat, m_absolutePaintRect.width(), m_absolutePaintRect.height(), 0, source, &er);
427
    if (er != CL_SUCCESS)
428
        context->OpenCLPrintError(er);
429
    context->OpenCLDebugImage(m_openclImageResult);
430
    return m_openclImageResult;
431
}
432
#endif
433
366
void FilterEffect::transformResultColorSpace(ColorSpace dstColorSpace)
434
void FilterEffect::transformResultColorSpace(ColorSpace dstColorSpace)
367
{
435
{
368
#if USE(CG)
436
#if USE(CG)
Lines 389-394 void FilterEffect::transformResultColorSpace(ColorSpace dstColorSpace) a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec9
389
#endif
457
#endif
390
}
458
}
391
459
460
#if ENABLE(OPENCL)
461
void FilterEffect::transformResultColorSpaceOpenCL(ColorSpace dstColorSpace)
462
{
463
    if (!hasResult() || dstColorSpace == m_resultColorSpace)
464
        return;
465
466
    if (!m_openclImageResult) {
467
        asOpenCLImage();
468
        ASSERT(m_openclImageResult);
469
    }
470
471
    FilterContextOpenCL* context = FilterContextOpenCL::context();
472
473
    m_openclImageResult = context->OpenCLTransformColorSpace(m_openclImageResult, m_resultColorSpace, dstColorSpace, absolutePaintRect());
474
475
    m_resultColorSpace = dstColorSpace;
476
}
477
#endif
478
392
TextStream& FilterEffect::externalRepresentation(TextStream& ts, int) const
479
TextStream& FilterEffect::externalRepresentation(TextStream& ts, int) const
393
{
480
{
394
    // FIXME: We should dump the subRegions of the filter primitives here later. This isn't
481
    // FIXME: We should dump the subRegions of the filter primitives here later. This isn't
- a/Source/WebCore/platform/graphics/filters/FilterEffect.h -1 / +25 lines
Lines 33-38 a/Source/WebCore/platform/graphics/filters/FilterEffect.h_sec1
33
#include <wtf/Uint8ClampedArray.h>
33
#include <wtf/Uint8ClampedArray.h>
34
#include <wtf/Vector.h>
34
#include <wtf/Vector.h>
35
35
36
#if ENABLE(OPENCL)
37
#include "OpenCL/OpenCLContext.h"
38
#endif
39
36
static const float kMaxFilterSize = 5000.0f;
40
static const float kMaxFilterSize = 5000.0f;
37
41
38
namespace WebCore {
42
namespace WebCore {
Lines 62-67 public: a/Source/WebCore/platform/graphics/filters/FilterEffect.h_sec2
62
    void copyUnmultipliedImage(Uint8ClampedArray* destination, const IntRect&);
66
    void copyUnmultipliedImage(Uint8ClampedArray* destination, const IntRect&);
63
    void copyPremultipliedImage(Uint8ClampedArray* destination, const IntRect&);
67
    void copyPremultipliedImage(Uint8ClampedArray* destination, const IntRect&);
64
68
69
#if ENABLE(OPENCL)
70
    cl_mem asOpenCLImage() { return m_openclImageResult; }
71
    ImageBuffer* getOpenCLImageResult();
72
#endif
73
65
    FilterEffectVector& inputEffects() { return m_inputEffects; }
74
    FilterEffectVector& inputEffects() { return m_inputEffects; }
66
    FilterEffect* inputEffect(unsigned) const;
75
    FilterEffect* inputEffect(unsigned) const;
67
    unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
76
    unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
Lines 69-75 public: a/Source/WebCore/platform/graphics/filters/FilterEffect.h_sec3
69
    inline bool hasResult() const
78
    inline bool hasResult() const
70
    {
79
    {
71
        // This function needs platform specific checks, if the memory managment is not done by FilterEffect.
80
        // This function needs platform specific checks, if the memory managment is not done by FilterEffect.
81
#if ENABLE(OPENCL)
82
        return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult || m_openclImageResult;
83
#else
72
        return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult;
84
        return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult;
85
#endif
73
    }
86
    }
74
87
75
    IntRect drawingRegionOfInputImage(const IntRect&) const;
88
    IntRect drawingRegionOfInputImage(const IntRect&) const;
Lines 93-98 public: a/Source/WebCore/platform/graphics/filters/FilterEffect.h_sec4
93
    virtual void correctFilterResultIfNeeded() { }
106
    virtual void correctFilterResultIfNeeded() { }
94
107
95
    virtual void platformApplySoftware() = 0;
108
    virtual void platformApplySoftware() = 0;
109
#if ENABLE(OPENCL)
110
    virtual bool platformApplyOpenCL() = 0;
111
#endif
96
#if USE(SKIA)
112
#if USE(SKIA)
97
    virtual bool platformApplySkia() { return false; }
113
    virtual bool platformApplySkia() { return false; }
98
#endif
114
#endif
Lines 133-138 public: a/Source/WebCore/platform/graphics/filters/FilterEffect.h_sec5
133
    ColorSpace colorSpace() const { return m_colorSpace; }
149
    ColorSpace colorSpace() const { return m_colorSpace; }
134
    void setColorSpace(ColorSpace colorSpace) { m_colorSpace = colorSpace; }
150
    void setColorSpace(ColorSpace colorSpace) { m_colorSpace = colorSpace; }
135
    void transformResultColorSpace(ColorSpace);
151
    void transformResultColorSpace(ColorSpace);
152
#if ENABLE(OPENCL)
153
    void transformResultColorSpaceOpenCL(ColorSpace);
154
#endif
136
155
137
protected:
156
protected:
138
    FilterEffect(Filter*);
157
    FilterEffect(Filter*);
Lines 140-145 protected: a/Source/WebCore/platform/graphics/filters/FilterEffect.h_sec6
140
    ImageBuffer* createImageBufferResult();
159
    ImageBuffer* createImageBufferResult();
141
    Uint8ClampedArray* createUnmultipliedImageResult();
160
    Uint8ClampedArray* createUnmultipliedImageResult();
142
    Uint8ClampedArray* createPremultipliedImageResult();
161
    Uint8ClampedArray* createPremultipliedImageResult();
162
#if ENABLE(OPENCL)
163
    cl_mem createOpenCLImageResult(unsigned char* = 0);
164
#endif
143
165
144
    // Return true if the filter will only operate correctly on valid RGBA values, with
166
    // Return true if the filter will only operate correctly on valid RGBA values, with
145
    // alpha in [0,255] and each color component in [0, alpha].
167
    // alpha in [0,255] and each color component in [0, alpha].
Lines 153-159 private: a/Source/WebCore/platform/graphics/filters/FilterEffect.h_sec7
153
    RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
175
    RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
154
    RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
176
    RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
155
    FilterEffectVector m_inputEffects;
177
    FilterEffectVector m_inputEffects;
156
178
#if ENABLE(OPENCL)
179
    cl_mem m_openclImageResult;
180
#endif
157
    bool m_alphaImage;
181
    bool m_alphaImage;
158
182
159
    IntRect m_absolutePaintRect;
183
    IntRect m_absolutePaintRect;
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLContext.cpp +418 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLContext.cpp_sec1
1
#include "config.h"
2
3
#if ENABLE(OPENCL)
4
#include "OpenCLContext.h"
5
#include <iostream>
6
#include <time.h>
7
#include "stdio.h"
8
9
#define PROGRAM_STR(Src) #Src
10
#define PROGRAM(Src) PROGRAM_STR(Src)
11
12
namespace WebCore {
13
14
FilterContextOpenCL* FilterContextOpenCL::context()
15
{
16
     static bool wasInitialized = false;
17
     static FilterContextOpenCL* context = 0;
18
19
     if (wasInitialized)
20
         return context;
21
22
#ifdef NDEBUG
23
     printf("debug\n");
24
#endif
25
     wasInitialized = true;
26
     context = new FilterContextOpenCL();
27
28
     // Initializing the context.
29
     cl_int errNum;
30
     cl_device_id *devices;
31
     cl_platform_id firstPlatformId;
32
     size_t deviceBufferSize = -1;
33
34
     errNum = clGetPlatformIDs(1, &firstPlatformId, NULL);
35
     cl_context_properties contextProperties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)firstPlatformId, 0};
36
     context->m_deviceContext = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_GPU, NULL, NULL, &errNum);
37
     if (errNum != CL_SUCCESS) {
38
         context->m_deviceContext = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_CPU, NULL, NULL, &errNum);
39
         if (errNum != CL_SUCCESS)
40
            return context;
41
     }
42
43
     errNum = clGetContextInfo(context->m_deviceContext, CL_CONTEXT_DEVICES, 0, NULL, &deviceBufferSize);
44
     if (errNum != CL_SUCCESS)
45
         return context;
46
47
     if (deviceBufferSize <= 0)
48
         return context;
49
50
     devices = new cl_device_id[deviceBufferSize / sizeof(cl_device_id)];
51
     errNum = clGetContextInfo(context->m_deviceContext, CL_CONTEXT_DEVICES, deviceBufferSize, devices, NULL);
52
     if (errNum != CL_SUCCESS)
53
         return context;
54
55
     context->m_commandQueue = clCreateCommandQueue(context->m_deviceContext, devices[0], 0, NULL);
56
     if (context->m_commandQueue == NULL)
57
         return context;
58
59
     context->m_device = devices[0];
60
     delete [] devices;
61
62
     cl_bool imageSupport = CL_FALSE;
63
     clGetDeviceInfo(context->m_device, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &imageSupport, NULL);
64
     if (imageSupport != CL_TRUE)
65
         return context;
66
67
     return context;
68
}
69
70
cl_program FilterContextOpenCL::compileProgram(const char* source)
71
{
72
    cl_int errNum;
73
    cl_program program;
74
75
    FilterContextOpenCL* context = FilterContextOpenCL::context();
76
77
    program = clCreateProgramWithSource(context->m_deviceContext, 1, (const char**) &source, NULL, &errNum);
78
    if (errNum != CL_SUCCESS)
79
        OpenCLPrintError(errNum);
80
    if (errNum != CL_SUCCESS)
81
        return 0;
82
83
    errNum = clBuildProgram(program, 0, 0, 0, 0, 0);
84
    if (errNum != CL_SUCCESS)
85
        OpenCLPrintError(errNum);
86
    if (errNum != CL_SUCCESS)
87
        return 0;
88
89
    return program;
90
}
91
92
static const char* OpenCLTransformColorSpaceKernelProgram =
93
PROGRAM_STR(
94
    const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
95
96
    __kernel void OpenCLTransformColorSpace(__read_only image2d_t source,
97
                                            __write_only image2d_t destination,
98
                                            __constant float *clLookUpTable)
99
    {
100
        int2 sourceCoord = (int2) (get_global_id(0), get_global_id(1));
101
        float4 pixel = read_imagef(source, sampler, sourceCoord);
102
103
        pixel = (float4)(clLookUpTable[(int)(round(pixel.x * 255))],
104
                         clLookUpTable[(int)(round(pixel.y * 255))],
105
                         clLookUpTable[(int)(round(pixel.z * 255))],
106
                         pixel.w);
107
108
        write_imagef(destination, sourceCoord, pixel);
109
    }
110
);
111
112
cl_mem FilterContextOpenCL::OpenCLTransformColorSpace(cl_mem source, ColorSpace resultColorSpace, ColorSpace dstColorSpace, IntRect sourceSize)
113
{
114
    DEFINE_STATIC_LOCAL(cl_mem, deviceRgbLUT, ());
115
    DEFINE_STATIC_LOCAL(cl_mem, linearRgbLUT, ());
116
117
    if ((resultColorSpace != ColorSpaceLinearRGB && resultColorSpace != ColorSpaceDeviceRGB)
118
        || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceDeviceRGB))
119
        return source;
120
121
122
    FilterContextOpenCL* context = FilterContextOpenCL::context();
123
124
    cl_image_format clImageFormat;
125
    clImageFormat.image_channel_order = CL_RGBA;
126
    clImageFormat.image_channel_data_type = CL_UNORM_INT8;
127
128
    cl_mem destination = clCreateImage2D(context->deviceContext(), CL_MEM_READ_WRITE,
129
        &clImageFormat, sourceSize.width(), sourceSize.height(), 0, 0, 0);
130
131
    if(!m_OpenCLTransformColorSpaceProgram){
132
        m_OpenCLTransformColorSpaceProgram = compileProgram(OpenCLTransformColorSpaceKernelProgram);
133
        m_OpenCLTransformColorSpace = kernelByName(m_OpenCLTransformColorSpaceProgram, "OpenCLTransformColorSpace");
134
    }
135
136
    RunKernel kernel(context, m_OpenCLTransformColorSpace, sourceSize.width(), sourceSize.height());
137
    kernel.addArgument(source);
138
    kernel.addArgument(destination);
139
140
    if (dstColorSpace == ColorSpaceLinearRGB) {
141
        if (!linearRgbLUT) {
142
            Vector<float> lookUpTable;
143
            for (unsigned i = 0; i < 256; i++) {
144
                float color = i  / 255.0f;
145
                color = (color <= 0.04045f ? color / 12.92f : pow((color + 0.055f) / 1.055f, 2.4f));
146
                color = std::max(0.0f, color);
147
                color = std::min(1.0f, color);
148
                lookUpTable.append((round(color * 255)) / 255);
149
            }
150
            linearRgbLUT = context->uploadBuffer(context, lookUpTable.data(), sizeof(float) * 256);
151
        }
152
        kernel.addArgument(linearRgbLUT);
153
    } else if (dstColorSpace == ColorSpaceDeviceRGB) {
154
        if (!deviceRgbLUT) {
155
            Vector<float> lookUpTable;
156
            for (unsigned i = 0; i < 256; i++) {
157
                float color = i / 255.0f;
158
                color = (powf(color, 1.0f / 2.4f) * 1.055f) - 0.055f;
159
                color = std::max(0.0f, color);
160
                color = std::min(1.0f, color);
161
                lookUpTable.append((round(color * 255)) / 255);
162
            }
163
            deviceRgbLUT = context->uploadBuffer(context, lookUpTable.data(), sizeof(float) * 256);
164
        }
165
        kernel.addArgument(deviceRgbLUT);
166
    }
167
168
    kernel.run();
169
170
    return destination;
171
}
172
173
static const char* FillKernelProgram =
174
PROGRAM_STR(
175
            __kernel void Fill(__write_only image2d_t destination,
176
                              float r,
177
                              float g,
178
                              float b,
179
                              float a)
180
            {
181
                float4 sourcePixel = (float4)(r,g,b,a);
182
                write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), sourcePixel);
183
            }
184
);
185
186
void FilterContextOpenCL::Fill(cl_mem image, IntSize imageSize, Color color)
187
{
188
189
    if (!m_Fill) {
190
        m_FillProgram = compileProgram(FillKernelProgram);
191
        ASSERT(m_FillProgram);
192
        m_Fill = kernelByName(m_FillProgram, "Fill");
193
        ASSERT(m_Fill);
194
    }
195
196
    float r,g,b,a;
197
198
    color.getRGBA(r,g,b,a);
199
200
    RunKernel kernel(this, m_Fill, imageSize.width(), imageSize.height());
201
    kernel.addArgument(image);
202
    kernel.addArgument(r);
203
    kernel.addArgument(g);
204
    kernel.addArgument(b);
205
    kernel.addArgument(a);
206
    kernel.run();
207
208
}
209
210
cl_mem FilterContextOpenCL::uploadBuffer(WebCore::FilterContextOpenCL* context, void* buffer, int size)
211
{
212
    cl_int err;
213
    cl_mem result = clCreateBuffer(context->deviceContext(), CL_MEM_READ_ONLY, size, 0, &err);
214
    if (err != CL_SUCCESS)
215
        OpenCLPrintError(err);
216
217
    err = clEnqueueWriteBuffer(context->commandQueue(), result, CL_TRUE, 0, size, buffer, 0, 0, 0);
218
    if (err != CL_SUCCESS)
219
        OpenCLPrintError(err);
220
221
    return result;
222
}
223
224
cl_mem FilterContextOpenCL::createOpenCLImage(FloatSize paintSize)
225
{
226
    FilterContextOpenCL* context = FilterContextOpenCL::context();
227
228
    cl_image_format clImageFormat;
229
    clImageFormat.image_channel_order = CL_RGBA;
230
    clImageFormat.image_channel_data_type = CL_UNORM_INT8;
231
232
    cl_int er;
233
    cl_mem image = clCreateImage2D(context->deviceContext(), CL_MEM_READ_WRITE ,
234
                           &clImageFormat, paintSize.width(), paintSize.height(), 0, 0, &er);
235
    if (er != CL_SUCCESS)
236
        context->OpenCLPrintError(er);
237
    context->OpenCLDebugImage(image);
238
    return image;
239
}
240
241
void FilterContextOpenCL::OpenCLPrintError(cl_int error)
242
{
243
    switch (error) {
244
    case CL_SUCCESS:
245
        fprintf(stderr, "CL_SUCCESS\n");
246
        break;
247
    case CL_DEVICE_NOT_FOUND:
248
        fprintf(stderr, "CL_DEVICE_NOT_FOUND\n");
249
        break;
250
    case CL_DEVICE_NOT_AVAILABLE:
251
        fprintf(stderr, "CL_DEVICE_NOT_AVAILABLE\n");
252
        break;
253
    case CL_COMPILER_NOT_AVAILABLE:
254
        fprintf(stderr, "CL_COMPILER_NOT_AVAILABLE\n");
255
        break;
256
    case CL_MEM_OBJECT_ALLOCATION_FAILURE:
257
        fprintf(stderr, "CL_MEM_OBJECT_ALLOCATION_FAILURE\n");
258
        break;
259
    case CL_OUT_OF_RESOURCES:
260
        fprintf(stderr, "CL_OUT_OF_RESOURCES\n");
261
        break;
262
    case CL_OUT_OF_HOST_MEMORY:
263
        fprintf(stderr, "CL_OUT_OF_HOST_MEMORY\n");
264
        break;
265
    case CL_PROFILING_INFO_NOT_AVAILABLE:
266
        fprintf(stderr, "CL_PROFILING_INFO_NOT_AVAILABLE\n");
267
        break;
268
    case CL_MEM_COPY_OVERLAP:
269
        fprintf(stderr, "CL_MEM_COPY_OVERLAP\n");
270
        break;
271
    case CL_IMAGE_FORMAT_MISMATCH:
272
        fprintf(stderr, "CL_IMAGE_FORMAT_MISMATCH\n");
273
        break;
274
    case CL_IMAGE_FORMAT_NOT_SUPPORTED:
275
        fprintf(stderr, "CL_IMAGE_FORMAT_NOT_SUPPORTED\n");
276
        break;
277
    case CL_BUILD_PROGRAM_FAILURE:
278
        fprintf(stderr, "CL_BUILD_PROGRAM_FAILURE\n");
279
        break;
280
    case CL_MAP_FAILURE:
281
        fprintf(stderr, "CL_MAP_FAILURE\n");
282
        break;
283
    case CL_INVALID_VALUE:
284
        fprintf(stderr, "CL_INVALID_VALUE\n");
285
        break;
286
    case CL_INVALID_DEVICE_TYPE:
287
        fprintf(stderr, "CL_INVALID_DEVICE_TYPE\n");
288
        break;
289
    case CL_INVALID_PLATFORM:
290
        fprintf(stderr, "CL_INVALID_PLATFORM\n");
291
        break;
292
    case CL_INVALID_DEVICE:
293
        fprintf(stderr, "CL_INVALID_DEVICE\n");
294
        break;
295
    case CL_INVALID_CONTEXT:
296
        fprintf(stderr, "CL_INVALID_CONTEXT\n");
297
        break;
298
    case CL_INVALID_QUEUE_PROPERTIES:
299
        fprintf(stderr, "CL_INVALID_QUEUE_PROPERTIES\n");
300
        break;
301
    case CL_INVALID_COMMAND_QUEUE:
302
        fprintf(stderr, "CL_INVALID_COMMAND_QUEUE\n");
303
        break;
304
    case CL_INVALID_HOST_PTR:
305
        fprintf(stderr, "CL_INVALID_HOST_PTR\n");
306
        break;
307
    case CL_INVALID_MEM_OBJECT:
308
        fprintf(stderr, "CL_INVALID_MEM_OBJECT\n");
309
        break;
310
    case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
311
        fprintf(stderr, "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR\n");
312
        break;
313
    case CL_INVALID_IMAGE_SIZE:
314
        fprintf(stderr, "CL_INVALID_IMAGE_SIZE\n");
315
        break;
316
    case CL_INVALID_SAMPLER:
317
        fprintf(stderr, "CL_INVALID_SAMPLER\n");
318
        break;
319
    case CL_INVALID_BINARY:
320
        fprintf(stderr, "CL_INVALID_BINARY\n");
321
        break;
322
    case CL_INVALID_BUILD_OPTIONS:
323
        fprintf(stderr, "CL_INVALID_BUILD_OPTIONS\n");
324
        break;
325
    case CL_INVALID_PROGRAM:
326
        fprintf(stderr, "CL_INVALID_PROGRAM\n");
327
        break;
328
    case CL_INVALID_PROGRAM_EXECUTABLE:
329
        fprintf(stderr, "CL_INVALID_PROGRAM_EXECUTABLE\n");
330
        break;
331
    case CL_INVALID_KERNEL_NAME:
332
        fprintf(stderr, "CL_INVALID_KERNEL_NAME\n");
333
        break;
334
    case CL_INVALID_KERNEL_DEFINITION:
335
        fprintf(stderr, "CL_INVALID_KERNEL_DEFINITION\n");
336
        break;
337
    case CL_INVALID_KERNEL:
338
        fprintf(stderr, "CL_INVALID_KERNEL\n");
339
        break;
340
    case CL_INVALID_ARG_INDEX:
341
        fprintf(stderr, "CL_INVALID_ARG_INDEX\n");
342
        break;
343
    case CL_INVALID_ARG_VALUE:
344
        fprintf(stderr, "CL_INVALID_ARG_VALUE\n");
345
        break;
346
    case CL_INVALID_ARG_SIZE:
347
        fprintf(stderr, "CL_INVALID_ARG_SIZE\n");
348
        break;
349
    case CL_INVALID_KERNEL_ARGS:
350
        fprintf(stderr, "CL_INVALID_KERNEL_ARGS\n");
351
        break;
352
    case CL_INVALID_WORK_DIMENSION:
353
        fprintf(stderr, "CL_INVALID_WORK_DIMENSION\n");
354
        break;
355
    case CL_INVALID_WORK_GROUP_SIZE:
356
        fprintf(stderr, "CL_INVALID_WORK_GROUP_SIZE\n");
357
        break;
358
    case CL_INVALID_WORK_ITEM_SIZE:
359
        fprintf(stderr, "CL_INVALID_WORK_ITEM_SIZE\n");
360
        break;
361
    case CL_INVALID_GLOBAL_OFFSET:
362
        fprintf(stderr, "CL_INVALID_GLOBAL_OFFSET\n");
363
        break;
364
    case CL_INVALID_EVENT_WAIT_LIST:
365
        fprintf(stderr, "CL_INVALID_EVENT_WAIT_LIST\n");
366
        break;
367
    case CL_INVALID_EVENT:
368
        fprintf(stderr, "CL_INVALID_EVENT\n");
369
        break;
370
    case CL_INVALID_OPERATION:
371
        fprintf(stderr, "CL_INVALID_OPERATION\n");
372
        break;
373
    case CL_INVALID_GL_OBJECT:
374
        fprintf(stderr, "CL_INVALID_GL_OBJECT\n");
375
        break;
376
    case CL_INVALID_BUFFER_SIZE:
377
        fprintf(stderr, "CL_INVALID_BUFFER_SIZE\n");
378
        break;
379
    case CL_INVALID_MIP_LEVEL:
380
        fprintf(stderr, "CL_INVALID_MIP_LEVEL\n");
381
        break;
382
    case CL_INVALID_GLOBAL_WORK_SIZE:
383
        fprintf(stderr, "CL_INVALID_GLOBAL_WORK_SIZE\n");
384
        break;
385
    default:
386
        fprintf(stderr, "Unknown error code : %d\n", error);
387
        break;
388
    }
389
}
390
391
void FilterContextOpenCL::OpenCLDebugImage(cl_mem image)
392
{
393
    size_t width;
394
    size_t height;
395
    cl_int err;
396
    size_t channelSize;
397
398
    err = clGetImageInfo(image, CL_IMAGE_WIDTH, sizeof(width), &width, NULL);
399
    if (err != CL_SUCCESS)
400
        OpenCLPrintError(err);
401
402
    err = clGetImageInfo(image, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL);
403
    if (err != CL_SUCCESS)
404
        OpenCLPrintError(err);
405
406
    err = clGetImageInfo(image, CL_IMAGE_ELEMENT_SIZE, sizeof(channelSize), &channelSize, NULL);
407
    if (err != CL_SUCCESS)
408
        OpenCLPrintError(err);
409
    if (err != CL_SUCCESS)
410
        printf("OpenCLDebugImage: width: %ld  height: %ld channelSize: %ld \n", width, height, channelSize);
411
}
412
413
414
415
416
} // namespace WebCore
417
418
#endif
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLContext.h +193 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLContext.h_sec1
1
#ifndef OpenCLContext_h
2
#define OpenCLContext_h
3
4
#include "config.h"
5
#if ENABLE(OPENCL)
6
7
#include "CL/cl.h"
8
#include "Color.h"
9
#include "ColorSpace.h"
10
#include "IntSize.h"
11
#include "IntRect.h"
12
#include "FloatPoint.h"
13
#include "FloatSize.h"
14
#include "stdio.h"
15
16
namespace WebCore {
17
18
class FilterContextOpenCL
19
{
20
public:
21
    // Returns NULL if initialization failed.
22
    static FilterContextOpenCL* context();
23
24
    cl_context deviceContext() { return m_deviceContext; }
25
    cl_command_queue commandQueue() { return m_commandQueue; }
26
27
    cl_mem createOpenCLImage(FloatSize);
28
29
    static cl_mem uploadBuffer(WebCore::FilterContextOpenCL* context, void* buffer, int size);
30
    cl_mem OpenCLTransformColorSpace(cl_mem, ColorSpace, ColorSpace, IntRect);
31
    void Fill(cl_mem, IntSize, Color);
32
33
    inline void compileFEComposite();
34
    inline void compileFEOffset();
35
    inline void compileFEBlend();
36
    inline void compileFEGaussianBlur();
37
    inline void compileFETurbulence();
38
    inline void compileFEColorMatrix();
39
    inline void compileFEConvolveMatrix();
40
    inline void compileFEComponentTransfer();
41
    inline void compileFEMerge();
42
    inline void compileFETile();
43
    inline void compileFEMorphology();
44
45
    inline void applyFEColorMatrix(cl_mem, IntSize, cl_mem, FloatPoint, cl_mem, int);
46
    inline void applyFEColorMatrixLuminanceToAlpha(cl_mem, IntSize, cl_mem, FloatPoint, int);
47
    inline void applyFEConvolveMatrix(cl_mem, IntSize, cl_mem, IntSize, cl_mem, int, float, float, IntPoint, bool);
48
    inline void applyFETurbulence(cl_mem, IntSize, cl_mem, cl_mem, cl_mem, cl_mem, cl_mem, cl_mem, int, int, int, int, float, float, bool, int, int);
49
    inline void applyFEComposite(cl_mem, IntSize, cl_mem, cl_mem, FloatPoint, FloatPoint, float, float, float, float, int);
50
    inline void applyFEComponentTransfer(cl_mem, IntSize, cl_mem, cl_mem, FloatPoint);
51
    inline void applyFEOffset(cl_mem, IntSize, cl_mem, FloatPoint);
52
    inline void applyFEBlend(cl_mem, IntSize, cl_mem, cl_mem, int,FloatPoint, FloatPoint);
53
    inline void applyFEGaussianBlur(cl_mem, IntSize, cl_mem);
54
    inline void applyFEMerge(cl_mem, IntSize, cl_mem, FloatRect);
55
    inline void applyFETiling(cl_mem, IntSize, cl_mem, FloatRect, FloatPoint);
56
    inline void applyFETileBuilder(cl_mem, FloatRect, cl_mem, FloatSize);
57
    inline void applyFEMorphology(cl_mem, IntSize, cl_mem, int, int, int, int, int);
58
59
    static void OpenCLPrintError(cl_int);
60
    static void OpenCLDebugImage(cl_mem);
61
62
private:
63
64
    class RunKernel {
65
    public:
66
        RunKernel(FilterContextOpenCL* context, cl_kernel kernel, size_t width, size_t height)
67
            : m_context(context)
68
            , m_kernel(kernel)
69
            , index(0)
70
        {
71
            m_globalSize[0] = width;
72
            m_globalSize[1] = height;
73
        }
74
75
        void addArgument(cl_mem handle)
76
        {
77
            cl_int err;
78
            err = clSetKernelArg(m_kernel, index++, sizeof(cl_mem), reinterpret_cast<void*>(&handle));
79
            if (err != CL_SUCCESS){
80
                m_context->OpenCLPrintError(err);
81
            }
82
        }
83
84
        void addArgument(cl_int value)
85
        {
86
            cl_int err;
87
            err = clSetKernelArg(m_kernel, index++, sizeof(cl_int), reinterpret_cast<void*>(&value));
88
            if (err != CL_SUCCESS){
89
                m_context->OpenCLPrintError(err);
90
            }
91
        }
92
93
        void addArgument(cl_float value)
94
        {
95
            cl_int err;
96
            err = clSetKernelArg(m_kernel, index++, sizeof(cl_float), reinterpret_cast<void*>(&value));
97
            if (err != CL_SUCCESS){
98
                m_context->OpenCLPrintError(err);
99
            }
100
        }
101
102
        void addArgument(cl_sampler handle)
103
        {
104
            cl_int err;
105
            err = clSetKernelArg(m_kernel, index++, sizeof(cl_sampler), reinterpret_cast<void*>(&handle));
106
            if (err != CL_SUCCESS){
107
                m_context->OpenCLPrintError(err);
108
            }
109
        }
110
111
        void run()
112
        {
113
            clFinish(m_context->m_commandQueue);
114
            clEnqueueNDRangeKernel(m_context->m_commandQueue, m_kernel, 2, 0, m_globalSize, 0, 0, 0, 0);
115
        }
116
117
        FilterContextOpenCL* m_context;
118
        cl_kernel m_kernel;
119
        size_t m_globalSize[2];
120
        int index;
121
    };
122
123
    static cl_program compileProgram(const char*);
124
    static inline cl_kernel kernelByName(cl_program program, const char* name) { return clCreateKernel(program, name, NULL); }
125
126
    cl_command_queue m_commandQueue;
127
    cl_device_id m_device;
128
    cl_context m_deviceContext;
129
130
    cl_program m_OpenCLTransformColorSpaceProgram;
131
    cl_kernel m_OpenCLTransformColorSpace;
132
133
    cl_program m_FEColorMatrixProgram;
134
    cl_kernel m_FEMatrix;
135
    cl_kernel m_FESaturate;
136
    cl_kernel m_FEHuerotate;
137
    cl_kernel m_FELuminance;
138
139
    cl_program m_FEConvolveMatrixProgram;
140
    cl_kernel m_FEConvolveMatrix;
141
    cl_kernel m_FEConvolveMatrixAlpha;
142
143
    cl_program m_FETurbulenceProgram;
144
    cl_kernel m_FETurbulence;
145
146
    cl_program m_feOffsetProgram;
147
    cl_kernel m_feOffset;
148
149
    cl_program m_feBlendProgram;
150
    cl_kernel m_feNormalBlend;
151
    cl_kernel m_feMultiplyBlend;
152
    cl_kernel m_feScreenBlend;
153
    cl_kernel m_feDarkenBlend;
154
    cl_kernel m_feLightenBlend;
155
    cl_kernel m_feUnknowBlend;
156
157
    cl_program m_feGaussianBlurProgram;
158
    cl_kernel m_feGaussianBlur;
159
160
    cl_program m_FEFloodProgram;
161
    cl_kernel m_FEFlood;
162
163
    cl_program m_feCompositeProgram;
164
    cl_kernel m_feArithmetic;
165
    cl_kernel m_feAtop;
166
    cl_kernel m_feIn;
167
    cl_kernel m_feOut;
168
    cl_kernel m_feOver;
169
    cl_kernel m_feXor;
170
171
    cl_program m_FEMergeProgram;
172
    cl_kernel m_FEMerge;
173
174
    cl_program m_feTileProgram;
175
    cl_kernel m_feTile;
176
    cl_kernel m_TileBuilder;
177
178
    cl_program m_feMorphologyProgram;
179
    cl_kernel m_feMorphologyDilate;
180
    cl_kernel m_feMorphologyErode;
181
182
    cl_program m_FillProgram;
183
    cl_kernel m_Fill;
184
185
    cl_program m_feComponentTransferProgram;
186
    cl_kernel m_feComponentTransfer;
187
};
188
189
} // namespace WebCore
190
191
#endif // ENABLE(OPENCL)
192
193
#endif
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEBlend.cpp +240 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEBlend.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEBlend.h"
23
#include "OpenCLContext.h"
24
25
#include <stdio.h>
26
27
#define PROGRAM_STR(Src) #Src
28
#define PROGRAM(Src) PROGRAM_STR(Src)
29
30
namespace WebCore {
31
32
static const char* FEBlendKernelProgram =
33
PROGRAM_STR(
34
            const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
35
36
            __kernel void NormalBlend(__write_only image2d_t destination,
37
                                      __read_only image2d_t sourceA,
38
                                      __read_only image2d_t sourceB,
39
                                      float xA,
40
                                      float yA,
41
                                      float xB,
42
                                      float yB)
43
                {
44
                    int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
45
                    int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
46
                    float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
47
                    float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
48
                    float4 destinationPixel = (float4)((1.0 - sourcePixelA.w) * sourcePixelB.x + sourcePixelA.x,
49
                                                       (1.0 - sourcePixelA.w) * sourcePixelB.y + sourcePixelA.y,
50
                                                       (1.0 - sourcePixelA.w) * sourcePixelB.z + sourcePixelA.z,
51
                                                        1.0 - (1.0 - sourcePixelA.w) * (1.0 - sourcePixelB.w));
52
                    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
53
                }
54
55
            __kernel void MultiplyBlend(__write_only image2d_t destination,
56
                                        __read_only image2d_t sourceA,
57
                                        __read_only image2d_t sourceB,
58
                                        float xA,
59
                                        float yA,
60
                                        float xB,
61
                                        float yB)
62
                {
63
                    int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
64
                    int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
65
                    float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
66
                    float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
67
                    float4 destinationPixel = (float4)((1.0 - sourcePixelA.w) * sourcePixelB.x + (1.0 - sourcePixelB.w) * sourcePixelA.x + sourcePixelA.x * sourcePixelB.x,
68
                                                       (1.0 - sourcePixelA.w) * sourcePixelB.y + (1.0 - sourcePixelB.w) * sourcePixelA.y + sourcePixelA.y * sourcePixelB.y,
69
                                                       (1.0 - sourcePixelA.w) * sourcePixelB.z + (1.0 - sourcePixelB.w) * sourcePixelA.z + sourcePixelA.z * sourcePixelB.z,
70
                                                        1.0 - (1.0 - sourcePixelA.w) * (1.0 - sourcePixelB.w));
71
                    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
72
                }
73
74
            __kernel void ScreenBlend(__write_only image2d_t destination,
75
                                      __read_only image2d_t sourceA,
76
                                      __read_only image2d_t sourceB,
77
                                      float xA,
78
                                      float yA,
79
                                      float xB,
80
                                      float yB)
81
                {
82
                    int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
83
                    int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
84
                    float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
85
                    float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
86
                    float4 destinationPixel = (float4)(sourcePixelB.x + sourcePixelA.x - sourcePixelA.x * sourcePixelB.x,
87
                                                       sourcePixelB.y + sourcePixelA.y - sourcePixelA.y * sourcePixelB.y,
88
                                                       sourcePixelB.z + sourcePixelA.z - sourcePixelA.z * sourcePixelB.z,
89
                                                       1.0 - (1.0 - sourcePixelA.w) * (1.0 - sourcePixelB.w));
90
                    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
91
                }
92
93
            __kernel void DarkenBlend(__write_only image2d_t destination,
94
                                      __read_only image2d_t sourceA,
95
                                      __read_only image2d_t sourceB,
96
                                      float xA,
97
                                      float yA,
98
                                      float xB,
99
                                      float yB)
100
                {
101
                    int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
102
                    int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
103
                    float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
104
                    float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
105
                    float4 destinationPixel = (float4)(min((1.0 - sourcePixelA.w) * sourcePixelB.x + sourcePixelA.x, (1.0 - sourcePixelB.w) * sourcePixelA.x + sourcePixelB.x),
106
                                                       min((1.0 - sourcePixelA.w) * sourcePixelB.y + sourcePixelA.y, (1.0 - sourcePixelB.w) * sourcePixelA.y + sourcePixelB.y),
107
                                                       min((1.0 - sourcePixelA.w) * sourcePixelB.z + sourcePixelA.z, (1.0 - sourcePixelB.w) * sourcePixelA.z + sourcePixelB.z),
108
                                                            1.0 - (1.0 - sourcePixelA.w) * (1.0 - sourcePixelB.w));
109
                    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
110
                }
111
112
            __kernel void LightenBlend(__write_only image2d_t destination,
113
                                       __read_only image2d_t sourceA,
114
                                       __read_only image2d_t sourceB,
115
                                       float xA,
116
                                       float yA,
117
                                       float xB,
118
                                       float yB)
119
                {
120
                    int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
121
                    int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
122
                    float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
123
                    float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
124
                    float4 destinationPixel = (float4)(max((1.0 - sourcePixelA.w) * sourcePixelB.x + sourcePixelA.x, (1.0 - sourcePixelB.w) * sourcePixelA.x + sourcePixelB.x),
125
                                                       max((1.0 - sourcePixelA.w) * sourcePixelB.y + sourcePixelA.y, (1.0 - sourcePixelB.w) * sourcePixelA.y + sourcePixelB.y),
126
                                                       max((1.0 - sourcePixelA.w) * sourcePixelB.z + sourcePixelA.z, (1.0 - sourcePixelB.w) * sourcePixelA.z + sourcePixelB.z),
127
                                                            1.0 - (1.0 - sourcePixelA.w) * (1.0 - sourcePixelB.w));
128
                    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
129
                }
130
131
            __kernel void UnknowBlend(__write_only image2d_t destination,
132
                                      __read_only image2d_t sourceA,
133
                                      __read_only image2d_t sourceB,
134
                                      float xA,
135
                                      float yA,
136
                                      float xB,
137
                                      float yB)
138
                {
139
                    int2 sourceCoord = (int2) (get_global_id(0), get_global_id(1));
140
                    float4 destinationPixel = (float4)(0.0,0.0,0.0,0.0);
141
                    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
142
                }
143
);
144
145
inline void FilterContextOpenCL::compileFEBlend()
146
{
147
    if (!m_feNormalBlend) {
148
        m_feBlendProgram = compileProgram(FEBlendKernelProgram);
149
        ASSERT(m_feBlendProgram);
150
151
        m_feNormalBlend = kernelByName(m_feBlendProgram, "NormalBlend");
152
        ASSERT(m_feNormalBlend);
153
        m_feMultiplyBlend = kernelByName(m_feBlendProgram, "MultiplyBlend");
154
        ASSERT(m_feNormalBlend);
155
        m_feScreenBlend = kernelByName(m_feBlendProgram, "ScreenBlend");
156
        ASSERT(m_feNormalBlend);
157
        m_feDarkenBlend = kernelByName(m_feBlendProgram, "DarkenBlend");
158
        ASSERT(m_feNormalBlend);
159
        m_feLightenBlend = kernelByName(m_feBlendProgram, "LightenBlend");
160
        ASSERT(m_feNormalBlend);
161
        m_feUnknowBlend = kernelByName(m_feBlendProgram, "UnknowBlend");
162
        ASSERT(m_feNormalBlend);
163
    }
164
}
165
166
inline void FilterContextOpenCL::applyFEBlend(cl_mem destination, IntSize destinationSize, cl_mem sourceA, cl_mem sourceB, int mode, FloatPoint relativeSourceLocationA, FloatPoint relativeSourceLocationB)
167
{
168
    cl_kernel blendMode;
169
170
    switch (mode) {
171
    case FEBLEND_MODE_NORMAL:
172
        blendMode = m_feNormalBlend;
173
        break;
174
    case FEBLEND_MODE_MULTIPLY:
175
        blendMode = m_feMultiplyBlend;
176
        break;
177
    case FEBLEND_MODE_SCREEN:
178
        blendMode = m_feScreenBlend;
179
        break;
180
    case FEBLEND_MODE_DARKEN:
181
        blendMode = m_feDarkenBlend;
182
        break;
183
    case FEBLEND_MODE_LIGHTEN:
184
        blendMode = m_feLightenBlend;
185
        break;
186
    case FEBLEND_MODE_UNKNOWN:
187
    default:
188
        blendMode = m_feUnknowBlend;
189
        break;
190
    }
191
192
    float xA = relativeSourceLocationA.x();
193
    float yA = relativeSourceLocationA.y();
194
195
    float xB = relativeSourceLocationB.x();
196
    float yB = relativeSourceLocationB.y();
197
198
    RunKernel kernel(this, blendMode, destinationSize.width(), destinationSize.height());
199
    kernel.addArgument(destination);
200
    kernel.addArgument(sourceA);
201
    kernel.addArgument(sourceB);
202
    kernel.addArgument(xA);
203
    kernel.addArgument(yA);
204
    kernel.addArgument(xB);
205
    kernel.addArgument(yB);
206
    kernel.run();
207
}
208
209
bool FEBlend::platformApplyOpenCL()
210
{
211
    FilterContextOpenCL* context = FilterContextOpenCL::context();
212
213
    if (!context)
214
        return false;
215
216
    context->compileFEBlend();
217
218
    FilterEffect* in = inputEffect(0);
219
    FilterEffect* in2 = inputEffect(1);
220
221
    FloatPoint relativeSourceLocationA(in->absolutePaintRect().location());
222
    relativeSourceLocationA.setX(absolutePaintRect().x() - relativeSourceLocationA.x());
223
    relativeSourceLocationA.setY(absolutePaintRect().y() - relativeSourceLocationA.y());
224
225
    FloatPoint relativeSourceLocationB(in2->absolutePaintRect().location());
226
    relativeSourceLocationB.setX(absolutePaintRect().x() - relativeSourceLocationB.x());
227
    relativeSourceLocationB.setY(absolutePaintRect().y() - relativeSourceLocationB.y());
228
229
    cl_mem sourceA = in->asOpenCLImage();
230
    cl_mem sourceB = in2->asOpenCLImage();
231
    cl_mem destination = createOpenCLImageResult();
232
233
    context->applyFEBlend(destination, absolutePaintRect().size(), sourceA, sourceB, m_mode, relativeSourceLocationA, relativeSourceLocationB);
234
235
    return true;
236
}
237
238
} // namespace WebCore
239
240
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEColorMatrix.cpp +205 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEColorMatrix.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEColorMatrix.h"
23
#include "OpenCLContext.h"
24
#include "stdio.h"
25
26
#define PROGRAM_STR(Src) #Src
27
#define PROGRAM(Src) PROGRAM_STR(Src)
28
29
namespace WebCore {
30
31
static const char* FEColorMatrixKernelProgram =
32
PROGRAM_STR(
33
    const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
34
    __constant float pi = 3.14159265358979323846;
35
36
    __kernel void Matrix(__write_only image2d_t destination,
37
                         __read_only image2d_t source,
38
                         float x,
39
                         float y,
40
                         __constant float *values)
41
    {
42
        int2 sourceCoord = (int2) (get_global_id(0) + x, get_global_id(1) + y);
43
        float4 sourcePixel = read_imagef(source, sampler, sourceCoord);
44
45
        float4 destinationPixel = (float4)(values[0]  * sourcePixel.x + values[1]  * sourcePixel.y + values[2]  * sourcePixel.z + values[3]  * sourcePixel.w + values[4] * 255,
46
                                             values[5]  * sourcePixel.x + values[6]  * sourcePixel.y + values[7]  * sourcePixel.z + values[8]  * sourcePixel.w + values[9] * 255,
47
                                             values[10] * sourcePixel.x + values[11] * sourcePixel.y + values[12] * sourcePixel.z + values[13] * sourcePixel.w + values[14] * 255,
48
                                             values[15] * sourcePixel.x + values[16] * sourcePixel.y + values[17] * sourcePixel.z + values[18] * sourcePixel.w + values[19] * 255);
49
50
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
51
    }
52
53
54
    __kernel void Saturate(__write_only image2d_t destination,
55
                         __read_only image2d_t source,
56
                         float x,
57
                         float y,
58
                         __constant float *values)
59
    {
60
        int2 sourceCoord = (int2) (get_global_id(0) + x, get_global_id(1) + y);
61
        float4 sourcePixel = read_imagef(source, sampler, sourceCoord);
62
63
        float4 destinationPixel = (float4)((0.213 + 0.787 * values[0]) * sourcePixel.x + (0.715 - 0.715 * values[0]) * sourcePixel.y + (0.072 - 0.072 * values[0]) * sourcePixel.z,
64
                                           (0.213 - 0.213 * values[0]) * sourcePixel.x + (0.715 + 0.285 * values[0]) * sourcePixel.y + (0.072 - 0.072 * values[0]) * sourcePixel.z,
65
                                           (0.213 - 0.213 * values[0]) * sourcePixel.x + (0.715 - 0.715 * values[0]) * sourcePixel.y + (0.072 + 0.928 * values[0]) * sourcePixel.z,
66
                                           sourcePixel.w);
67
68
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
69
    }
70
71
    __kernel void Huerotate(__write_only image2d_t destination,
72
                         __read_only image2d_t source,
73
                         float x,
74
                         float y,
75
                         __constant float *values)
76
    {
77
        int2 sourceCoord = (int2) (get_global_id(0) + x, get_global_id(1) + y);
78
        float4 sourcePixel = read_imagef(source, sampler, sourceCoord);
79
80
        float cosHue = cos(values[0] * pi / 180);
81
        float sinHue = sin(values[0] * pi / 180);
82
83
        float4 destinationPixel = (float4)(sourcePixel.x * (0.213 + cosHue * 0.787 - sinHue * 0.213) + sourcePixel.y * (0.715 - cosHue * 0.715 - sinHue * 0.715) + sourcePixel.z  * (0.072 - cosHue * 0.072 + sinHue * 0.928),
84
                                           sourcePixel.x * (0.213 - cosHue * 0.213 + sinHue * 0.143) + sourcePixel.y * (0.715 + cosHue * 0.285 + sinHue * 0.140) + sourcePixel.z  * (0.072 - cosHue * 0.072 - sinHue * 0.283),
85
                                           sourcePixel.x * (0.213 - cosHue * 0.213 - sinHue * 0.787) + sourcePixel.y * (0.715 - cosHue * 0.715 + sinHue * 0.715) + sourcePixel.z  * (0.072 + cosHue * 0.928 + sinHue * 0.072),
86
                                           sourcePixel.w);
87
88
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), destinationPixel);
89
    }
90
91
    __kernel void Luminance(__write_only image2d_t destination,
92
                         __read_only image2d_t source,
93
                         float x,
94
                         float y)
95
    {
96
        int2 sourceCoord = (int2) (get_global_id(0) + x, get_global_id(1) + y);
97
        float4 sourcePixel = read_imagef(source, sampler, sourceCoord);
98
99
        float4 destinationPixel = (float4)(0, 0, 0, 0.2125 * sourcePixel.x + 0.7154 * sourcePixel.y + 0.0721 * sourcePixel.z);
100
101
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), sourcePixel);
102
    }
103
104
105
);
106
107
inline void FilterContextOpenCL::compileFEColorMatrix()
108
{
109
    if (!m_FEColorMatrixProgram) {
110
        m_FEColorMatrixProgram = compileProgram(FEColorMatrixKernelProgram);
111
        ASSERT(m_FEColorMatrixProgram);
112
113
        m_FEMatrix = kernelByName(m_FEColorMatrixProgram, "Matrix");
114
        ASSERT(m_FEMatrix);
115
        m_FESaturate = kernelByName(m_FEColorMatrixProgram, "Saturate");
116
        ASSERT(m_FESaturate);
117
        m_FEHuerotate = kernelByName(m_FEColorMatrixProgram, "Huerotate");
118
        ASSERT(m_FEHuerotate);
119
        m_FELuminance = kernelByName(m_FEColorMatrixProgram, "Luminance");
120
        ASSERT(m_FELuminance);
121
    }
122
}
123
124
inline void FilterContextOpenCL::applyFEColorMatrix(cl_mem destination, IntSize destinationSize, cl_mem source, FloatPoint relativeSourceLocation, cl_mem values, int type)
125
{
126
    float x = relativeSourceLocation.x();
127
    float y = relativeSourceLocation.y();
128
129
    cl_kernel m_FEColorMatrix;
130
131
    switch (type) {
132
    case FECOLORMATRIX_TYPE_MATRIX:
133
        m_FEColorMatrix = m_FEMatrix;
134
        break;
135
    case FECOLORMATRIX_TYPE_SATURATE:
136
        m_FEColorMatrix = m_FESaturate;
137
        break;
138
    case FECOLORMATRIX_TYPE_HUEROTATE:
139
        m_FEColorMatrix = m_FEHuerotate;
140
        break;
141
    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
142
        m_FEColorMatrix = m_FELuminance;
143
        break;
144
    default:
145
        m_FEColorMatrix = 0;
146
    }
147
148
    RunKernel kernel(this, m_FEColorMatrix, destinationSize.width(), destinationSize.height());
149
    kernel.addArgument(destination);
150
    kernel.addArgument(source);
151
    kernel.addArgument(x);
152
    kernel.addArgument(y);
153
    kernel.addArgument(values);
154
    kernel.run();
155
156
}
157
158
inline void FilterContextOpenCL::applyFEColorMatrixLuminanceToAlpha(cl_mem destination, IntSize destinationSize, cl_mem source, FloatPoint relativeSourceLocation, int m_type)
159
{
160
    float x = relativeSourceLocation.x();
161
    float y = relativeSourceLocation.y();
162
163
    RunKernel kernel(this, m_FELuminance, destinationSize.width(), destinationSize.height());
164
    kernel.addArgument(destination);
165
    kernel.addArgument(source);
166
    kernel.addArgument(x);
167
    kernel.addArgument(y);
168
    kernel.run();
169
}
170
171
bool FEColorMatrix::platformApplyOpenCL()
172
{
173
    FilterContextOpenCL* context = FilterContextOpenCL::context();
174
175
    if (!context)
176
        return false;
177
178
    context->compileFEColorMatrix();
179
180
    FilterEffect* in = inputEffect(0);
181
    cl_mem source = in->asOpenCLImage();
182
    cl_mem destination = createOpenCLImageResult();
183
    cl_mem clValues = 0;
184
185
    if(m_type != FECOLORMATRIX_TYPE_LUMINANCETOALPHA)
186
        clValues = context->uploadBuffer(context, m_values.data(), sizeof(float) * 20);
187
188
    FloatPoint relativeSourceLocation(in->absolutePaintRect().location());
189
    relativeSourceLocation.setX(absolutePaintRect().x() - relativeSourceLocation.x());
190
    relativeSourceLocation.setY(absolutePaintRect().y() - relativeSourceLocation.y());
191
192
    if(m_type != FECOLORMATRIX_TYPE_LUMINANCETOALPHA)
193
        context->applyFEColorMatrix(destination, absolutePaintRect().size(), source, relativeSourceLocation, clValues, m_type);
194
    else
195
        context->applyFEColorMatrixLuminanceToAlpha(destination, absolutePaintRect().size(), source, relativeSourceLocation, m_type);
196
197
    clReleaseMemObject(clValues);
198
    return true;
199
}
200
201
202
203
} // namespace WebCore
204
205
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEComposite.cpp +321 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEComposite.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEComposite.h"
23
#include "OpenCLContext.h"
24
25
#include <stdio.h>
26
27
#define PROGRAM_STR(Src) #Src
28
#define PROGRAM(Src) PROGRAM_STR(Src)
29
30
namespace WebCore {
31
32
static const char* FECompositeKernelProgram =
33
PROGRAM_STR(
34
    const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
35
36
    __kernel void Arithmetic(__write_only image2d_t destination,
37
                         __read_only image2d_t sourceA,
38
                         __read_only image2d_t sourceB,
39
                         float xA,
40
                         float yA,
41
                         float xB,
42
                         float yB,
43
                         float k1,
44
                         float k2,
45
                         float k3,
46
                         float k4)
47
    {
48
        int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
49
        int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
50
        float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
51
        float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
52
        sourcePixelA.xyz *= sourcePixelA.w;
53
        sourcePixelB.xyz *= sourcePixelB.w;
54
55
        float4 destinationPixel = (float4)(k1 * sourcePixelA.x * sourcePixelB.x + k2 * sourcePixelA.x + k3 * sourcePixelB.x + k4 ,
56
                                           k1 * sourcePixelA.y * sourcePixelB.y + k2 * sourcePixelA.y + k3 * sourcePixelB.y + k4 ,
57
                                           k1 * sourcePixelA.z * sourcePixelB.z + k2 * sourcePixelA.z + k3 * sourcePixelB.z + k4 ,
58
                                           k1 * sourcePixelA.w * sourcePixelB.w + k2 * sourcePixelA.w + k3 * sourcePixelB.w + k4);
59
60
        destinationPixel.w = clamp(destinationPixel.w, 0.0, 1.0);
61
        float rec = 1 / destinationPixel.w;
62
        destinationPixel.x = clamp(destinationPixel.x, 0.0, 1.0) * rec;
63
        destinationPixel.y = clamp(destinationPixel.y, 0.0, 1.0) * rec;
64
        destinationPixel.z = clamp(destinationPixel.z, 0.0, 1.0) * rec;
65
66
        write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), destinationPixel);
67
    }
68
69
    __kernel void Over(__write_only image2d_t destination,
70
                         __read_only image2d_t sourceA,
71
                         __read_only image2d_t sourceB,
72
                         float xA,
73
                         float yA,
74
                         float xB,
75
                         float yB)
76
    {
77
        int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
78
        int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
79
        float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
80
        float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
81
        sourcePixelA.xyz *= sourcePixelA.w;
82
        sourcePixelB.xyz *= sourcePixelB.w;
83
84
        float4 destinationPixel = (float4)(sourcePixelA.x + sourcePixelB.x * (1 - sourcePixelA.w),
85
                                           sourcePixelA.y + sourcePixelB.y * (1 - sourcePixelA.w),
86
                                           sourcePixelA.z + sourcePixelB.z * (1 - sourcePixelA.w),
87
                                           sourcePixelA.w + sourcePixelB.w * (1 - sourcePixelA.w));
88
89
        destinationPixel.w = clamp(destinationPixel.w, 0.0, 1.0);
90
        float rec = 1 / destinationPixel.w;
91
        destinationPixel.x = clamp(destinationPixel.x, 0.0, 1.0) * rec;
92
        destinationPixel.y = clamp(destinationPixel.y, 0.0, 1.0) * rec;
93
        destinationPixel.z = clamp(destinationPixel.z, 0.0, 1.0) * rec;
94
95
        write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), destinationPixel);
96
    }
97
98
    __kernel void In(__write_only image2d_t destination,
99
                         __read_only image2d_t sourceA,
100
                         __read_only image2d_t sourceB,
101
                         float xA,
102
                         float yA,
103
                         float xB,
104
                         float yB)
105
    {
106
        int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
107
        int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
108
        float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
109
        float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
110
        sourcePixelA.xyz *= sourcePixelA.w;
111
        sourcePixelB.xyz *= sourcePixelB.w;
112
113
        float4 destinationPixel = (float4)(sourcePixelA.x * sourcePixelB.w,
114
                                           sourcePixelA.y * sourcePixelB.w,
115
                                           sourcePixelA.z * sourcePixelB.w,
116
                                           sourcePixelA.w * sourcePixelB.w);
117
118
        destinationPixel.w = clamp(destinationPixel.w, 0.0, 1.0);
119
        float rec = 1 / destinationPixel.w;
120
        destinationPixel.x = clamp(destinationPixel.x, 0.0, 1.0) * rec;
121
        destinationPixel.y = clamp(destinationPixel.y, 0.0, 1.0) * rec;
122
        destinationPixel.z = clamp(destinationPixel.z, 0.0, 1.0) * rec;
123
124
        write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), destinationPixel);
125
    }
126
127
    __kernel void Out(__write_only image2d_t destination,
128
                         __read_only image2d_t sourceA,
129
                         __read_only image2d_t sourceB,
130
                         float xA,
131
                         float yA,
132
                         float xB,
133
                         float yB)
134
    {
135
        int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
136
        int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
137
        float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
138
        float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
139
        sourcePixelA.xyz *= sourcePixelA.w;
140
        sourcePixelB.xyz *= sourcePixelB.w;
141
142
        float4 destinationPixel = (float4)(sourcePixelA.x * (1 - sourcePixelB.w),
143
                                           sourcePixelA.y * (1 - sourcePixelB.w),
144
                                           sourcePixelA.z * (1 - sourcePixelB.w),
145
                                           sourcePixelA.w * (1 - sourcePixelB.w));
146
147
        destinationPixel.w = clamp(destinationPixel.w, 0.0, 1.0);
148
        float rec = 1 / destinationPixel.w;
149
        destinationPixel.x = clamp(destinationPixel.x, 0.0, 1.0) * rec;
150
        destinationPixel.y = clamp(destinationPixel.y, 0.0, 1.0) * rec;
151
        destinationPixel.z = clamp(destinationPixel.z, 0.0, 1.0) * rec;
152
153
        write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), destinationPixel);
154
    }
155
156
    __kernel void Atop(__write_only image2d_t destination,
157
                         __read_only image2d_t sourceA,
158
                         __read_only image2d_t sourceB,
159
                         float xA,
160
                         float yA,
161
                         float xB,
162
                         float yB)
163
    {
164
        int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
165
        int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
166
        float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
167
        float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
168
        sourcePixelA.xyz *= sourcePixelA.w;
169
        sourcePixelB.xyz *= sourcePixelB.w;
170
171
        float4 destinationPixel = (float4)(sourcePixelA.x * sourcePixelB.w + sourcePixelB.x * (1 - sourcePixelA.w),
172
                                           sourcePixelA.y * sourcePixelB.w + sourcePixelB.y * (1 - sourcePixelA.w),
173
                                           sourcePixelA.z * sourcePixelB.w + sourcePixelB.z * (1 - sourcePixelA.w),
174
                                           sourcePixelA.w * sourcePixelB.w + sourcePixelB.w * (1 - sourcePixelA.w));
175
176
        destinationPixel.w = clamp(destinationPixel.w, 0.0, 1.0);
177
        float rec = (destinationPixel.w == 0) ? 1.0 :  1.0 / destinationPixel.w;
178
        destinationPixel.x = clamp(destinationPixel.x, 0.0, 1.0) * rec;
179
        destinationPixel.y = clamp(destinationPixel.y, 0.0, 1.0) * rec;
180
        destinationPixel.z = clamp(destinationPixel.z, 0.0, 1.0) * rec;
181
182
        write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), destinationPixel);
183
    }
184
185
    __kernel void Xor(__write_only image2d_t destination,
186
                         __read_only image2d_t sourceA,
187
                         __read_only image2d_t sourceB,
188
                         float xA,
189
                         float yA,
190
                         float xB,
191
                         float yB)
192
    {
193
        int2 sourceCoordA = (int2) (get_global_id(0) + xA, get_global_id(1) + yA);
194
        int2 sourceCoordB = (int2) (get_global_id(0) + xB, get_global_id(1) + yB);
195
        float4 sourcePixelA = read_imagef(sourceA, sampler, sourceCoordA);
196
        float4 sourcePixelB = read_imagef(sourceB, sampler, sourceCoordB);
197
        sourcePixelA.xyz *= sourcePixelA.w;
198
        sourcePixelB.xyz *= sourcePixelB.w;
199
200
        float4 destinationPixel = (float4)(sourcePixelA.x * (1 - sourcePixelB.w) + sourcePixelB.x * (1 - sourcePixelA.w),
201
                                           sourcePixelA.y * (1 - sourcePixelB.w) + sourcePixelB.y * (1 - sourcePixelA.w),
202
                                           sourcePixelA.z * (1 - sourcePixelB.w) + sourcePixelB.z * (1 - sourcePixelA.w),
203
                                           sourcePixelA.w * (1 - sourcePixelB.w) + sourcePixelB.w * (1 - sourcePixelA.w));
204
205
        destinationPixel.w = clamp(destinationPixel.w, 0.0, 1.0);
206
        float rec = 1 / destinationPixel.w;
207
        destinationPixel.x = clamp(destinationPixel.x, 0.0, 1.0) * rec;
208
        destinationPixel.y = clamp(destinationPixel.y, 0.0, 1.0) * rec;
209
        destinationPixel.z = clamp(destinationPixel.z, 0.0, 1.0) * rec;
210
211
        write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), destinationPixel);
212
    }
213
214
);
215
216
inline void FilterContextOpenCL::compileFEComposite()
217
{
218
    if (!m_feCompositeProgram) {
219
        m_feCompositeProgram = compileProgram(FECompositeKernelProgram);
220
        ASSERT(m_feCompositeProgram);
221
222
        m_feArithmetic = kernelByName(m_feCompositeProgram, "Arithmetic");
223
        ASSERT(m_feArithmetic);
224
        m_feOver = kernelByName(m_feCompositeProgram, "Over");
225
        ASSERT(m_feOver);
226
        m_feIn = kernelByName(m_feCompositeProgram, "In");
227
        ASSERT(m_feIn);
228
        m_feOut = kernelByName(m_feCompositeProgram, "Out");
229
        ASSERT(m_feOut);
230
        m_feAtop = kernelByName(m_feCompositeProgram, "Atop");
231
        ASSERT(m_feAtop);
232
        m_feXor = kernelByName(m_feCompositeProgram, "Xor");
233
        ASSERT(m_feXor);
234
    }
235
}
236
237
inline void FilterContextOpenCL::applyFEComposite(cl_mem destination, IntSize destinationSize, cl_mem sourceA, cl_mem sourceB, FloatPoint relativeSourceLocationA, FloatPoint relativeSourceLocationB, float k1, float k2, float k3, float k4, int mode)
238
{
239
    cl_kernel compositeMode;
240
241
    switch (mode) {
242
    case FECOMPOSITE_OPERATOR_ARITHMETIC:
243
        compositeMode = m_feArithmetic;
244
        break;
245
    case FECOMPOSITE_OPERATOR_OVER:
246
        compositeMode = m_feOver;
247
        break;
248
    case FECOMPOSITE_OPERATOR_IN:
249
        compositeMode = m_feIn;
250
        break;
251
    case FECOMPOSITE_OPERATOR_OUT:
252
        compositeMode = m_feOut;
253
        break;
254
    case FECOMPOSITE_OPERATOR_ATOP:
255
        compositeMode = m_feAtop;
256
        break;
257
    case FECOMPOSITE_OPERATOR_XOR:
258
        compositeMode = m_feXor;
259
        break;
260
    default:
261
        compositeMode = m_feOver;
262
        break;
263
    }
264
265
    float xA = relativeSourceLocationA.x();
266
    float yA = relativeSourceLocationA.y();
267
268
    float xB = relativeSourceLocationB.x();
269
    float yB = relativeSourceLocationB.y();
270
271
    RunKernel kernel(this, compositeMode, destinationSize.width(), destinationSize.height());
272
    kernel.addArgument(destination);
273
    kernel.addArgument(sourceA);
274
    kernel.addArgument(sourceB);
275
    kernel.addArgument(xA);
276
    kernel.addArgument(yA);
277
    kernel.addArgument(xB);
278
    kernel.addArgument(yB);
279
    if (mode == FECOMPOSITE_OPERATOR_ARITHMETIC) {
280
        kernel.addArgument(k1);
281
        kernel.addArgument(k2);
282
        kernel.addArgument(k3);
283
        kernel.addArgument(k4);
284
    }
285
    kernel.run();
286
287
}
288
289
bool FEComposite::platformApplyOpenCL()
290
{
291
    FilterContextOpenCL* context = FilterContextOpenCL::context();
292
293
    if (!context)
294
        return false;
295
296
    context->compileFEComposite();
297
298
    FilterEffect* in = inputEffect(0);
299
    cl_mem sourceA = in->asOpenCLImage();
300
301
    FilterEffect* in2 = inputEffect(1);
302
    cl_mem sourceB = in2->asOpenCLImage();
303
304
    cl_mem destination = createOpenCLImageResult();
305
306
    FloatPoint relativeSourceLocationA(in->absolutePaintRect().location());
307
    relativeSourceLocationA.setX(absolutePaintRect().x() - relativeSourceLocationA.x());
308
    relativeSourceLocationA.setY(absolutePaintRect().y() - relativeSourceLocationA.y());
309
310
    FloatPoint relativeSourceLocationB(in2->absolutePaintRect().location());
311
    relativeSourceLocationB.setX(absolutePaintRect().x() - relativeSourceLocationB.x());
312
    relativeSourceLocationB.setY(absolutePaintRect().y() - relativeSourceLocationB.y());
313
314
    context->applyFEComposite(destination, absolutePaintRect().size(), sourceA, sourceB, relativeSourceLocationA, relativeSourceLocationB, m_k1, m_k2, m_k3, m_k4, m_type);
315
316
    return true;
317
}
318
319
} // namespace WebCore
320
321
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEConvolveMatrix.cpp +149 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEConvolveMatrix.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEConvolveMatrix.h"
23
#include "OpenCLContext.h"
24
#include "SVGFilter.h"
25
#include <fstream>
26
#include <stdio.h>
27
28
#define PROGRAM_STR(Src) #Src
29
#define PROGRAM(Src) PROGRAM_STR(Src)
30
31
namespace WebCore {
32
33
static const char* FEConvolveMatrixKernelProgram =
34
PROGRAM_STR(
35
__kernel void ConvolveMatrix(__write_only image2d_t destination, __read_only image2d_t source, __constant float *kernelMatrix,
36
                            int kernelSizeWidth, int kernelSizeHeight, int kernelOffsetX, int kernelOffsetY, float divisor,
37
                            float bias, sampler_t sampler)
38
{
39
    int XCoord = get_global_id(0) - kernelOffsetX;
40
    int YCoord = get_global_id(1) - kernelOffsetY;
41
    float4 totals = (float4)(0,0,0,0);
42
    int kernelIndex = kernelSizeWidth * kernelSizeHeight - 1;
43
    for(int y = 0; y < kernelSizeHeight; ++y) {
44
       for(int x = 0; x < kernelSizeWidth; ++x) {
45
           float4 sourcePixel = read_imagef(source, sampler, (int2)(XCoord + x, YCoord + y));
46
           sourcePixel.xzy *= sourcePixel.w;
47
           totals += sourcePixel * kernelMatrix[kernelIndex];
48
           --kernelIndex;
49
       }
50
    }
51
    totals = totals / divisor + bias;
52
    totals.w = clamp(totals.w, 0.0f, 1.0f);
53
    totals.xyz = clamp(totals.xyz, 0.0f, totals.w) / totals.w;
54
    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), totals);
55
}
56
57
__kernel void ConvolveMatrixAlpha(__write_only image2d_t destination, __read_only image2d_t source, __constant float *kernelMatrix,
58
                                int kernelSizeWidth, int kernelSizeHeight, int kernelOffsetX, int kernelOffsetY, float divisor,
59
                                float bias, sampler_t sampler)
60
{
61
    int XCoord = get_global_id(0) - kernelOffsetX;
62
    int YCoord = get_global_id(1) - kernelOffsetY;
63
    float4 totals = (float4)(0,0,0,0);
64
    int kernelIndex = kernelSizeWidth * kernelSizeHeight - 1;
65
    for(int y = 0; y < kernelSizeHeight; ++y) {
66
       for(int x = 0; x < kernelSizeWidth; ++x) {
67
           float4 sourcePixel = read_imagef(source, sampler, (int2)(XCoord + x, YCoord + y));
68
           totals.xyz += sourcePixel.xyz * kernelMatrix[kernelIndex];
69
           --kernelIndex;
70
       }
71
    }
72
    float4 alpha = read_imagef(source, sampler, (int2)(get_global_id(0), get_global_id(1)));
73
    totals.xyz = clamp(totals.xyz / divisor + bias, 0.0f, 1.0f);
74
    totals.w = alpha.w;
75
    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), totals);
76
}
77
);
78
79
inline void FilterContextOpenCL::compileFEConvolveMatrix()
80
{
81
82
    if (!m_FEConvolveMatrix) {
83
        m_FEConvolveMatrixProgram = compileProgram(FEConvolveMatrixKernelProgram);
84
        ASSERT(m_FEConvolveMatrixProgram);
85
        m_FEConvolveMatrix = kernelByName(m_FEConvolveMatrixProgram, "ConvolveMatrix");
86
        ASSERT(m_FEConvolveMatrix);
87
        m_FEConvolveMatrixAlpha = kernelByName(m_FEConvolveMatrixProgram, "ConvolveMatrixAlpha");
88
        ASSERT(m_FEConvolveMatrixAlpha);
89
    }
90
}
91
92
inline void FilterContextOpenCL::applyFEConvolveMatrix(cl_mem destination, IntSize destinationSize, cl_mem source, IntSize kernelSize, cl_mem kernelMatrix, int edgeMode, float divisor, float bias, IntPoint targetOffset, bool preserveAlpha)
93
{
94
    cl_sampler sampler;
95
96
    switch (edgeMode) {
97
    case EDGEMODE_DUPLICATE:
98
        sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_REPEAT, CL_FILTER_NEAREST, 0);
99
        break;
100
    case EDGEMODE_WRAP:
101
        sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, 0);
102
        break;
103
    default:
104
        sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, 0);
105
    }
106
107
    int kernelOffsetX = targetOffset.x();
108
    int kernelOffsetY = targetOffset.y();
109
110
    int kernelSizeWidth = kernelSize.width();
111
    int kernelSizeHeight = kernelSize.height();
112
113
    RunKernel kernel(this, preserveAlpha ? m_FEConvolveMatrixAlpha : m_FEConvolveMatrix, destinationSize.width(), destinationSize.height());
114
    kernel.addArgument(destination);
115
    kernel.addArgument(source);
116
    kernel.addArgument(kernelMatrix);
117
    kernel.addArgument(kernelSizeWidth);
118
    kernel.addArgument(kernelSizeHeight);
119
    kernel.addArgument(kernelOffsetX);
120
    kernel.addArgument(kernelOffsetY);
121
    kernel.addArgument(divisor);
122
    kernel.addArgument(bias);
123
    kernel.addArgument(sampler);
124
    kernel.run();
125
}
126
127
bool FEConvolveMatrix::platformApplyOpenCL()
128
{
129
    FilterContextOpenCL* context = FilterContextOpenCL::context();
130
    if (!context)
131
        return false;
132
133
    context->compileFEConvolveMatrix();
134
135
    FilterEffect* in = inputEffect(0);
136
137
    cl_mem source = in->asOpenCLImage();
138
    cl_mem destination = createOpenCLImageResult();
139
140
    cl_mem kernelMatrix = context->uploadBuffer(context, m_kernelMatrix.data(), sizeof(float) * m_kernelSize.width() * m_kernelSize.height());
141
142
    context->applyFEConvolveMatrix(destination, absolutePaintRect().size(), source, m_kernelSize, kernelMatrix, m_edgeMode, m_divisor, m_bias, m_targetOffset, m_preserveAlpha);
143
144
    return true;
145
}
146
147
} // namespace WebCore
148
149
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEFlood.cpp +50 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEFlood.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEFlood.h"
23
#include "OpenCLContext.h"
24
25
#include <stdio.h>
26
27
#define PROGRAM_STR(Src) #Src
28
#define PROGRAM(Src) PROGRAM_STR(Src)
29
30
namespace WebCore {
31
32
bool FEFlood::platformApplyOpenCL()
33
{
34
    FilterContextOpenCL* context = FilterContextOpenCL::context();
35
36
    if (!context)
37
        return false;
38
39
    cl_mem destination = createOpenCLImageResult();
40
41
    Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
42
43
    context->Fill(destination, absolutePaintRect().size(), color);
44
45
    return true;
46
}
47
48
} // namespace WebCore
49
50
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEImage.cpp +42 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEImage.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
23
#include "OpenCLContext.h"
24
#include "SVGFEImage.h"
25
#include "SVGFilter.h"
26
#include "SharedBuffer.h"
27
28
#define PROGRAM_STR(Src) #Src
29
#define PROGRAM(Src) PROGRAM_STR(Src)
30
31
namespace WebCore {
32
33
bool FEImage::platformApplyOpenCL()
34
{
35
    platformApplySoftware();
36
    createOpenCLImageResult(asPremultipliedImage(absolutePaintRect())->data());
37
    return true;
38
}
39
40
} // namespace WebCore
41
42
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEMerge.cpp +113 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEMerge.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEMerge.h"
23
#include "OpenCLContext.h"
24
25
#define PROGRAM_STR(Src) #Src
26
#define PROGRAM(Src) PROGRAM_STR(Src)
27
28
namespace WebCore {
29
30
static const char* FEMergeKernelProgram =
31
PROGRAM_STR(
32
    __kernel void Merge(__write_only image2d_t destination,
33
                      __read_only image2d_t source,
34
                      float x,
35
                      float y,
36
                      float width,
37
                      float height,
38
                      sampler_t sampler)
39
    {
40
        int2 sourceCoord = (int2) (get_global_id(0) + x, get_global_id(1) + y);
41
        float4 sourcePixel = read_imagef(source, sampler, sourceCoord);
42
        if(sourceCoord.x >= 0 && sourceCoord.y >= 0 && sourceCoord.x < width && sourceCoord.y < height)
43
            write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), sourcePixel);
44
    }
45
46
);
47
48
inline void FilterContextOpenCL::compileFEMerge()
49
{
50
    if (!m_FEMergeProgram) {
51
        m_FEMergeProgram = compileProgram(FEMergeKernelProgram);
52
        ASSERT(m_FEMergeProgram);
53
        m_FEMerge = kernelByName(m_FEMergeProgram, "Merge");
54
        ASSERT(m_FEMerge);
55
    }
56
}
57
58
inline void FilterContextOpenCL::applyFEMerge(cl_mem destination, IntSize destinationSize, cl_mem source, FloatRect relativeSourceRect)
59
{
60
    float x = relativeSourceRect.x();
61
    float y = relativeSourceRect.y();
62
    float width = relativeSourceRect.width();
63
    float height = relativeSourceRect.height();
64
65
    cl_sampler sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_CLAMP,
66
                                         (round(x) == x && round(y) == y) ? CL_FILTER_NEAREST : CL_FILTER_LINEAR, 0);
67
68
    RunKernel kernel(this, m_FEMerge, destinationSize.width(), destinationSize.height());
69
    kernel.addArgument(destination);
70
    kernel.addArgument(source);
71
    kernel.addArgument(x);
72
    kernel.addArgument(y);
73
    kernel.addArgument(width);
74
    kernel.addArgument(height);
75
    kernel.addArgument(sampler);
76
    kernel.run();
77
78
}
79
80
bool FEMerge::platformApplyOpenCL()
81
{
82
    FilterContextOpenCL* context = FilterContextOpenCL::context();
83
84
    if (!context)
85
        return false;
86
87
    context->compileFEMerge();
88
89
    unsigned size = numberOfEffectInputs();
90
    ASSERT(size > 0);
91
92
    cl_mem destination = createOpenCLImageResult();
93
    cl_mem source;
94
    FilterEffect* in;
95
96
    for (unsigned i = 0; i < size; ++i){
97
        in = inputEffect(i);
98
        source = in->asOpenCLImage();
99
        FloatRect relativeSourceRect(in->absolutePaintRect());
100
        relativeSourceRect.setX(absolutePaintRect().x() - relativeSourceRect.x());
101
        relativeSourceRect.setY(absolutePaintRect().y() - relativeSourceRect.y());
102
103
        context->applyFEMerge(destination, absolutePaintRect().size(), source, relativeSourceRect);
104
    }
105
106
    return true;
107
}
108
109
110
111
} // namespace WebCore
112
113
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEMorphology.cpp +153 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEMorphology.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEMorphology.h"
23
#include "OpenCLContext.h"
24
#include "stdio.h"
25
26
#define PROGRAM_STR(Src) #Src
27
#define PROGRAM(Src) PROGRAM_STR(Src)
28
29
using std::min;
30
31
namespace WebCore {
32
33
static const char* FEMorphologyKernelProgram =
34
PROGRAM_STR(
35
    __kernel void MorphologyDilate(__write_only image2d_t destination,
36
                     __read_only image2d_t source,
37
                      int width,
38
                      int height,
39
                      int radiusX,
40
                      int radiusY,
41
                      sampler_t sampler)
42
    {
43
        int coordX = get_global_id(0);
44
        int coordY = get_global_id(1);
45
46
        int startX = max(0, coordX - radiusX);
47
        int endX = min(width, coordX + radiusX);
48
49
        int startY = max(0, coordY - radiusY);
50
        int endY = min(height, coordY + radiusY);
51
52
        float4 sourcePixel = (float4)(0,0,0,0);
53
54
        for(int y = startY; y <= endY; y++)
55
            for(int x = startX; x <= endX; x++){
56
                sourcePixel = max(sourcePixel , read_imagef(source, sampler, (int2)(x, y)));
57
            }
58
59
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), sourcePixel);
60
    }
61
62
    __kernel void MorphologyErode(__write_only image2d_t destination,
63
                     __read_only image2d_t source,
64
                      int width,
65
                      int height,
66
                      int radiusX,
67
                      int radiusY,
68
                      sampler_t sampler)
69
    {
70
        int coordX = get_global_id(0);
71
        int coordY = get_global_id(1);
72
73
        int startX = max(0, coordX - radiusX);
74
        int endX = min(width - 1, coordX + radiusX);
75
76
        int startY = max(0, coordY - radiusY);
77
        int endY = min(height - 1, coordY + radiusY);
78
79
        float4 sourcePixel = (float4)(256,256,256,256);
80
81
        for(int y = startY; y <= endY; y++)
82
            for(int x = startX; x <= endX; x++){
83
                sourcePixel = min(sourcePixel , read_imagef(source, sampler, (int2)(x, y)));
84
            }
85
86
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), sourcePixel);
87
    }
88
89
);
90
91
inline void FilterContextOpenCL::compileFEMorphology()
92
{
93
    if (!m_feMorphologyDilate && !m_feMorphologyErode) {
94
        m_feMorphologyProgram = compileProgram(FEMorphologyKernelProgram);
95
        ASSERT(m_feMorphologyProgram);
96
        m_feMorphologyDilate = kernelByName(m_feMorphologyProgram, "MorphologyDilate");
97
        ASSERT(m_feMorphologyDilate);
98
        m_feMorphologyErode = kernelByName(m_feMorphologyProgram, "MorphologyErode");
99
        ASSERT(m_feMorphologyErode);
100
    }
101
}
102
103
inline void FilterContextOpenCL::applyFEMorphology(cl_mem destination, IntSize destinationSize, cl_mem source, int width, int height, int radiusX, int radiusY, int type)
104
{
105
106
    cl_sampler sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, 0);
107
108
    RunKernel kernel(this, (type == 1) ? m_feMorphologyErode : m_feMorphologyDilate, destinationSize.width(), destinationSize.height());
109
110
    kernel.addArgument(destination);
111
    kernel.addArgument(source);
112
    kernel.addArgument(width);
113
    kernel.addArgument(height);
114
    kernel.addArgument(radiusX);
115
    kernel.addArgument(radiusY);
116
    kernel.addArgument(sampler);
117
    kernel.run();
118
}
119
120
bool FEMorphology::platformApplyOpenCL()
121
{
122
    FilterContextOpenCL* context = FilterContextOpenCL::context();
123
124
    if (!context)
125
        return false;
126
127
    context->compileFEMorphology();
128
129
    FilterEffect* in = inputEffect(0);
130
    cl_mem source = in->asOpenCLImage();
131
    cl_mem destination = createOpenCLImageResult();
132
133
    setIsAlphaImage(in->isAlphaImage());
134
    if (m_radiusX <= 0 || m_radiusY <= 0) {
135
        context->Fill(destination, absolutePaintRect().size(), Color(0,0,0,0));
136
        return true;
137
    }
138
139
    Filter* filter = this->filter();
140
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
141
    int width = effectDrawingRect.width();
142
    int height = effectDrawingRect.height();
143
    int radiusX = min(width - 1, static_cast<int>(floorf(filter->applyHorizontalScale(m_radiusX))));
144
    int radiusY = min(height - 1, static_cast<int>(floorf(filter->applyVerticalScale(m_radiusY))));
145
146
    context->applyFEMorphology(destination, absolutePaintRect().size(), source, width, height, radiusX, radiusY, m_type);
147
148
    return true;
149
}
150
151
} // namespace WebCore
152
153
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEOffset.cpp +97 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFEOffset.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEOffset.h"
23
#include "OpenCLContext.h"
24
#include "stdio.h"
25
26
#define PROGRAM_STR(Src) #Src
27
#define PROGRAM(Src) PROGRAM_STR(Src)
28
29
namespace WebCore {
30
31
static const char* FEOffsetKernelProgram =
32
PROGRAM_STR(
33
    __kernel void Offset(__write_only image2d_t destination,
34
                     __read_only image2d_t source,
35
                      float x,
36
                      float y,
37
                      sampler_t sampler)
38
    {
39
        int2 sourceCoord = (int2) (get_global_id(0) + x , get_global_id(1) + y);
40
        float4 sourcePixel = read_imagef(source, sampler, sourceCoord);
41
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), sourcePixel);
42
    }
43
44
);
45
46
inline void FilterContextOpenCL::compileFEOffset()
47
{
48
    if (!m_feOffset) {
49
        m_feOffsetProgram = compileProgram(FEOffsetKernelProgram);
50
        ASSERT(m_feOffsetProgram);
51
        m_feOffset = kernelByName(m_feOffsetProgram, "Offset");
52
        ASSERT(m_feOffset);
53
    }
54
}
55
56
inline void FilterContextOpenCL::applyFEOffset(cl_mem destination, IntSize destinationSize, cl_mem source, FloatPoint relativeSourceLocation)
57
{
58
59
    float x = relativeSourceLocation.x();
60
    float y = relativeSourceLocation.y();
61
62
    cl_sampler sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE,
63
                                         (round(x) == x && round(y) == y) ? CL_FILTER_NEAREST : CL_FILTER_LINEAR, 0);
64
65
    RunKernel kernel(this, m_feOffset, destinationSize.width(), destinationSize.height());
66
    kernel.addArgument(destination);
67
    kernel.addArgument(source);
68
    kernel.addArgument(x);
69
    kernel.addArgument(y);
70
    kernel.addArgument(sampler);
71
    kernel.run();
72
}
73
74
bool FEOffset::platformApplyOpenCL()
75
{
76
    FilterContextOpenCL* context = FilterContextOpenCL::context();
77
78
    if (!context)
79
        return false;
80
81
    context->compileFEOffset();
82
83
    FilterEffect* in = inputEffect(0);
84
    cl_mem source = in->asOpenCLImage();
85
    cl_mem destination = createOpenCLImageResult();
86
87
    FloatPoint relativeSourceLocation(in->absolutePaintRect().location());
88
    relativeSourceLocation.setX(absolutePaintRect().x() - (relativeSourceLocation.x() + filter()->applyHorizontalScale(m_dx)));
89
    relativeSourceLocation.setY(absolutePaintRect().y() - (relativeSourceLocation.y() + filter()->applyVerticalScale(m_dy)));
90
    context->applyFEOffset(destination, absolutePaintRect().size(), source,relativeSourceLocation);
91
92
    return true;
93
}
94
95
} // namespace WebCore
96
97
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFESourceAlpha.cpp +60 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFESourceAlpha.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "Filter.h"
23
#include "ImageBuffer.h"
24
#include "SourceAlpha.h"
25
#include "OpenCLContext.h"
26
27
namespace WebCore {
28
29
bool SourceAlpha::platformApplyOpenCL()
30
{
31
    FilterContextOpenCL* context = FilterContextOpenCL::context();
32
33
    if (!context)
34
        return false;
35
36
    Filter* filter = this->filter();
37
    if (!filter->sourceImage()) {
38
        return true;
39
    }
40
41
    ImageBuffer* sourceImage = filter->sourceImage();
42
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
43
44
    unsigned char* dst = sourceImageData->data();
45
    unsigned char* end = dst + sourceImageData->length();
46
    while (dst < end) {
47
        dst[0] = 0;
48
        dst[1] = 0;
49
        dst[2] = 0;
50
        dst += 4;
51
    }
52
53
    createOpenCLImageResult(sourceImageData->data());
54
55
    return true;
56
}
57
58
} // namespace WebCore
59
60
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFESourceGraphic.cpp +51 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFESourceGraphic.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "Filter.h"
23
#include "ImageBuffer.h"
24
#include "SourceGraphic.h"
25
#include "OpenCLContext.h"
26
27
namespace WebCore {
28
29
bool SourceGraphic::platformApplyOpenCL()
30
{
31
    FilterContextOpenCL* context = FilterContextOpenCL::context();
32
33
    if (!context)
34
        return false;
35
36
    Filter* filter = this->filter();
37
    if (!filter->sourceImage()) {
38
        return true;
39
    }
40
41
    ImageBuffer* sourceImage = filter->sourceImage();
42
    RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getPremultipliedImageData(IntRect(IntPoint(),sourceImage->internalSize()));
43
44
    createOpenCLImageResult(sourceImageData->data());
45
46
    return true;
47
}
48
49
} // namespace WebCore
50
51
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFETile.cpp +152 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFETile.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FETile.h"
23
#include "OpenCLContext.h"
24
25
#include <stdio.h>
26
27
#define PROGRAM_STR(Src) #Src
28
#define PROGRAM(Src) PROGRAM_STR(Src)
29
30
namespace WebCore {
31
32
static const char* FETileKernelProgram =
33
PROGRAM_STR(
34
    __kernel void Tiling(__write_only image2d_t destination,
35
                     __read_only image2d_t source,
36
                       float width,
37
                       float height,
38
                       float x,
39
                       float y,
40
                       sampler_t sampler)
41
    {
42
        int coordX = get_global_id(0);
43
        int coordY = get_global_id(1);
44
45
        int2 unnormalizedCoord = (int2)(coordX,coordY);
46
        float2 normalizedCoord = (float2)((coordX + 0.5f + x) / width, (coordY + 0.5f + y) / height);
47
48
        float4 sourcePixel = read_imagef(source, sampler, normalizedCoord);
49
        write_imagef(destination, unnormalizedCoord, sourcePixel);
50
    }
51
52
53
54
__kernel void TileBuilder(__write_only image2d_t destination,
55
                          __read_only image2d_t source,
56
                          float sourceWidth,
57
                          float sourceHeight,
58
                          sampler_t sampler)
59
{
60
61
    int2 coord = (int2) (get_global_id(0) , get_global_id(1) );
62
    float4 sourcePixel = (float4)(1,1,1,1);
63
64
    if(coord.x <= sourceWidth && coord.y <= sourceHeight)
65
        sourcePixel = read_imagef(source, sampler, coord);
66
67
    write_imagef(destination, coord, sourcePixel);
68
}
69
70
);
71
72
inline void FilterContextOpenCL::compileFETile()
73
{
74
    if (!m_feTile) {
75
        m_feTileProgram = compileProgram(FETileKernelProgram);
76
        ASSERT(m_feTileProgram);
77
78
        m_feTile = kernelByName(m_feTileProgram, "Tiling");
79
        ASSERT(m_feTile);
80
81
        m_TileBuilder = kernelByName(m_feTileProgram, "TileBuilder");
82
83
    }
84
}
85
86
inline void FilterContextOpenCL::applyFETiling(cl_mem destination, IntSize destinationSize, cl_mem source, FloatRect sourceRect, FloatPoint relativeSourceLocation)
87
{
88
    cl_sampler sampler = clCreateSampler(deviceContext(), CL_TRUE, CL_ADDRESS_REPEAT,
89
                                          CL_FILTER_LINEAR, 0);
90
    RunKernel kernel(this, m_feTile, destinationSize.width(), destinationSize.height());
91
    kernel.addArgument(destination);
92
    kernel.addArgument(source);
93
    kernel.addArgument(sourceRect.width());
94
    kernel.addArgument(sourceRect.height());
95
    kernel.addArgument(relativeSourceLocation.x());
96
    kernel.addArgument(relativeSourceLocation.y());
97
    kernel.addArgument(sampler);
98
    kernel.run();
99
100
}
101
102
inline void FilterContextOpenCL::applyFETileBuilder(cl_mem destination, FloatRect destinationSize, cl_mem source, FloatSize sourceSize)
103
{
104
    cl_sampler sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_NONE, CL_FILTER_LINEAR, 0);
105
106
    RunKernel kernel2(this, m_TileBuilder, destinationSize.width(), destinationSize.height());
107
    kernel2.addArgument(destination);
108
    kernel2.addArgument(source);
109
    kernel2.addArgument(sourceSize.width());
110
    kernel2.addArgument(sourceSize.height());
111
    kernel2.addArgument(sampler);
112
    kernel2.run();
113
114
}
115
116
bool FETile::platformApplyOpenCL()
117
{
118
    FilterContextOpenCL* context = FilterContextOpenCL::context();
119
120
    if (!context)
121
        return false;
122
123
    context->compileFETile();
124
125
    FilterEffect* in = inputEffect(0);
126
    cl_mem source = in->asOpenCLImage();
127
    cl_mem destination = createOpenCLImageResult();
128
129
    FloatRect tileRect = in->maxEffectRect();
130
131
    if (in->filterEffectType() == FilterEffectTypeSourceInput) {
132
        Filter* filter = this->filter();
133
        tileRect = filter->filterRegion();
134
        tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
135
    }
136
137
    cl_mem tile = context->createOpenCLImage(tileRect.size());
138
139
    context->applyFETileBuilder(tile, tileRect, source, in->absolutePaintRect().size());
140
141
    FloatPoint relativeSourceLocation(in->absolutePaintRect().location());
142
    relativeSourceLocation.setX(absolutePaintRect().x() - relativeSourceLocation.x());
143
    relativeSourceLocation.setY(absolutePaintRect().y() - relativeSourceLocation.y());
144
145
    context->applyFETiling(destination, absolutePaintRect().size(), tile, tileRect, relativeSourceLocation);
146
147
    return true;
148
}
149
150
} // namespace WebCore
151
152
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFETurbulence.cpp +270 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/OpenCLFETurbulence.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FETurbulence.h"
23
#include "FETurbulence.cpp"
24
#include "OpenCLContext.h"
25
#include "SVGFilter.h"
26
#include <fstream>
27
#include <stdio.h>
28
29
#define PROGRAM_STR(Src) #Src
30
#define PROGRAM(Src) PROGRAM_STR(Src)
31
32
namespace WebCore {
33
34
static const char* FETurbulenceKernelProgram =
35
PROGRAM_STR(
36
__constant int s_perlinNoise = 4096;
37
__constant int s_blockSize = 256;
38
__constant int s_blockMask = 255;
39
40
typedef struct
41
{
42
    int noisePositionIntegerValue;
43
    float noisePositionFractionValue;
44
} Noise;
45
46
typedef struct
47
{
48
    int width;
49
    int wrapX;
50
    int height;
51
    int wrapY;
52
} StitchData;
53
54
float linearInterpolation(float t, float a, float b)
55
{
56
    return a + t * (b - a);
57
}
58
59
float noise2D(__constant float *component, __constant int *latticeSelector, StitchData stitchData, float noiseVectorX, float noiseVectorY, int stitchTiles)
60
{
61
    Noise noiseX;
62
    noiseX.noisePositionIntegerValue = (int)(noiseVectorX + s_perlinNoise);
63
    noiseX.noisePositionFractionValue = (noiseVectorX + s_perlinNoise) - noiseX.noisePositionIntegerValue;
64
    Noise noiseY;
65
    noiseY.noisePositionIntegerValue = (int)(noiseVectorY + s_perlinNoise);
66
    noiseY.noisePositionFractionValue = (noiseVectorY + s_perlinNoise) - noiseY.noisePositionIntegerValue;
67
68
    // If stitching, adjust lattice points accordingly.
69
    if (stitchTiles) {
70
        if (noiseX.noisePositionIntegerValue >= stitchData.wrapX)
71
            noiseX.noisePositionIntegerValue -= stitchData.width;
72
        if (noiseX.noisePositionIntegerValue >= stitchData.wrapX - 1)
73
            noiseX.noisePositionIntegerValue -= stitchData.width - 1;
74
        if (noiseY.noisePositionIntegerValue >= stitchData.wrapY)
75
            noiseY.noisePositionIntegerValue -= stitchData.height;
76
        if (noiseY.noisePositionIntegerValue >= stitchData.wrapY - 1)
77
            noiseY.noisePositionIntegerValue -= stitchData.height - 1;
78
    }
79
80
    noiseX.noisePositionIntegerValue &= s_blockMask;
81
    noiseY.noisePositionIntegerValue &= s_blockMask;
82
    int latticeIndex = latticeSelector[noiseX.noisePositionIntegerValue];
83
    int nextLatticeIndex = latticeSelector[(noiseX.noisePositionIntegerValue + 1) & s_blockMask];
84
85
    float sx = noiseX.noisePositionFractionValue * noiseX.noisePositionFractionValue * (3 - 2 * noiseX.noisePositionFractionValue);
86
    float sy = noiseY.noisePositionFractionValue * noiseY.noisePositionFractionValue * (3 - 2 * noiseY.noisePositionFractionValue);
87
88
    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
89
    int temp = latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
90
    float u = noiseX.noisePositionFractionValue * component[temp * 2] + noiseY.noisePositionFractionValue * component[temp * 2 + 1];
91
    temp = latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
92
    float v = (noiseX.noisePositionFractionValue - 1) * component[temp * 2] + noiseY.noisePositionFractionValue * component[temp * 2 + 1];
93
    float a = linearInterpolation(sx, u, v);
94
    temp = latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
95
    u = noiseX.noisePositionFractionValue * component[temp * 2] + (noiseY.noisePositionFractionValue - 1) * component[temp * 2 + 1];
96
    temp = latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
97
    v = (noiseX.noisePositionFractionValue - 1) * component[temp * 2] + (noiseY.noisePositionFractionValue - 1) * component[temp * 2 + 1];
98
    float b = linearInterpolation(sx, u, v);
99
    return linearInterpolation(sy, a, b);
100
}
101
102
__kernel void Turbulence(__write_only image2d_t destination,
103
                         __constant float *transform,
104
                         __constant float *redComponent,
105
                         __constant float *greenComponent,
106
                         __constant float *blueComponent,
107
                         __constant float *alphaComponent,
108
                         __constant int *latticeSelector,
109
                         __private int offsetX,
110
                         __private int offsetY,
111
                         __private int tileWidth,
112
                         __private int tileHeight,
113
                         __private float baseFrequencyX,
114
                         __private float baseFrequencyY,
115
                         __private int stitchTiles,
116
                         __private int numOctaves,
117
                         __private int type,
118
                         __private int filter_height)
119
{
120
    StitchData stitchData;
121
    stitchData.width = 0;
122
    stitchData.wrapX = 0;
123
    stitchData.height = 0;
124
    stitchData.wrapY = 0;
125
    // Adjust the base frequencies if necessary for stitching.
126
    if (stitchTiles) {
127
        // When stitching tiled turbulence, the frequencies must be adjusted
128
        // so that the tile borders will be continuous.
129
        if (baseFrequencyX) {
130
            float lowFrequency = floor(tileWidth * baseFrequencyX) / tileWidth;
131
            float highFrequency = ceil(tileWidth * baseFrequencyX) / tileWidth;
132
            // BaseFrequency should be non-negative according to the standard.
133
            if (baseFrequencyX / lowFrequency < highFrequency / baseFrequencyX)
134
                baseFrequencyX = lowFrequency;
135
            else
136
                baseFrequencyX = highFrequency;
137
        }
138
        if (baseFrequencyY) {
139
            float lowFrequency = floor(tileHeight * baseFrequencyY) / tileHeight;
140
            float highFrequency = ceil(tileHeight * baseFrequencyY) / tileHeight;
141
            if (baseFrequencyY / lowFrequency < highFrequency / baseFrequencyY)
142
                baseFrequencyY = lowFrequency;
143
            else
144
                baseFrequencyY = highFrequency;
145
        }
146
        // Set up TurbulenceInitial stitch values.
147
        stitchData.width = round(tileWidth * baseFrequencyX);
148
        stitchData.wrapX = s_perlinNoise + stitchData.width;
149
        stitchData.height = round(tileHeight * baseFrequencyY);
150
        stitchData.wrapY = s_perlinNoise + stitchData.height;
151
    }
152
    float4 turbulenceFunctionResult = (float4)(0,0,0,0);
153
    float x = (get_global_id(0) + offsetX) * baseFrequencyX;
154
    float y = (get_global_id(1) + offsetY) * baseFrequencyY;
155
156
    float noiseVectorX = transform[0] * x + transform[2] * y + transform[4];
157
    float noiseVectorY = transform[1] * x + transform[3] * y + transform[5];
158
159
    float ratio = 1;
160
    for (int octave = 0; octave < numOctaves; ++octave) {
161
        if (type == 1) {
162
            turbulenceFunctionResult.x += noise2D(redComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles) / ratio;
163
            turbulenceFunctionResult.y += noise2D(greenComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles) / ratio;
164
            turbulenceFunctionResult.z += noise2D(blueComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles) / ratio;
165
            turbulenceFunctionResult.w += noise2D(alphaComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles) / ratio;
166
        } else {
167
            turbulenceFunctionResult.x += fabs(noise2D(redComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles)) / ratio;
168
            turbulenceFunctionResult.y += fabs(noise2D(greenComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles)) / ratio;
169
            turbulenceFunctionResult.z += fabs(noise2D(blueComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles)) / ratio;
170
            turbulenceFunctionResult.w += fabs(noise2D(alphaComponent, latticeSelector, stitchData, noiseVectorX, noiseVectorY, stitchTiles)) / ratio;
171
        }
172
        noiseVectorX *= 2;
173
        noiseVectorY *= 2;
174
        ratio *= 2;
175
        if (stitchTiles) {
176
            // Update stitch values. Subtracting s_perlinNoiseoise before the multiplication and
177
            // adding it afterward simplifies to subtracting it once.
178
            stitchData.width *= 2;
179
            stitchData.wrapX = 2 * stitchData.wrapX - s_perlinNoise;
180
            stitchData.height *= 2;
181
            stitchData.wrapY = 2 * stitchData.wrapY - s_perlinNoise;
182
        }
183
    }
184
185
    if (type == 1)
186
        turbulenceFunctionResult = turbulenceFunctionResult * 0.5f + 0.5f;
187
    // Clamp result
188
    turbulenceFunctionResult = clamp(turbulenceFunctionResult, 0.0f, 1.0f);
189
190
    write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), turbulenceFunctionResult);
191
}
192
);
193
194
inline void FilterContextOpenCL::compileFETurbulence()
195
{
196
197
    if (!m_FETurbulence) {
198
        m_FETurbulenceProgram = compileProgram(FETurbulenceKernelProgram);
199
        ASSERT(m_FETurbulenceProgram);
200
        m_FETurbulence = kernelByName(m_FETurbulenceProgram, "Turbulence");
201
        ASSERT(m_FETurbulence);
202
    }
203
}
204
205
inline void FilterContextOpenCL::applyFETurbulence(cl_mem destination, IntSize destinationSize, cl_mem transformHandle, cl_mem redComponentHandle, cl_mem greenComponentHandle,
206
                                                   cl_mem blueComponentHandle, cl_mem alphaComponentHandle, cl_mem latticeSelectorHandle, int offsetX, int offsetY, int tileWidth, int tileHeight,
207
                                                   float baseFrequencyX, float baseFrequencyY, bool stitchTiles, int numOctaves, int type)
208
{
209
    RunKernel kernel(this, m_FETurbulence, destinationSize.width(), destinationSize.height());
210
    kernel.addArgument(destination);
211
    kernel.addArgument(transformHandle);
212
    kernel.addArgument(redComponentHandle);
213
    kernel.addArgument(greenComponentHandle);
214
    kernel.addArgument(blueComponentHandle);
215
    kernel.addArgument(alphaComponentHandle);
216
    kernel.addArgument(latticeSelectorHandle);
217
    kernel.addArgument(offsetX);
218
    kernel.addArgument(offsetY);
219
    kernel.addArgument(tileWidth);
220
    kernel.addArgument(tileHeight);
221
    kernel.addArgument(baseFrequencyX);
222
    kernel.addArgument(baseFrequencyY);
223
    kernel.addArgument(stitchTiles);
224
    kernel.addArgument(numOctaves);
225
    kernel.addArgument(type);
226
    kernel.addArgument(destinationSize.height());
227
    kernel.run();
228
}
229
230
bool FETurbulence::platformApplyOpenCL()
231
{
232
    FilterContextOpenCL* context = FilterContextOpenCL::context();
233
    if (!context)
234
        return false;
235
236
    context->compileFETurbulence();
237
238
    cl_mem destination = createOpenCLImageResult();
239
240
    PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size()));
241
    initPaint(paintingData);
242
243
    AffineTransform invertedTransform = reinterpret_cast<SVGFilter*>(filter())->absoluteTransform().inverse();
244
    float transformComponents[6] = { invertedTransform.a(), invertedTransform.b(), invertedTransform.c(), invertedTransform.d(), invertedTransform.e(), invertedTransform.f() };
245
246
    cl_mem transformHandle = context->uploadBuffer(context, transformComponents, sizeof(float) * 6);
247
    cl_mem redComponentHandle = context->uploadBuffer(context, paintingData.gradient + 0, sizeof(float) * (2 * s_blockSize + 2) * 2);
248
    cl_mem greenComponentHandle = context->uploadBuffer(context, paintingData.gradient + 1, sizeof(float) * (2 * s_blockSize + 2) * 2);
249
    cl_mem blueComponentHandle = context->uploadBuffer(context, paintingData.gradient + 2, sizeof(float) * (2 * s_blockSize + 2) * 2);
250
    cl_mem alphaComponentHandle = context->uploadBuffer(context, paintingData.gradient + 3, sizeof(float) * (2 * s_blockSize + 2) * 2);
251
    cl_mem latticeSelectorHandle = context->uploadBuffer(context, paintingData.latticeSelector, sizeof(int) * (2 * s_blockSize + 2));
252
253
    context->applyFETurbulence(destination, absolutePaintRect().size(), transformHandle, redComponentHandle, greenComponentHandle,
254
                               blueComponentHandle, alphaComponentHandle, latticeSelectorHandle, absolutePaintRect().x(), absolutePaintRect().y(),
255
                               paintingData.filterSize.width(), paintingData.filterSize.height(), m_baseFrequencyX, m_baseFrequencyY, m_stitchTiles,
256
                               m_numOctaves, m_type);
257
258
    clReleaseMemObject(transformHandle);
259
    clReleaseMemObject(redComponentHandle);
260
    clReleaseMemObject(greenComponentHandle);
261
    clReleaseMemObject(blueComponentHandle);
262
    clReleaseMemObject(alphaComponentHandle);
263
    clReleaseMemObject(latticeSelectorHandle);
264
265
    return true;
266
}
267
268
} // namespace WebCore
269
270
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/OpenCL/Samplertest.cpp +201 lines
Line 0 a/Source/WebCore/platform/graphics/filters/OpenCL/Samplertest.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public License
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
#include "config.h"
21
#if ENABLE(FILTERS) && ENABLE(OPENCL)
22
#include "FEOffset.h"
23
#include "OpenCLContext.h"
24
#include "stdio.h"
25
26
#define PROGRAM_STR(Src) #Src
27
#define PROGRAM(Src) PROGRAM_STR(Src)
28
29
struct BMPHeader {
30
  unsigned short bfType;
31
  unsigned int bfSize;
32
  unsigned short bfReserved1;
33
  unsigned short bfReserved2;
34
  unsigned int bfOffBits;
35
36
  unsigned int biSize;
37
  unsigned int biWidth;
38
  unsigned int biHeight;
39
  unsigned short biPlanes;
40
  unsigned short biBitCount;
41
  unsigned int biCompression;
42
  unsigned int biSizeImage;
43
  unsigned int biXPelsPerMeter;
44
  unsigned int biYPelsPerMeter;
45
  unsigned int biClrUsed;
46
  unsigned int biClrImportant;
47
 } __attribute__((__packed__));
48
49
 static void dumpAsBMP(const char* fileName, RefPtr<Uint8ClampedArray> pixels, int x, int y, int width, int height, int srcScanline)
50
 {
51
  BMPHeader* header;
52
  unsigned char* src;
53
  unsigned char* dst;
54
  int dstScanline;
55
  int size, i, j;
56
  FILE* f;
57
58
  dstScanline = ((width * 3) + 3) & ~3;
59
  srcScanline *= 4;
60
61
  size = (dstScanline * height) + sizeof(BMPHeader);
62
  header = (BMPHeader*)fastMalloc(size);
63
  if (!header)
64
  return;
65
66
  f = fopen(fileName, "w");
67
  if (!f) {
68
  fastFree(header);
69
  return;
70
  }
71
72
  memset(header, 0, size);
73
  header->bfType = 0x4d42;
74
  header->bfSize = size;
75
  header->bfOffBits = sizeof(BMPHeader);
76
  header->biSize = 40;
77
  header->biWidth = width;
78
  header->biHeight = height;
79
  header->biPlanes = 1;
80
  header->biBitCount = 24;
81
  size -= sizeof(BMPHeader);
82
  header->biSizeImage = size;
83
84
  dst = ((unsigned char*)header) + sizeof(BMPHeader);
85
  src = pixels->data() + ((y + height - 1) * srcScanline) + x * 4;
86
87
  dstScanline -= (width * 3);
88
  srcScanline += (width * 4);
89
  for (i = 0; i < height; ++i) {
90
  for (j = 0; j < width; ++j) {
91
  dst[0] = src[2];
92
  dst[1] = src[1];
93
  dst[2] = src[0];
94
  src += 4;
95
  dst += 3;
96
  }
97
  dst += dstScanline;
98
  src -= srcScanline;
99
  }
100
101
  fwrite(header, size, 1, f);
102
  fclose(f);
103
  fastFree(header);
104
  printf("'%s' written\n", fileName);
105
  fflush(stdout);
106
}
107
108
namespace WebCore {
109
110
static const char* FEOffsetKernelProgram =
111
PROGRAM_STR(
112
    __kernel void Offset(__write_only image2d_t destination,
113
                     __read_only image2d_t source,
114
                      float x,
115
                      float y,
116
                      sampler_t sampler)
117
    {
118
        int2 sourceCoord = (int2) (get_global_id(0) + x  , get_global_id(1) + y);
119
        float4 sourcePixel = read_imagef(source, sampler, sourceCoord);
120
        write_imagef(destination, (int2)(get_global_id(0), get_global_id(1)), sourcePixel);
121
    }
122
123
);
124
125
inline void FilterContextOpenCL::compileFEOffset()
126
{
127
    if (!m_feOffset) {
128
        m_feOffsetProgram = compileProgram(FEOffsetKernelProgram);
129
        ASSERT(m_feOffsetProgram);
130
        m_feOffset = kernelByName(m_feOffsetProgram, "Offset");
131
        ASSERT(m_feOffset);
132
    }
133
}
134
135
inline void FilterContextOpenCL::applyFEOffset(cl_mem destination, IntSize destinationSize, cl_mem source, FloatPoint relativeSourceLocation)
136
{
137
138
    float x = relativeSourceLocation.x();
139
    float y = relativeSourceLocation.y();
140
141
    cl_sampler sampler = clCreateSampler(deviceContext(), CL_FALSE, CL_ADDRESS_CLAMP,
142
                                         CL_FILTER_LINEAR, 0);
143
144
    RunKernel kernel(this, m_feOffset, destinationSize.width(), destinationSize.height());
145
    kernel.addArgument(destination);
146
    kernel.addArgument(source);
147
    kernel.addArgument(x);
148
    kernel.addArgument(y);
149
    kernel.addArgument(sampler);
150
    kernel.run();
151
}
152
153
bool FEOffset::platformApplyOpenCL()
154
{
155
    FilterContextOpenCL* context = FilterContextOpenCL::context();
156
157
    if (!context)
158
        return false;
159
160
    context->compileFEOffset();
161
162
    FilterEffect* in = inputEffect(0);
163
    cl_mem source = in->asOpenCLImage();
164
    cl_mem destination = createOpenCLImageResult();
165
166
    size_t origin[3] = { 0, 0, 0 };
167
    size_t region[3] = { absolutePaintRect().width(), absolutePaintRect().height(), 1};
168
169
    RefPtr<Uint8ClampedArray> destinationPixelArray = Uint8ClampedArray::create(absolutePaintRect().width() * absolutePaintRect().height() * 4);
170
171
    clEnqueueReadImage(context->commandQueue(), source, CL_TRUE, origin, region, 0, 0, destinationPixelArray->data(), 0, 0, 0);
172
173
    dumpAsBMP("kep3.bmp", destinationPixelArray, 0, 0, absolutePaintRect().width(), absolutePaintRect().height(), absolutePaintRect().width());
174
175
    clEnqueueReadImage(context->commandQueue(), destination, CL_TRUE, origin, region, 0, 0, destinationPixelArray->data(), 0, 0, 0);
176
177
    dumpAsBMP("kep4.bmp", destinationPixelArray, 0, 0, absolutePaintRect().width(), absolutePaintRect().height(), absolutePaintRect().width());
178
179
180
    FloatPoint relativeSourceLocation(in->absolutePaintRect().location());
181
    //relativeSourceLocation.setX(absolutePaintRect().x() - (relativeSourceLocation.x() + filter()->applyHorizontalScale(m_dx)));
182
    //relativeSourceLocation.setY(absolutePaintRect().y() - (relativeSourceLocation.y() + filter()->applyVerticalScale(m_dy)));
183
    context->applyFEOffset(destination, absolutePaintRect().size(), source,relativeSourceLocation);
184
185
    clEnqueueReadImage(context->commandQueue(), destination, CL_TRUE, origin, region, 0, 0, destinationPixelArray->data(), 0, 0, 0);
186
187
    dumpAsBMP("kep5.bmp", destinationPixelArray, 0, 0, absolutePaintRect().width(), absolutePaintRect().height(), absolutePaintRect().width());
188
189
   // platformApplySoftware();
190
191
192
193
    dumpAsBMP("kep7.bmp", asImageBuffer()->getPremultipliedImageData(absolutePaintRect()), 0, 0, absolutePaintRect().width(), absolutePaintRect().height(), absolutePaintRect().width());
194
195
196
    return true;
197
}
198
199
} // namespace WebCore
200
201
#endif // ENABLE(FILTERS) && ENABLE(OPENCL)
- a/Source/WebCore/platform/graphics/filters/SourceAlpha.h +3 lines
Lines 33-38 public: a/Source/WebCore/platform/graphics/filters/SourceAlpha.h_sec1
33
    static const AtomicString& effectName();
33
    static const AtomicString& effectName();
34
34
35
    virtual void platformApplySoftware();
35
    virtual void platformApplySoftware();
36
#if ENABLE(OPENCL)
37
    virtual bool platformApplyOpenCL();
38
#endif
36
    virtual void dump();
39
    virtual void dump();
37
40
38
    virtual void determineAbsolutePaintRect();
41
    virtual void determineAbsolutePaintRect();
- a/Source/WebCore/platform/graphics/filters/SourceGraphic.h +3 lines
Lines 34-39 public: a/Source/WebCore/platform/graphics/filters/SourceGraphic.h_sec1
34
    static const AtomicString& effectName();
34
    static const AtomicString& effectName();
35
35
36
    virtual void platformApplySoftware();
36
    virtual void platformApplySoftware();
37
#if ENABLE(OPENCL)
38
    virtual bool platformApplyOpenCL();
39
#endif
37
    virtual void dump();
40
    virtual void dump();
38
41
39
    virtual void determineAbsolutePaintRect();
42
    virtual void determineAbsolutePaintRect();
- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp -3 / +10 lines
Lines 302-310 void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp_sec1
302
            lastEffect->apply();
302
            lastEffect->apply();
303
            lastEffect->correctFilterResultIfNeeded();
303
            lastEffect->correctFilterResultIfNeeded();
304
#if !USE(CG)
304
#if !USE(CG)
305
            ImageBuffer* resultImage = lastEffect->asImageBuffer();
305
#if ENABLE(OPENCL)
306
            if (resultImage)
306
        cl_mem resultImage = lastEffect->asOpenCLImage();
307
                resultImage->transformColorSpace(lastEffect->colorSpace(), ColorSpaceDeviceRGB);
307
        FilterContextOpenCL* context = FilterContextOpenCL::context();
308
        if (resultImage && context)
309
            context->OpenCLTransformColorSpace(resultImage, ColorSpaceDeviceRGB, lastEffect->colorSpace(), lastEffect->absolutePaintRect());
310
#else
311
        ImageBuffer* resultImage = lastEffect->asImageBuffer();
312
        if (resultImage)
313
            resultImage->transformColorSpace(lastEffect->colorSpace(), ColorSpaceDeviceRGB);
314
#endif
308
#endif
315
#endif
309
        }
316
        }
310
        filterData->builded = true;
317
        filterData->builded = true;
- a/Source/WebCore/svg/graphics/filters/SVGFEImage.h +3 lines
Lines 39-44 public: a/Source/WebCore/svg/graphics/filters/SVGFEImage.h_sec1
39
    static PassRefPtr<FEImage> createWithIRIReference(Filter*, Document*, const String&, const SVGPreserveAspectRatio&);
39
    static PassRefPtr<FEImage> createWithIRIReference(Filter*, Document*, const String&, const SVGPreserveAspectRatio&);
40
40
41
    virtual void platformApplySoftware();
41
    virtual void platformApplySoftware();
42
#if ENABLE(OPENCL)
43
    virtual bool platformApplyOpenCL();
44
#endif
42
    virtual void dump();
45
    virtual void dump();
43
46
44
    virtual void determineAbsolutePaintRect();
47
    virtual void determineAbsolutePaintRect();

Return to Bug 70099