Add config8888 support to writePixels
Review URL: http://codereview.appspot.com/5374052/
git-svn-id: http://skia.googlecode.com/svn/trunk@2662 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index e063112..cd835ac 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -580,10 +580,11 @@
}
}
-void SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) {
+void SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y,
+ Config8888 config8888) {
SkDevice* device = this->getDevice();
if (device) {
- device->writePixels(bitmap, x, y);
+ device->writePixels(bitmap, x, y, config8888);
}
}
diff --git a/src/core/SkConfig8888.h b/src/core/SkConfig8888.h
new file mode 100644
index 0000000..8a666e7
--- /dev/null
+++ b/src/core/SkConfig8888.h
@@ -0,0 +1,286 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkCanvas.h"
+#include "SkColorPriv.h"
+
+namespace {
+
+/**
+ Copies all pixels from a bitmap to a dst ptr with a given rowBytes and
+ Config8888. The bitmap must have kARGB_8888_Config.
+ */
+inline void SkCopyBitmapToConfig8888(uint32_t* dstPixels,
+ size_t dstRowBytes,
+ SkCanvas::Config8888 dstConfig8888,
+ const SkBitmap& srcBmp);
+
+/**
+ * Copies all pixels in a bitmap to a dst ptr with row bytes. The src bitmap
+ * is assumed to have pixels and be kARGB_8888_Config. No conversion is applied
+ */
+inline void SkCopyARGB8888BitmapTo(uint32_t* dstPixels,
+ size_t dstRowBytes,
+ const SkBitmap& srcBmp);
+
+/**
+ Copies over all pixels in a bitmap from a src ptr with a given rowBytes and
+ Config8888. The bitmap must have pixels and be kARGB_8888_Config.
+ */
+inline void SkCopyConfig8888ToBitmap(const SkBitmap& dstBmp,
+ const uint32_t* srcPixels,
+ size_t srcRowBytes,
+ SkCanvas::Config8888 srcConfig8888);
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation
+
+namespace {
+
+template <int A_IDX, int R_IDX, int G_IDX, int B_IDX>
+inline uint32_t pack_config8888(uint32_t a, uint32_t r,
+ uint32_t g, uint32_t b) {
+#ifdef SK_CPU_LENDIAN
+ return (a << (A_IDX * 8)) | (r << (R_IDX * 8)) |
+ (g << (G_IDX * 8)) | (b << (B_IDX * 8));
+#else
+ return (a << ((3-A_IDX) * 8)) | (r << ((3-R_IDX) * 8)) |
+ (g << ((3-G_IDX) * 8)) | (b << ((3-B_IDX) * 8));
+#endif
+}
+
+template <int A_IDX, int R_IDX, int G_IDX, int B_IDX>
+inline void unpack_config8888(uint32_t color,
+ uint32_t* a, uint32_t* r,
+ uint32_t* g, uint32_t* b) {
+#ifdef SK_CPU_LENDIAN
+ *a = (color >> (A_IDX * 8)) & 0xff;
+ *r = (color >> (R_IDX * 8)) & 0xff;
+ *g = (color >> (G_IDX * 8)) & 0xff;
+ *b = (color >> (B_IDX * 8)) & 0xff;
+#else
+ *a = (color >> ((3 - A_IDX) * 8)) & 0xff;
+ *r = (color >> ((3 - R_IDX) * 8)) & 0xff;
+ *g = (color >> ((3 - G_IDX) * 8)) & 0xff;
+ *b = (color >> ((3 - B_IDX) * 8)) & 0xff;
+#endif
+}
+
+template <bool UNPM, int A_IDX, int R_IDX, int G_IDX, int B_IDX>
+inline void bitmap_copy_to_config8888(uint32_t* dstPixels,
+ size_t dstRowBytes,
+ const SkBitmap& srcBmp) {
+ SkASSERT(SkBitmap::kARGB_8888_Config == srcBmp.config());
+ SkAutoLockPixels alp(srcBmp);
+ int w = srcBmp.width();
+ int h = srcBmp.height();
+ size_t srcRowBytes = srcBmp.rowBytes();
+
+ intptr_t src = reinterpret_cast<intptr_t>(srcBmp.getPixels());
+ intptr_t dst = reinterpret_cast<intptr_t>(dstPixels);
+
+ for (int y = 0; y < h; ++y) {
+ const SkPMColor* srcRow = reinterpret_cast<SkPMColor*>(src);
+ uint32_t* dstRow = reinterpret_cast<uint32_t*>(dst);
+ for (int x = 0; x < w; ++x) {
+ SkPMColor pmcolor = srcRow[x];
+ if (UNPM) {
+ U8CPU a, r, g, b;
+ a = SkGetPackedA32(pmcolor);
+ if (a) {
+ // We're doing the explicit divide to match WebKit layout
+ // test expectations. We can modify and rebaseline if there
+ // it can be shown that there is a more performant way to
+ // unpremul.
+ r = SkGetPackedR32(pmcolor) * 0xff / a;
+ g = SkGetPackedG32(pmcolor) * 0xff / a;
+ b = SkGetPackedB32(pmcolor) * 0xff / a;
+ dstRow[x] = pack_config8888<A_IDX, R_IDX,
+ G_IDX, B_IDX>(a, r, g, b);
+ } else {
+ dstRow[x] = 0;
+ }
+ } else {
+ dstRow[x] = pack_config8888<A_IDX, R_IDX,
+ G_IDX, B_IDX>(
+ SkGetPackedA32(pmcolor),
+ SkGetPackedR32(pmcolor),
+ SkGetPackedG32(pmcolor),
+ SkGetPackedB32(pmcolor));
+ }
+ }
+ dst += dstRowBytes;
+ src += srcRowBytes;
+ }
+}
+
+template <bool PM, int A_IDX, int R_IDX, int G_IDX, int B_IDX>
+inline void config8888_copy_to_bitmap(const SkBitmap& dstBmp,
+ const uint32_t* srcPixels,
+ size_t srcRowBytes) {
+ SkASSERT(SkBitmap::kARGB_8888_Config == dstBmp.config());
+ SkAutoLockPixels alp(dstBmp);
+ int w = dstBmp.width();
+ int h = dstBmp.height();
+ size_t dstRowBytes = dstBmp.rowBytes();
+
+ intptr_t src = reinterpret_cast<intptr_t>(srcPixels);
+ intptr_t dst = reinterpret_cast<intptr_t>(dstBmp.getPixels());
+
+ for (int y = 0; y < h; ++y) {
+ const uint32_t* srcRow = reinterpret_cast<uint32_t*>(src);
+ SkPMColor* dstRow = reinterpret_cast<SkPMColor*>(dst);
+ for (int x = 0; x < w; ++x) {
+ uint32_t c8888 = srcRow[x];
+ uint32_t a, r, g, b;
+ unpack_config8888<A_IDX, R_IDX, G_IDX, B_IDX>(c8888, &a, &r,
+ &g, &b);
+ if (PM) {
+ // This matches WebKit's conversion which we are replacing.
+ // We can consider alternative rounding rules for performance.
+ r = SkMulDiv255Ceiling(r, a);
+ g = SkMulDiv255Ceiling(g, a);
+ b = SkMulDiv255Ceiling(b, a);
+ }
+ dstRow[x] = SkPackARGB32(a, r, g, b);
+ }
+ src += srcRowBytes;
+ dst += dstRowBytes;
+ }
+}
+
+#ifdef SK_CPU_LENDIAN
+ static const int SK_NATIVE_A_IDX = SK_A32_SHIFT / 8;
+ static const int SK_NATIVE_R_IDX = SK_R32_SHIFT / 8;
+ static const int SK_NATIVE_G_IDX = SK_G32_SHIFT / 8;
+ static const int SK_NATIVE_B_IDX = SK_B32_SHIFT / 8;
+#else
+ static const int SK_NATIVE_A_IDX = 3 - (SK_A32_SHIFT / 8);
+ static const int SK_NATIVE_R_IDX = 3 - (SK_R32_SHIFT / 8);
+ static const int SK_NATIVE_G_IDX = 3 - (SK_G32_SHIFT / 8);
+ static const int SK_NATIVE_B_IDX = 3 - (SK_B32_SHIFT / 8);
+#endif
+
+inline void SkCopyBitmapToConfig8888(uint32_t* dstPixels,
+ size_t dstRowBytes,
+ SkCanvas::Config8888 dstConfig8888,
+ const SkBitmap& srcBmp) {
+ switch (dstConfig8888) {
+ case SkCanvas::kNative_Premul_Config8888:
+ bitmap_copy_to_config8888<false,
+ SK_NATIVE_A_IDX, SK_NATIVE_R_IDX,
+ SK_NATIVE_G_IDX, SK_NATIVE_B_IDX>(
+ dstPixels,
+ dstRowBytes,
+ srcBmp);
+ break;
+ case SkCanvas::kNative_Unpremul_Config8888:
+ bitmap_copy_to_config8888<true,
+ SK_NATIVE_A_IDX, SK_NATIVE_R_IDX,
+ SK_NATIVE_G_IDX, SK_NATIVE_B_IDX>(
+ dstPixels,
+ dstRowBytes,
+ srcBmp);
+ break;
+ case SkCanvas::kBGRA_Premul_Config8888:
+ bitmap_copy_to_config8888<false, 3, 2, 1, 0> (
+ dstPixels, dstRowBytes, srcBmp);
+ break;
+ case SkCanvas::kBGRA_Unpremul_Config8888:
+ bitmap_copy_to_config8888<true, 3, 2, 1, 0> (
+ dstPixels, dstRowBytes, srcBmp);
+ break;
+ case SkCanvas::kRGBA_Premul_Config8888:
+ bitmap_copy_to_config8888<false, 3, 0, 1, 2> (
+ dstPixels, dstRowBytes, srcBmp);
+ break;
+ case SkCanvas::kRGBA_Unpremul_Config8888:
+ bitmap_copy_to_config8888<true, 3, 0, 1, 2> (
+ dstPixels, dstRowBytes, srcBmp);
+ break;
+ default:
+ SkASSERT(false && "unexpected Config8888");
+ break;
+ }
+}
+
+inline void SkCopyConfig8888ToBitmap(const SkBitmap& dstBmp,
+ const uint32_t* srcPixels,
+ size_t srcRowBytes,
+ SkCanvas::Config8888 srcConfig8888) {
+ switch (srcConfig8888) {
+ case SkCanvas::kNative_Premul_Config8888:
+ config8888_copy_to_bitmap<false,
+ SK_NATIVE_A_IDX, SK_NATIVE_R_IDX,
+ SK_NATIVE_G_IDX, SK_NATIVE_B_IDX>(
+ dstBmp,
+ srcPixels,
+ srcRowBytes);
+ break;
+ case SkCanvas::kNative_Unpremul_Config8888:
+ config8888_copy_to_bitmap<true,
+ SK_NATIVE_A_IDX, SK_NATIVE_R_IDX,
+ SK_NATIVE_G_IDX, SK_NATIVE_B_IDX>(
+ dstBmp,
+ srcPixels,
+ srcRowBytes);
+ break;
+ case SkCanvas::kBGRA_Premul_Config8888:
+ config8888_copy_to_bitmap<false, 3, 2, 1, 0> (
+ dstBmp, srcPixels, srcRowBytes);
+ break;
+ case SkCanvas::kBGRA_Unpremul_Config8888:
+ config8888_copy_to_bitmap<true, 3, 2, 1, 0> (
+ dstBmp, srcPixels, srcRowBytes);
+ break;
+ case SkCanvas::kRGBA_Premul_Config8888:
+ config8888_copy_to_bitmap<false, 3, 0, 1, 2> (
+ dstBmp, srcPixels, srcRowBytes);
+ break;
+ case SkCanvas::kRGBA_Unpremul_Config8888:
+ config8888_copy_to_bitmap<true, 3, 0, 1, 2> (
+ dstBmp, srcPixels, srcRowBytes);
+ break;
+ default:
+ SkASSERT(false && "unexpected Config8888");
+ break;
+ }
+}
+
+inline void SkCopyARGB8888BitmapTo(uint32_t* dstPixels,
+ size_t dstRowBytes,
+ const SkBitmap& srcBmp) {
+ SkASSERT(SkBitmap::kARGB_8888_Config == srcBmp.config());
+
+ SkAutoLockPixels alp(srcBmp);
+
+ int w = srcBmp.width();
+ int h = srcBmp.height();
+ size_t srcRowBytes = srcBmp.rowBytes();
+
+ size_t tightRowBytes = w * 4;
+
+ char* src = reinterpret_cast<char*>(srcBmp.getPixels());
+ char* dst = reinterpret_cast<char*>(dstPixels);
+
+ if (tightRowBytes == srcRowBytes &&
+ tightRowBytes == dstRowBytes) {
+ memcpy(dst, src, tightRowBytes * h);
+ } else {
+ for (int y = 0; y < h; ++y) {
+ memcpy(dst, src, tightRowBytes);
+ dst += dstRowBytes;
+ src += srcRowBytes;
+ }
+ }
+}
+
+}
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index a66f2a9..dd2301d 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -159,10 +159,6 @@
const SkCanvas::Config8888 SkDevice::kPMColorAlias =
(SkCanvas::Config8888) -1;
#endif
- static const int NATIVE_A_IDX = SK_A32_SHIFT / 8;
- static const int NATIVE_R_IDX = SK_R32_SHIFT / 8;
- static const int NATIVE_G_IDX = SK_G32_SHIFT / 8;
- static const int NATIVE_B_IDX = SK_B32_SHIFT / 8;
#else
#if 0 == SK_A32_SHIFT && 8 == SK_R32_SHIFT && \
16 == SK_G32_SHIFT && 24 == SK_B32_SHIFT
@@ -176,105 +172,9 @@
const SkCanvas::Config8888 SkDevice::kPMColorAlias =
(SkCanvas::Config8888) -1;
#endif
- static const int NATIVE_A_IDX = 3 - (SK_A32_SHIFT / 8);
- static const int NATIVE_R_IDX = 3 - (SK_R32_SHIFT / 8);
- static const int NATIVE_G_IDX = 3 - (SK_G32_SHIFT / 8);
- static const int NATIVE_B_IDX = 3 - (SK_B32_SHIFT / 8);
#endif
-#include <SkColorPriv.h>
-
-namespace {
-
-template <int A_IDX, int R_IDX, int G_IDX, int B_IDX>
-inline uint32_t pack_config8888(uint32_t a, uint32_t r,
- uint32_t g, uint32_t b) {
-#ifdef SK_CPU_LENDIAN
- return (a << (A_IDX * 8)) | (r << (R_IDX * 8)) |
- (g << (G_IDX * 8)) | (b << (B_IDX * 8));
-#else
- return (a << ((3-A_IDX) * 8)) | (r << ((3-R_IDX) * 8)) |
- (g << ((3-G_IDX) * 8)) | (b << ((3-B_IDX) * 8));
-#endif
-}
-
-template <bool UNPM, int A_IDX, int R_IDX, int G_IDX, int B_IDX>
-inline void bitmap_copy_to_config8888(const SkBitmap& srcBmp,
- uint32_t* dstPixels,
- size_t dstRowBytes) {
- SkASSERT(SkBitmap::kARGB_8888_Config == srcBmp.config());
- SkAutoLockPixels alp(srcBmp);
- int w = srcBmp.width();
- int h = srcBmp.height();
- size_t srcRowBytes = srcBmp.rowBytes();
-
- intptr_t src = reinterpret_cast<intptr_t>(srcBmp.getPixels());
- intptr_t dst = reinterpret_cast<intptr_t>(dstPixels);
-
- for (int y = 0; y < h; ++y) {
- const SkPMColor* srcRow = reinterpret_cast<SkPMColor*>(src);
- uint32_t* dstRow = reinterpret_cast<uint32_t*>(dst);
- for (int x = 0; x < w; ++x) {
- SkPMColor pmcolor = srcRow[x];
- if (UNPM) {
- U8CPU a, r, g, b;
- a = SkGetPackedA32(pmcolor);
- if (a) {
- // We're doing the explicit divide to match WebKit layout
- // test expectations. We can modify and rebaseline if there
- // it can be shown that there is a more performant way to
- // unpremul.
- r = SkGetPackedR32(pmcolor) * 0xff / a;
- g = SkGetPackedG32(pmcolor) * 0xff / a;
- b = SkGetPackedB32(pmcolor) * 0xff / a;
- dstRow[x] = pack_config8888<A_IDX, R_IDX,
- G_IDX, B_IDX>(a, r, g, b);
- } else {
- dstRow[x] = 0;
- }
- } else {
- dstRow[x] = pack_config8888<A_IDX, R_IDX,
- G_IDX, B_IDX>(
- SkGetPackedA32(pmcolor),
- SkGetPackedR32(pmcolor),
- SkGetPackedG32(pmcolor),
- SkGetPackedB32(pmcolor));
- }
- }
- dst += dstRowBytes;
- src += srcRowBytes;
- }
-}
-
-inline void bitmap_copy_to_native(const SkBitmap& srcBmp,
- uint32_t* dstPixels,
- size_t dstRowBytes) {
- SkASSERT(SkBitmap::kARGB_8888_Config == srcBmp.config());
-
- SkAutoLockPixels alp(srcBmp);
-
- int w = srcBmp.width();
- int h = srcBmp.height();
- size_t srcRowBytes = srcBmp.rowBytes();
-
- size_t tightRowBytes = w * 4;
-
- char* src = reinterpret_cast<char*>(srcBmp.getPixels());
- char* dst = reinterpret_cast<char*>(dstPixels);
-
- if (tightRowBytes == srcRowBytes &&
- tightRowBytes == dstRowBytes) {
- memcpy(dst, src, tightRowBytes * h);
- } else {
- for (int y = 0; y < h; ++y) {
- memcpy(dst, src, tightRowBytes);
- dst += dstRowBytes;
- src += srcRowBytes;
- }
- }
-}
-
-}
+#include <SkConfig8888.h>
bool SkDevice::onReadPixels(const SkBitmap& bitmap,
int x, int y,
@@ -299,55 +199,78 @@
uint32_t* bmpPixels = reinterpret_cast<uint32_t*>(bitmap.getPixels());
if ((SkCanvas::kNative_Premul_Config8888 == config8888 ||
kPMColorAlias == config8888)) {
- bitmap_copy_to_native(subset, bmpPixels, bitmap.rowBytes());
+ SkCopyARGB8888BitmapTo(bmpPixels, bitmap.rowBytes(), subset);
} else {
- switch (config8888) {
- case SkCanvas::kNative_Premul_Config8888:
- bitmap_copy_to_config8888<false,
- NATIVE_A_IDX, NATIVE_R_IDX,
- NATIVE_G_IDX, NATIVE_B_IDX>(
- subset,
- bmpPixels,
- bitmap.rowBytes());
- break;
- case SkCanvas::kNative_Unpremul_Config8888:
- bitmap_copy_to_config8888<true,
- NATIVE_A_IDX, NATIVE_R_IDX,
- NATIVE_G_IDX, NATIVE_B_IDX>(
- subset,
- bmpPixels,
- bitmap.rowBytes());
- break;
- case SkCanvas::kBGRA_Premul_Config8888:
- bitmap_copy_to_config8888<false, 3, 2, 1, 0> (
- subset, bmpPixels, bitmap.rowBytes());
- break;
- case SkCanvas::kBGRA_Unpremul_Config8888:
- bitmap_copy_to_config8888<true, 3, 2, 1, 0> (
- subset, bmpPixels, bitmap.rowBytes());
- break;
- case SkCanvas::kRGBA_Premul_Config8888:
- bitmap_copy_to_config8888<false, 3, 0, 1, 2> (
- subset, bmpPixels, bitmap.rowBytes());
- break;
- case SkCanvas::kRGBA_Unpremul_Config8888:
- bitmap_copy_to_config8888<true, 3, 0, 1, 2> (
- subset, bmpPixels, bitmap.rowBytes());
- break;
- default:
- SkASSERT(false && "unexpected Config8888");
- break;
- }
+ SkCopyBitmapToConfig8888(bmpPixels,
+ bitmap.rowBytes(),
+ config8888,
+ subset);
}
return true;
}
-void SkDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
+void SkDevice::writePixels(const SkBitmap& bitmap,
+ int x, int y,
+ SkCanvas::Config8888 config8888) {
+ if (bitmap.isNull() || bitmap.getTexture()) {
+ return;
+ }
+ const SkBitmap* sprite = &bitmap;
+ // check whether we have to handle a config8888 that doesn't match SkPMColor
+ if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
+ SkCanvas::kNative_Premul_Config8888 != config8888 &&
+ kPMColorAlias != config8888) {
+
+ // We're going to have to convert from a config8888 to the native config
+ // First we clip to the device bounds.
+ SkBitmap dstBmp = this->accessBitmap(true);
+ SkIRect spriteRect = SkIRect::MakeXYWH(x, y,
+ bitmap.width(), bitmap.height());
+ SkIRect devRect = SkIRect::MakeWH(dstBmp.width(), dstBmp.height());
+ if (!spriteRect.intersect(devRect)) {
+ return;
+ }
+
+ // write directly to the device if it has pixels and is SkPMColor
+ bool drawSprite;
+ if (SkBitmap::kARGB_8888_Config == dstBmp.config() && !dstBmp.isNull()) {
+ // we can write directly to the dst when doing the conversion
+ dstBmp.extractSubset(&dstBmp, spriteRect);
+ drawSprite = false;
+ } else {
+ // we convert to a temporary bitmap and draw that as a sprite
+ dstBmp.setConfig(SkBitmap::kARGB_8888_Config,
+ spriteRect.width(),
+ spriteRect.height());
+ if (!dstBmp.allocPixels()) {
+ return;
+ }
+ drawSprite = true;
+ }
+
+ // copy pixels to dstBmp and convert from config8888 to native config.
+ SkAutoLockPixels alp(bitmap);
+ uint32_t* srcPixels = bitmap.getAddr32(spriteRect.fLeft - x,
+ spriteRect.fTop - y);
+ SkCopyConfig8888ToBitmap(dstBmp,
+ srcPixels,
+ bitmap.rowBytes(),
+ config8888);
+
+ if (drawSprite) {
+ // we've clipped the sprite when we made a copy
+ x = spriteRect.fLeft;
+ y = spriteRect.fTop;
+ sprite = &dstBmp;
+ } else {
+ return;
+ }
+ }
+
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
-
SkCanvas canvas(this);
- canvas.drawSprite(bitmap, x, y, &paint);
+ canvas.drawSprite(*sprite, x, y, &paint);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 64d74ee..7230516 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -299,20 +299,48 @@
bitmap.rowBytes());
}
-void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
+// This can be removed when temporary code in writePixels is removed
+#include "SkConfig8888.h"
+
+void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y,
+ SkCanvas::Config8888 config8888) {
SkAutoLockPixels alp(bitmap);
if (!bitmap.readyToDraw()) {
return;
}
- GrPixelConfig config = SkGr::BitmapConfig2PixelConfig(bitmap.config(),
- bitmap.isOpaque());
+
+ GrPixelConfig config;
+ if (SkBitmap::kARGB_8888_Config == bitmap.config()) {
+ config = config8888_to_gr_config(config8888);
+ } else {
+ config= SkGr::BitmapConfig2PixelConfig(bitmap.config(),
+ bitmap.isOpaque());
+ }
+
+ // Temporary until we add support for drawing from an unpremul config in
+ // GrContext
+ const SkBitmap* src = &bitmap;
+ SkBitmap tmp;
+ if (GrPixelConfigIsUnpremultiplied(config)) {
+ config = kSkia8888_PM_GrPixelConfig;
+ tmp.setConfig(SkBitmap::kARGB_8888_Config,
+ bitmap.width(), bitmap.height());
+ if (!tmp.allocPixels()) {
+ return;
+ }
+ SkAutoLockPixels alp(bitmap);
+ uint32_t* pixels = reinterpret_cast<uint32_t*>(bitmap.getPixels());
+ SkCopyConfig8888ToBitmap(tmp, pixels, bitmap.rowBytes(), config8888);
+ src = &tmp;
+ }
+
fContext->setRenderTarget(fRenderTarget);
// we aren't setting the clip or matrix, so mark as dirty
// we don't need to set them for this call and don't have them anyway
fNeedPrepareRenderTarget = true;
- fContext->writePixels(x, y, bitmap.width(), bitmap.height(),
- config, bitmap.getPixels(), bitmap.rowBytes());
+ fContext->writePixels(x, y, src->width(), src->height(),
+ config, src->getPixels(), src->rowBytes());
}
///////////////////////////////////////////////////////////////////////////////