[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Thu Apr 8 00:43:40 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit c95eeb46cb1d42220748b301457b72f48f8289b2
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sat Dec 19 21:58:51 2009 +0000

    2009-12-19  Dirk Schulze  <krit at webkit.org>
    
            Reviewed by Nikolas Zimmermann.
    
            Speed-up SVG Masking
            https://bugs.webkit.org/show_bug.cgi?id=32738
    
            This patch makes SVG Masking faster. At the moment we create a new ImageBuffer
            and copy the complete pixel array. That is rather inefficient. This patch
            uses the mask image directly.
            It also bounds the direct pixel manipultation to the viewable area to minimize
            the calculation of the mask.
    
            No change in functionality. So no new test.
    
            * svg/SVGMaskElement.cpp:
            (WebCore::SVGMaskElement::drawMaskerContent):
            * svg/SVGMaskElement.h:
            * svg/graphics/SVGResourceMasker.cpp:
            (WebCore::SVGResourceMasker::applyMask):
            * svg/graphics/SVGResourceMasker.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52395 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 9f5a14f..aa3cd31 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -2,6 +2,28 @@
 
         Reviewed by Nikolas Zimmermann.
 
+        Speed-up SVG Masking
+        https://bugs.webkit.org/show_bug.cgi?id=32738
+
+        This patch makes SVG Masking faster. At the moment we create a new ImageBuffer
+        and copy the complete pixel array. That is rather inefficient. This patch
+        uses the mask image directly.
+        It also bounds the direct pixel manipultation to the viewable area to minimize
+        the calculation of the mask.
+
+        No change in functionality. So no new test.
+
+        * svg/SVGMaskElement.cpp:
+        (WebCore::SVGMaskElement::drawMaskerContent):
+        * svg/SVGMaskElement.h:
+        * svg/graphics/SVGResourceMasker.cpp:
+        (WebCore::SVGResourceMasker::applyMask):
+        * svg/graphics/SVGResourceMasker.h:
+
+2009-12-19  Dirk Schulze  <krit at webkit.org>
+
+        Reviewed by Nikolas Zimmermann.
+
         Add tests to check filter, mask, clip, opacity and marker ordering
         https://bugs.webkit.org/show_bug.cgi?id=14010
 
diff --git a/WebCore/svg/SVGMaskElement.cpp b/WebCore/svg/SVGMaskElement.cpp
index e131d34..5d68ab1 100644
--- a/WebCore/svg/SVGMaskElement.cpp
+++ b/WebCore/svg/SVGMaskElement.cpp
@@ -126,7 +126,7 @@ void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, N
     m_masker->invalidate();
 }
 
-PassOwnPtr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targetRect, FloatRect& maskDestRect) const
+PassOwnPtr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targetRect, FloatRect& maskDestRect, IntRect& paintRect) const
 {    
     // Determine specified mask size
     if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
@@ -169,14 +169,15 @@ PassOwnPtr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targe
     GraphicsContext* maskImageContext = maskImage->context();
     ASSERT(maskImageContext);
 
-    maskImageContext->save();
-    maskImageContext->translate(-maskContextLocation.x(), -maskContextLocation.y());
+    TransformationMatrix contextTransform;
+    contextTransform.translate(-maskContextLocation.x(), -maskContextLocation.y());
+    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
+        contextTransform.scaleNonUniform(targetRect.width(), targetRect.height());
 
-    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-        maskImageContext->save();
-        maskImageContext->scale(FloatSize(targetRect.width(), targetRect.height()));
-    }
+    maskImageContext->save();
+    maskImageContext->concatCTM(contextTransform);
 
+    FloatRect repaintRect;
     // Render subtree into ImageBuffer
     for (Node* n = firstChild(); n; n = n->nextSibling()) {
         SVGElement* elem = 0;
@@ -191,10 +192,16 @@ PassOwnPtr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targe
             continue;
 
         renderSubtreeToImage(maskImage.get(), item);
+        repaintRect.unite(item->repaintRectInLocalCoordinates());
     }
 
-    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
-        maskImageContext->restore();
+    if (contextTransform.isInvertible()) {
+        contextTransform.inverse();
+        repaintRect = contextTransform.mapRect(repaintRect);
+        repaintRect.intersect(FloatRect(FloatPoint(), maskDestRect.size()));
+        paintRect = enclosingIntRect(repaintRect);
+    } else
+        paintRect = enclosingIntRect(FloatRect(FloatPoint(), maskDestRect.size()));
 
     maskImageContext->restore();
     return maskImage.release();
diff --git a/WebCore/svg/SVGMaskElement.h b/WebCore/svg/SVGMaskElement.h
index 362c730..c64649b 100644
--- a/WebCore/svg/SVGMaskElement.h
+++ b/WebCore/svg/SVGMaskElement.h
@@ -50,7 +50,7 @@ namespace WebCore {
         virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
         virtual SVGResource* canvasResource();
 
-        PassOwnPtr<ImageBuffer> drawMaskerContent(const FloatRect& targetRect, FloatRect& maskRect) const;
+        PassOwnPtr<ImageBuffer> drawMaskerContent(const FloatRect& targetRect, FloatRect& maskRect, IntRect& paintRect) const;
 
     private:
         ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::maskUnitsAttrString, int, MaskUnits, maskUnits)
diff --git a/WebCore/svg/graphics/SVGResourceMasker.cpp b/WebCore/svg/graphics/SVGResourceMasker.cpp
index 97467c1..097efa2 100644
--- a/WebCore/svg/graphics/SVGResourceMasker.cpp
+++ b/WebCore/svg/graphics/SVGResourceMasker.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann at kde.org>
+ *               2009 Dirk Schulze <krit at webkit.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,8 +39,6 @@
 #include "SVGRenderStyle.h"
 #include "TextStream.h"
 
-#include <wtf/ByteArray.h>
-
 using namespace std;
 
 namespace WebCore {
@@ -63,39 +62,28 @@ void SVGResourceMasker::invalidate()
 void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& boundingBox)
 {
     if (!m_mask)
-        m_mask = m_ownerElement->drawMaskerContent(boundingBox, m_maskRect);
+        m_mask = m_ownerElement->drawMaskerContent(boundingBox, m_maskRect, m_paintRect);
 
     if (!m_mask)
         return;
 
-    IntSize imageSize(m_mask->size());
-    IntRect intImageRect(0, 0, imageSize.width(), imageSize.height());
-
-    // Create new ImageBuffer to apply luminance
-    OwnPtr<ImageBuffer> luminancedImage = ImageBuffer::create(imageSize);
-    if (!luminancedImage)
-        return;
-
-    PassRefPtr<CanvasPixelArray> srcPixelArray(m_mask->getUnmultipliedImageData(intImageRect)->data());
-    PassRefPtr<ImageData> destImageData(luminancedImage->getUnmultipliedImageData(intImageRect));
+    RefPtr<ImageData> imageData(m_mask->getUnmultipliedImageData(m_paintRect));
+    CanvasPixelArray* srcPixelArray(imageData->data());
 
-    for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset++) {
-        unsigned pixelByteOffset = pixelOffset * 4;
-
-        unsigned char r = 0, g = 0, b = 0, a = 0;
-        srcPixelArray->get(pixelByteOffset, r);
-        srcPixelArray->get(pixelByteOffset + 1, g);
-        srcPixelArray->get(pixelByteOffset + 2, b);
-        srcPixelArray->get(pixelByteOffset + 3, a);
+    for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) {
+        unsigned char a = srcPixelArray->get(pixelOffset + 3);
+        if (!a)
+            continue;
+        unsigned char r = srcPixelArray->get(pixelOffset);
+        unsigned char g = srcPixelArray->get(pixelOffset + 1);
+        unsigned char b = srcPixelArray->get(pixelOffset + 2);
 
         double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
-
-        destImageData->data()->set(pixelByteOffset + 3, luma);
+        srcPixelArray->set(pixelOffset + 3, luma);
     }
 
-    luminancedImage->putUnmultipliedImageData(destImageData.get(), intImageRect, IntPoint(0, 0));
-
-    context->clipToImageBuffer(m_maskRect, luminancedImage.get());
+    m_mask->putUnmultipliedImageData(imageData.get(), IntRect(IntPoint(), m_paintRect.size()), m_paintRect.location());
+    context->clipToImageBuffer(m_maskRect, m_mask.get());
 }
 
 TextStream& SVGResourceMasker::externalRepresentation(TextStream& ts) const
diff --git a/WebCore/svg/graphics/SVGResourceMasker.h b/WebCore/svg/graphics/SVGResourceMasker.h
index f945f56..b925511 100644
--- a/WebCore/svg/graphics/SVGResourceMasker.h
+++ b/WebCore/svg/graphics/SVGResourceMasker.h
@@ -62,6 +62,7 @@ namespace WebCore {
         
         OwnPtr<ImageBuffer> m_mask;
         FloatRect m_maskRect;
+        IntRect m_paintRect;
     };
 
     SVGResourceMasker* getMaskerById(Document*, const AtomicString&);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list