Changeset 181301 in webkit


Ignore:
Timestamp:
Mar 9, 2015 6:24:14 PM (9 years ago)
Author:
Chris Dumez
Message:

[CG] Have Canvas use the IOSurfacePool
https://bugs.webkit.org/show_bug.cgi?id=142417
<rdar://problem/20044440>

Reviewed by Darin Adler.

PerformanceTests:

Lower the number of different canvas sizes from 1000 to 100 so that
the test does not require such a huge cache size. With 100, we now
get over 90% cache hit rate with the default IOSurfacePool size.

  • Canvas/reuse.html:

Source/WebCore:

Have ImageBufferDataCG use the IOSurfacePool so that Canvas can
benefit from it. I see a ~75% progression on Canvas/reuse.html
performance test on my Macbook Pro with 1000 different canvas
sizes and ~110% progression with 100 different canvas sizes.

I also see a ~65% cache hit rate on the mobile version of
cnn.com.

Note that ImageData calls CGContextClearRect() after calling
IOSurface::create() so recycling IOSurfaces in this case should
be safe.

Performance test: Canvas/reuse.html

  • platform/graphics/ImageBuffer.h:

(WebCore::ImageBuffer::baseTransform):

  • platform/graphics/cg/ImageBufferCG.cpp:

(WebCore::ImageBuffer::ImageBuffer):
(WebCore::ImageBuffer::context):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::copyNativeImage):
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::clip):
(WebCore::ImageBuffer::putByteArray):
(WebCore::ImageBuffer::toDataURL):

  • platform/graphics/cg/ImageBufferDataCG.cpp:

(WebCore::ImageBufferData::~ImageBufferData):
(WebCore::ImageBufferData::getData):
(WebCore::ImageBufferData::putData):
(WebCore::ImageBufferData::ImageBufferData): Deleted.

  • platform/graphics/cg/ImageBufferDataCG.h:
  • platform/graphics/cocoa/IOSurface.h:
  • platform/graphics/cocoa/IOSurface.mm:

(IOSurface::surfaceFromPool):
(IOSurface::create):
(IOSurface::createFromSendRight):
(IOSurface::createFromImage):
(IOSurface::setContextSize):

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/PerformanceTests/Canvas/reuse.html

    r161235 r181301  
    55<script>
    66
    7 var numCreated = 1000;
     7var numCreated = 100;
    88
    99function testCreation() {
  • trunk/PerformanceTests/ChangeLog

    r179335 r181301  
     12015-03-09  Chris Dumez  <cdumez@apple.com>
     2
     3        [CG] Have Canvas use the IOSurfacePool
     4        https://bugs.webkit.org/show_bug.cgi?id=142417
     5        <rdar://problem/20044440>
     6
     7        Reviewed by Darin Adler.
     8
     9        Lower the number of different canvas sizes from 1000 to 100 so that
     10        the test does not require such a huge cache size. With 100, we now
     11        get over 90% cache hit rate with the default IOSurfacePool size.
     12
     13        * Canvas/reuse.html:
     14
    1152015-01-28  Said Abou-Hallawa  <sabouhallawa@apple.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r181300 r181301  
     12015-03-09  Chris Dumez  <cdumez@apple.com>
     2
     3        [CG] Have Canvas use the IOSurfacePool
     4        https://bugs.webkit.org/show_bug.cgi?id=142417
     5        <rdar://problem/20044440>
     6
     7        Reviewed by Darin Adler.
     8
     9        Have ImageBufferDataCG use the IOSurfacePool so that Canvas can
     10        benefit from it. I see a ~75% progression on Canvas/reuse.html
     11        performance test on my Macbook Pro with 1000 different canvas
     12        sizes and ~110% progression with 100 different canvas sizes.
     13
     14        I also see a ~65% cache hit rate on the mobile version of
     15        cnn.com.
     16
     17        Note that ImageData calls CGContextClearRect() after calling
     18        IOSurface::create() so recycling IOSurfaces in this case should
     19        be safe.
     20
     21        Performance test: Canvas/reuse.html
     22
     23        * platform/graphics/ImageBuffer.h:
     24        (WebCore::ImageBuffer::baseTransform):
     25        * platform/graphics/cg/ImageBufferCG.cpp:
     26        (WebCore::ImageBuffer::ImageBuffer):
     27        (WebCore::ImageBuffer::context):
     28        (WebCore::ImageBuffer::copyImage):
     29        (WebCore::ImageBuffer::copyNativeImage):
     30        (WebCore::ImageBuffer::draw):
     31        (WebCore::ImageBuffer::clip):
     32        (WebCore::ImageBuffer::putByteArray):
     33        (WebCore::ImageBuffer::toDataURL):
     34        * platform/graphics/cg/ImageBufferDataCG.cpp:
     35        (WebCore::ImageBufferData::~ImageBufferData):
     36        (WebCore::ImageBufferData::getData):
     37        (WebCore::ImageBufferData::putData):
     38        (WebCore::ImageBufferData::ImageBufferData): Deleted.
     39        * platform/graphics/cg/ImageBufferDataCG.h:
     40        * platform/graphics/cocoa/IOSurface.h:
     41        * platform/graphics/cocoa/IOSurface.mm:
     42        (IOSurface::surfaceFromPool):
     43        (IOSurface::create):
     44        (IOSurface::createFromSendRight):
     45        (IOSurface::createFromImage):
     46        (IOSurface::setContextSize):
     47
    1482015-03-09  Brent Fulgham  <bfulgham@apple.com>
    249
  • trunk/Source/WebCore/platform/graphics/ImageBuffer.h

    r180531 r181301  
    115115    void platformTransformColorSpace(const Vector<int>&);
    116116#else
    117     AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.m_backingStoreSize.height()); }
     117    AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.backingStoreSize.height()); }
    118118#endif
    119119    PlatformLayer* platformLayer() const;
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp

    r180342 r181301  
    8282
    8383    m_size = IntSize(scaledWidth, scaledHeight);
    84     m_data.m_backingStoreSize = m_size;
     84    m_data.backingStoreSize = m_size;
    8585
    8686    success = false;  // Make early return mean failure.
     
    9595
    9696    // Prevent integer overflows
    97     m_data.m_bytesPerRow = 4 * Checked<unsigned, RecordOverflow>(m_data.m_backingStoreSize.width());
    98     Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.m_backingStoreSize.height()) * m_data.m_bytesPerRow;
     97    m_data.bytesPerRow = 4 * Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.width());
     98    Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.height()) * m_data.bytesPerRow;
    9999    if (numBytes.hasOverflowed())
    100100        return;
     
    108108#endif
    109109
    110     m_data.m_colorSpace = cachedCGColorSpace(imageColorSpace);
     110    m_data.colorSpace = cachedCGColorSpace(imageColorSpace);
    111111
    112112    RetainPtr<CGContextRef> cgContext;
    113113    if (accelerateRendering) {
    114114#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    115         FloatSize userBounds = scaleSizeToUserSpace(FloatSize(width.unsafeGet(), height.unsafeGet()), m_data.m_backingStoreSize, m_size);
    116         m_data.m_surface = IOSurface::create(m_data.m_backingStoreSize, IntSize(userBounds), imageColorSpace);
    117         cgContext = m_data.m_surface->ensurePlatformContext();
     115        FloatSize userBounds = scaleSizeToUserSpace(FloatSize(width.unsafeGet(), height.unsafeGet()), m_data.backingStoreSize, m_size);
     116        m_data.surface = IOSurface::create(m_data.backingStoreSize, IntSize(userBounds), imageColorSpace);
     117        cgContext = m_data.surface->ensurePlatformContext();
    118118        if (cgContext)
    119119            CGContextClearRect(cgContext.get(), FloatRect(FloatPoint(), userBounds));
     
    125125
    126126    if (!accelerateRendering) {
    127         if (!tryFastCalloc(m_data.m_backingStoreSize.height(), m_data.m_bytesPerRow.unsafeGet()).getValue(m_data.m_data))
     127        if (!tryFastCalloc(m_data.backingStoreSize.height(), m_data.bytesPerRow.unsafeGet()).getValue(m_data.data))
    128128            return;
    129         ASSERT(!(reinterpret_cast<intptr_t>(m_data.m_data) & 3));
     129        ASSERT(!(reinterpret_cast<intptr_t>(m_data.data) & 3));
    130130
    131131#if USE_ARGB32
    132         m_data.m_bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
     132        m_data.bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
    133133#else
    134         m_data.m_bitmapInfo = kCGImageAlphaPremultipliedLast;
    135 #endif
    136         cgContext = adoptCF(CGBitmapContextCreate(m_data.m_data, m_data.m_backingStoreSize.width(), m_data.m_backingStoreSize.height(), 8, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo));
     134        m_data.bitmapInfo = kCGImageAlphaPremultipliedLast;
     135#endif
     136        cgContext = adoptCF(CGBitmapContextCreate(m_data.data, m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo));
    137137        // Create a live image that wraps the data.
    138         m_data.m_dataProvider = adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, numBytes.unsafeGet(), releaseImageData));
     138        m_data.dataProvider = adoptCF(CGDataProviderCreateWithData(0, m_data.data, numBytes.unsafeGet(), releaseImageData));
    139139
    140140        if (!cgContext)
    141141            return;
    142142
    143         m_data.m_context = adoptPtr(new GraphicsContext(cgContext.get()));
     143        m_data.context = adoptPtr(new GraphicsContext(cgContext.get()));
    144144    }
    145145
    146146    context()->scale(FloatSize(1, -1));
    147     context()->translate(0, -m_data.m_backingStoreSize.height());
     147    context()->translate(0, -m_data.backingStoreSize.height());
    148148    context()->applyDeviceScaleFactor(m_resolutionScale);
    149149
     
    158158{
    159159#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    160     if (m_data.m_surface)
    161         return &m_data.m_surface->ensureGraphicsContext();
    162 #endif
    163     return m_data.m_context.get();
     160    if (m_data.surface)
     161        return &m_data.surface->ensureGraphicsContext();
     162#endif
     163    return m_data.context.get();
    164164}
    165165
     
    189189        CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
    190190        CGContextClipToRect(context.get(), FloatRect(FloatPoint::zero(), logicalSize()));
    191         FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
     191        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.backingStoreSize, internalSize());
    192192        CGContextDrawImage(context.get(), FloatRect(FloatPoint::zero(), imageSizeInUserSpace), image.get());
    193193        image = adoptCF(CGBitmapContextCreateImage(context.get()));
     
    214214        switch (copyBehavior) {
    215215        case DontCopyBackingStore:
    216             image = adoptCF(CGImageCreate(m_data.m_backingStoreSize.width(), m_data.m_backingStoreSize.height(), 8, 32, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo, m_data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault));
     216            image = adoptCF(CGImageCreate(m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, 32, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo, m_data.dataProvider.get(), 0, true, kCGRenderingIntentDefault));
    217217            break;
    218218        case CopyBackingStore:
     
    226226#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    227227    else
    228         image = m_data.m_surface->createImage();
     228        image = m_data.surface->createImage();
    229229#endif
    230230
     
    245245    FloatRect adjustedSrcRect = srcRect;
    246246    adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale);
    247     destContext->drawNativeImage(image.get(), m_data.m_backingStoreSize, colorSpace, destRect, adjustedSrcRect, op, blendMode);
     247    destContext->drawNativeImage(image.get(), m_data.backingStoreSize, colorSpace, destRect, adjustedSrcRect, op, blendMode);
    248248}
    249249
     
    269269void ImageBuffer::clip(GraphicsContext* contextToClip, const FloatRect& rect) const
    270270{
    271     FloatSize backingStoreSizeInUserSpace = scaleSizeToUserSpace(rect.size(), m_data.m_backingStoreSize, internalSize());
     271    FloatSize backingStoreSizeInUserSpace = scaleSizeToUserSpace(rect.size(), m_data.backingStoreSize, internalSize());
    272272
    273273    CGContextRef platformContextToClip = contextToClip->platformContext();
     
    343343
    344344    // Draw the image in CG coordinate space
    345     FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.m_backingStoreSize, internalSize());
     345    FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.backingStoreSize, internalSize());
    346346    IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), scaledDestSize.height() - (destPoint.y() + sourceRect.y()) - sourceRect.height());
    347347    IntRect destRectInCGCoords(destPointInCGCoords, sourceCopySize);
     
    462462        CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
    463463        CGContextClipToRect(context.get(), CGRectMake(0, 0, logicalSize().width(), logicalSize().height()));
    464         FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
     464        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.backingStoreSize, internalSize());
    465465        CGContextDrawImage(context.get(), CGRectMake(0, 0, imageSizeInUserSpace.width(), imageSizeInUserSpace.height()), image.get());
    466466        image = adoptCF(CGBitmapContextCreateImage(context.get()));
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp

    r180342 r181301  
    3838#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    3939#include "IOSurface.h"
     40#include "IOSurfacePool.h"
    4041#include "IOSurfaceSPI.h"
    4142#include <dispatch/dispatch.h>
     
    5758namespace WebCore {
    5859
    59 ImageBufferData::ImageBufferData()
    60     : m_data(nullptr)
     60ImageBufferData::~ImageBufferData()
     61{
    6162#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    62     , m_surface(nullptr)
    63 #endif
    64 {
     63    if (surface)
     64        IOSurfacePool::sharedPool().addSurface(WTF::move(surface));
     65#endif
    6566}
    6667
     
    118119
    119120    RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(area.unsafeGet());
    120     unsigned char* data = result->data();
     121    unsigned char* resultData = result->data();
    121122   
    122123    Checked<int> endx = rect.maxX();
     
    159160   
    160161    unsigned destBytesPerRow = 4 * rect.width();
    161     unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
     162    unsigned char* destRows = resultData + desty * destBytesPerRow + destx * 4;
    162163   
    163164    unsigned srcBytesPerRow;
     
    165166   
    166167    if (!accelerateRendering) {
    167         srcBytesPerRow = m_bytesPerRow.unsafeGet();
    168         srcRows = reinterpret_cast<unsigned char*>(m_data) + originy * srcBytesPerRow + originx * 4;
     168        srcBytesPerRow = bytesPerRow.unsafeGet();
     169        srcRows = reinterpret_cast<unsigned char*>(data) + originy * srcBytesPerRow + originx * 4;
    169170       
    170171#if USE(ACCELERATE)
     
    206207#endif
    207208        if (resolutionScale != 1) {
    208             RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     209            RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    209210            RetainPtr<CGImageRef> sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
    210             RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     211            RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    211212            CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
    212213            CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
     
    273274#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    274275        // FIXME: WebCore::IOSurface should have a locking RAII object and base-address getter.
    275         IOSurfaceRef surface = m_surface->surface();
    276         IOSurfaceLock(surface, kIOSurfaceLockReadOnly, 0);
    277         srcBytesPerRow = IOSurfaceGetBytesPerRow(surface);
    278         srcRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + originy * srcBytesPerRow + originx * 4;
     276        IOSurfaceRef surfaceRef = surface->surface();
     277        IOSurfaceLock(surfaceRef, kIOSurfaceLockReadOnly, nullptr);
     278        srcBytesPerRow = IOSurfaceGetBytesPerRow(surfaceRef);
     279        srcRows = static_cast<unsigned char*>(IOSurfaceGetBaseAddress(surfaceRef)) + originy * srcBytesPerRow + originx * 4;
    279280
    280281#if USE(ACCELERATE)
     
    321322#else
    322323        if (resolutionScale != 1) {
    323             RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     324            RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    324325            RetainPtr<CGImageRef> sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
    325             RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     326            RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    326327            CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
    327328            CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
     
    372373        }
    373374#endif // USE(ACCELERATE)
    374         IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, 0);
     375        IOSurfaceUnlock(surfaceRef, kIOSurfaceLockReadOnly, nullptr);
    375376#else
    376377        ASSERT_NOT_REACHED();
     
    429430   
    430431    if (!accelerateRendering) {
    431         destBytesPerRow = m_bytesPerRow.unsafeGet();
    432         destRows = reinterpret_cast<unsigned char*>(m_data) + (desty * destBytesPerRow + destx * 4).unsafeGet();
     432        destBytesPerRow = bytesPerRow.unsafeGet();
     433        destRows = reinterpret_cast<unsigned char*>(data) + (desty * destBytesPerRow + destx * 4).unsafeGet();
    433434       
    434435#if  USE(ACCELERATE)
     
    471472#endif
    472473        if (resolutionScale != 1) {
    473             RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     474            RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    474475            RetainPtr<CGImageRef> sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
    475             RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     476            RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    476477            CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
    477478            CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
     
    517518    } else {
    518519#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    519         IOSurfaceRef surface = m_surface->surface();
    520         IOSurfaceLock(surface, 0, 0);
    521         destBytesPerRow = IOSurfaceGetBytesPerRow(surface);
    522         destRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + (desty * destBytesPerRow + destx * 4).unsafeGet();
     520        IOSurfaceRef surfaceRef = surface->surface();
     521        IOSurfaceLock(surfaceRef, 0, nullptr);
     522        destBytesPerRow = IOSurfaceGetBytesPerRow(surfaceRef);
     523        destRows = static_cast<unsigned char*>(IOSurfaceGetBaseAddress(surfaceRef)) + (desty * destBytesPerRow + destx * 4).unsafeGet();
    523524
    524525#if USE(ACCELERATE)
     
    565566#else
    566567        if (resolutionScale != 1) {
    567             RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     568            RetainPtr<CGContextRef> sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    568569            RetainPtr<CGImageRef> sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
    569             RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
     570            RetainPtr<CGContextRef> destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
    570571            CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
    571572            CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
     
    599600#endif // USE(ACCELERATE)
    600601
    601         IOSurfaceUnlock(surface, 0, 0);
     602        IOSurfaceUnlock(surfaceRef, 0, nullptr);
    602603#else
    603604        ASSERT_NOT_REACHED();
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h

    r180342 r181301  
    4747class IntSize;
    4848
    49 class ImageBufferData {
    50 public:
    51     ImageBufferData();
     49struct ImageBufferData {
     50    ~ImageBufferData();
    5251
    53     IntSize m_backingStoreSize;
    54     Checked<unsigned, RecordOverflow> m_bytesPerRow;
    55     CGColorSpaceRef m_colorSpace;
     52    IntSize backingStoreSize;
     53    Checked<unsigned, RecordOverflow> bytesPerRow;
     54    CGColorSpaceRef colorSpace;
    5655
    5756    // Only for Software ImageBuffers.
    58     void* m_data;
    59     RetainPtr<CGDataProviderRef> m_dataProvider;
    60     CGBitmapInfo m_bitmapInfo;
    61     OwnPtr<GraphicsContext> m_context;
     57    void* data { nullptr };
     58    RetainPtr<CGDataProviderRef> dataProvider;
     59    CGBitmapInfo bitmapInfo;
     60    OwnPtr<GraphicsContext> context;
    6261
    6362#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    6463    // Only for Accelerated ImageBuffers.
    65     std::unique_ptr<IOSurface> m_surface;
     64    std::unique_ptr<IOSurface> surface;
    6665#endif
    6766
  • trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h

    r180308 r181301  
    8686    IOSurface(IOSurfaceRef, ColorSpace);
    8787
     88    static std::unique_ptr<IOSurface> surfaceFromPool(IntSize, IntSize contextSize, ColorSpace);
     89    IntSize contextSize() const { return m_contextSize; }
     90    void setContextSize(IntSize);
     91
    8892    ColorSpace m_colorSpace;
    8993    IntSize m_size;
  • trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm

    r180308 r181301  
    4242using namespace WebCore;
    4343
     44inline std::unique_ptr<IOSurface> IOSurface::surfaceFromPool(IntSize size, IntSize contextSize, ColorSpace colorSpace)
     45{
     46    auto cachedSurface = IOSurfacePool::sharedPool().takeSurface(size, colorSpace);
     47    if (!cachedSurface)
     48        return nullptr;
     49
     50    cachedSurface->setContextSize(contextSize);
     51    return cachedSurface;
     52}
     53
    4454std::unique_ptr<IOSurface> IOSurface::create(IntSize size, ColorSpace colorSpace)
    4555{
    46     if (std::unique_ptr<IOSurface> cachedSurface = IOSurfacePool::sharedPool().takeSurface(size, colorSpace))
     56    if (auto cachedSurface = surfaceFromPool(size, size, colorSpace))
    4757        return cachedSurface;
    4858    return std::unique_ptr<IOSurface>(new IOSurface(size, colorSpace));
     
    5161std::unique_ptr<IOSurface> IOSurface::create(IntSize size, IntSize contextSize, ColorSpace colorSpace)
    5262{
    53     // FIXME: We should be able to pull surfaces out of the IOSurfacePool and adjust their contextSize.
     63    if (auto cachedSurface = surfaceFromPool(size, contextSize, colorSpace))
     64        return cachedSurface;
    5465    return std::unique_ptr<IOSurface>(new IOSurface(size, contextSize, colorSpace));
    5566}
     
    5768std::unique_ptr<IOSurface> IOSurface::createFromSendRight(const MachSendRight& sendRight, ColorSpace colorSpace)
    5869{
    59     RetainPtr<IOSurfaceRef> surface = adoptCF(IOSurfaceLookupFromMachPort(sendRight.sendRight()));
     70    auto surface = adoptCF(IOSurfaceLookupFromMachPort(sendRight.sendRight()));
    6071    return IOSurface::createFromSurface(surface.get(), colorSpace);
    6172}
     
    7485    size_t height = CGImageGetHeight(image);
    7586
    76     std::unique_ptr<IOSurface> surface = IOSurface::create(IntSize(width, height), ColorSpaceDeviceRGB);
     87    auto surface = IOSurface::create(IntSize(width, height), ColorSpaceDeviceRGB);
    7788    auto surfaceContext = surface->ensurePlatformContext();
    7889    CGContextDrawImage(surfaceContext, CGRectMake(0, 0, width, height), image);
     
    144155}
    145156
     157void IOSurface::setContextSize(IntSize contextSize)
     158{
     159    if (contextSize == m_contextSize)
     160        return;
     161
     162    // Release the graphics context and update the context size. Next time the graphics context is
     163    // accessed, we will construct it again with the right size.
     164    releaseGraphicsContext();
     165    m_contextSize = contextSize;
     166}
     167
    146168CGContextRef IOSurface::ensurePlatformContext()
    147169{
Note: See TracChangeset for help on using the changeset viewer.