Add SkCanvas::writePixels that takes info+pixels directly

add corresponding methods to device (w/ diff name to avoid colliding with exising virtuals)

BUG=skia:
R=bsalomon@google.com, robertphillips@google.com, junov@google.com, junov@chromium.org

Author: reed@google.com

Review URL: https://codereview.chromium.org/180113010

git-svn-id: http://skia.googlecode.com/svn/trunk@13697 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp
index 488d93e..68fbec8 100644
--- a/tests/PremulAlphaRoundTripTest.cpp
+++ b/tests/PremulAlphaRoundTripTest.cpp
@@ -9,32 +9,62 @@
 #include "SkCanvas.h"
 #include "SkConfig8888.h"
 #include "Test.h"
+#include "sk_tool_utils.h"
 
 #if SK_SUPPORT_GPU
 #include "GrContextFactory.h"
 #include "SkGpuDevice.h"
 #endif
 
-static void fillCanvas(SkCanvas* canvas, SkCanvas::Config8888 unpremulConfig) {
-    SkBitmap bmp;
-    bmp.allocN32Pixels(256, 256);
-    SkAutoLockPixels alp(bmp);
-    uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels());
-
-    for (int a = 0; a < 256; ++a) {
-        for (int r = 0; r < 256; ++r) {
-            pixels[a * 256 + r] = SkPackConfig8888(unpremulConfig, a, r, 0, 0);
-        }
-    }
-    canvas->writePixels(bmp, 0, 0, unpremulConfig);
+static uint32_t pack_unpremul_rgba(SkColor c) {
+    uint32_t packed;
+    uint8_t* byte = reinterpret_cast<uint8_t*>(&packed);
+    byte[0] = SkColorGetR(c);
+    byte[1] = SkColorGetG(c);
+    byte[2] = SkColorGetB(c);
+    byte[3] = SkColorGetA(c);
+    return packed;
 }
 
-static const SkCanvas::Config8888 gUnpremulConfigs[] = {
-    SkCanvas::kNative_Unpremul_Config8888,
-    SkCanvas::kBGRA_Unpremul_Config8888,
-    SkCanvas::kRGBA_Unpremul_Config8888,
+static uint32_t pack_unpremul_bgra(SkColor c) {
+    uint32_t packed;
+    uint8_t* byte = reinterpret_cast<uint8_t*>(&packed);
+    byte[0] = SkColorGetB(c);
+    byte[1] = SkColorGetG(c);
+    byte[2] = SkColorGetR(c);
+    byte[3] = SkColorGetA(c);
+    return packed;
+}
+
+typedef uint32_t (*PackUnpremulProc)(SkColor);
+
+const struct {
+    SkColorType             fColorType;
+    PackUnpremulProc        fPackProc;
+    SkCanvas::Config8888    fConfig8888;
+} gUnpremul[] = {
+    { kRGBA_8888_SkColorType, pack_unpremul_rgba, SkCanvas::kRGBA_Unpremul_Config8888 },
+    { kBGRA_8888_SkColorType, pack_unpremul_bgra, SkCanvas::kBGRA_Unpremul_Config8888 },
 };
 
+static void fillCanvas(SkCanvas* canvas, SkColorType colorType, PackUnpremulProc proc) {
+    // Don't strictly need a bitmap, but its a handy way to allocate the pixels
+    SkBitmap bmp;
+    bmp.allocN32Pixels(256, 256);
+
+    for (int a = 0; a < 256; ++a) {
+        uint32_t* pixels = bmp.getAddr32(0, a);
+        for (int r = 0; r < 256; ++r) {
+            pixels[r] = proc(SkColorSetARGB(a, r, 0, 0));
+        }
+    }
+
+    SkImageInfo info = bmp.info();
+    info.fColorType = colorType;
+    info.fAlphaType = kUnpremul_SkAlphaType;
+    canvas->writePixels(info, bmp.getPixels(), bmp.rowBytes(), 0, 0);
+}
+
 DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) {
     const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
 
@@ -74,32 +104,23 @@
             SkBitmap readBmp2;
             readBmp2.allocN32Pixels(256, 256);
 
-            for (size_t upmaIdx = 0;
-                 upmaIdx < SK_ARRAY_COUNT(gUnpremulConfigs);
-                 ++upmaIdx) {
-                fillCanvas(&canvas, gUnpremulConfigs[upmaIdx]);
-                {
-                    SkAutoLockPixels alp1(readBmp1);
-                    SkAutoLockPixels alp2(readBmp2);
-                    sk_bzero(readBmp1.getPixels(), readBmp1.getSafeSize());
-                    sk_bzero(readBmp2.getPixels(), readBmp2.getSafeSize());
-                }
+            for (size_t upmaIdx = 0; upmaIdx < SK_ARRAY_COUNT(gUnpremul); ++upmaIdx) {
+                fillCanvas(&canvas, gUnpremul[upmaIdx].fColorType, gUnpremul[upmaIdx].fPackProc);
+                
+                readBmp1.eraseColor(0);
+                readBmp2.eraseColor(0);
 
-                canvas.readPixels(&readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
-                canvas.writePixels(readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
-                canvas.readPixels(&readBmp2, 0, 0, gUnpremulConfigs[upmaIdx]);
+                canvas.readPixels(&readBmp1, 0, 0, gUnpremul[upmaIdx].fConfig8888);
+                sk_tool_utils::write_pixels(&canvas, readBmp1, 0, 0, gUnpremul[upmaIdx].fColorType,
+                                            kUnpremul_SkAlphaType);
+                canvas.readPixels(&readBmp2, 0, 0, gUnpremul[upmaIdx].fConfig8888);
 
-                SkAutoLockPixels alp1(readBmp1);
-                SkAutoLockPixels alp2(readBmp2);
-                uint32_t* pixels1 =
-                    reinterpret_cast<uint32_t*>(readBmp1.getPixels());
-                uint32_t* pixels2 =
-                    reinterpret_cast<uint32_t*>(readBmp2.getPixels());
                 bool success = true;
                 for (int y = 0; y < 256 && success; ++y) {
+                    const uint32_t* pixels1 = readBmp1.getAddr32(0, y);
+                    const uint32_t* pixels2 = readBmp2.getAddr32(0, y);
                     for (int x = 0; x < 256 && success; ++x) {
-                        int i = y * 256 + x;
-                        REPORTER_ASSERT(reporter, success = pixels1[i] == pixels2[i]);
+                        REPORTER_ASSERT(reporter, success = pixels1[x] == pixels2[x]);
                     }
                 }
             }