Changeset 25187 in webkit


Ignore:
Timestamp:
Aug 22, 2007, 12:58:44 PM (18 years ago)
Author:
hyatt
Message:

Fix for <rdar://problem/5249757> Painting of JPGs in WebKit is too slow.

Use a new Leopard API for fast tiling of images. We only use this API
when the whole image is being tiled and when the current CGImageRef to tile
has a size that matches the size of the whole image.

We can optimize border-image in the future by adding a cache of the 9
sub-images.

Reviewed by darin

  • platform/graphics/cg/ImageCG.cpp: (WebCore::Image::drawPattern):
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r25186 r25187  
     12007-08-21  David Hyatt  <hyatt@apple.com>
     2
     3        Fix for <rdar://problem/5249757> Painting of JPGs in WebKit is too slow.
     4
     5        Use a new Leopard API for fast tiling of images.  We only use this API
     6        when the whole image is being tiled and when the current CGImageRef to tile
     7        has a size that matches the size of the whole image.
     8
     9        We can optimize border-image in the future by adding a cache of the 9
     10        sub-images.
     11
     12        Reviewed by darin
     13
     14        * platform/graphics/cg/ImageCG.cpp:
     15        (WebCore::Image::drawPattern):
     16
    1172007-08-22  Kevin McCullough  <kmccullough@apple.com>
    218
  • trunk/WebCore/platform/graphics/cg/ImageCG.cpp

    r24970 r25187  
    3030
    3131#include "AffineTransform.h"
     32#include "FloatConversion.h"
    3233#include "FloatRect.h"
    3334#include "GraphicsContext.h"
     
    177178
    178179void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
    179                                 const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
    180 {
     180                        const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
     181{
     182    CGContextRef context = ctxt->platformContext();
     183
     184#ifndef BUILDING_ON_TIGER
     185    // Leopard has an optimized call for the tiling of image patterns, but we can only use it if the image has been decoded enough that
     186    // its buffer is the same size as the overall image.  Because a partially decoded CGImageRef with a smaller width or height than the
     187    // overall image buffer needs to tile with "gaps", we can't use the optimized tiling call in that case.  We also avoid this optimization
     188    // when tiling portions of an image, since until we can actually cache the subimage we want to tile, this code won't be any faster.
     189    // FIXME: Could create WebKitSystemInterface SPI for CGCreatePatternWithImage2 and probably make Tiger tile faster as well.
     190    CGImageRef tileImage = nativeImageForCurrentFrame();
     191    float w = CGImageGetWidth(tileImage);
     192    float h = CGImageGetHeight(tileImage);
     193    if (w == size().width() && h == size().height() && tileRect.size() == size()) {
     194        ctxt->save();
     195        CGContextClipToRect(context, destRect);
     196        ctxt->setCompositeOperation(op);
     197        CGContextTranslateCTM(context, destRect.x(), destRect.y());
     198        CGContextScaleCTM(context, 1, -1);
     199        CGContextTranslateCTM(context, 0, -destRect.height());
     200       
     201        // Compute the scaled tile size.
     202        float scaledTileWidth = tileRect.width() * narrowPrecisionToCGFloat(patternTransform.a());
     203        float scaledTileHeight = tileRect.height() * narrowPrecisionToCGFloat(patternTransform.d());
     204   
     205        // We have to adjust the phase to deal with the fact we're in Cartesian space now (with the bottom left corner of destRect being
     206        // the origin).
     207        float adjustedX = phase.x() - destRect.x(); // We translated the context so that destRect.x() is the origin, so subtract it out.
     208        float adjustedY = destRect.height() - (phase.y() - destRect.y() + scaledTileHeight);
     209
     210        CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), tileImage);
     211        ctxt->restore();
     212    } else {
     213#endif
     214
     215    // On Leopard, this code now only runs for partially decoded images whose buffers do not yet match the overall size of the image or for
     216    // tiling a portion of an image (i.e., a subimage like the ones used by CSS border-image).
     217    // On Tiger this code runs all the time.  This code is suboptimal because the pattern does not reference the image directly, and the
     218    // pattern is destroyed before exiting the function.  This means any decoding the pattern does doesn't end up cached anywhere, so we
     219    // redecode every time we paint.
    181220    static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, NULL };
    182221    CGPatternRef pattern = CGPatternCreate(this, FloatRect(tileRect.x(), -tileRect.y() - tileRect.height(), tileRect.width(), tileRect.height()),
     
    186225        return;
    187226   
    188     CGContextRef context = ctxt->platformContext();
    189227    ctxt->save();
    190228   
     
    206244    CGPatternRelease(pattern);
    207245
     246#ifndef BUILDING_ON_TIGER
     247    }
     248#endif
     249
    208250    if (imageObserver())
    209251        imageObserver()->didDraw(this);
Note: See TracChangeset for help on using the changeset viewer.