[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

ariya at webkit.org ariya at webkit.org
Wed Dec 22 13:26:31 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 08771259a737276196152f49337324fbe09a514a
Author: ariya at webkit.org <ariya at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Sep 15 16:44:31 2010 +0000

    2010-09-15  Ariya Hidayat  <ariya at sencha.com>
    
            [Qt] Improve the speed of blur shadow
            https://bugs.webkit.org/show_bug.cgi?id=44222
    
            Update pixel test result.
    
            * platform/qt/fast/box-shadow/basic-shadows-expected.checksum:
            * platform/qt/fast/box-shadow/basic-shadows-expected.png:
    2010-09-15  Ariya Hidayat  <ariya at sencha.com>
    
            [Qt] Improve the speed of blur shadow
            https://bugs.webkit.org/show_bug.cgi?id=44222
    
            Rewrite the shadow blur function with loop unrolls and sliding step
            unification for both horizontal and vertical directions.
            This gives significant performance improvement on most cases.
    
            * platform/graphics/qt/ContextShadow.cpp:
            (WebCore::shadowBlur):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67559 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 8fc5a4c..e8fcb27 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-09-15  Ariya Hidayat  <ariya at sencha.com>
+
+        [Qt] Improve the speed of blur shadow
+        https://bugs.webkit.org/show_bug.cgi?id=44222
+
+        Update pixel test result.
+
+        * platform/qt/fast/box-shadow/basic-shadows-expected.checksum:
+        * platform/qt/fast/box-shadow/basic-shadows-expected.png:
+
 2010-09-15  Steve Block  <steveblock at google.com>
 
         Reviewed by Jeremy Orlow.
diff --git a/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.checksum b/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.checksum
index 08ccf98..508d9d8 100644
--- a/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.checksum
+++ b/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.checksum
@@ -1 +1 @@
-5aa5b68d30be16c04417274964e31549
\ No newline at end of file
+bf0645db3ac83b5464a8b108b42a66c9
\ No newline at end of file
diff --git a/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.png b/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.png
index bc1f431..ac28589 100644
Binary files a/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.png and b/LayoutTests/platform/qt/fast/box-shadow/basic-shadows-expected.png differ
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e598277..375ad1c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,15 @@
+2010-09-15  Ariya Hidayat  <ariya at sencha.com>
+
+        [Qt] Improve the speed of blur shadow
+        https://bugs.webkit.org/show_bug.cgi?id=44222
+
+        Rewrite the shadow blur function with loop unrolls and sliding step
+        unification for both horizontal and vertical directions.
+        This gives significant performance improvement on most cases.
+
+        * platform/graphics/qt/ContextShadow.cpp:
+        (WebCore::shadowBlur):
+
 2010-09-14  Pavel Feldman  <pfeldman at chromium.org>
 
         Reviewed by Yury Semikhatsky.
diff --git a/WebCore/platform/graphics/qt/ContextShadow.cpp b/WebCore/platform/graphics/qt/ContextShadow.cpp
index 829ca82..4609923 100644
--- a/WebCore/platform/graphics/qt/ContextShadow.cpp
+++ b/WebCore/platform/graphics/qt/ContextShadow.cpp
@@ -139,134 +139,80 @@ void ContextShadow::clear()
     offset = QPointF(0, 0);
 }
 
-// Instead of integer division, we use 18.14 for fixed-point division.
-static const int BlurSumShift = 14;
+// Instead of integer division, we use 17.15 for fixed-point division.
+static const int BlurSumShift = 15;
 
-// Note: image must be RGB32 format
-static void blurHorizontal(QImage& image, int radius, bool swap = false)
-{
-    Q_ASSERT(image.format() == QImage::Format_ARGB32_Premultiplied);
+// Check http://www.w3.org/TR/SVG/filters.html#feGaussianBlur.
+// As noted in the SVG filter specification, running box blur 3x
+// approximates a real gaussian blur nicely.
 
+void shadowBlur(QImage& image, int radius, const QColor& shadowColor)
+{
     // See comments in http://webkit.org/b/40793, it seems sensible
-    // to follow Skia's limit of 128 pixels of blur radius
-    radius = qMin(128, radius);
-
-    int imgWidth = image.width();
-    int imgHeight = image.height();
+    // to follow Skia's limit of 128 pixels for the blur radius.
+    if (radius > 128)
+        radius = 128;
 
-    // Check http://www.w3.org/TR/SVG/filters.html#feGaussianBlur
-    // for the approaches when the box-blur radius is even vs odd.
+    int channels[4] = { 3, 0, 1, 3 };
     int dmax = radius >> 1;
-    int dmin = qMax(0, dmax - 1 + (radius & 1));
-
-    for (int y = 0; y < imgHeight; ++y) {
-
-        unsigned char* pixels = image.scanLine(y);
-
-        int left;
-        int right;
-        int pixelCount;
-        int prev;
-        int next;
-        int firstAlpha;
-        int lastAlpha;
-        int totalAlpha;
-        unsigned char* target;
-        unsigned char* prevPtr;
-        unsigned char* nextPtr;
-
-        int invCount;
-
-        static const int alphaChannel = 3;
-        static const int blueChannel = 0;
-        static const int greenChannel = 1;
-
-        // For each step, we use sliding window algorithm. This is much more
-        // efficient than computing the sum of each pixels covered by the box
-        // kernel size for each x.
-
-        // As noted in the SVG filter specification, running box blur 3x
-        // approximates a real gaussian blur nicely.
-
-        // Step 1: blur alpha channel and store the result in the blue channel.
-        left = swap ? dmax : dmin;
-        right = swap ? dmin : dmax;
-        pixelCount = left + 1 + right;
-        invCount = (1 << BlurSumShift) / pixelCount;
-        prev = -left;
-        next = 1 + right;
-        firstAlpha = pixels[alphaChannel];
-        lastAlpha = pixels[(imgWidth - 1) * 4 + alphaChannel];
-        totalAlpha = 0;
-        for (int i = 0; i < pixelCount; ++i)
-            totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + alphaChannel];
-        target = pixels + blueChannel;
-        prevPtr = pixels + prev * 4 + alphaChannel;
-        nextPtr = pixels + next * 4 + alphaChannel;
-        for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) {
-            *target = (totalAlpha * invCount) >> BlurSumShift;
-            int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) -
-                        ((prev > 0) ? *prevPtr : firstAlpha);
-            totalAlpha += delta;
-        }
-
-        // Step 2: blur blue channel and store the result in the green channel.
-        left = swap ? dmin : dmax;
-        right = swap ? dmax : dmin;
-        pixelCount = left + 1 + right;
-        invCount = (1 << BlurSumShift) / pixelCount;
-        prev = -left;
-        next = 1 + right;
-        firstAlpha = pixels[blueChannel];
-        lastAlpha = pixels[(imgWidth - 1) * 4 + blueChannel];
-        totalAlpha = 0;
-        for (int i = 0; i < pixelCount; ++i)
-            totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + blueChannel];
-        target = pixels + greenChannel;
-        prevPtr = pixels + prev * 4 + blueChannel;
-        nextPtr = pixels + next * 4 + blueChannel;
-        for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) {
-            *target = (totalAlpha * invCount) >> BlurSumShift;
-            int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) -
-                        ((prev > 0) ? *prevPtr : firstAlpha);
-            totalAlpha += delta;
-        }
-
-        // Step 3: blur green channel and store the result in the alpha channel.
-        left = dmax;
-        right = dmax;
-        pixelCount = left + 1 + right;
-        invCount = (1 << BlurSumShift) / pixelCount;
-        prev = -left;
-        next = 1 + right;
-        firstAlpha = pixels[greenChannel];
-        lastAlpha = pixels[(imgWidth - 1) * 4 + greenChannel];
-        totalAlpha = 0;
-        for (int i = 0; i < pixelCount; ++i)
-            totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + greenChannel];
-        target = pixels + alphaChannel;
-        prevPtr = pixels + prev * 4 + greenChannel;
-        nextPtr = pixels + next * 4 + greenChannel;
-        for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) {
-            *target = (totalAlpha * invCount) >> BlurSumShift;
-            int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) -
-                        ((prev > 0) ? *prevPtr : firstAlpha);
-            totalAlpha += delta;
+    int dmin = dmax - 1 + (radius & 1);
+    if (dmin < 0)
+        dmin = 0;
+
+    // Two stages: horizontal and vertical
+    for (int k = 0; k < 2; ++k) {
+
+        unsigned char* pixels = image.bits();
+        int stride = (!k) ? 4 : image.bytesPerLine();
+        int delta = (!k) ? image.bytesPerLine() : 4;
+        int jfinal = (!k) ? image.height() : image.width();
+        int dim = (!k) ? image.width() : image.height();
+
+        for (int j = 0; j < jfinal; ++j, pixels += delta) {
+
+            // For each step, we blur the alpha in a channel and store the result
+            // in another channel for the subsequent step.
+            // We use sliding window algorithm to accumulate the alpha values.
+            // This is much more efficient than computing the sum of each pixels
+            // covered by the box kernel size for each x.
+
+            for (int step = 0; step < 3; ++step) {
+                int side1 = (!step) ? dmin : dmax;
+                int side2 = (step == 1) ? dmin : dmax;
+                int pixelCount = side1 + 1 + side2;
+                int invCount = ((1 << BlurSumShift) + pixelCount - 1) / pixelCount;
+                int ofs = 1 + side2;
+                int alpha1 = pixels[channels[step]];
+                int alpha2 = pixels[(dim - 1) * stride + channels[step]];
+                unsigned char* ptr = pixels + channels[step + 1];
+                unsigned char* prev = pixels + stride + channels[step];
+                unsigned char* next = pixels + ofs * stride + channels[step];
+
+                int i;
+                int sum = side1 * alpha1 + alpha1;
+                int limit = (dim < side2 + 1) ? dim : side2 + 1;
+                for (i = 1; i < limit; ++i, prev += stride)
+                    sum += *prev;
+                if (limit <= side2)
+                    sum += (side2 - limit + 1) * alpha2;
+
+                limit = (side1 < dim) ? side1 : dim;
+                for (i = 0; i < limit; ptr += stride, next += stride, ++i, ++ofs) {
+                    *ptr = (sum * invCount) >> BlurSumShift;
+                    sum += ((ofs < dim) ? *next : alpha2) - alpha1;
+                }
+                prev = pixels + channels[step];
+                for (; ofs < dim; ptr += stride, prev += stride, next += stride, ++i, ++ofs) {
+                    *ptr = (sum * invCount) >> BlurSumShift;
+                    sum += (*next) - (*prev);
+                }
+                for (; i < dim; ptr += stride, prev += stride, ++i) {
+                    *ptr = (sum * invCount) >> BlurSumShift;
+                    sum += alpha2 - (*prev);
+                }
+            }
         }
     }
-}
-
-static void shadowBlur(QImage& image, int radius, const QColor& shadowColor)
-{
-    blurHorizontal(image, radius);
-
-    QTransform transform;
-    transform.rotate(90);
-    image = image.transformed(transform);
-    blurHorizontal(image, radius, true);
-    transform.reset();
-    transform.rotate(270);
-    image = image.transformed(transform);
 
     // "Colorize" with the right shadow color.
     QPainter p(&image);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list