Changeset 82151 in webkit


Ignore:
Timestamp:
Mar 28, 2011 1:45:58 PM (13 years ago)
Author:
andersca@apple.com
Message:

2011-03-28 Anders Carlsson <andersca@apple.com>

Reviewed by Sam Weinig.

CGImageRefs must hold a strong reference to underlying data
https://bugs.webkit.org/show_bug.cgi?id=57263
<rdar://problem/9146179>

Make paintBitmapContext use CGBitmapContextCreateImage, which creates a copy-on-write copy
of the bitmap data. Also, add ShareableBitmap::makeCGImageCopy which does the same thing, and
ShareableBitmap::makeCGImage in the cases where we know that the ShareableBitmap data will never change.

  • Platform/cg/CGUtilities.cpp: (WebKit::paintImage): Factor image painting code out into a separate function.

(WebKit::paintBitmapContext):
Call paintImage.

  • Shared/API/c/cg/WKImageCG.cpp: (WKImagemakeCGImage): Use ShareableBitmap::makeCGImageCopy.
  • Shared/ShareableBitmap.h:
  • Shared/cg/ShareableBitmapCG.cpp: (WebKit::ShareableBitmap::createGraphicsContext): (WebKit::ShareableBitmap::paint): (WebKit::ShareableBitmap::makeCGImageCopy): (WebKit::ShareableBitmap::makeCGImage): (WebKit::ShareableBitmap::releaseBitmapContextData): (WebKit::ShareableBitmap::releaseDataProviderData): Add makeCGImage and makeCGImageCopy.
  • Shared/cg/WebCoreArgumentCodersCG.cpp: (CoreIPC::createImage): Use ShareableBitmap::makeCGImage.


  • UIProcess/API/mac/PageClientImpl.mm: (WebKit::PageClientImpl::setDragImage): Use ShareableBitmap::makeCGImage and plug a CGImageRef leak.
Location:
trunk/Source/WebKit2
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r82150 r82151  
     12011-03-28  Anders Carlsson  <andersca@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        CGImageRefs must hold a strong reference to underlying data
     6        https://bugs.webkit.org/show_bug.cgi?id=57263
     7        <rdar://problem/9146179>
     8
     9        Make paintBitmapContext use CGBitmapContextCreateImage, which creates a copy-on-write copy
     10        of the bitmap data. Also, add ShareableBitmap::makeCGImageCopy which does the same thing, and
     11        ShareableBitmap::makeCGImage in the cases where we know that the ShareableBitmap data will never change.
     12
     13        * Platform/cg/CGUtilities.cpp:
     14        (WebKit::paintImage):
     15        Factor image painting code out into a separate function.
     16
     17        (WebKit::paintBitmapContext):
     18        Call paintImage.
     19
     20        * Shared/API/c/cg/WKImageCG.cpp:
     21        (WKImagemakeCGImage):
     22        Use ShareableBitmap::makeCGImageCopy.
     23
     24        * Shared/ShareableBitmap.h:
     25        * Shared/cg/ShareableBitmapCG.cpp:
     26        (WebKit::ShareableBitmap::createGraphicsContext):
     27        (WebKit::ShareableBitmap::paint):
     28        (WebKit::ShareableBitmap::makeCGImageCopy):
     29        (WebKit::ShareableBitmap::makeCGImage):
     30        (WebKit::ShareableBitmap::releaseBitmapContextData):
     31        (WebKit::ShareableBitmap::releaseDataProviderData):
     32        Add makeCGImage and makeCGImageCopy.
     33
     34        * Shared/cg/WebCoreArgumentCodersCG.cpp:
     35        (CoreIPC::createImage):
     36        Use ShareableBitmap::makeCGImage.
     37       
     38        * UIProcess/API/mac/PageClientImpl.mm:
     39        (WebKit::PageClientImpl::setDragImage):
     40        Use ShareableBitmap::makeCGImage and plug a CGImageRef leak.
     41
    1422011-03-28  Alexey Proskuryakov  <ap@apple.com>
    243
  • trunk/Source/WebKit2/Platform/cg/CGUtilities.cpp

    r76916 r82151  
    3030
    3131namespace WebKit {
    32    
    33 void paintBitmapContext(CGContextRef context, CGContextRef bitmapContext, CGPoint destination, CGRect source)
     32
     33void paintImage(CGContextRef context, CGImageRef image, CGPoint destination, CGRect source)
    3434{
    35     void* bitmapData = CGBitmapContextGetData(bitmapContext);
    36     ASSERT(bitmapData);
    37 
    38     size_t imageWidth = CGBitmapContextGetWidth(bitmapContext);
    39     size_t imageHeight = CGBitmapContextGetHeight(bitmapContext);
    40 
    41     size_t bytesPerRow = CGBitmapContextGetBytesPerRow(bitmapContext);
    42 
    43     RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithData(0, bitmapData, bytesPerRow * imageHeight, 0));
    44     RetainPtr<CGImageRef> image(AdoptCF, CGImageCreate(imageWidth, imageHeight,
    45                                                        CGBitmapContextGetBitsPerComponent(bitmapContext),
    46                                                        CGBitmapContextGetBitsPerPixel(bitmapContext),
    47                                                        bytesPerRow,
    48                                                        CGBitmapContextGetColorSpace(bitmapContext),
    49                                                        CGBitmapContextGetBitmapInfo(bitmapContext),
    50                                                        dataProvider.get(), 0, false, kCGRenderingIntentDefault));
    51 
    5235    CGContextSaveGState(context);
    5336
     
    5538    CGContextScaleCTM(context, 1, -1);
    5639
     40    size_t imageHeight = CGImageGetHeight(image);
     41    size_t imageWidth = CGImageGetWidth(image);
     42
    5743    CGFloat destX = destination.x - source.origin.x;
    5844    CGFloat destY = -static_cast<CGFloat>(imageHeight) - destination.y + source.origin.y;
    5945
    60     CGContextDrawImage(context, CGRectMake(destX, destY, imageWidth, imageHeight), image.get());
     46    CGContextDrawImage(context, CGRectMake(destX, destY, imageWidth, imageHeight), image);
    6147    CGContextRestoreGState(context);
    6248}
    63    
     49
     50void paintBitmapContext(CGContextRef context, CGContextRef bitmapContext, CGPoint destination, CGRect source)
     51{
     52    RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(bitmapContext));
     53    paintImage(context, image.get(), destination, source);
     54}
     55
    6456} // namespace WebKit
    6557
  • trunk/Source/WebKit2/Platform/cg/CGUtilities.h

    r75962 r82151  
    2929namespace WebKit {
    3030
     31void paintImage(CGContextRef, CGImageRef, CGPoint destination, CGRect source);
    3132void paintBitmapContext(CGContextRef, CGContextRef bitmapContext, CGPoint destination, CGRect source);
    3233
  • trunk/Source/WebKit2/Shared/API/c/cg/WKImageCG.cpp

    r81087 r82151  
    3737CGImageRef WKImageCreateCGImage(WKImageRef imageRef)
    3838{
    39     OwnPtr<GraphicsContext> sourceContext = toImpl(imageRef)->bitmap()->createGraphicsContext();
    40     return CGBitmapContextCreateImage(sourceContext->platformContext());
     39    return toImpl(imageRef)->bitmap()->makeCGImageCopy().leakRef();
    4140}
    4241
  • trunk/Source/WebKit2/Shared/ShareableBitmap.h

    r80917 r82151  
    3333#include <wtf/RefCounted.h>
    3434#include <wtf/RefPtr.h>
     35
     36#if PLATFORM(MAC)
     37#include <wtf/RetainPtr.h>
     38#endif
    3539
    3640namespace WebCore {
     
    7276    bool isBackedBySharedMemory() const { return m_sharedMemory; }
    7377
     78#if PLATFORM(CG)
     79    // This creates a copied CGImageRef (most likely a copy-on-write) of the shareable bitmap.
     80    RetainPtr<CGImageRef> makeCGImageCopy();
     81
     82    // This creates a CGImageRef that directly references the shared bitmap data.
     83    // This is only safe to use when we know that the contents of the shareable bitmap won't change.
     84    RetainPtr<CGImageRef> makeCGImage();
     85#endif
     86
    7487private:
    7588    ShareableBitmap(const WebCore::IntSize&, void*);
     
    7891    static size_t numBytesForSize(const WebCore::IntSize& size) { return size.width() * size.height() * 4; }
    7992
    80     static void releaseData(void* typelessBitmap, void* typelessData);
    81    
     93#if PLATFORM(CG)
     94    static void releaseBitmapContextData(void* typelessBitmap, void* typelessData);
     95    static void releaseDataProviderData(void* typelessBitmap, const void* typelessData, size_t);
     96#endif
     97
    8298    void* data() const;
    8399    size_t sizeInBytes() const { return numBytesForSize(m_size); }
  • trunk/Source/WebKit2/Shared/cg/ShareableBitmapCG.cpp

    r79652 r82151  
    3939    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    4040
    41     ref(); // Balanced by deref in releaseData.
     41    ref(); // Balanced by deref in releaseBitmapContextData.
    4242    RetainPtr<CGContextRef> bitmapContext(AdoptCF, CGBitmapContextCreateWithData(data(),
    4343        m_size.width(), m_size.height(), 8, m_size.width() * 4, colorSpace.get(),
    44         kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, releaseData, this));
     44        kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, releaseBitmapContextData, this));
    4545
    4646    // We want the origin to be in the top left corner so we flip the backing store context.
     
    5353void ShareableBitmap::paint(WebCore::GraphicsContext& context, const IntPoint& dstPoint, const IntRect& srcRect)
    5454{
    55     paintBitmapContext(context.platformContext(), createGraphicsContext()->platformContext(), dstPoint, srcRect);
     55    paintImage(context.platformContext(), makeCGImageCopy().get(), dstPoint, srcRect);
    5656}
    5757
    58 void ShareableBitmap::releaseData(void* typelessBitmap, void* typelessData)
     58RetainPtr<CGImageRef> ShareableBitmap::makeCGImageCopy()
     59{
     60    OwnPtr<GraphicsContext> graphicsContext = createGraphicsContext();
     61    RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(graphicsContext->platformContext()));
     62    return image;
     63}
     64
     65RetainPtr<CGImageRef> ShareableBitmap::makeCGImage()
     66{
     67    ref(); // Balanced by deref in releaseDataProviderData.
     68    RetainPtr<CGDataProvider> dataProvider(AdoptCF, CGDataProviderCreateWithData(this, data(), sizeInBytes(), releaseDataProviderData));
     69
     70    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
     71    RetainPtr<CGImageRef> image(AdoptCF, CGImageCreate(m_size.width(), m_size.height(), 8, 32, m_size.width() * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
     72    return image;
     73}
     74
     75void ShareableBitmap::releaseBitmapContextData(void* typelessBitmap, void* typelessData)
    5976{
    6077    ShareableBitmap* bitmap = static_cast<ShareableBitmap*>(typelessBitmap);
     
    6380}
    6481
     82void ShareableBitmap::releaseDataProviderData(void* typelessBitmap, const void* typelessData, size_t)
     83{
     84    ShareableBitmap* bitmap = static_cast<ShareableBitmap*>(typelessBitmap);
     85    ASSERT_UNUSED(typelessData, bitmap->data() == typelessData);
     86    bitmap->deref(); // Balanced by ref in createCGImage.
     87}
     88
    6589} // namespace WebKit
  • trunk/Source/WebKit2/Shared/cg/WebCoreArgumentCodersCG.cpp

    r79652 r82151  
    3737RefPtr<Image> createImage(ShareableBitmap* bitmap)
    3838{
    39     RetainPtr<CGImageRef> platformImage(AdoptCF, CGBitmapContextCreateImage(bitmap->createGraphicsContext()->platformContext()));
     39    RetainPtr<CGImageRef> platformImage = bitmap->makeCGImage();
    4040    if (!platformImage)
    4141        return 0;
  • trunk/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm

    r81890 r82151  
    300300void PageClientImpl::setDragImage(const IntPoint& clientPosition, const IntSize& imageSize, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag)
    301301{
    302     OwnPtr<GraphicsContext> graphicsContext = dragImage->createGraphicsContext();
    303     RetainPtr<NSImage> dragNSImage(AdoptNS, [[NSImage alloc] initWithCGImage:CGBitmapContextCreateImage(graphicsContext->platformContext()) size:imageSize]);
     302    RetainPtr<CGImageRef> dragCGImage = dragImage->makeCGImage();
     303    RetainPtr<NSImage> dragNSImage(AdoptNS, [[NSImage alloc] initWithCGImage:dragCGImage.get() size:imageSize]);
     304
    304305    [m_wkView _setDragImage:dragNSImage.get() at:clientPosition linkDrag:isLinkDrag];
    305306}
Note: See TracChangeset for help on using the changeset viewer.