Changeset 73894 in webkit


Ignore:
Timestamp:
Dec 13, 2010 2:15:53 AM (13 years ago)
Author:
zherczeg@webkit.org
Message:

Better result passing in filter primitives
https://bugs.webkit.org/show_bug.cgi?id=49907

Reviewed by Dirk Schulze.

SVG filter primitives can use the output of other filters. The
input and output format of a filter can be a premultiplied or
unmultiplied RGBA array, or an image buffer. All filter
primitive results were converted to image buffers before, which
could be an unecessary (and really costly) operation, if
a filter expects its input in the same format as the output
of the input filter primitive. This overhead is removed by
this patch. All apply() methods are updated according to this
new filter primitive interface.

Filters do not generate their results twice (or more) anymore,
when their apply() called multiple times.

The existing tests cover this feature.

  • manual-tests/svg-filter-animation.svg: Added.
  • platform/graphics/filters/FEBlend.cpp:

(WebCore::FEBlend::apply):

  • platform/graphics/filters/FEColorMatrix.cpp:

(WebCore::FEColorMatrix::apply):

  • platform/graphics/filters/FEComponentTransfer.cpp:

(WebCore::FEComponentTransfer::apply):

  • platform/graphics/filters/FEComposite.cpp:

(WebCore::FEComposite::apply):

  • platform/graphics/filters/FEConvolveMatrix.cpp:

(WebCore::FEConvolveMatrix::apply):

  • platform/graphics/filters/FEDisplacementMap.cpp:

(WebCore::FEDisplacementMap::apply):

  • platform/graphics/filters/FEFlood.cpp:

(WebCore::FEFlood::apply):

  • platform/graphics/filters/FEGaussianBlur.cpp:

(WebCore::FEGaussianBlur::apply):

  • platform/graphics/filters/FELighting.cpp:

(WebCore::FELighting::apply):

  • platform/graphics/filters/FEMerge.cpp:

(WebCore::FEMerge::apply):

  • platform/graphics/filters/FEMerge.h:
  • platform/graphics/filters/FEMorphology.cpp:

(WebCore::FEMorphology::apply):

  • platform/graphics/filters/FEOffset.cpp:

(WebCore::FEOffset::apply):

  • platform/graphics/filters/FETile.cpp:

(WebCore::FETile::apply):

  • platform/graphics/filters/FETurbulence.cpp:

(WebCore::FETurbulence::apply):

  • platform/graphics/filters/FilterEffect.cpp:

(WebCore::FilterEffect::requestedRegionOfInputImageData):
(WebCore::FilterEffect::asImageBuffer):
(WebCore::FilterEffect::asUnmultipliedImage):
(WebCore::FilterEffect::asPremultipliedImage):
(WebCore::FilterEffect::copyImageBytes):
(WebCore::FilterEffect::copyUnmultipliedImage):
(WebCore::FilterEffect::copyPremultipliedImage):
(WebCore::FilterEffect::createImageBufferResult):
(WebCore::FilterEffect::createUnmultipliedImageResult):
(WebCore::FilterEffect::createPremultipliedImageResult):

  • platform/graphics/filters/FilterEffect.h:

(WebCore::FilterEffect::hasResult):

  • platform/graphics/filters/SourceAlpha.cpp:

(WebCore::SourceAlpha::apply):

  • platform/graphics/filters/SourceGraphic.cpp:

(WebCore::SourceGraphic::apply):

  • platform/graphics/filters/SourceGraphic.h:
  • rendering/RenderSVGResourceFilter.cpp:

(WebCore::RenderSVGResourceFilter::postApplyResource):

  • svg/graphics/filters/SVGFEImage.cpp:

(WebCore::FEImage::apply):

Location:
trunk/WebCore
Files:
1 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r73892 r73894  
     12010-12-13  Zoltan Herczeg  <zherczeg@webkit.org>
     2
     3        Reviewed by Dirk Schulze.
     4
     5        Better result passing in filter primitives
     6        https://bugs.webkit.org/show_bug.cgi?id=49907
     7
     8        SVG filter primitives can use the output of other filters. The
     9        input and output format of a filter can be a premultiplied or
     10        unmultiplied RGBA array, or an image buffer. All filter
     11        primitive results were converted to image buffers before, which
     12        could be an unecessary (and really costly) operation, if
     13        a filter expects its input in the same format as the output
     14        of the input filter primitive. This overhead is removed by
     15        this patch. All apply() methods are updated according to this
     16        new filter primitive interface.
     17
     18        Filters do not generate their results twice (or more) anymore,
     19        when their apply() called multiple times.
     20
     21        The existing tests cover this feature.
     22
     23        * manual-tests/svg-filter-animation.svg: Added.
     24        * platform/graphics/filters/FEBlend.cpp:
     25        (WebCore::FEBlend::apply):
     26        * platform/graphics/filters/FEColorMatrix.cpp:
     27        (WebCore::FEColorMatrix::apply):
     28        * platform/graphics/filters/FEComponentTransfer.cpp:
     29        (WebCore::FEComponentTransfer::apply):
     30        * platform/graphics/filters/FEComposite.cpp:
     31        (WebCore::FEComposite::apply):
     32        * platform/graphics/filters/FEConvolveMatrix.cpp:
     33        (WebCore::FEConvolveMatrix::apply):
     34        * platform/graphics/filters/FEDisplacementMap.cpp:
     35        (WebCore::FEDisplacementMap::apply):
     36        * platform/graphics/filters/FEFlood.cpp:
     37        (WebCore::FEFlood::apply):
     38        * platform/graphics/filters/FEGaussianBlur.cpp:
     39        (WebCore::FEGaussianBlur::apply):
     40        * platform/graphics/filters/FELighting.cpp:
     41        (WebCore::FELighting::apply):
     42        * platform/graphics/filters/FEMerge.cpp:
     43        (WebCore::FEMerge::apply):
     44        * platform/graphics/filters/FEMerge.h:
     45        * platform/graphics/filters/FEMorphology.cpp:
     46        (WebCore::FEMorphology::apply):
     47        * platform/graphics/filters/FEOffset.cpp:
     48        (WebCore::FEOffset::apply):
     49        * platform/graphics/filters/FETile.cpp:
     50        (WebCore::FETile::apply):
     51        * platform/graphics/filters/FETurbulence.cpp:
     52        (WebCore::FETurbulence::apply):
     53        * platform/graphics/filters/FilterEffect.cpp:
     54        (WebCore::FilterEffect::requestedRegionOfInputImageData):
     55        (WebCore::FilterEffect::asImageBuffer):
     56        (WebCore::FilterEffect::asUnmultipliedImage):
     57        (WebCore::FilterEffect::asPremultipliedImage):
     58        (WebCore::FilterEffect::copyImageBytes):
     59        (WebCore::FilterEffect::copyUnmultipliedImage):
     60        (WebCore::FilterEffect::copyPremultipliedImage):
     61        (WebCore::FilterEffect::createImageBufferResult):
     62        (WebCore::FilterEffect::createUnmultipliedImageResult):
     63        (WebCore::FilterEffect::createPremultipliedImageResult):
     64        * platform/graphics/filters/FilterEffect.h:
     65        (WebCore::FilterEffect::hasResult):
     66        * platform/graphics/filters/SourceAlpha.cpp:
     67        (WebCore::SourceAlpha::apply):
     68        * platform/graphics/filters/SourceGraphic.cpp:
     69        (WebCore::SourceGraphic::apply):
     70        * platform/graphics/filters/SourceGraphic.h:
     71        * rendering/RenderSVGResourceFilter.cpp:
     72        (WebCore::RenderSVGResourceFilter::postApplyResource):
     73        * svg/graphics/filters/SVGFEImage.cpp:
     74        (WebCore::FEImage::apply):
     75
    1762010-12-13  Csaba Osztrogonác  <ossy@webkit.org>
    277
  • trunk/WebCore/platform/graphics/filters/FEBlend.cpp

    r72474 r73894  
    8989void FEBlend::apply()
    9090{
     91    if (hasResult())
     92        return;
    9193    FilterEffect* in = inputEffect(0);
    9294    FilterEffect* in2 = inputEffect(1);
    9395    in->apply();
    9496    in2->apply();
    95     if (!in->resultImage() || !in2->resultImage())
     97    if (!in->hasResult() || !in2->hasResult())
    9698        return;
    9799
     
    99101        return;
    100102
    101     if (!effectContext())
     103    ImageData* resultImage = createPremultipliedImageResult();
     104    if (!resultImage)
    102105        return;
    103106
    104107    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    105     RefPtr<ImageData> srcImageDataA = in->resultImage()->getPremultipliedImageData(effectADrawingRect);
     108    RefPtr<ImageData> srcImageDataA = in->asPremultipliedImage(effectADrawingRect);
    106109    ByteArray* srcPixelArrayA = srcImageDataA->data()->data();
    107110
    108111    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
    109     RefPtr<ImageData> srcImageDataB = in2->resultImage()->getPremultipliedImageData(effectBDrawingRect);
     112    RefPtr<ImageData> srcImageDataB = in2->asPremultipliedImage(effectBDrawingRect);
    110113    ByteArray* srcPixelArrayB = srcImageDataB->data()->data();
    111114
    112     IntRect imageRect(IntPoint(), resultImage()->size());
    113     RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
    114     ByteArray* dstPixelArray = imageData->data()->data();
     115    ByteArray* dstPixelArray = resultImage->data()->data();
    115116
    116117    // Keep synchronized with BlendModeType
     
    132133        dstPixelArray->set(pixelOffset + 3, alphaR);
    133134    }
    134 
    135     resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
    136135}
    137136
  • trunk/WebCore/platform/graphics/filters/FEColorMatrix.cpp

    r72474 r73894  
    151151void FEColorMatrix::apply()
    152152{
     153    if (hasResult())
     154        return;
    153155    FilterEffect* in = inputEffect(0);
    154156    in->apply();
    155     if (!in->resultImage())
     157    if (!in->hasResult())
    156158        return;
    157159
    158     GraphicsContext* filterContext = effectContext();
    159     if (!filterContext)
     160    ImageBuffer* resultImage = createImageBufferResult();
     161    if (!resultImage)
    160162        return;
    161163
    162     filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
    163 
    164     IntRect imageRect(IntPoint(), resultImage()->size());
    165     RefPtr<ImageData> imageData = resultImage()->getUnmultipliedImageData(imageRect);
     164    resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
     165
     166    IntRect imageRect(IntPoint(), absolutePaintRect().size());
     167    RefPtr<ImageData> imageData = resultImage->getUnmultipliedImageData(imageRect);
    166168    ByteArray* pixelArray = imageData->data()->data();
    167169
     
    184186    }
    185187
    186     resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
     188    resultImage->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
    187189}
    188190
  • trunk/WebCore/platform/graphics/filters/FEComponentTransfer.cpp

    r72474 r73894  
    150150void FEComponentTransfer::apply()
    151151{
     152    if (hasResult())
     153        return;
    152154    FilterEffect* in = inputEffect(0);
    153155    in->apply();
    154     if (!in->resultImage())
    155         return;
    156 
    157     if (!effectContext())
     156    if (!in->hasResult())
     157        return;
     158
     159    ImageData* imageData = createUnmultipliedImageResult();
     160    if (!imageData)
    158161        return;
    159162
     
    169172
    170173    IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    171     RefPtr<ImageData> imageData = in->resultImage()->getUnmultipliedImageData(drawingRect);
     174    in->copyUnmultipliedImage(imageData, drawingRect);
    172175    ByteArray* pixelArray = imageData->data()->data();
    173176
     
    179182        }
    180183    }
    181 
    182     resultImage()->putUnmultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
    183184}
    184185
  • trunk/WebCore/platform/graphics/filters/FEComposite.cpp

    r72474 r73894  
    138138void FEComposite::apply()
    139139{
     140    if (hasResult())
     141        return;
    140142    FilterEffect* in = inputEffect(0);
    141143    FilterEffect* in2 = inputEffect(1);
    142144    in->apply();
    143145    in2->apply();
    144     if (!in->resultImage() || !in2->resultImage())
    145         return;
    146 
    147     GraphicsContext* filterContext = effectContext();
    148     if (!filterContext)
    149         return;
     146    if (!in->hasResult() || !in2->hasResult())
     147        return;
     148
     149    ImageBuffer* resultImage = createImageBufferResult();
     150    if (!resultImage)
     151        return;
     152    GraphicsContext* filterContext = resultImage->context();
    150153
    151154    FloatRect srcRect = FloatRect(0, 0, -1, -1);
    152155    switch (m_type) {
    153156    case FECOMPOSITE_OPERATOR_OVER:
    154         filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
    155         filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
     157        filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
     158        filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
    156159        break;
    157160    case FECOMPOSITE_OPERATOR_IN:
    158161        filterContext->save();
    159         filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->absolutePaintRect()));
    160         filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
     162        filterContext->clipToImageBuffer(in2->asImageBuffer(), drawingRegionOfInputImage(in2->absolutePaintRect()));
     163        filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
    161164        filterContext->restore();
    162165        break;
    163166    case FECOMPOSITE_OPERATOR_OUT:
    164         filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
    165         filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut);
     167        filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
     168        filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut);
    166169        break;
    167170    case FECOMPOSITE_OPERATOR_ATOP:
    168         filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
    169         filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop);
     171        filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
     172        filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop);
    170173        break;
    171174    case FECOMPOSITE_OPERATOR_XOR:
    172         filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
    173         filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR);
     175        filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
     176        filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR);
    174177        break;
    175178    case FECOMPOSITE_OPERATOR_ARITHMETIC: {
    176179        IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    177         RefPtr<ImageData> srcImageData = in->resultImage()->getPremultipliedImageData(effectADrawingRect);
     180        RefPtr<ImageData> srcImageData = in->asImageBuffer()->getPremultipliedImageData(effectADrawingRect);
    178181        ByteArray* srcPixelArrayA = srcImageData->data()->data();
    179182
    180183        IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
    181         RefPtr<ImageData> imageData = in2->resultImage()->getPremultipliedImageData(effectBDrawingRect);
     184        RefPtr<ImageData> imageData = in2->asImageBuffer()->getPremultipliedImageData(effectBDrawingRect);
    182185        ByteArray* srcPixelArrayB = imageData->data()->data();
    183186
    184187        arithmetic(srcPixelArrayA, srcPixelArrayB, m_k1, m_k2, m_k3, m_k4);
    185         resultImage()->putPremultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
     188        resultImage->putPremultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage->size()), IntPoint());
    186189        }
    187190        break;
  • trunk/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp

    r72474 r73894  
    373373void FEConvolveMatrix::apply()
    374374{
     375    if (hasResult())
     376        return;
    375377    FilterEffect* in = inputEffect(0);
    376378    in->apply();
    377     if (!in->resultImage())
     379    if (!in->hasResult())
    378380        return;
    379381
    380     if (!effectContext())
     382    ImageData* resultImage;
     383    if (m_preserveAlpha)
     384        resultImage = createUnmultipliedImageResult();
     385    else
     386        resultImage = createPremultipliedImageResult();
     387    if (!resultImage)
    381388        return;
    382389
    383     IntRect imageRect(IntPoint(), resultImage()->size());
    384390    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    385391
    386392    RefPtr<CanvasPixelArray> srcPixelArray;
    387393    if (m_preserveAlpha)
    388         srcPixelArray = in->resultImage()->getUnmultipliedImageData(effectDrawingRect)->data();
     394        srcPixelArray = in->asUnmultipliedImage(effectDrawingRect)->data();
    389395    else
    390         srcPixelArray = in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data();
    391 
    392     RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
    393 
     396        srcPixelArray = in->asPremultipliedImage(effectDrawingRect)->data();
     397
     398    IntSize paintSize = absolutePaintRect().size();
    394399    PaintingData paintingData;
    395400    paintingData.srcPixelArray = srcPixelArray.get();
    396     paintingData.dstPixelArray = imageData->data();
    397     paintingData.width = imageRect.width();
    398     paintingData.height = imageRect.height();
     401    paintingData.dstPixelArray = resultImage->data();
     402    paintingData.width = paintSize.width();
     403    paintingData.height = paintSize.height();
    399404    paintingData.bias = m_bias * 255;
    400405
    401406    // Drawing fully covered pixels
    402     int clipRight = imageRect.width() - m_kernelSize.width();
    403     int clipBottom = imageRect.height() - m_kernelSize.height();
     407    int clipRight = paintSize.width() - m_kernelSize.width();
     408    int clipBottom = paintSize.height() - m_kernelSize.height();
    404409
    405410    if (clipRight >= 0 && clipBottom >= 0) {
     
    409414        clipBottom += m_targetOffset.y() + 1;
    410415        if (m_targetOffset.y() > 0)
    411             setOuterPixels(paintingData, 0, 0, imageRect.width(), m_targetOffset.y());
    412         if (clipBottom < imageRect.height())
    413             setOuterPixels(paintingData, 0, clipBottom, imageRect.width(), imageRect.height());
     416            setOuterPixels(paintingData, 0, 0, paintSize.width(), m_targetOffset.y());
     417        if (clipBottom < paintSize.height())
     418            setOuterPixels(paintingData, 0, clipBottom, paintSize.width(), paintSize.height());
    414419        if (m_targetOffset.x() > 0)
    415420            setOuterPixels(paintingData, 0, m_targetOffset.y(), m_targetOffset.x(), clipBottom);
    416         if (clipRight < imageRect.width())
    417             setOuterPixels(paintingData, clipRight, m_targetOffset.y(), imageRect.width(), clipBottom);
     421        if (clipRight < paintSize.width())
     422            setOuterPixels(paintingData, clipRight, m_targetOffset.y(), paintSize.width(), clipBottom);
    418423    } else {
    419424        // Rare situation, not optimizied for speed
    420         setOuterPixels(paintingData, 0, 0, imageRect.width(), imageRect.height());
     425        setOuterPixels(paintingData, 0, 0, paintSize.width(), paintSize.height());
    421426    }
    422 
    423     if (m_preserveAlpha)
    424         resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
    425     else
    426         resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
    427427}
    428428
  • trunk/WebCore/platform/graphics/filters/FEDisplacementMap.cpp

    r72474 r73894  
    7979void FEDisplacementMap::apply()
    8080{
     81    if (hasResult())
     82        return;
    8183    FilterEffect* in = inputEffect(0);
    8284    FilterEffect* in2 = inputEffect(1);
    8385    in->apply();
    8486    in2->apply();
    85     if (!in->resultImage() || !in2->resultImage())
     87    if (!in->hasResult() || !in2->hasResult())
    8688        return;
    8789
     
    8991        return;
    9092
    91     if (!effectContext())
     93    ImageData* resultImage = createPremultipliedImageResult();
     94    if (!resultImage)
    9295        return;
    9396
    9497    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    95     RefPtr<ImageData> srcImageDataA = in->resultImage()->getPremultipliedImageData(effectADrawingRect);
    96     ByteArray* srcPixelArrayA = srcImageDataA->data()->data() ;
     98    RefPtr<ImageData> srcImageDataA = in->asPremultipliedImage(effectADrawingRect);
     99    ByteArray* srcPixelArrayA = srcImageDataA->data()->data();
    97100
    98101    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
    99     RefPtr<ImageData> srcImageDataB = in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect);
     102    RefPtr<ImageData> srcImageDataB = in2->asUnmultipliedImage(effectBDrawingRect);
    100103    ByteArray* srcPixelArrayB = srcImageDataB->data()->data();
    101104
    102     IntRect imageRect(IntPoint(), resultImage()->size());
    103     RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
    104     ByteArray* dstPixelArray = imageData->data()->data();
     105    ByteArray* dstPixelArray = resultImage->data()->data();
    105106
    106107    ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
    107108
    108109    Filter* filter = this->filter();
     110    IntSize paintSize = absolutePaintRect().size();
    109111    float scaleX = filter->applyHorizontalScale(m_scale / 255);
    110112    float scaleY = filter->applyVerticalScale(m_scale / 255);
    111113    float scaleAdjustmentX = filter->applyHorizontalScale(0.5f - 0.5f * m_scale);
    112114    float scaleAdjustmentY = filter->applyVerticalScale(0.5f - 0.5f * m_scale);
    113     int stride = imageRect.width() * 4;
    114     for (int y = 0; y < imageRect.height(); ++y) {
     115    int stride = paintSize.width() * 4;
     116    for (int y = 0; y < paintSize.height(); ++y) {
    115117        int line = y * stride;
    116         for (int x = 0; x < imageRect.width(); ++x) {
     118        for (int x = 0; x < paintSize.width(); ++x) {
    117119            int dstIndex = line + x * 4;
    118120            int srcX = x + static_cast<int>(scaleX * srcPixelArrayB->get(dstIndex + m_xChannelSelector - 1) + scaleAdjustmentX);
    119121            int srcY = y + static_cast<int>(scaleY * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustmentY);
    120122            for (unsigned channel = 0; channel < 4; ++channel) {
    121                 if (srcX < 0 || srcX >= imageRect.width() || srcY < 0 || srcY >= imageRect.height())
     123                if (srcX < 0 || srcX >= paintSize.width() || srcY < 0 || srcY >= paintSize.height())
    122124                    dstPixelArray->set(dstIndex + channel, static_cast<unsigned char>(0));
    123125                else {
     
    126128                }
    127129            }
    128 
    129130        }
    130131    }
    131     resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
    132132}
    133133
  • trunk/WebCore/platform/graphics/filters/FEFlood.cpp

    r72474 r73894  
    6565void FEFlood::apply()
    6666{
    67     GraphicsContext* filterContext = effectContext();
    68     if (!filterContext)
     67    if (hasResult())
     68        return;
     69    ImageBuffer* resultImage = createImageBufferResult();
     70    if (!resultImage)
    6971        return;
    7072
    7173    Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
    72     filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, ColorSpaceDeviceRGB);
     74    resultImage->context()->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, ColorSpaceDeviceRGB);
    7375}
    7476
  • trunk/WebCore/platform/graphics/filters/FEGaussianBlur.cpp

    r72474 r73894  
    165165void FEGaussianBlur::apply()
    166166{
     167    if (hasResult())
     168        return;
    167169    FilterEffect* in = inputEffect(0);
    168170    in->apply();
    169     if (!in->resultImage())
    170         return;
    171 
    172     if (!effectContext())
     171    if (!in->hasResult())
     172        return;
     173
     174    ImageData* resultImage = createPremultipliedImageResult();
     175    if (!resultImage)
    173176        return;
    174177
     
    176179
    177180    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    178     RefPtr<ImageData> srcImageData = in->resultImage()->getPremultipliedImageData(effectDrawingRect);
    179     IntRect imageRect(IntPoint(), resultImage()->size());
    180 
    181     if (!m_stdX && !m_stdY) {
    182         resultImage()->putPremultipliedImageData(srcImageData.get(), imageRect, IntPoint());
    183         return;
    184     }
     181    in->copyPremultipliedImage(resultImage, effectDrawingRect);
     182
     183    if (!m_stdX && !m_stdY)
     184        return;
    185185
    186186    unsigned kernelSizeX = 0;
     
    188188    calculateKernelSize(filter(), kernelSizeX, kernelSizeY, m_stdX, m_stdY);
    189189
    190     ByteArray* srcPixelArray = srcImageData->data()->data();
    191     RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height());
     190    IntSize paintSize = absolutePaintRect().size();
     191    ByteArray* srcPixelArray = resultImage->data()->data();
     192    RefPtr<ImageData> tmpImageData = ImageData::create(paintSize.width(), paintSize.height());
    192193    ByteArray* tmpPixelArray = tmpImageData->data()->data();
    193194
    194     int stride = 4 * imageRect.width();
     195    int stride = 4 * paintSize.width();
    195196    int dxLeft = 0;
    196197    int dxRight = 0;
     
    200201        if (kernelSizeX) {
    201202            kernelPosition(i, kernelSizeX, dxLeft, dxRight);
    202             boxBlur(srcPixelArray, tmpPixelArray, kernelSizeX, dxLeft, dxRight, 4, stride, imageRect.width(), imageRect.height(), isAlphaImage());
     203            boxBlur(srcPixelArray, tmpPixelArray, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), isAlphaImage());
    203204        } else {
    204205            ByteArray* auxPixelArray = tmpPixelArray;
     
    209210        if (kernelSizeY) {
    210211            kernelPosition(i, kernelSizeY, dyLeft, dyRight);
    211             boxBlur(tmpPixelArray, srcPixelArray, kernelSizeY, dyLeft, dyRight, stride, 4, imageRect.height(), imageRect.width(), isAlphaImage());
     212            boxBlur(tmpPixelArray, srcPixelArray, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), isAlphaImage());
    212213        } else {
    213214            ByteArray* auxPixelArray = tmpPixelArray;
     
    216217        }
    217218    }
    218 
    219     resultImage()->putPremultipliedImageData(srcImageData.get(), imageRect, IntPoint());
    220219}
    221220
  • trunk/WebCore/platform/graphics/filters/FELighting.cpp

    r72474 r73894  
    332332void FELighting::apply()
    333333{
     334    if (hasResult())
     335        return;
    334336    FilterEffect* in = inputEffect(0);
    335337    in->apply();
    336     if (!in->resultImage())
     338    if (!in->hasResult())
    337339        return;
    338340
    339     if (!effectContext())
     341    ImageData* resultImage = createUnmultipliedImageResult();
     342    if (!resultImage)
    340343        return;
    341344
     
    343346
    344347    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    345     RefPtr<ImageData> srcImageData = in->resultImage()->getUnmultipliedImageData(effectDrawingRect);
    346     ByteArray* srcPixelArray = srcImageData->data()->data();
     348    in->copyUnmultipliedImage(resultImage, effectDrawingRect);
     349    ByteArray* srcPixelArray = resultImage->data()->data();
    347350
    348351    // FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3
     
    352355
    353356    IntSize absolutePaintSize = absolutePaintRect().size();
    354     if (drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height()))
    355         resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), absolutePaintSize), IntPoint());
     357    drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height());
    356358}
    357359
  • trunk/WebCore/platform/graphics/filters/FEMerge.cpp

    r72474 r73894  
    4242void FEMerge::apply()
    4343{
     44    if (hasResult())
     45        return;
    4446    unsigned size = numberOfEffectInputs();
    4547    ASSERT(size > 0);
     
    4749        FilterEffect* in = inputEffect(i);
    4850        in->apply();
    49         if (!in->resultImage())
     51        if (!in->hasResult())
    5052            return;
    5153    }
    5254
    53     GraphicsContext* filterContext = effectContext();
    54     if (!filterContext)
     55    ImageBuffer* resultImage = createImageBufferResult();
     56    if (!resultImage)
    5557        return;
    5658
     59    GraphicsContext* filterContext = resultImage->context();
    5760    for (unsigned i = 0; i < size; ++i) {
    5861        FilterEffect* in = inputEffect(i);
    59         filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
     62        filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
    6063    }
    6164}
  • trunk/WebCore/platform/graphics/filters/FEMerge.h

    r72474 r73894  
    2121
    2222#ifndef FEMerge_h
    23 #define EMerge_h
     23#define FEMerge_h
    2424
    2525#if ENABLE(FILTERS)
  • trunk/WebCore/platform/graphics/filters/FEMorphology.cpp

    r72474 r73894  
    9292void FEMorphology::apply()
    9393{
     94    if (hasResult())
     95        return;
    9496    FilterEffect* in = inputEffect(0);
    9597    in->apply();
    96     if (!in->resultImage())
    97         return;
    98 
    99     if (!effectContext())
     98    if (!in->hasResult())
     99        return;
     100
     101    ImageData* resultImage = createPremultipliedImageResult();
     102    if (!resultImage)
    100103        return;
    101104
     
    108111    int radiusY = static_cast<int>(floorf(filter->applyVerticalScale(m_radiusY)));
    109112
    110     IntRect imageRect(IntPoint(), resultImage()->size());
    111113    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    112     RefPtr<ImageData> srcImageData = in->resultImage()->getPremultipliedImageData(effectDrawingRect);
     114    RefPtr<ImageData> srcImageData = in->asPremultipliedImage(effectDrawingRect);
    113115    ByteArray* srcPixelArray = srcImageData->data()->data();
    114     RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
    115     ByteArray* dstPixelArray = imageData->data()->data();
     116    ByteArray* dstPixelArray = resultImage->data()->data();
    116117
    117118    int effectWidth = effectDrawingRect.width() * 4;
     
    163164        }
    164165    }
    165     resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
    166166}
    167167
  • trunk/WebCore/platform/graphics/filters/FEOffset.cpp

    r72474 r73894  
    7575void FEOffset::apply()
    7676{
     77    if (hasResult())
     78        return;
    7779    FilterEffect* in = inputEffect(0);
    7880    in->apply();
    79     if (!in->resultImage())
     81    if (!in->hasResult())
    8082        return;
    8183
    82     GraphicsContext* filterContext = effectContext();
    83     if (!filterContext)
     84    ImageBuffer* resultImage = createImageBufferResult();
     85    if (!resultImage)
    8486        return;
    8587
     
    8991    Filter* filter = this->filter();
    9092    drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
    91     filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegion);
     93    resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegion);
    9294}
    9395
  • trunk/WebCore/platform/graphics/filters/FETile.cpp

    r72474 r73894  
    4646// FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise.
    4747#if ENABLE(SVG)
     48    if (hasResult())
     49        return;
    4850    FilterEffect* in = inputEffect(0);
    4951    in->apply();
    50     if (!in->resultImage())
     52    if (!in->hasResult())
    5153        return;
    5254
    53     GraphicsContext* filterContext = effectContext();
    54     if (!filterContext)
     55    ImageBuffer* resultImage = createImageBufferResult();
     56    if (!resultImage)
    5557        return;
    5658
     
    7476    GraphicsContext* tileImageContext = tileImage->context();
    7577    tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
    76     tileImageContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, in->absolutePaintRect().location());
     78    tileImageContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, in->absolutePaintRect().location());
    7779
    7880    RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);
     
    8183    patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y());
    8284    pattern->setPatternSpaceTransform(patternTransform);
     85    GraphicsContext* filterContext = resultImage->context();
    8386    filterContext->setFillPattern(pattern);
    8487    filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
  • trunk/WebCore/platform/graphics/filters/FETurbulence.cpp

    r72474 r73894  
    321321void FETurbulence::apply()
    322322{
    323     if (!effectContext())
     323    if (hasResult())
    324324        return;
    325 
    326     IntRect imageRect(IntPoint(), resultImage()->size());
    327     if (!imageRect.size().width() || !imageRect.size().height())
     325    ImageData* resultImage = createUnmultipliedImageResult();
     326    if (!resultImage)
    328327        return;
    329328
    330     RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
    331     ByteArray* pixelArray = imageData->data()->data();
     329    if (absolutePaintRect().isEmpty())
     330        return;
     331
     332    ByteArray* pixelArray = resultImage->data()->data();
    332333    PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size()));
    333334    initPaint(paintingData);
     
    337338    point.setY(filterRegion.y());
    338339    int indexOfPixelChannel = 0;
    339     for (int y = 0; y < imageRect.height(); ++y) {
     340    for (int y = 0; y < absolutePaintRect().height(); ++y) {
    340341        point.setY(point.y() + 1);
    341342        point.setX(filterRegion.x());
    342         for (int x = 0; x < imageRect.width(); ++x) {
     343        for (int x = 0; x < absolutePaintRect().width(); ++x) {
    343344            point.setX(point.x() + 1);
    344345            for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel)
     
    346347        }
    347348    }
    348     resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
    349349}
    350350
  • trunk/WebCore/platform/graphics/filters/FilterEffect.cpp

    r72474 r73894  
    2424#if ENABLE(FILTERS)
    2525#include "FilterEffect.h"
     26#include "ImageData.h"
    2627
    2728namespace WebCore {
     
    5556IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const
    5657{
    57     ASSERT(m_effectBuffer);
     58    ASSERT(hasResult());
    5859    IntPoint location = m_absolutePaintRect.location();
    5960    location.move(-effectRect.x(), -effectRect.y());
    60     return IntRect(location, m_effectBuffer->size());
     61    return IntRect(location, m_absolutePaintRect.size());
    6162}
    6263
     
    7374}
    7475
    75 GraphicsContext* FilterEffect::effectContext()
    76 {
     76ImageBuffer* FilterEffect::asImageBuffer()
     77{
     78    if (!hasResult())
     79        return 0;
     80    if (m_imageBufferResult)
     81        return m_imageBufferResult.get();
     82    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB);
     83    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
     84    if (m_premultipliedImageResult)
     85        m_imageBufferResult->putPremultipliedImageData(m_premultipliedImageResult.get(), destinationRect, IntPoint());
     86    else
     87        m_imageBufferResult->putUnmultipliedImageData(m_unmultipliedImageResult.get(), destinationRect, IntPoint());
     88    return m_imageBufferResult.get();
     89}
     90
     91PassRefPtr<ImageData> FilterEffect::asUnmultipliedImage(const IntRect& rect)
     92{
     93    RefPtr<ImageData> imageData = ImageData::create(rect.width(), rect.height());
     94    copyUnmultipliedImage(imageData.get(), rect);
     95    return imageData.release();
     96}
     97
     98PassRefPtr<ImageData> FilterEffect::asPremultipliedImage(const IntRect& rect)
     99{
     100    RefPtr<ImageData> imageData = ImageData::create(rect.width(), rect.height());
     101    copyPremultipliedImage(imageData.get(), rect);
     102    return imageData.release();
     103}
     104
     105inline void FilterEffect::copyImageBytes(ImageData* source, ImageData* destination, const IntRect& rect)
     106{
     107    // Copy the necessary lines.
     108    ASSERT(IntSize(destination->width(), destination->height()) == rect.size());
     109    if (rect.x() < 0 || rect.y() < 0 || rect.bottom() > m_absolutePaintRect.width() || rect.bottom() > m_absolutePaintRect.height())
     110        memset(destination->data()->data()->data(), 0, destination->data()->length());
     111
     112    int xOrigin = rect.x();
     113    int xDest = 0;
     114    if (xOrigin < 0) {
     115        xDest = -xOrigin;
     116        xOrigin = 0;
     117    }
     118    int xEnd = rect.right();
     119    if (xEnd > m_absolutePaintRect.width())
     120        xEnd = m_absolutePaintRect.width();
     121
     122    int yOrigin = rect.y();
     123    int yDest = 0;
     124    if (yOrigin < 0) {
     125        yDest = -yOrigin;
     126        yOrigin = 0;
     127    }
     128    int yEnd = rect.bottom();
     129    if (yEnd > m_absolutePaintRect.height())
     130        yEnd = m_absolutePaintRect.height();
     131
     132    int size = (xEnd - xOrigin) * 4;
     133    int destinationScanline = rect.width() * 4;
     134    int sourceScanline = m_absolutePaintRect.width() * 4;
     135    unsigned char *destinationPixel = destination->data()->data()->data() + ((yDest * rect.width()) + xDest) * 4;
     136    unsigned char *sourcePixel = source->data()->data()->data() + ((yOrigin * m_absolutePaintRect.width()) + xOrigin) * 4;
     137
     138    while (yOrigin < yEnd) {
     139        memcpy(destinationPixel, sourcePixel, size);
     140        destinationPixel += destinationScanline;
     141        sourcePixel += sourceScanline;
     142        ++yOrigin;
     143    }
     144}
     145
     146void FilterEffect::copyUnmultipliedImage(ImageData* destination, const IntRect& rect)
     147{
     148    ASSERT(hasResult());
     149
     150    if (!m_unmultipliedImageResult) {
     151        // We prefer a conversion from the image buffer.
     152        if (m_imageBufferResult)
     153            m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
     154        else {
     155            m_unmultipliedImageResult = ImageData::create(m_absolutePaintRect.width(), m_absolutePaintRect.height());
     156            unsigned char* sourceComponent = m_premultipliedImageResult->data()->data()->data();
     157            unsigned char* destinationComponent = m_unmultipliedImageResult->data()->data()->data();
     158            unsigned char* end = sourceComponent + (m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
     159            while (sourceComponent < end) {
     160                int alpha = sourceComponent[3];
     161                if (alpha) {
     162                    destinationComponent[0] = static_cast<int>(sourceComponent[0]) * 255 / alpha;
     163                    destinationComponent[1] = static_cast<int>(sourceComponent[1]) * 255 / alpha;
     164                    destinationComponent[2] = static_cast<int>(sourceComponent[2]) * 255 / alpha;
     165                } else {
     166                    destinationComponent[0] = 0;
     167                    destinationComponent[1] = 0;
     168                    destinationComponent[2] = 0;
     169                }
     170                destinationComponent[3] = alpha;
     171                sourceComponent += 4;
     172                destinationComponent += 4;
     173            }
     174        }
     175    }
     176    copyImageBytes(m_unmultipliedImageResult.get(), destination, rect);
     177}
     178
     179void FilterEffect::copyPremultipliedImage(ImageData* destination, const IntRect& rect)
     180{
     181    ASSERT(hasResult());
     182
     183    if (!m_premultipliedImageResult) {
     184        // We prefer a conversion from the image buffer.
     185        if (m_imageBufferResult)
     186            m_premultipliedImageResult = m_imageBufferResult->getPremultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
     187        else {
     188            m_premultipliedImageResult = ImageData::create(m_absolutePaintRect.width(), m_absolutePaintRect.height());
     189            unsigned char* sourceComponent = m_unmultipliedImageResult->data()->data()->data();
     190            unsigned char* destinationComponent = m_premultipliedImageResult->data()->data()->data();
     191            unsigned char* end = sourceComponent + (m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
     192            while (sourceComponent < end) {
     193                int alpha = sourceComponent[3];
     194                destinationComponent[0] = static_cast<int>(sourceComponent[0]) * alpha / 255;
     195                destinationComponent[1] = static_cast<int>(sourceComponent[1]) * alpha / 255;
     196                destinationComponent[2] = static_cast<int>(sourceComponent[2]) * alpha / 255;
     197                destinationComponent[3] = alpha;
     198                sourceComponent += 4;
     199                destinationComponent += 4;
     200            }
     201        }
     202    }
     203    copyImageBytes(m_premultipliedImageResult.get(), destination, rect);
     204}
     205
     206ImageBuffer* FilterEffect::createImageBufferResult()
     207{
     208    // Only one result type is allowed.
     209    ASSERT(!hasResult());
    77210    determineAbsolutePaintRect();
    78211    if (m_absolutePaintRect.isEmpty())
    79212        return 0;
    80     m_effectBuffer = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB);
    81     if (!m_effectBuffer)
    82         return 0;
    83     return m_effectBuffer->context();
     213    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB);
     214    if (!m_imageBufferResult)
     215        return 0;
     216    ASSERT(m_imageBufferResult->context());
     217    return m_imageBufferResult.get();
     218}
     219
     220ImageData* FilterEffect::createUnmultipliedImageResult()
     221{
     222    // Only one result type is allowed.
     223    ASSERT(!hasResult());
     224    determineAbsolutePaintRect();
     225    if (m_absolutePaintRect.isEmpty())
     226        return 0;
     227    m_unmultipliedImageResult = ImageData::create(m_absolutePaintRect.width(), m_absolutePaintRect.height());
     228    return m_unmultipliedImageResult.get();
     229}
     230
     231ImageData* FilterEffect::createPremultipliedImageResult()
     232{
     233    // Only one result type is allowed.
     234    ASSERT(!hasResult());
     235    determineAbsolutePaintRect();
     236    if (m_absolutePaintRect.isEmpty())
     237        return 0;
     238    m_premultipliedImageResult = ImageData::create(m_absolutePaintRect.width(), m_absolutePaintRect.height());
     239    return m_premultipliedImageResult.get();
    84240}
    85241
  • trunk/WebCore/platform/graphics/filters/FilterEffect.h

    r72474 r73894  
    5151    virtual ~FilterEffect();
    5252
    53     // The result is bounded to the size of the filter primitive to save resources.
    54     ImageBuffer* resultImage() const { return m_effectBuffer.get(); }
    55     void setEffectBuffer(PassOwnPtr<ImageBuffer> effectBuffer) { m_effectBuffer = effectBuffer; }
    56 
    57     // Creates the ImageBuffer for the current filter primitive result in the size of the
    58     // repaintRect. Gives back the GraphicsContext of the own ImageBuffer.
    59     GraphicsContext* effectContext();
     53    bool hasResult() const { return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult; }
     54    ImageBuffer* asImageBuffer();
     55    PassRefPtr<ImageData> asUnmultipliedImage(const IntRect&);
     56    PassRefPtr<ImageData> asPremultipliedImage(const IntRect&);
     57    void copyUnmultipliedImage(ImageData* destination, const IntRect&);
     58    void copyPremultipliedImage(ImageData* destination, const IntRect&);
    6059
    6160    FilterEffectVector& inputEffects() { return m_inputEffects; }
     
    111110    FilterEffect(Filter*);
    112111
     112    ImageBuffer* createImageBufferResult();
     113    ImageData* createUnmultipliedImageResult();
     114    ImageData* createPremultipliedImageResult();
     115
    113116private:
    114     OwnPtr<ImageBuffer> m_effectBuffer;
     117    OwnPtr<ImageBuffer> m_imageBufferResult;
     118    RefPtr<ImageData> m_unmultipliedImageResult;
     119    RefPtr<ImageData> m_premultipliedImageResult;
    115120    FilterEffectVector m_inputEffects;
    116121
     
    125130
    126131private:
     132    inline void copyImageBytes(ImageData* source, ImageData* destination, const IntRect&);
     133
    127134    // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive.
    128135    // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
  • trunk/WebCore/platform/graphics/filters/SourceAlpha.cpp

    r72474 r73894  
    5353void SourceAlpha::apply()
    5454{
    55     GraphicsContext* filterContext = effectContext();
     55    if (hasResult())
     56        return;
     57    ImageBuffer* resultImage = createImageBufferResult();
    5658    Filter* filter = this->filter();
    57     if (!filterContext || !filter->sourceImage())
     59    if (!resultImage || !filter->sourceImage())
    5860        return;
    5961
     
    6163
    6264    FloatRect imageRect(FloatPoint(), absolutePaintRect().size());
     65    GraphicsContext* filterContext = resultImage->context();
    6366    filterContext->save();
    6467    filterContext->clipToImageBuffer(filter->sourceImage(), imageRect);
  • trunk/WebCore/platform/graphics/filters/SourceGraphic.cpp

    r72474 r73894  
    5252void SourceGraphic::apply()
    5353{
    54     GraphicsContext* filterContext = effectContext();
     54    if (hasResult())
     55        return;
     56    ImageBuffer* resultImage = createImageBufferResult();
    5557    Filter* filter = this->filter();
    56     if (!filterContext || !filter->sourceImage())
     58    if (!resultImage || !filter->sourceImage())
    5759        return;
    5860
    59     filterContext->drawImageBuffer(filter->sourceImage(), ColorSpaceDeviceRGB, IntPoint());
     61    resultImage->context()->drawImageBuffer(filter->sourceImage(), ColorSpaceDeviceRGB, IntPoint());
    6062}
    6163
  • trunk/WebCore/platform/graphics/filters/SourceGraphic.h

    r72474 r73894  
    2020
    2121#ifndef SourceGraphic_h
    22 #define SourceGrahpic_h
     22#define SourceGraphic_h
    2323
    2424#if ENABLE(FILTERS)
  • trunk/WebCore/rendering/RenderSVGResourceFilter.cpp

    r73258 r73894  
    294294            lastEffect->apply();
    295295#if !PLATFORM(CG)
    296             ImageBuffer* resultImage = lastEffect->resultImage();
     296            ImageBuffer* resultImage = lastEffect->asImageBuffer();
    297297            if (resultImage)
    298298                resultImage->transformColorSpace(ColorSpaceLinearRGB, ColorSpaceDeviceRGB);
     
    301301        }
    302302
    303         ImageBuffer* resultImage = lastEffect->resultImage();
     303        ImageBuffer* resultImage = lastEffect->asImageBuffer();
    304304        if (resultImage) {
    305305            context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse());
  • trunk/WebCore/svg/graphics/filters/SVGFEImage.cpp

    r72474 r73894  
    6060        return;
    6161
    62     GraphicsContext* filterContext = effectContext();
    63     if (!filterContext)
     62    ImageBuffer* resultImage = createImageBufferResult();
     63    if (!resultImage)
    6464        return;
    6565
     
    7171    destRect.move(-paintLocation.x(), -paintLocation.y());
    7272
    73     filterContext->drawImage(m_image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
     73    resultImage->context()->drawImage(m_image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
    7474}
    7575
Note: See TracChangeset for help on using the changeset viewer.