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

krit at webkit.org krit at webkit.org
Thu Apr 8 00:44:44 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 38625db3d1cca6fb92f996d4514c4e39d4fe1d45
Author: krit at webkit.org <krit at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Dec 21 20:00:55 2009 +0000

    2009-12-21  Dirk Schulze  <krit at webkit.org>
    
            Reviewed by Darin Adler and Nikolas Zimmermann.
    
            Speed-up SVG Masking
            https://bugs.webkit.org/show_bug.cgi?id=32738
    
            This patch makes SVG Masking faster. The luminance calculaton of the ImageBuffer,
            that is created by pixel manipulation, got optimized. The ImageBuffer and it's
            luminance is created once now, not on every call of applyMask.
            The size of the intermediate ImageBuffer depends on the visible area now and is
            clipped by the mask rect.
    
            The patch doesn't change functionality so no new tests needed.
            The new ImageBuffer handling in Mask causes two updates of test results. The pixel
            tests and LayoutTests pass, but the checksum doesn't match.
    
            * svg/SVGMaskElement.cpp:
            (WebCore::SVGMaskElement::drawMaskerContent):
            * svg/graphics/SVGResourceMasker.cpp:
            (WebCore::SVGResourceMasker::applyMask):
    
    2009-12-21  Dirk Schulze  <krit at webkit.org>
    
            Reviewed by Darin Adler and Nikolas Zimmermann.
    
            Speed-up SVG Masking
            https://bugs.webkit.org/show_bug.cgi?id=32738
    
            Update pixel test results for two SVG masking operations. They don't fail
            and there is no noticable difference between the old and new results. But
            Masking uses smaller ImageBuffers now and that changed the checksum.
    
            * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum:
            * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png:
            * platform/mac/svg/batik/masking/maskRegions-expected.checksum:
            * platform/mac/svg/batik/masking/maskRegions-expected.png:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52449 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 43f5dda..d170e9e 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2009-12-21  Dirk Schulze  <krit at webkit.org>
+
+        Reviewed by Darin Adler and Nikolas Zimmermann.
+
+        Speed-up SVG Masking
+        https://bugs.webkit.org/show_bug.cgi?id=32738
+
+        Update pixel test results for two SVG masking operations. They don't fail
+        and there is no noticable difference between the old and new results. But
+        Masking uses smaller ImageBuffers now and that changed the checksum.
+
+        * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum:
+        * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png:
+        * platform/mac/svg/batik/masking/maskRegions-expected.checksum:
+        * platform/mac/svg/batik/masking/maskRegions-expected.png:
+
 2009-12-21  Andreas Kling  <andreas.kling at nokia.com>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum b/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum
index ee125f1..4ad0dd6 100644
--- a/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum
+++ b/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum
@@ -1 +1 @@
-a7bb2e35279390f23a9de7171762eb20
\ No newline at end of file
+b0f6900bcc82d46b4ca04966064a9cfc
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png b/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png
index 92bdd7e..b531b17 100644
Binary files a/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png and b/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.checksum b/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.checksum
index a612e0d..2136b25 100644
--- a/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.checksum
+++ b/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.checksum
@@ -1 +1 @@
-707af5beecfe3ba1edf84fc86b3d3380
\ No newline at end of file
+367e3619b5c94ebd2bc6d7a884c5fde1
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png b/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png
index 82c53a3..fb7d13c 100644
Binary files a/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png and b/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png differ
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index a114362..0875543 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,25 @@
+2009-12-21  Dirk Schulze  <krit at webkit.org>
+
+        Reviewed by Darin Adler and Nikolas Zimmermann.
+
+        Speed-up SVG Masking
+        https://bugs.webkit.org/show_bug.cgi?id=32738
+
+        This patch makes SVG Masking faster. The luminance calculaton of the ImageBuffer,
+        that is created by pixel manipulation, got optimized. The ImageBuffer and it's
+        luminance is created once now, not on every call of applyMask.
+        The size of the intermediate ImageBuffer depends on the visible area now and is
+        clipped by the mask rect.
+        
+        The patch doesn't change functionality so no new tests needed.
+        The new ImageBuffer handling in Mask causes two updates of test results. The pixel
+        tests and LayoutTests pass, but the checksum doesn't match.
+
+        * svg/SVGMaskElement.cpp:
+        (WebCore::SVGMaskElement::drawMaskerContent):
+        * svg/graphics/SVGResourceMasker.cpp:
+        (WebCore::SVGResourceMasker::applyMask):
+
 2009-12-21  Andreas Kling  <andreas.kling at nokia.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/svg/SVGMaskElement.cpp b/WebCore/svg/SVGMaskElement.cpp
index e131d34..327bd74 100644
--- a/WebCore/svg/SVGMaskElement.cpp
+++ b/WebCore/svg/SVGMaskElement.cpp
@@ -25,9 +25,12 @@
 #if ENABLE(SVG)
 #include "SVGMaskElement.h"
 
+#include "CanvasPixelArray.h"
 #include "CSSStyleSelector.h"
 #include "GraphicsContext.h"
+#include "Image.h"
 #include "ImageBuffer.h"
+#include "ImageData.h"
 #include "MappedAttribute.h"
 #include "RenderSVGContainer.h"
 #include "SVGLength.h"
@@ -37,6 +40,7 @@
 #include <math.h>
 #include <wtf/MathExtras.h>
 #include <wtf/OwnPtr.h>
+#include <wtf/Vector.h>
 
 using namespace std;
 
@@ -126,77 +130,94 @@ 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& objectBoundingBox, FloatRect& maskDestRect) const
 {    
     // Determine specified mask size
     if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
-        maskDestRect = FloatRect(x().valueAsPercentage() * targetRect.width(),
-                                 y().valueAsPercentage() * targetRect.height(),
-                                 width().valueAsPercentage() * targetRect.width(),
-                                 height().valueAsPercentage() * targetRect.height());
+        maskDestRect = FloatRect(x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(),
+                                 y().valueAsPercentage() * objectBoundingBox.height() + objectBoundingBox.y(),
+                                 width().valueAsPercentage() * objectBoundingBox.width(),
+                                 height().valueAsPercentage() * objectBoundingBox.height());
     else
         maskDestRect = FloatRect(x().value(this),
                                  y().value(this),
                                  width().value(this),
                                  height().value(this));
 
-    IntSize imageSize(lroundf(maskDestRect.width()), lroundf(maskDestRect.height()));
-    clampImageBufferSizeToViewport(document()->view(), imageSize);
-
-    if (imageSize.width() < static_cast<int>(maskDestRect.width()))
-        maskDestRect.setWidth(imageSize.width());
+    // Calculate the smallest rect for the mask ImageBuffer.
+    FloatRect repaintRect;
+    Vector<RenderObject*> rendererList;
+    for (Node* node = firstChild(); node; node = node->nextSibling()) {
+        if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
+            continue;
+        // FIXME: repaintRectInLocalCoordinates() is not correctly implemented.
+        // The current implementation gives back the union rect of the
+        // the stroke and marker from every child. This is what we need here.
+        // We create the union of all direct childs to get the common drawing area.
+        // See also bug: https://bugs.webkit.org/show_bug.cgi?id=32815
+        rendererList.append(node->renderer());
+        repaintRect.unite(node->renderer()->repaintRectInLocalCoordinates());
+    }
 
-    if (imageSize.height() < static_cast<int>(maskDestRect.height()))
-        maskDestRect.setHeight(imageSize.height());
+    TransformationMatrix contextTransform;
+    // We need to scale repaintRect for objectBoundingBox to get the drawing area.
+    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+        contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+        FloatPoint contextAdjustment = repaintRect.location();
+        repaintRect = contextTransform.mapRect(repaintRect);
+        repaintRect.move(objectBoundingBox.x(), objectBoundingBox.y());
+        contextTransform.translate(-contextAdjustment.x(), -contextAdjustment.y());
+    }
+    repaintRect.intersect(maskDestRect);
+    maskDestRect = repaintRect;
+    IntRect maskImageRect = enclosingIntRect(maskDestRect);
+    maskImageRect.setLocation(IntPoint());
 
     // FIXME: This changes color space to linearRGB, the default color space
     // for masking operations in SVG. We need a switch for the other color-space
     // attribute values sRGB, inherit and auto.
-    OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(imageSize, LinearRGB);
+    OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskImageRect.size(), LinearRGB);
     if (!maskImage)
         return 0;
 
-    FloatPoint maskContextLocation = maskDestRect.location();
-    if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-        maskDestRect.move(targetRect.x(), targetRect.y());
-        if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
-            maskContextLocation.move(targetRect.x(), targetRect.y());
-    } else {
-        if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
-            maskContextLocation.move(-targetRect.x(), -targetRect.y());
-    }
-
     GraphicsContext* maskImageContext = maskImage->context();
     ASSERT(maskImageContext);
 
     maskImageContext->save();
-    maskImageContext->translate(-maskContextLocation.x(), -maskContextLocation.y());
 
-    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-        maskImageContext->save();
-        maskImageContext->scale(FloatSize(targetRect.width(), targetRect.height()));
-    }
+    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
+        maskImageContext->translate(-maskDestRect.x(), -maskDestRect.y());
+    maskImageContext->concatCTM(contextTransform);
 
-    // Render subtree into ImageBuffer
-    for (Node* n = firstChild(); n; n = n->nextSibling()) {
-        SVGElement* elem = 0;
-        if (n->isSVGElement())
-            elem = static_cast<SVGElement*>(n);
-        if (!elem || !elem->isStyled())
-            continue;
+    // draw the content into the ImageBuffer
+    Vector<RenderObject*>::iterator end = rendererList.end();
+    for (Vector<RenderObject*>::iterator it = rendererList.begin(); it != end; it++)
+        renderSubtreeToImage(maskImage.get(), *it);
+
+
+    maskImageContext->restore();
+
+    if (!maskImageRect.width() || !maskImageRect.height())
+        return maskImage.release();
 
-        SVGStyledElement* e = static_cast<SVGStyledElement*>(elem);
-        RenderObject* item = e->renderer();
-        if (!item)
+    // create the luminance mask
+    RefPtr<ImageData> imageData(maskImage->getUnmultipliedImageData(maskImageRect));
+    CanvasPixelArray* srcPixelArray(imageData->data());
+
+    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);
 
-        renderSubtreeToImage(maskImage.get(), item);
+        double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
+        srcPixelArray->set(pixelOffset + 3, luma);
     }
 
-    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
-        maskImageContext->restore();
+    maskImage->putUnmultipliedImageData(imageData.get(), maskImageRect, IntPoint());
 
-    maskImageContext->restore();
     return maskImage.release();
 }
  
diff --git a/WebCore/svg/graphics/SVGResourceMasker.cpp b/WebCore/svg/graphics/SVGResourceMasker.cpp
index 97467c1..5c2dad8 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 {
@@ -68,34 +67,7 @@ void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& bou
     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));
-
-    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);
-
-        double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
-
-        destImageData->data()->set(pixelByteOffset + 3, luma);
-    }
-
-    luminancedImage->putUnmultipliedImageData(destImageData.get(), intImageRect, IntPoint(0, 0));
-
-    context->clipToImageBuffer(m_maskRect, luminancedImage.get());
+    context->clipToImageBuffer(m_maskRect, m_mask.get());
 }
 
 TextStream& SVGResourceMasker::externalRepresentation(TextStream& ts) const

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list