Changeset 135733 in webkit


Ignore:
Timestamp:
Nov 26, 2012, 9:18:25 AM (13 years ago)
Author:
commit-queue@webkit.org
Message:

OpenCL version of SourceAlpha, SourceGraphics and FETurbulence filter effects
https://bugs.webkit.org/show_bug.cgi?id=99829

Patch by Tamas Czene <tczene@inf.u-szeged.hu> on 2012-11-26
Reviewed by Zoltan Herczeg.

This patch contains the OpenCL implementation of SourceAlpha, SourceGraphic, FETurbulence and a simple OpenCL environment.
At the moment only the Qt build system is supported
~3x speed-up (depending on hardware configuration)

  • Target.pri:
  • WebCore.pri:
  • platform/graphics/filters/FETurbulence.h: Added platformApplyOpenCL() virtual function.

(FETurbulence):

  • platform/graphics/filters/FilterEffect.cpp: Added platform specific apply.

(WebCore::FilterEffect::apply):
(WebCore):
(WebCore::FilterEffect::platformApplyOpenCL): A function to use software computing if a filter is not implemented on OpenCL. It will be deleted after all of the filters are implemented.
(WebCore::FilterEffect::clearResult):
(WebCore::FilterEffect::asImageBuffer):
(WebCore::FilterEffect::openCLImageToImageBuffer): Gets the result of the filter from the OpenCL device and converts it to ImageBuffer type.
(WebCore::FilterEffect::createOpenCLImageResult): Allocates memory on OpenCL device and if it gets an image as a parameter, it uploads the image to the OpenCL device.
(WebCore::FilterEffect::transformResultColorSpace):

  • platform/graphics/filters/FilterEffect.h:

(FilterEffect):
(WebCore::FilterEffect::openCLImage):
(WebCore::FilterEffect::setOpenCLImage):
(WebCore::FilterEffect::hasResult):

  • platform/graphics/filters/SourceAlpha.h:

(SourceAlpha):

  • platform/graphics/filters/SourceGraphic.h:

(SourceGraphic):

  • platform/graphics/gpu/opencl/FilterContextOpenCL.cpp: Added.

(WebCore):
(WebCore::FilterContextOpenCL::context): Configures the OpenCL environment.
(WebCore::FilterContextOpenCL::createOpenCLImage): Allocates memory on OpenCL device.
(WebCore::FilterContextOpenCL::openCLTransformColorSpace): OpenCL implementation of transformColorSpace.
(WebCore::FilterContextOpenCL::compileProgram):

  • platform/graphics/gpu/opencl/FilterContextOpenCL.h: Added.

(WebCore):
(FilterContextOpenCL):
(WebCore::FilterContextOpenCL::deviceId):
(WebCore::FilterContextOpenCL::deviceContext):
(WebCore::FilterContextOpenCL::commandQueue):
(RunKernel):
(WebCore::FilterContextOpenCL::RunKernel::RunKernel):
(WebCore::FilterContextOpenCL::RunKernel::addArgument):
(WebCore::FilterContextOpenCL::RunKernel::run):
(WebCore::FilterContextOpenCL::kernelByName): Returns the reference of a function in the OpenCL program.

  • platform/graphics/gpu/opencl/OpenCLFESourceAlpha.cpp: Added.

(WebCore):
(WebCore::SourceAlpha::platformApplyOpenCL):

  • platform/graphics/gpu/opencl/OpenCLFESourceGraphic.cpp: Added.

(WebCore):
(WebCore::SourceGraphic::platformApplyOpenCL):

  • platform/graphics/gpu/opencl/OpenCLFETurbulence.cpp: Added.

(WebCore):
(WebCore::FilterContextOpenCL::compileFETurbulence):
(WebCore::FilterContextOpenCL::applyFETurbulence):
(WebCore::FETurbulence::platformApplyOpenCL):

  • platform/graphics/gpu/opencl/OpenCLHandle.h: Added.

(WebCore):
(OpenCLHandle):
(WebCore::OpenCLHandle::OpenCLHandle):
(WebCore::OpenCLHandle::operator cl_mem):
(WebCore::OpenCLHandle::operator=):
(WebCore::OpenCLHandle::operator UnspecifiedBoolType):
(WebCore::OpenCLHandle::handleAddress):
(WebCore::OpenCLHandle::clear):

Location:
trunk/Source/WebCore
Files:
7 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r135732 r135733  
     12012-11-26  Tamas Czene  <tczene@inf.u-szeged.hu>
     2
     3        OpenCL version of SourceAlpha, SourceGraphics and FETurbulence filter effects
     4        https://bugs.webkit.org/show_bug.cgi?id=99829
     5
     6        Reviewed by Zoltan Herczeg.
     7
     8        This patch contains the OpenCL implementation of SourceAlpha, SourceGraphic, FETurbulence and a simple OpenCL environment.
     9        At the moment only the Qt build system is supported
     10        ~3x speed-up (depending on hardware configuration)
     11
     12        * Target.pri:
     13        * WebCore.pri:
     14        * platform/graphics/filters/FETurbulence.h: Added platformApplyOpenCL() virtual function.
     15        (FETurbulence):
     16        * platform/graphics/filters/FilterEffect.cpp: Added platform specific apply.
     17        (WebCore::FilterEffect::apply):
     18        (WebCore):
     19        (WebCore::FilterEffect::platformApplyOpenCL): A function to use software computing if a filter is not implemented on OpenCL. It will be deleted after all of the filters are implemented.
     20        (WebCore::FilterEffect::clearResult):
     21        (WebCore::FilterEffect::asImageBuffer):
     22        (WebCore::FilterEffect::openCLImageToImageBuffer): Gets the result of the filter from the OpenCL device and converts it to ImageBuffer type.
     23        (WebCore::FilterEffect::createOpenCLImageResult): Allocates memory on OpenCL device and if it gets an image as a parameter, it uploads the image to the OpenCL device.
     24        (WebCore::FilterEffect::transformResultColorSpace):
     25        * platform/graphics/filters/FilterEffect.h:
     26        (FilterEffect):
     27        (WebCore::FilterEffect::openCLImage):
     28        (WebCore::FilterEffect::setOpenCLImage):
     29        (WebCore::FilterEffect::hasResult):
     30        * platform/graphics/filters/SourceAlpha.h:
     31        (SourceAlpha):
     32        * platform/graphics/filters/SourceGraphic.h:
     33        (SourceGraphic):
     34        * platform/graphics/gpu/opencl/FilterContextOpenCL.cpp: Added.
     35        (WebCore):
     36        (WebCore::FilterContextOpenCL::context): Configures the OpenCL environment.
     37        (WebCore::FilterContextOpenCL::createOpenCLImage): Allocates memory on OpenCL device.
     38        (WebCore::FilterContextOpenCL::openCLTransformColorSpace): OpenCL implementation of transformColorSpace.
     39        (WebCore::FilterContextOpenCL::compileProgram):
     40        * platform/graphics/gpu/opencl/FilterContextOpenCL.h: Added.
     41        (WebCore):
     42        (FilterContextOpenCL):
     43        (WebCore::FilterContextOpenCL::deviceId):
     44        (WebCore::FilterContextOpenCL::deviceContext):
     45        (WebCore::FilterContextOpenCL::commandQueue):
     46        (RunKernel):
     47        (WebCore::FilterContextOpenCL::RunKernel::RunKernel):
     48        (WebCore::FilterContextOpenCL::RunKernel::addArgument):
     49        (WebCore::FilterContextOpenCL::RunKernel::run):
     50        (WebCore::FilterContextOpenCL::kernelByName): Returns the reference of a function in the OpenCL program.
     51        * platform/graphics/gpu/opencl/OpenCLFESourceAlpha.cpp: Added.
     52        (WebCore):
     53        (WebCore::SourceAlpha::platformApplyOpenCL):
     54        * platform/graphics/gpu/opencl/OpenCLFESourceGraphic.cpp: Added.
     55        (WebCore):
     56        (WebCore::SourceGraphic::platformApplyOpenCL):
     57        * platform/graphics/gpu/opencl/OpenCLFETurbulence.cpp: Added.
     58        (WebCore):
     59        (WebCore::FilterContextOpenCL::compileFETurbulence):
     60        (WebCore::FilterContextOpenCL::applyFETurbulence):
     61        (WebCore::FETurbulence::platformApplyOpenCL):
     62        * platform/graphics/gpu/opencl/OpenCLHandle.h: Added.
     63        (WebCore):
     64        (OpenCLHandle):
     65        (WebCore::OpenCLHandle::OpenCLHandle):
     66        (WebCore::OpenCLHandle::operator cl_mem):
     67        (WebCore::OpenCLHandle::operator=):
     68        (WebCore::OpenCLHandle::operator UnspecifiedBoolType):
     69        (WebCore::OpenCLHandle::handleAddress):
     70        (WebCore::OpenCLHandle::clear):
     71
    1722012-11-26  'Pavel Feldman'  <pfeldman@chromium.org>
    273
  • trunk/Source/WebCore/Target.pri

    r135690 r135733  
    40824082}
    40834083
     4084contains(DEFINES, ENABLE_OPENCL=1) {
     4085    HEADERS += \
     4086        platform/graphics/gpu/opencl/OpenCLHandle.h \
     4087        platform/graphics/gpu/opencl/FilterContextOpenCL.h
     4088    SOURCES += \
     4089        platform/graphics/gpu/opencl/FilterContextOpenCL.cpp \
     4090        platform/graphics/gpu/opencl/OpenCLFESourceAlpha.cpp \
     4091        platform/graphics/gpu/opencl/OpenCLFESourceGraphic.cpp \
     4092        platform/graphics/gpu/opencl/OpenCLFETurbulence.cpp
     4093}
     4094
    40844095use?(GRAPHICS_SURFACE) {
    40854096    mac {
  • trunk/Source/WebCore/WebCore.pri

    r135407 r135733  
    295295}
    296296
     297contains(DEFINES, ENABLE_OPENCL=1) {
     298    LIBS += -lOpenCL
     299
     300    INCLUDEPATH += $$SOURCE_DIR/platform/graphics/gpu/opencl
     301}
     302
    297303# Disable C++0x mode in WebCore for those who enabled it in their Qt's mkspec
    298304*-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x
  • trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h

    r114992 r135733  
    6262
    6363    virtual void platformApplySoftware();
     64#if ENABLE(OPENCL)
     65    virtual bool platformApplyOpenCL();
     66#endif
    6467    virtual void dump();
    6568   
  • trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp

    r125462 r135733  
    33 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
    44 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
     5 * Copyright (C) 2012 University of Szeged
    56 *
    67 * This library is free software; you can redistribute it and/or
     
    124125   
    125126    // Add platform specific apply functions here and return earlier.
     127#if ENABLE(OPENCL)
     128    if (platformApplyOpenCL())
     129        return;
     130#endif
    126131#if USE(SKIA)
    127132    if (platformApplySkia())
     
    130135    platformApplySoftware();
    131136}
     137
     138#if ENABLE(OPENCL)
     139// This function will be changed to abstract virtual when all filters are landed.
     140bool FilterEffect::platformApplyOpenCL()
     141{
     142    if (!FilterContextOpenCL::context())
     143        return false;
     144
     145    unsigned size = m_inputEffects.size();
     146    for (unsigned i = 0; i < size; ++i) {
     147        FilterEffect* in = m_inputEffects.at(i).get();
     148        // Software code path expects that at least one of the following fileds is valid.
     149        if (!in->m_imageBufferResult && !in->m_unmultipliedImageResult && !in->m_premultipliedImageResult)
     150            in->asImageBuffer();
     151    }
     152
     153    platformApplySoftware();
     154    ImageBuffer* sourceImage = asImageBuffer();
     155    if (sourceImage) {
     156        RefPtr<Uint8ClampedArray> sourceImageData = sourceImage->getUnmultipliedImageData(IntRect(IntPoint(), sourceImage->internalSize()));
     157        createOpenCLImageResult(sourceImageData->data());
     158    }
     159    return true;
     160}
     161#endif
    132162
    133163void FilterEffect::forceValidPreMultipliedPixels()
     
    188218    if (m_premultipliedImageResult)
    189219        m_premultipliedImageResult.clear();
     220#if ENABLE(OPENCL)
     221    if (m_openCLImageResult)
     222        m_openCLImageResult.clear();
     223#endif
    190224}
    191225
     
    196230    if (m_imageBufferResult)
    197231        return m_imageBufferResult.get();
     232#if ENABLE(OPENCL)
     233    if (m_openCLImageResult)
     234        return openCLImageToImageBuffer();
     235#endif
    198236    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), 1, m_resultColorSpace, m_filter->renderingMode());
    199237    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
     
    204242    return m_imageBufferResult.get();
    205243}
     244
     245#if ENABLE(OPENCL)
     246ImageBuffer* FilterEffect::openCLImageToImageBuffer()
     247{
     248    FilterContextOpenCL* context = FilterContextOpenCL::context();
     249    ASSERT(context);
     250
     251    size_t origin[3] = { 0, 0, 0 };
     252    size_t region[3] = { m_absolutePaintRect.width(), m_absolutePaintRect.height(), 1 };
     253
     254    RefPtr<Uint8ClampedArray> destinationPixelArray = Uint8ClampedArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
     255
     256    clFinish(context->commandQueue());
     257    clEnqueueReadImage(context->commandQueue(), m_openCLImageResult, CL_TRUE, origin, region, 0, 0, destinationPixelArray->data(), 0, 0, 0);
     258
     259    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size());
     260    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
     261    m_imageBufferResult->putByteArray(Unmultiplied, destinationPixelArray.get(), destinationRect.size(), destinationRect, IntPoint());
     262
     263    return m_imageBufferResult.get();
     264}
     265#endif
    206266
    207267PassRefPtr<Uint8ClampedArray> FilterEffect::asUnmultipliedImage(const IntRect& rect)
     
    364424}
    365425
     426#if ENABLE(OPENCL)
     427OpenCLHandle FilterEffect::createOpenCLImageResult(uint8_t* source)
     428{
     429    ASSERT(!hasResult());
     430    cl_image_format clImageFormat;
     431    clImageFormat.image_channel_order = CL_RGBA;
     432    clImageFormat.image_channel_data_type = CL_UNORM_INT8;
     433
     434    FilterContextOpenCL* context = FilterContextOpenCL::context();
     435    ASSERT(context);
     436    m_openCLImageResult = clCreateImage2D(context->deviceContext(), CL_MEM_READ_WRITE | (source ? CL_MEM_COPY_HOST_PTR : 0),
     437        &clImageFormat, m_absolutePaintRect.width(), m_absolutePaintRect.height(), 0, source, 0);
     438    return m_openCLImageResult;
     439}
     440#endif
     441
    366442void FilterEffect::transformResultColorSpace(ColorSpace dstColorSpace)
    367443{
     
    375451    // FIXME: We can avoid this potentially unnecessary ImageBuffer conversion by adding
    376452    // color space transform support for the {pre,un}multiplied arrays.
     453#if ENABLE(OPENCL)
     454    if (openCLImage()) {
     455        FilterContextOpenCL* context = FilterContextOpenCL::context();
     456        ASSERT(context);
     457        context->openCLTransformColorSpace(m_openCLImageResult, absolutePaintRect(), m_resultColorSpace, dstColorSpace);
     458        if (m_imageBufferResult)
     459            m_imageBufferResult.clear();
     460        goto skipSoftwareCodePath;
     461    }
     462#endif
    377463    if (!m_imageBufferResult) {
    378464        asImageBuffer();
     
    381467
    382468    m_imageBufferResult->transformColorSpace(m_resultColorSpace, dstColorSpace);
     469
     470#if ENABLE(OPENCL)
     471skipSoftwareCodePath:
     472#endif
     473
    383474    m_resultColorSpace = dstColorSpace;
    384475
  • trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h

    r133608 r135733  
    3434#include <wtf/Vector.h>
    3535
     36#if ENABLE(OPENCL)
     37#include "FilterContextOpenCL.h"
     38#endif
     39
    3640static const float kMaxFilterSize = 5000.0f;
    3741
     
    7175    void copyPremultipliedImage(Uint8ClampedArray* destination, const IntRect&);
    7276
     77#if ENABLE(OPENCL)
     78    OpenCLHandle openCLImage() { return m_openCLImageResult; }
     79    void setOpenCLImage(OpenCLHandle openCLImage) { m_openCLImageResult = openCLImage; }
     80    ImageBuffer* openCLImageToImageBuffer();
     81#endif
     82
    7383    FilterEffectVector& inputEffects() { return m_inputEffects; }
    7484    FilterEffect* inputEffect(unsigned) const;
     
    7888    {
    7989        // This function needs platform specific checks, if the memory managment is not done by FilterEffect.
    80         return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult;
     90        return m_imageBufferResult
     91#if ENABLE(OPENCL)
     92            || m_openCLImageResult
     93#endif
     94            || m_unmultipliedImageResult
     95            || m_premultipliedImageResult;
    8196    }
    8297
     
    102117
    103118    virtual void platformApplySoftware() = 0;
     119#if ENABLE(OPENCL)
     120    virtual bool platformApplyOpenCL();
     121#endif
    104122#if USE(SKIA)
    105123    virtual bool platformApplySkia() { return false; }
     
    150168    Uint8ClampedArray* createUnmultipliedImageResult();
    151169    Uint8ClampedArray* createPremultipliedImageResult();
     170#if ENABLE(OPENCL)
     171    OpenCLHandle createOpenCLImageResult(uint8_t* = 0);
     172#endif
    152173
    153174    // Return true if the filter will only operate correctly on valid RGBA values, with
     
    163184    RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
    164185    FilterEffectVector m_inputEffects;
     186#if ENABLE(OPENCL)
     187    OpenCLHandle m_openCLImageResult;
     188#endif
    165189
    166190    bool m_alphaImage;
  • trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h

    r127757 r135733  
    3434
    3535    virtual void platformApplySoftware();
     36#if ENABLE(OPENCL)
     37    virtual bool platformApplyOpenCL();
     38#endif
    3639    virtual void dump();
    3740
  • trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.h

    r127757 r135733  
    3535
    3636    virtual void platformApplySoftware();
     37#if ENABLE(OPENCL)
     38    virtual bool platformApplyOpenCL();
     39#endif
    3740    virtual void dump();
    3841
Note: See TracChangeset for help on using the changeset viewer.