⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 136174 in webkit


Ignore:
Timestamp:
Nov 29, 2012, 3:21:09 PM (14 years ago)
Author:
Simon Fraser
Message:

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):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r136171 r136174  
     12012-11-29  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Avoid painting lots of small rects in WebLayer painting
     4        https://bugs.webkit.org/show_bug.cgi?id=103673
     5
     6        Reviewed by Tim Horton.
     7
     8        r109186 added code in drawLayerContents() to enumerate over the rects in
     9        the CALayer's dirty region, and paint them individually. This was done
     10        to help performance on the IE Maze Solver test.
     11       
     12        On large, complex pages like Facebook, the overhead of traversing the
     13        RenderLayer tree for painting is such that it's better to paint a single,
     14        or fewer rects rather than lots of little ones.
     15       
     16        So adopt a heuristic similar to that in DrawingArea, where if the
     17        combined area of the small rects is 75% or more of the combined rect,
     18        just paint the combined rect. Also paint the combined rect if there
     19        are more than 5 individual rects.
     20       
     21        I verified that this preserves the optimization for IE Maze Solver.
     22
     23        * platform/graphics/mac/WebLayer.mm:
     24        (drawLayerContents):
     25
    1262012-11-29  Eugene Klyuchnikov  <eustas@chromium.org>
    227
  • trunk/Source/WebCore/platform/graphics/mac/WebLayer.mm

    r135882 r136174  
    8686
    8787#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
    88     __block GraphicsContext* ctx = &graphicsContext;
    89 
    90     wkCALayerEnumerateRectsBeingDrawnWithBlock(layer, context, ^(CGRect rect){
    91         FloatRect rectBeingDrawn(rect);
    92         rectBeingDrawn.intersect(clipBounds);
    93        
    94         GraphicsContextStateSaver stateSaver(*ctx);
    95         ctx->clip(rectBeingDrawn);
    96        
    97         layerContents->platformCALayerPaintContents(*ctx, enclosingIntRect(rectBeingDrawn));
     88    const float wastedSpaceThreshold = 0.75f;
     89    const unsigned maxRectsToPaint = 5;
     90
     91    double clipArea = clipBounds.width() * clipBounds.height();
     92    __block double totalRectArea = 0;
     93    __block unsigned rectCount = 0;
     94    __block Vector<FloatRect, maxRectsToPaint> dirtyRects;
     95   
     96    wkCALayerEnumerateRectsBeingDrawnWithBlock(layer, context, ^(CGRect rect) {
     97        if (++rectCount > maxRectsToPaint)
     98            return;
     99
     100        totalRectArea += rect.size.width * rect.size.height;
     101        dirtyRects.append(rect);
    98102    });
     103
     104    if (rectCount < maxRectsToPaint && totalRectArea < clipArea * wastedSpaceThreshold) {
     105        for (unsigned i = 0; i < rectCount; ++i) {
     106            const FloatRect& currentRect = dirtyRects[i];
     107           
     108            GraphicsContextStateSaver stateSaver(graphicsContext);
     109            graphicsContext.clip(currentRect);
     110           
     111            layerContents->platformCALayerPaintContents(graphicsContext, enclosingIntRect(currentRect));
     112        }
     113    } else {
     114        // CGContextGetClipBoundingBox() gives us the bounds of the dirty region, so clipBounds
     115        // encompasses all the dirty rects.
     116        layerContents->platformCALayerPaintContents(graphicsContext, enclosingIntRect(clipBounds));
     117    }
    99118
    100119#else
Note: See TracChangeset for help on using the changeset viewer.