Source/WebCore: [CHROMIUM/SKIA] Handle put[Un/Pre]multipliedImageData conversions...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Dec 2011 18:08:25 +0000 (18:08 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Dec 2011 18:08:25 +0000 (18:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=73953

Patch by Brian Salomon <bsalomon@google.com> on 2011-12-07
Reviewed by Stephen White.

Tested by existing canvas2d layout tests.

* platform/graphics/skia/ImageBufferSkia.cpp:
(WebCore::putImageData):
(WebCore::ImageBuffer::putUnmultipliedImageData):
(WebCore::ImageBuffer::putPremultipliedImageData):

LayoutTests: [CHROMIUM] Make canvas/philip/tests/2d.imageData.put.unchanged.html be expected to fail
on the GPU due to slight difference in alpha-premul computation.

https://bugs.webkit.org/show_bug.cgi?id=73953

Patch by Brian Salomon <bsalomon@google.com> on 2011-12-07
Reviewed by Stephen White.

* platform/chromium/test_expectations.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@102244 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/platform/chromium/test_expectations.txt
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp

index 0accb46..5fc2101 100644 (file)
@@ -1,3 +1,14 @@
+2011-12-07  Brian Salomon  <bsalomon@google.com>
+
+        [CHROMIUM] Make canvas/philip/tests/2d.imageData.put.unchanged.html be expected to fail
+        on the GPU due to slight difference in alpha-premul computation.
+
+        https://bugs.webkit.org/show_bug.cgi?id=73953
+
+        Reviewed by Stephen White.
+
+        * platform/chromium/test_expectations.txt:
+
 2011-12-07  Balazs Kelemen  <kbalazs@webkit.org>
 
         [Qt][WK2] REGRESSION(102228): lot of test failures after enabled page cache
index f0059d9..fffc67a 100644 (file)
@@ -2653,6 +2653,12 @@ BUGCR71783 : scrollbars/custom-scrollbar-with-incomplete-style.html = IMAGE
 // 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
index fb267bf..d3f9f2f 100644 (file)
@@ -1,3 +1,17 @@
+2011-12-07  Brian Salomon  <bsalomon@google.com>
+
+        [CHROMIUM/SKIA] Handle put[Un/Pre]multipliedImageData conversions in Skia rather than ImageBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=73953
+
+        Reviewed by Stephen White.
+
+        Tested by existing canvas2d layout tests.
+
+        * platform/graphics/skia/ImageBufferSkia.cpp:
+        (WebCore::putImageData):
+        (WebCore::ImageBuffer::putUnmultipliedImageData):
+        (WebCore::ImageBuffer::putPremultipliedImageData):
+
 2011-12-07  Andreas Kling  <kling@webkit.org>
 
         Micro-optimize ScrollView::visibleContentRect().
index 2845099..9b10c48 100644 (file)
@@ -292,7 +292,7 @@ PassRefPtr<ByteArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect
 
 template <Multiply multiplied>
 void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint,
-                  SkDevice* dstDevice, const IntSize& size)
+                  SkCanvas* canvas, const IntSize& size)
 {
     ASSERT(sourceRect.width() > 0);
     ASSERT(sourceRect.height() > 0);
@@ -321,52 +321,27 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
     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);
 
-    SkBitmap deviceBitmap = dstDevice->accessBitmap(true);
-
-    // 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;
-    }
+    SkCanvas::Config8888 config8888;
+    if (multiplied == Premultiplied)
+        config8888 = SkCanvas::kRGBA_Premul_Config8888;
+    else
+        config8888 = SkCanvas::kRGBA_Unpremul_Config8888;
 
-    // If we used a temporary then write it to the device
-    if (temporaryBitmap)
-        dstDevice->writePixels(destBitmap, destX, destY);
+    canvas->writePixels(srcBitmap, destX, destY, config8888);
 }
 
 void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
 {
-    putImageData<Unmultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas()->getDevice(), m_size);
+    putImageData<Unmultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas(), 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()->getDevice(), m_size);
+    putImageData<Premultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas(), m_size);
 }
 
 template <typename T>