Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (102264 => 102265)
--- trunk/LayoutTests/platform/chromium/test_expectations.txt 2011-12-07 20:03:50 UTC (rev 102264)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt 2011-12-07 20:08:00 UTC (rev 102265)
@@ -2653,12 +2653,6 @@
// GPU
//
-// This test expects that putImageData followed by getImageData at the same location
-// will return the exact same pixel values. However, the spec allows some fuzziness
-// due to conversion to/from premultiplied-alpha. When we do the conversions on the
-// GPU we may be off by one in r, g, and/or b.
-BUGWK73952 GPU : canvas/philip/tests/2d.imageData.put.unchanged.html = TEXT
-
// Will need windows and linux baselines
BUGWK47923 : compositing/geometry/limit-layer-bounds-opacity-transition.html = TIMEOUT
Modified: trunk/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp (102264 => 102265)
--- trunk/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp 2011-12-07 20:03:50 UTC (rev 102264)
+++ trunk/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp 2011-12-07 20:08:00 UTC (rev 102265)
@@ -292,7 +292,7 @@
template <Multiply multiplied>
void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint,
- SkCanvas* canvas, const IntSize& size)
+ SkDevice* dstDevice, const IntSize& size)
{
ASSERT(sourceRect.width() > 0);
ASSERT(sourceRect.height() > 0);
@@ -321,27 +321,52 @@
int numRows = endY - destY;
unsigned srcBytesPerRow = 4 * sourceSize.width();
- SkBitmap srcBitmap;
- srcBitmap.setConfig(SkBitmap::kARGB_8888_Config, numColumns, numRows, srcBytesPerRow);
- srcBitmap.setPixels(source->data() + originY * srcBytesPerRow + originX * 4);
- SkCanvas::Config8888 config8888;
- if (multiplied == Premultiplied)
- config8888 = SkCanvas::kRGBA_Premul_Config8888;
- else
- config8888 = SkCanvas::kRGBA_Unpremul_Config8888;
+ SkBitmap deviceBitmap = dstDevice->accessBitmap(true);
- canvas->writePixels(srcBitmap, destX, destY, config8888);
+ // If the device's bitmap doesn't have pixels we will make a temp and call writePixels on the device.
+ bool temporaryBitmap = !!deviceBitmap.getTexture();
+ SkBitmap destBitmap;
+
+ if (temporaryBitmap) {
+ destBitmap.setConfig(SkBitmap::kARGB_8888_Config, numColumns, numRows, srcBytesPerRow);
+ if (!destBitmap.allocPixels())
+ CRASH();
+ } else
+ deviceBitmap.extractSubset(&destBitmap, SkIRect::MakeXYWH(destX, destY, numColumns, numRows));
+
+ // Whether we made a temporary or not destBitmap is always configured to be written at 0,0
+ SkAutoLockPixels destAutoLock(destBitmap);
+ const unsigned char* srcRow = source->data() + originY * srcBytesPerRow + originX * 4;
+ for (int y = 0; y < numRows; ++y) {
+ SkPMColor* destRow = destBitmap.getAddr32(0, y);
+ for (int x = 0; x < numColumns; ++x) {
+ const unsigned char* srcPixel = &srcRow[x * 4];
+ if (multiplied == Unmultiplied) {
+ unsigned char alpha = srcPixel[3];
+ unsigned char r = SkMulDiv255Ceiling(srcPixel[0], alpha);
+ unsigned char g = SkMulDiv255Ceiling(srcPixel[1], alpha);
+ unsigned char b = SkMulDiv255Ceiling(srcPixel[2], alpha);
+ destRow[x] = SkPackARGB32(alpha, r, g, b);
+ } else
+ destRow[x] = SkPackARGB32NoCheck(srcPixel[3], srcPixel[0], srcPixel[1], srcPixel[2]);
+ }
+ srcRow += srcBytesPerRow;
+ }
+
+ // If we used a temporary then write it to the device
+ if (temporaryBitmap)
+ dstDevice->writePixels(destBitmap, destX, destY);
}
void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
- putImageData<Unmultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas(), m_size);
+ putImageData<Unmultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas()->getDevice(), m_size);
}
void ImageBuffer::putPremultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
- putImageData<Premultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas(), m_size);
+ putImageData<Premultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas()->getDevice(), m_size);
}
template <typename T>