Diff
Modified: trunk/LayoutTests/ChangeLog (160120 => 160121)
--- trunk/LayoutTests/ChangeLog 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/LayoutTests/ChangeLog 2013-12-04 21:35:38 UTC (rev 160121)
@@ -1,3 +1,23 @@
+2013-12-04 Myles C. Maxfield <[email protected]>
+
+ Allow ImageBuffer to use an IOSurface that is larger than necessary
+ https://bugs.webkit.org/show_bug.cgi?id=124626
+
+ Reviewed by Simon Fraser.
+
+ Update tests to be more robust with respect to accelerated vs
+ non-accelerated ImageBuffers.
+
+ * fast/canvas/script-tests/canvas-fillPath-shadow.js: Don't sample a canvas at exactly
+ the corner of a drawn shape (because the corner might be antialiased). Instead, sample
+ a single pixel inside the shape
+ * fast/canvas/script-tests/canvas-scale-shadowBlur.js: Don't sample a canvas at exactly
+ the edge of the blur radius. Instead, sample a single pixel past the blur radius.
+ * fast/canvas/script-tests/canvas-scale-strokePath-shadow.js:
+ (shouldBeAround): Allow this test to be less strict when sampling inside a blurred region
+ * platform/mac/fast/canvas/canvas-scale-shadowBlur-expected.txt: Matching update w/r/t
+ canvas-scale-shadowBlur.js
+
2013-12-03 Dean Jackson <[email protected]>
[WebGL] Support for texImage2D/texSubImage2D of type HALF_FLOAT_OES
Modified: trunk/LayoutTests/fast/canvas/script-tests/canvas-fillPath-shadow.js (160120 => 160121)
--- trunk/LayoutTests/fast/canvas/script-tests/canvas-fillPath-shadow.js 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/LayoutTests/fast/canvas/script-tests/canvas-fillPath-shadow.js 2013-12-04 21:35:38 UTC (rev 160121)
@@ -70,7 +70,7 @@
shouldBe('data[1]', '20');
shouldBe('data[2]', '0');
-imageData = ctx.getImageData(380, 30, 1, 1);
+imageData = ctx.getImageData(381, 31, 1, 1);
data = ""
shouldBe('data[0]', '255');
shouldBe('data[1]', '20');
Modified: trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-shadowBlur.js (160120 => 160121)
--- trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-shadowBlur.js 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-shadowBlur.js 2013-12-04 21:35:38 UTC (rev 160121)
@@ -67,7 +67,7 @@
shouldBe('d[2]', '0');
shouldBeAround('d[3]', '255');
-d = ctx.getImageData(250, 175, 1, 1).data;
+d = ctx.getImageData(250, 174, 1, 1).data;
shouldBe('d[0]', '0');
shouldBe('d[1]', '0');
shouldBe('d[2]', '0');
@@ -79,7 +79,7 @@
shouldBe('d[2]', '0');
shouldBe('d[3]', '0');
-d = ctx.getImageData(175, 250, 1, 1).data;
+d = ctx.getImageData(174, 250, 1, 1).data;
shouldBe('d[0]', '0');
shouldBe('d[1]', '0');
shouldBe('d[2]', '0');
@@ -135,7 +135,7 @@
shouldBe('d[2]', '0');
shouldBeAround('d[3]', '255');
-d = ctx.getImageData(450, 175, 1, 1).data;
+d = ctx.getImageData(450, 174, 1, 1).data;
shouldBe('d[0]', '0');
shouldBe('d[1]', '0');
shouldBe('d[2]', '0');
@@ -147,7 +147,7 @@
shouldBe('d[2]', '0');
shouldBe('d[3]', '0');
-d = ctx.getImageData(375, 250, 1, 1).data;
+d = ctx.getImageData(374, 250, 1, 1).data;
shouldBe('d[0]', '0');
shouldBe('d[1]', '0');
shouldBe('d[2]', '0');
Modified: trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-strokePath-shadow.js (160120 => 160121)
--- trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-strokePath-shadow.js 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-strokePath-shadow.js 2013-12-04 21:35:38 UTC (rev 160121)
@@ -10,7 +10,7 @@
document.getElementById("console").appendChild(paragraph);
}
-function shouldBeAround(a, b)
+function shouldBeAround(a, b, argdelta)
{
var evalA;
try {
@@ -19,7 +19,11 @@
evalA = e;
}
- if (Math.abs(evalA - b) < 20)
+ var delta = 20;
+ if (typeof argdelta != "undefined")
+ delta = argdelta;
+
+ if (Math.abs(evalA - b) < delta)
print("PASS " + a + " is around " + b , "green")
else
print("FAIL " + a + " is not around " + b + " (actual: " + evalA + ")", "red");
@@ -119,7 +123,7 @@
shouldBe('d[0]', '255');
shouldBe('d[1]', '0');
shouldBe('d[2]', '0');
-shouldBeAround('d[3]', '200');
+shouldBeAround('d[3]', '200', 25);
d = ctx.getImageData(508, 250, 1, 1).data;
shouldBe('d[0]', '255');
@@ -131,7 +135,7 @@
shouldBe('d[0]', '255');
shouldBe('d[1]', '0');
shouldBe('d[2]', '0');
-shouldBeAround('d[3]', '199');
+shouldBeAround('d[3]', '199', 25);
// Verify blurry alpha shadow.
d = ctx.getImageData(505, 450, 1, 1).data;
Modified: trunk/LayoutTests/platform/mac/fast/canvas/canvas-scale-shadowBlur-expected.txt (160120 => 160121)
--- trunk/LayoutTests/platform/mac/fast/canvas/canvas-scale-shadowBlur-expected.txt 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/LayoutTests/platform/mac/fast/canvas/canvas-scale-shadowBlur-expected.txt 2013-12-04 21:35:38 UTC (rev 160121)
@@ -10,7 +10,7 @@
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
-FAIL d[3] should be 0. Was 6.
+FAIL d[3] should be 0. Was 5.
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
@@ -18,7 +18,7 @@
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
-FAIL d[3] should be 0. Was 6.
+FAIL d[3] should be 0. Was 5.
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
@@ -54,7 +54,7 @@
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
-FAIL d[3] should be 0. Was 6.
+FAIL d[3] should be 0. Was 5.
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
@@ -62,7 +62,7 @@
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
-FAIL d[3] should be 0. Was 6.
+FAIL d[3] should be 0. Was 5.
FAIL d[0] should be 0. Was 255.
PASS d[1] is 0
PASS d[2] is 0
Modified: trunk/Source/WebCore/ChangeLog (160120 => 160121)
--- trunk/Source/WebCore/ChangeLog 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/Source/WebCore/ChangeLog 2013-12-04 21:35:38 UTC (rev 160121)
@@ -1,3 +1,42 @@
+2013-12-04 Myles C. Maxfield <[email protected]>
+
+ Allow ImageBuffer to use an IOSurface that is larger than necessary
+ https://bugs.webkit.org/show_bug.cgi?id=124626
+
+ Reviewed by Simon Fraser.
+
+ Because creating ImageBuffer's backing store can be so expensive, it
+ would be beneficial to have a pool of pre-created backing stores
+ available. However, this means that ImageBuffer might have to use a
+ backing store that is larger than the exact dimensions that it needs.
+ This patch adds a field, m_backingStoreSize, to CG's ImageBufferData
+ class, and uses this new field when performing ImageBuffer operations
+ to allow for larger-than-necessary backing stores. Content is always
+ drawn in the top left corner of the backing store.
+
+ No new tests are necessary because there is no behavior change.
+
+ * platform/graphics/ImageBuffer.h:
+ (WebCore::ImageBuffer::baseTransform): The base transform has to put
+ content at the top left corner instead of bottom left
+ * platform/graphics/cg/ImageBufferCG.cpp:
+ (WebCore::createCroppedImageIfNecessary): Convenience function to figure out
+ the dimensions of the backing texture in user space
+ (WebCore::ImageBuffer::ImageBuffer): Set up new m_backingStoreSize member
+ (WebCore::maybeCropToBounds): Some ImageBuffer API functions require
+ outputting an image with logical size. This function performs the cropping
+ (WebCore::ImageBuffer::copyImage): Updated for larger-than-necessary
+ backing stores
+ (WebCore::ImageBuffer::copyNativeImage): Ditto
+ (WebCore::ImageBuffer::draw): Ditto
+ (WebCore::ImageBuffer::clip): Ditto
+ (WebCore::ImageBuffer::putByteArray): Ditto
+ (WebCore::ImageBuffer::toDataURL): Ditto
+ * platform/graphics/cg/ImageBufferDataCG.cpp:
+ (WebCore::ImageBufferData::getData): Ditto
+ (WebCore::ImageBufferData::putData): Ditto
+ * platform/graphics/cg/ImageBufferDataCG.h: New m_backingStoreSize field
+
2013-12-03 Dean Jackson <[email protected]>
[WebGL] Support for texImage2D of type HALF_FLOAT_OES
Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (160120 => 160121)
--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h 2013-12-04 21:35:38 UTC (rev 160121)
@@ -117,7 +117,7 @@
void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace);
void platformTransformColorSpace(const Vector<int>&);
#else
- AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, internalSize().height()); }
+ AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.m_backingStoreSize.height()); }
#endif
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
@@ -135,6 +135,8 @@
private:
#if USE(CG)
+ // The returned image might be larger than the internalSize(). If you want the smaller
+ // image, crop the result.
RetainPtr<CGImageRef> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
void flushContext() const;
#endif
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (160120 => 160121)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp 2013-12-04 21:35:38 UTC (rev 160121)
@@ -98,6 +98,13 @@
fastFree(const_cast<void*>(data));
}
+static FloatSize scaleSizeToUserSpace(const FloatSize& logicalSize, const IntSize& backingStoreSize, const IntSize& internalSize)
+{
+ float xMagnification = static_cast<float>(backingStoreSize.width()) / internalSize.width();
+ float yMagnification = static_cast<float>(backingStoreSize.height()) / internalSize.height();
+ return FloatSize(logicalSize.width() * xMagnification, logicalSize.height() * yMagnification);
+}
+
ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace imageColorSpace, RenderingMode renderingMode, bool& success)
: m_data(size) // NOTE: The input here isn't important as ImageBufferDataCG's constructor just ignores it.
, m_logicalSize(size)
@@ -111,6 +118,7 @@
return;
m_size = IntSize(scaledWidth, scaledHeight);
+ m_data.m_backingStoreSize = m_size;
success = false; // Make early return mean failure.
bool accelerateRendering = renderingMode == Accelerated;
@@ -121,8 +129,8 @@
Checked<int, RecordOverflow> height = m_size.height();
// Prevent integer overflows
- m_data.m_bytesPerRow = 4 * width;
- Checked<size_t, RecordOverflow> numBytes = height * m_data.m_bytesPerRow;
+ m_data.m_bytesPerRow = 4 * Checked<unsigned, RecordOverflow>(m_data.m_backingStoreSize.width());
+ Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.m_backingStoreSize.height()) * m_data.m_bytesPerRow;
if (numBytes.hasOverflowed())
return;
@@ -148,20 +156,21 @@
RetainPtr<CGContextRef> cgContext;
if (accelerateRendering) {
#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- m_data.m_surface = createIOSurface(m_size);
- cgContext = adoptCF(wkIOSurfaceContextCreate(m_data.m_surface.get(), width.unsafeGet(), height.unsafeGet(), m_data.m_colorSpace));
+ m_data.m_surface = createIOSurface(m_data.m_backingStoreSize);
+ FloatSize userBounds = scaleSizeToUserSpace(FloatSize(width.unsafeGet(), height.unsafeGet()), m_data.m_backingStoreSize, m_size);
+ cgContext = adoptCF(wkIOSurfaceContextCreate(m_data.m_surface.get(), userBounds.width(), userBounds.height(), m_data.m_colorSpace));
#endif
if (!cgContext)
accelerateRendering = false; // If allocation fails, fall back to non-accelerated path.
}
if (!accelerateRendering) {
- if (!tryFastCalloc(height.unsafeGet(), m_data.m_bytesPerRow.unsafeGet()).getValue(m_data.m_data))
+ if (!tryFastCalloc(m_data.m_backingStoreSize.height(), m_data.m_bytesPerRow.unsafeGet()).getValue(m_data.m_data))
return;
ASSERT(!(reinterpret_cast<intptr_t>(m_data.m_data) & 3));
m_data.m_bitmapInfo = kCGImageAlphaPremultipliedLast;
- cgContext = adoptCF(CGBitmapContextCreate(m_data.m_data, width.unsafeGet(), height.unsafeGet(), 8, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo));
+ 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));
// Create a live image that wraps the data.
m_data.m_dataProvider = adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, numBytes.unsafeGet(), releaseImageData));
}
@@ -170,9 +179,9 @@
return;
m_context = adoptPtr(new GraphicsContext(cgContext.get()));
+ m_context->scale(FloatSize(1, -1));
+ m_context->translate(0, -m_data.m_backingStoreSize.height());
m_context->applyDeviceScaleFactor(m_resolutionScale);
- m_context->scale(FloatSize(1, -1));
- m_context->translate(0, -size.height());
m_context->setIsAcceleratedContext(accelerateRendering);
success = true;
}
@@ -191,6 +200,15 @@
CGContextFlush(m_context->platformContext());
}
+static RetainPtr<CGImageRef> createCroppedImageIfNecessary(CGImageRef image, const IntSize& bounds)
+{
+ if (image && (CGImageGetWidth(image) != static_cast<size_t>(bounds.width())
+ || CGImageGetHeight(image) != static_cast<size_t>(bounds.height()))) {
+ return adoptCF(CGImageCreateWithImageInRect(image, CGRectMake(0, static_cast<int>(CGImageGetHeight(image)) - bounds.height(), bounds.width(), bounds.height())));
+ }
+ return image;
+}
+
PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBehavior scaleBehavior) const
{
RetainPtr<CGImageRef> image;
@@ -200,13 +218,18 @@
image = copyNativeImage(DontCopyBackingStore);
RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(0, logicalSize().width(), logicalSize().height(), 8, 4 * logicalSize().width(), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast));
CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
- CGContextDrawImage(context.get(), CGRectMake(0, 0, logicalSize().width(), logicalSize().height()), image.get());
+ CGContextDrawImage(context.get(), CGRectMake(0, 0, m_data.m_backingStoreSize.width(), m_data.m_backingStoreSize.height()), image.get());
image = adoptCF(CGBitmapContextCreateImage(context.get()));
}
+
+ image = createCroppedImageIfNecessary(image.get(), internalSize());
if (!image)
return 0;
+ ASSERT(CGImageGetWidth(image.get()) == static_cast<size_t>(m_logicalSize.width()));
+ ASSERT(CGImageGetHeight(image.get()) == static_cast<size_t>(m_logicalSize.height()));
+
RefPtr<BitmapImage> bitmapImage = BitmapImage::create(image.get());
bitmapImage->setSpaceSize(spaceSize());
@@ -224,7 +247,7 @@
if (!m_context->isAcceleratedContext()) {
switch (copyBehavior) {
case DontCopyBackingStore:
- image = CGImageCreate(internalSize().width(), internalSize().height(), 8, 32, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo, m_data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault);
+ image = 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);
break;
case CopyBackingStore:
image = CGBitmapContextCreateImage(context()->platformContext());
@@ -279,12 +302,15 @@
void ImageBuffer::clip(GraphicsContext* contextToClip, const FloatRect& rect) const
{
+ FloatSize backingStoreSizeInUserSpace = scaleSizeToUserSpace(rect.size(), m_data.m_backingStoreSize, internalSize());
+
CGContextRef platformContextToClip = contextToClip->platformContext();
// FIXME: This image needs to be grayscale to be used as an alpha mask here.
RetainPtr<CGImageRef> image = copyNativeImage(DontCopyBackingStore);
- CGContextTranslateCTM(platformContextToClip, rect.x(), rect.y() + rect.height());
+ CGContextTranslateCTM(platformContextToClip, rect.x(), rect.y() + backingStoreSizeInUserSpace.height());
CGContextScaleCTM(platformContextToClip, 1, -1);
- CGContextClipToMask(platformContextToClip, FloatRect(FloatPoint(), rect.size()), image.get());
+ CGContextClipToRect(platformContextToClip, FloatRect(FloatPoint(0, backingStoreSizeInUserSpace.height() - rect.height()), rect.size()));
+ CGContextClipToMask(platformContextToClip, FloatRect(FloatPoint(), backingStoreSizeInUserSpace), image.get());
CGContextScaleCTM(platformContextToClip, 1, -1);
CGContextTranslateCTM(platformContextToClip, -rect.x(), -rect.y() - rect.height());
}
@@ -335,10 +361,14 @@
CGContextSetShadowWithColor(destContext, CGSizeZero, 0, 0);
// Draw the image in CG coordinate space
- IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), (coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize()).height() - (destPoint.y() + sourceRect.y()) - sourceRect.height());
+ FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.m_backingStoreSize, internalSize());
+ IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), scaledDestSize.height() - (destPoint.y() + sourceRect.y()) - sourceRect.height());
IntRect destRectInCGCoords(destPointInCGCoords, sourceCopySize);
+ CGContextClipToRect(destContext, destRectInCGCoords);
+
RetainPtr<CGImageRef> sourceCopyImage = sourceCopy->copyNativeImage();
- CGContextDrawImage(destContext, destRectInCGCoords, sourceCopyImage.get());
+ FloatRect backingStoreInDestRect = FloatRect(FloatPoint(destPointInCGCoords.x(), destPointInCGCoords.y() + sourceCopySize.height() - (int)CGImageGetHeight(sourceCopyImage.get())), FloatSize(CGImageGetWidth(sourceCopyImage.get()), CGImageGetHeight(sourceCopyImage.get())));
+ CGContextDrawImage(destContext, backingStoreInDestRect, sourceCopyImage.get());
CGContextRestoreGState(destContext);
#endif
}
@@ -442,13 +472,16 @@
image = adoptCF(CGImageCreate(logicalSize().width(), logicalSize().height(), 8, 32, 4 * logicalSize().width(),
deviceRGBColorSpaceRef(), kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast,
dataProvider.get(), 0, false, kCGRenderingIntentDefault));
- } else if (m_resolutionScale == 1)
+ } else if (m_resolutionScale == 1) {
image = copyNativeImage(CopyBackingStore);
- else {
+ image = createCroppedImageIfNecessary(image.get(), internalSize());
+ } else {
image = copyNativeImage(DontCopyBackingStore);
RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(0, logicalSize().width(), logicalSize().height(), 8, 4 * logicalSize().width(), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast));
CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
- CGContextDrawImage(context.get(), CGRectMake(0, 0, logicalSize().width(), logicalSize().height()), image.get());
+ CGContextClipToRect(context.get(), CGRectMake(0, 0, logicalSize().width(), logicalSize().height()));
+ FloatSize imageRectInUserBounds = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
+ CGContextDrawImage(context.get(), CGRectMake(0, 0, imageRectInUserBounds.width(), imageRectInUserBounds.height()), image.get());
image = adoptCF(CGBitmapContextCreateImage(context.get()));
}
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp (160120 => 160121)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp 2013-12-04 21:35:38 UTC (rev 160121)
@@ -158,7 +158,7 @@
unsigned char* srcRows;
if (!accelerateRendering) {
- srcBytesPerRow = 4 * size.width();
+ srcBytesPerRow = m_bytesPerRow.unsafeGet();
srcRows = reinterpret_cast<unsigned char*>(m_data) + originy * srcBytesPerRow + originx * 4;
#if USE(ACCELERATE)
@@ -339,6 +339,10 @@
void ImageBufferData::putData(Uint8ClampedArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool accelerateRendering, bool unmultiplied, float resolutionScale)
{
+#if ASSERT_DISABLED
+ UNUSED_PARAM(size);
+#endif
+
ASSERT(sourceRect.width() > 0);
ASSERT(sourceRect.height() > 0);
@@ -381,7 +385,7 @@
unsigned char* destRows;
if (!accelerateRendering) {
- destBytesPerRow = 4 * size.width();
+ destBytesPerRow = m_bytesPerRow.unsafeGet();
destRows = reinterpret_cast<unsigned char*>(m_data) + (desty * destBytesPerRow + destx * 4).unsafeGet();
#if USE(ACCELERATE)
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h (160120 => 160121)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h 2013-12-04 21:29:45 UTC (rev 160120)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h 2013-12-04 21:35:38 UTC (rev 160121)
@@ -54,6 +54,7 @@
Checked<unsigned, RecordOverflow> m_bytesPerRow;
CGColorSpaceRef m_colorSpace;
RetainPtr<IOSurfaceRef> m_surface;
+ IntSize m_backingStoreSize;
PassRefPtr<Uint8ClampedArray> getData(const IntRect&, const IntSize&, bool accelerateRendering, bool unmultiplied, float resolutionScale) const;
void putData(Uint8ClampedArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering, bool unmultiplied, float resolutionScale);