Title: [122507] trunk/Source/WebKit/qt
Revision
122507
Author
k...@webkit.org
Date
2012-07-12 14:37:30 -0700 (Thu, 12 Jul 2012)

Log Message

[Qt] Increase the drawing performance by merging dirty rects.
https://bugs.webkit.org/show_bug.cgi?id=91075

Patch by Huang Dongsung <luxte...@company100.net> on 2012-07-12
Reviewed by Noam Rosenthal.

QWebFramePrivate calls FrameView::paintContents as many as the number of dirty
rects, so it causes too many redundant render tree traversals.
I changed it to merge dirty rects and call FrameView::paintContents only once.
The algorithm to merge rects is copied from GTK.

When parallel image decoders are in use, each image is independently repainted
when decoding is finished. This creates a lot by repaint requests. So by merging
these repaint requests, I could improve rendering performance.

For example, I tested parallel image decoders on the locally mirrored Pinterest site.
QWebFramePrivate called FrameView::paintContents 165 times after parallel image
decoders decoded all the images. It took about 120ms on my six-core Intel Xeon machine.
This patch decreases painting time from 120ms to 30ms.

* Api/qwebframe.cpp:
(coalesceRectsIfPossible):
(QWebFramePrivate::renderRelativeCoords):

Modified Paths

Diff

Modified: trunk/Source/WebKit/qt/Api/qwebframe.cpp (122506 => 122507)


--- trunk/Source/WebKit/qt/Api/qwebframe.cpp	2012-07-12 21:35:34 UTC (rev 122506)
+++ trunk/Source/WebKit/qt/Api/qwebframe.cpp	2012-07-12 21:37:30 UTC (rev 122507)
@@ -356,6 +356,32 @@
 }
 #endif
 
+// This code is copied from ChromeClientGtk.cpp.
+static void coalesceRectsIfPossible(const QRect& clipRect, QVector<QRect>& rects)
+{
+    const unsigned int rectThreshold = 10;
+    const float wastedSpaceThreshold = 0.75f;
+    bool useUnionedRect = (rects.size() <= 1) || (rects.size() > rectThreshold);
+    if (!useUnionedRect) {
+        // Attempt to guess whether or not we should use the unioned rect or the individual rects.
+        // We do this by computing the percentage of "wasted space" in the union. If that wasted space
+        // is too large, then we will do individual rect painting instead.
+        float unionPixels = (clipRect.width() * clipRect.height());
+        float singlePixels = 0;
+        for (size_t i = 0; i < rects.size(); ++i)
+            singlePixels += rects[i].width() * rects[i].height();
+        float wastedSpace = 1 - (singlePixels / unionPixels);
+        if (wastedSpace <= wastedSpaceThreshold)
+            useUnionedRect = true;
+    }
+
+    if (!useUnionedRect)
+        return;
+
+    rects.clear();
+    rects.append(clipRect);
+}
+
 void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QFlags<QWebFrame::RenderLayer> layers, const QRegion& clip)
 {
     if (!frame->view() || !frame->contentRenderer())
@@ -371,6 +397,8 @@
     view->updateLayoutAndStyleIfNeededRecursive();
 
     if (layers & QWebFrame::ContentsLayer) {
+        QRect clipBoundingRect = clip.boundingRect();
+        coalesceRectsIfPossible(clipBoundingRect, vector);
         for (int i = 0; i < vector.size(); ++i) {
             const QRect& clipRect = vector.at(i);
 
@@ -396,7 +424,7 @@
             context->restore();
         }
 #if USE(ACCELERATED_COMPOSITING)
-        renderCompositedLayers(context, IntRect(clip.boundingRect()));
+        renderCompositedLayers(context, IntRect(clipBoundingRect));
 #endif
     }
     renderFrameExtras(context, layers, clip);

Modified: trunk/Source/WebKit/qt/ChangeLog (122506 => 122507)


--- trunk/Source/WebKit/qt/ChangeLog	2012-07-12 21:35:34 UTC (rev 122506)
+++ trunk/Source/WebKit/qt/ChangeLog	2012-07-12 21:37:30 UTC (rev 122507)
@@ -1,3 +1,28 @@
+2012-07-12  Huang Dongsung  <luxte...@company100.net>
+
+        [Qt] Increase the drawing performance by merging dirty rects.
+        https://bugs.webkit.org/show_bug.cgi?id=91075
+
+        Reviewed by Noam Rosenthal.
+
+        QWebFramePrivate calls FrameView::paintContents as many as the number of dirty
+        rects, so it causes too many redundant render tree traversals.
+        I changed it to merge dirty rects and call FrameView::paintContents only once.
+        The algorithm to merge rects is copied from GTK.
+
+        When parallel image decoders are in use, each image is independently repainted
+        when decoding is finished. This creates a lot by repaint requests. So by merging
+        these repaint requests, I could improve rendering performance.
+
+        For example, I tested parallel image decoders on the locally mirrored Pinterest site.
+        QWebFramePrivate called FrameView::paintContents 165 times after parallel image
+        decoders decoded all the images. It took about 120ms on my six-core Intel Xeon machine.
+        This patch decreases painting time from 120ms to 30ms.
+
+        * Api/qwebframe.cpp:
+        (coalesceRectsIfPossible):
+        (QWebFramePrivate::renderRelativeCoords):
+
 2012-07-11  Steffen Imhof  <steffen.im...@basyskom.com>
 
         [Qt] Middle clicking a scrollbar causes text to be pasted.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to