Title: [136179] branches/safari-536.28-branch/Source/WebCore
Revision
136179
Author
[email protected]
Date
2012-11-29 16:20:46 -0800 (Thu, 29 Nov 2012)

Log Message

<rdar://problem/12781055>

Merge r136174

    2012-11-29  Simon Fraser  <[email protected]>

    Avoid painting lots of small rects in WebLayer painting
    https://bugs.webkit.org/show_bug.cgi?id=103673

    Reviewed by Tim Horton.

    r109186 added code in drawLayerContents() to enumerate over the rects in
    the CALayer's dirty region, and paint them individually. This was done
    to help performance on the IE Maze Solver test.

    On large, complex pages like Facebook, the overhead of traversing the
    RenderLayer tree for painting is such that it's better to paint a single,
    or fewer rects rather than lots of little ones.

    So adopt a heuristic similar to that in DrawingArea, where if the
    combined area of the small rects is 75% or more of the combined rect,
    just paint the combined rect. Also paint the combined rect if there
    are more than 5 individual rects.

    I verified that this preserves the optimization for IE Maze Solver.

    * platform/graphics/mac/WebLayer.mm:
    (drawLayerContents):

Modified Paths

Diff

Modified: branches/safari-536.28-branch/Source/WebCore/ChangeLog (136178 => 136179)


--- branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-30 00:01:59 UTC (rev 136178)
+++ branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-30 00:20:46 UTC (rev 136179)
@@ -1,3 +1,34 @@
+2012-11-29  Simon Fraser  <[email protected]>
+
+        <rdar://problem/12781055>
+        
+        Merge r136174
+
+    2012-11-29  Simon Fraser  <[email protected]>
+    
+            Avoid painting lots of small rects in WebLayer painting
+            https://bugs.webkit.org/show_bug.cgi?id=103673
+    
+            Reviewed by Tim Horton.
+    
+            r109186 added code in drawLayerContents() to enumerate over the rects in
+            the CALayer's dirty region, and paint them individually. This was done
+            to help performance on the IE Maze Solver test.
+            
+            On large, complex pages like Facebook, the overhead of traversing the
+            RenderLayer tree for painting is such that it's better to paint a single,
+            or fewer rects rather than lots of little ones.
+            
+            So adopt a heuristic similar to that in DrawingArea, where if the
+            combined area of the small rects is 75% or more of the combined rect,
+            just paint the combined rect. Also paint the combined rect if there
+            are more than 5 individual rects.
+            
+            I verified that this preserves the optimization for IE Maze Solver.
+    
+            * platform/graphics/mac/WebLayer.mm:
+            (drawLayerContents):
+
 2012-11-28  Lucas Forschler  <[email protected]>
 
         Windows build fix after r134704.

Modified: branches/safari-536.28-branch/Source/WebCore/platform/graphics/mac/WebLayer.mm (136178 => 136179)


--- branches/safari-536.28-branch/Source/WebCore/platform/graphics/mac/WebLayer.mm	2012-11-30 00:01:59 UTC (rev 136178)
+++ branches/safari-536.28-branch/Source/WebCore/platform/graphics/mac/WebLayer.mm	2012-11-30 00:20:46 UTC (rev 136179)
@@ -85,18 +85,37 @@
     ThemeMac::setFocusRingClipRect(transform.mapRect(clipBounds));
 
 #if !defined(BUILDING_ON_SNOW_LEOPARD)
-    __block GraphicsContext* ctx = &graphicsContext;
+    const float wastedSpaceThreshold = 0.75f;
+    const unsigned maxRectsToPaint = 5;
 
-    wkCALayerEnumerateRectsBeingDrawnWithBlock(layer, context, ^(CGRect rect){
-        FloatRect rectBeingDrawn(rect);
-        rectBeingDrawn.intersect(clipBounds);
-        
-        GraphicsContextStateSaver stateSaver(*ctx);
-        ctx->clip(rectBeingDrawn);
-        
-        layerContents->platformCALayerPaintContents(*ctx, enclosingIntRect(rectBeingDrawn));
+    double clipArea = clipBounds.width() * clipBounds.height();
+    __block double totalRectArea = 0;
+    __block unsigned rectCount = 0;
+    __block Vector<FloatRect, maxRectsToPaint> dirtyRects;
+    
+    wkCALayerEnumerateRectsBeingDrawnWithBlock(layer, context, ^(CGRect rect) {
+        if (++rectCount > maxRectsToPaint)
+            return;
+
+        totalRectArea += rect.size.width * rect.size.height;
+        dirtyRects.append(rect);
     });
 
+    if (rectCount < maxRectsToPaint && totalRectArea < clipArea * wastedSpaceThreshold) {
+        for (unsigned i = 0; i < rectCount; ++i) {
+            const FloatRect& currentRect = dirtyRects[i];
+            
+            GraphicsContextStateSaver stateSaver(graphicsContext);
+            graphicsContext.clip(currentRect);
+            
+            layerContents->platformCALayerPaintContents(graphicsContext, enclosingIntRect(currentRect));
+        }
+    } else {
+        // CGContextGetClipBoundingBox() gives us the bounds of the dirty region, so clipBounds
+        // encompasses all the dirty rects.
+        layerContents->platformCALayerPaintContents(graphicsContext, enclosingIntRect(clipBounds));
+    }
+
 #else
     IntRect clip(enclosingIntRect(clipBounds));
     layerContents->platformCALayerPaintContents(graphicsContext, clip);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to