[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