diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-25 12:00:30 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-25 12:00:30 +0000 |
commit | 1121170477302e25ef2a020cf2092aa6b399b3ef (patch) | |
tree | 8202440265569ad57c1aa3238f643be66b25506d /src | |
parent | 9b62aa156bcf1db6f11af9302bf8bb8ef2567142 (diff) |
implement readPixels and writePixels natively, w/o using the (deprecated)
SkCanvas::Config8888 enum.
Revert "Revert "hide Config8888 entirely". Broke a bunch of builds."
This reverts commit 763277ba157fef0f651004bb98a189e9f1ac730b.
Needs chrome to remove the READPIXELS guard from skia's .gyp
Review URL: https://codereview.chromium.org/199733016
git-svn-id: http://skia.googlecode.com/svn/trunk@13931 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmapDevice.cpp | 48 | ||||
-rw-r--r-- | src/core/SkConfig8888.cpp | 333 | ||||
-rw-r--r-- | src/core/SkConfig8888.h | 82 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 111 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 21 |
6 files changed, 171 insertions, 434 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index f0f4df41f1..d968cb850b 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -221,47 +221,27 @@ static void rect_memcpy(void* dst, size_t dstRB, const void* src, size_t srcRB, } } -static bool info2config8888(const SkImageInfo& info, SkCanvas::Config8888* config) { - bool pre; - switch (info.alphaType()) { - case kPremul_SkAlphaType: - case kOpaque_SkAlphaType: - pre = true; - break; - case kUnpremul_SkAlphaType: - pre = false; - break; - default: - return false; - } - switch (info.colorType()) { - case kRGBA_8888_SkColorType: - *config = pre ? SkCanvas::kRGBA_Premul_Config8888 : SkCanvas::kRGBA_Unpremul_Config8888; - return true; - case kBGRA_8888_SkColorType: - *config = pre ? SkCanvas::kBGRA_Premul_Config8888 : SkCanvas::kBGRA_Unpremul_Config8888; - return true; - default: - return false; - } -} - -// TODO: make this guy real, and not rely on legacy config8888 utility #include "SkConfig8888.h" + static bool copy_pixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRowBytes) { if (srcInfo.dimensions() != dstInfo.dimensions()) { return false; } if (4 == srcInfo.bytesPerPixel() && 4 == dstInfo.bytesPerPixel()) { - SkCanvas::Config8888 srcConfig, dstConfig; - if (!info2config8888(srcInfo, &srcConfig) || !info2config8888(dstInfo, &dstConfig)) { - return false; - } - SkConvertConfig8888Pixels((uint32_t*)dstPixels, dstRowBytes, dstConfig, - (const uint32_t*)srcPixels, srcRowBytes, srcConfig, - srcInfo.width(), srcInfo.height()); - return true; + SkDstPixelInfo dstPI; + dstPI.fColorType = dstInfo.colorType(); + dstPI.fAlphaType = dstInfo.alphaType(); + dstPI.fPixels = dstPixels; + dstPI.fRowBytes = dstRowBytes; + + SkSrcPixelInfo srcPI; + srcPI.fColorType = srcInfo.colorType(); + srcPI.fAlphaType = srcInfo.alphaType(); + srcPI.fPixels = srcPixels; + srcPI.fRowBytes = srcRowBytes; + + return srcPI.convertPixelsTo(&dstPI, srcInfo.width(), srcInfo.height()); } if (srcInfo.colorType() == dstInfo.colorType()) { switch (srcInfo.colorType()) { diff --git a/src/core/SkConfig8888.cpp b/src/core/SkConfig8888.cpp index dd5cbc4724..189309dae6 100644 --- a/src/core/SkConfig8888.cpp +++ b/src/core/SkConfig8888.cpp @@ -1,280 +1,117 @@ #include "SkConfig8888.h" +#include "SkColorPriv.h" #include "SkMathPriv.h" #include "SkUnPreMultiply.h" -namespace { +enum AlphaVerb { + kNothing_AlphaVerb, + kPremul_AlphaVerb, + kUnpremul_AlphaVerb, +}; -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 -} - -#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 - -/** - * convert_pixel<OUT_CFG, IN_CFG converts a pixel value from one Config8888 to - * another. It is implemented by first expanding OUT_CFG to r, g, b, a indices - * and an is_premul bool as params to another template function. Then IN_CFG is - * expanded via another function call. - */ - -template <bool OUT_PM, int OUT_A_IDX, int OUT_R_IDX, int OUT_G_IDX, int OUT_B_IDX, - bool IN_PM, int IN_A_IDX, int IN_R_IDX, int IN_G_IDX, int IN_B_IDX> -inline uint32_t convert_pixel(uint32_t pixel) { - uint32_t a, r, g, b; - unpack_config8888<IN_A_IDX, IN_R_IDX, IN_G_IDX, IN_B_IDX>(pixel, &a, &r, &g, &b); - if (IN_PM && !OUT_PM) { - // Using SkUnPreMultiply::ApplyScale is faster than (value * 0xff) / a. - if (a) { - SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(a); - r = SkUnPreMultiply::ApplyScale(scale, r); - g = SkUnPreMultiply::ApplyScale(scale, g); - b = SkUnPreMultiply::ApplyScale(scale, b); - } else { - return 0; - } - } else if (!IN_PM && OUT_PM) { - // This matches SkUnPreMultiply conversion which we are replacing. - r = SkMulDiv255Round(r, a); - g = SkMulDiv255Round(g, a); - b = SkMulDiv255Round(b, a); +template <bool doSwapRB, AlphaVerb doAlpha> uint32_t convert32(uint32_t c) { + if (doSwapRB) { + c = SkSwizzle_RB(c); } - return pack_config8888<OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX>(a, r, g, b); -} -template <bool OUT_PM, int OUT_A_IDX, int OUT_R_IDX, int OUT_G_IDX, int OUT_B_IDX, SkCanvas::Config8888 IN_CFG> -inline uint32_t convert_pixel(uint32_t pixel) { - switch(IN_CFG) { - case SkCanvas::kNative_Premul_Config8888: - return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX, - true, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NATIVE_G_IDX, SK_NATIVE_B_IDX>(pixel); - break; - case SkCanvas::kNative_Unpremul_Config8888: - return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX, - false, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NATIVE_G_IDX, SK_NATIVE_B_IDX>(pixel); - break; - case SkCanvas::kBGRA_Premul_Config8888: - return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX, - true, 3, 2, 1, 0>(pixel); - break; - case SkCanvas::kBGRA_Unpremul_Config8888: - return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX, - false, 3, 2, 1, 0>(pixel); - break; - case SkCanvas::kRGBA_Premul_Config8888: - return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX, - true, 3, 0, 1, 2>(pixel); + // Lucky for us, in both RGBA and BGRA, the alpha component is always in the same place, so + // we can perform premul or unpremul the same way without knowing the swizzles for RGB. + switch (doAlpha) { + case kNothing_AlphaVerb: + // no change break; - case SkCanvas::kRGBA_Unpremul_Config8888: - return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX, - false, 3, 0, 1, 2>(pixel); + case kPremul_AlphaVerb: + c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c), + SkGetPackedG32(c), SkGetPackedB32(c)); break; - default: - SkDEBUGFAIL("Unexpected config8888"); - return 0; + case kUnpremul_AlphaVerb: + c = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(c); break; } + return c; } -template <SkCanvas::Config8888 OUT_CFG, SkCanvas::Config8888 IN_CFG> -inline uint32_t convert_pixel(uint32_t pixel) { - switch(OUT_CFG) { - case SkCanvas::kNative_Premul_Config8888: - return convert_pixel<true, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NATIVE_G_IDX, SK_NATIVE_B_IDX, IN_CFG>(pixel); - break; - case SkCanvas::kNative_Unpremul_Config8888: - return convert_pixel<false, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NATIVE_G_IDX, SK_NATIVE_B_IDX, IN_CFG>(pixel); - break; - case SkCanvas::kBGRA_Premul_Config8888: - return convert_pixel<true, 3, 2, 1, 0, IN_CFG>(pixel); - break; - case SkCanvas::kBGRA_Unpremul_Config8888: - return convert_pixel<false, 3, 2, 1, 0, IN_CFG>(pixel); - break; - case SkCanvas::kRGBA_Premul_Config8888: - return convert_pixel<true, 3, 0, 1, 2, IN_CFG>(pixel); - break; - case SkCanvas::kRGBA_Unpremul_Config8888: - return convert_pixel<false, 3, 0, 1, 2, IN_CFG>(pixel); - break; - default: - SkDEBUGFAIL("Unexpected config8888"); - return 0; - break; +template <bool doSwapRB, AlphaVerb doAlpha> +void convert32_row(uint32_t* dst, const uint32_t* src, int count) { + // This has to be correct if src == dst (but not partial overlap) + for (int i = 0; i < count; ++i) { + dst[i] = convert32<doSwapRB, doAlpha>(src[i]); } } -/** - * SkConvertConfig8888Pixels has 6 * 6 possible combinations of src and dst - * configs. Each is implemented as an instantiation templated function. Two - * levels of switch statements are used to select the correct instantiation, one - * for the src config and one for the dst config. - */ +static bool is_32bit_colortype(SkColorType ct) { + return kRGBA_8888_SkColorType == ct || kBGRA_8888_SkColorType == ct; +} -template <SkCanvas::Config8888 DST_CFG, SkCanvas::Config8888 SRC_CFG> -inline void convert_config8888(uint32_t* dstPixels, - size_t dstRowBytes, - const uint32_t* srcPixels, - size_t srcRowBytes, - int width, - int height) { - intptr_t dstPix = reinterpret_cast<intptr_t>(dstPixels); - intptr_t srcPix = reinterpret_cast<intptr_t>(srcPixels); +static AlphaVerb compute_AlphaVerb(SkAlphaType src, SkAlphaType dst) { + SkASSERT(kIgnore_SkAlphaType != src); + SkASSERT(kIgnore_SkAlphaType != dst); - for (int y = 0; y < height; ++y) { - srcPixels = reinterpret_cast<const uint32_t*>(srcPix); - dstPixels = reinterpret_cast<uint32_t*>(dstPix); - for (int x = 0; x < width; ++x) { - dstPixels[x] = convert_pixel<DST_CFG, SRC_CFG>(srcPixels[x]); - } - dstPix += dstRowBytes; - srcPix += srcRowBytes; + if (kOpaque_SkAlphaType == src || kOpaque_SkAlphaType == dst || src == dst) { + return kNothing_AlphaVerb; } -} - -template <SkCanvas::Config8888 SRC_CFG> -inline void convert_config8888(uint32_t* dstPixels, - size_t dstRowBytes, - SkCanvas::Config8888 dstConfig, - const uint32_t* srcPixels, - size_t srcRowBytes, - int width, - int height) { - switch(dstConfig) { - case SkCanvas::kNative_Premul_Config8888: - convert_config8888<SkCanvas::kNative_Premul_Config8888, SRC_CFG>(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kNative_Unpremul_Config8888: - convert_config8888<SkCanvas::kNative_Unpremul_Config8888, SRC_CFG>(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kBGRA_Premul_Config8888: - convert_config8888<SkCanvas::kBGRA_Premul_Config8888, SRC_CFG>(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kBGRA_Unpremul_Config8888: - convert_config8888<SkCanvas::kBGRA_Unpremul_Config8888, SRC_CFG>(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kRGBA_Premul_Config8888: - convert_config8888<SkCanvas::kRGBA_Premul_Config8888, SRC_CFG>(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kRGBA_Unpremul_Config8888: - convert_config8888<SkCanvas::kRGBA_Unpremul_Config8888, SRC_CFG>(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); - break; - default: - SkDEBUGFAIL("Unexpected config8888"); - break; + if (kPremul_SkAlphaType == dst) { + SkASSERT(kUnpremul_SkAlphaType == src); + return kPremul_AlphaVerb; + } else { + SkASSERT(kPremul_SkAlphaType == src); + SkASSERT(kUnpremul_SkAlphaType == dst); + return kUnpremul_AlphaVerb; } } +static void memcpy32_row(uint32_t* dst, const uint32_t* src, int count) { + memcpy(dst, src, count * 4); } -void SkConvertConfig8888Pixels(uint32_t* dstPixels, - size_t dstRowBytes, - SkCanvas::Config8888 dstConfig, - const uint32_t* srcPixels, - size_t srcRowBytes, - SkCanvas::Config8888 srcConfig, - int width, - int height) { - if (srcConfig == dstConfig) { - if (srcPixels == dstPixels) { - return; - } - if (dstRowBytes == srcRowBytes && - 4U * width == srcRowBytes) { - memcpy(dstPixels, srcPixels, srcRowBytes * height); - return; - } else { - intptr_t srcPix = reinterpret_cast<intptr_t>(srcPixels); - intptr_t dstPix = reinterpret_cast<intptr_t>(dstPixels); - for (int y = 0; y < height; ++y) { - srcPixels = reinterpret_cast<const uint32_t*>(srcPix); - dstPixels = reinterpret_cast<uint32_t*>(dstPix); - memcpy(dstPixels, srcPixels, 4 * width); - srcPix += srcRowBytes; - dstPix += dstRowBytes; - } - return; - } +bool SkSrcPixelInfo::convertPixelsTo(SkDstPixelInfo* dst, int width, int height) const { + if (width <= 0 || height <= 0) { + return false; } - switch(srcConfig) { - case SkCanvas::kNative_Premul_Config8888: - convert_config8888<SkCanvas::kNative_Premul_Config8888>(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kNative_Unpremul_Config8888: - convert_config8888<SkCanvas::kNative_Unpremul_Config8888>(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kBGRA_Premul_Config8888: - convert_config8888<SkCanvas::kBGRA_Premul_Config8888>(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kBGRA_Unpremul_Config8888: - convert_config8888<SkCanvas::kBGRA_Unpremul_Config8888>(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); - break; - case SkCanvas::kRGBA_Premul_Config8888: - convert_config8888<SkCanvas::kRGBA_Premul_Config8888>(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + + if (!is_32bit_colortype(fColorType) || !is_32bit_colortype(dst->fColorType)) { + return false; + } + + void (*proc)(uint32_t* dst, const uint32_t* src, int count); + AlphaVerb doAlpha = compute_AlphaVerb(fAlphaType, dst->fAlphaType); + bool doSwapRB = fColorType != dst->fColorType; + + switch (doAlpha) { + case kNothing_AlphaVerb: + if (doSwapRB) { + proc = convert32_row<true, kNothing_AlphaVerb>; + } else { + if (fPixels == dst->fPixels) { + return true; + } + proc = memcpy32_row; + } break; - case SkCanvas::kRGBA_Unpremul_Config8888: - convert_config8888<SkCanvas::kRGBA_Unpremul_Config8888>(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + case kPremul_AlphaVerb: + if (doSwapRB) { + proc = convert32_row<true, kPremul_AlphaVerb>; + } else { + proc = convert32_row<false, kPremul_AlphaVerb>; + } break; - default: - SkDEBUGFAIL("Unexpected config8888"); + case kUnpremul_AlphaVerb: + if (doSwapRB) { + proc = convert32_row<true, kUnpremul_AlphaVerb>; + } else { + proc = convert32_row<false, kUnpremul_AlphaVerb>; + } break; } -} -uint32_t SkPackConfig8888(SkCanvas::Config8888 config, - uint32_t a, - uint32_t r, - uint32_t g, - uint32_t b) { - switch (config) { - case SkCanvas::kNative_Premul_Config8888: - case SkCanvas::kNative_Unpremul_Config8888: - return pack_config8888<SK_NATIVE_A_IDX, - SK_NATIVE_R_IDX, - SK_NATIVE_G_IDX, - SK_NATIVE_B_IDX>(a, r, g, b); - case SkCanvas::kBGRA_Premul_Config8888: - case SkCanvas::kBGRA_Unpremul_Config8888: - return pack_config8888<3, 2, 1, 0>(a, r, g, b); - case SkCanvas::kRGBA_Premul_Config8888: - case SkCanvas::kRGBA_Unpremul_Config8888: - return pack_config8888<3, 0, 1, 2>(a, r, g, b); - default: - SkDEBUGFAIL("Unexpected config8888"); - return 0; + uint32_t* dstP = static_cast<uint32_t*>(dst->fPixels); + const uint32_t* srcP = static_cast<const uint32_t*>(fPixels); + size_t srcInc = fRowBytes >> 2; + size_t dstInc = dst->fRowBytes >> 2; + for (int y = 0; y < height; ++y) { + proc(dstP, srcP, width); + dstP += dstInc; + srcP += srcInc; } + return true; } diff --git a/src/core/SkConfig8888.h b/src/core/SkConfig8888.h index 041773e6df..97a3433ad2 100644 --- a/src/core/SkConfig8888.h +++ b/src/core/SkConfig8888.h @@ -5,75 +5,27 @@ * found in the LICENSE file. */ -#ifndef SkConfig8888_DEFINED -#define SkConfig8888_DEFINED +#ifndef SkPixelInfo_DEFINED +#define SkPixelInfo_DEFINED -#include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkImageInfo.h" -/** - * Converts pixels from one Config8888 to another Config8888 - */ -void SkConvertConfig8888Pixels(uint32_t* dstPixels, - size_t dstRowBytes, - SkCanvas::Config8888 dstConfig, - const uint32_t* srcPixels, - size_t srcRowBytes, - SkCanvas::Config8888 srcConfig, - int width, - int height); - -/** - * Packs a, r, g, b, values into byte order specified by config. - */ -uint32_t SkPackConfig8888(SkCanvas::Config8888 config, - uint32_t a, - uint32_t r, - uint32_t g, - uint32_t b); - -/////////////////////////////////////////////////////////////////////////////// -// Implementation - -namespace { +struct SkPixelInfo { + SkColorType fColorType; + SkAlphaType fAlphaType; + size_t fRowBytes; +}; -/** - Copies all pixels from a bitmap to a dst ptr with a given rowBytes and - Config8888. The bitmap must have kARGB_8888_Config. - */ - -static inline void SkCopyBitmapToConfig8888(uint32_t* dstPixels, - size_t dstRowBytes, - SkCanvas::Config8888 dstConfig8888, - 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(); - const uint32_t* srcPixels = reinterpret_cast<uint32_t*>(srcBmp.getPixels()); - - SkConvertConfig8888Pixels(dstPixels, dstRowBytes, dstConfig8888, srcPixels, srcRowBytes, SkCanvas::kNative_Premul_Config8888, w, h); -} - -/** - 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. - */ -static inline void SkCopyConfig8888ToBitmap(const SkBitmap& dstBmp, - const uint32_t* srcPixels, - size_t srcRowBytes, - SkCanvas::Config8888 srcConfig8888) { - SkASSERT(SkBitmap::kARGB_8888_Config == dstBmp.config()); - SkAutoLockPixels alp(dstBmp); - int w = dstBmp.width(); - int h = dstBmp.height(); - size_t dstRowBytes = dstBmp.rowBytes(); - uint32_t* dstPixels = reinterpret_cast<uint32_t*>(dstBmp.getPixels()); +struct SkDstPixelInfo : SkPixelInfo { + void* fPixels; +}; - SkConvertConfig8888Pixels(dstPixels, dstRowBytes, SkCanvas::kNative_Premul_Config8888, srcPixels, srcRowBytes, srcConfig8888, w, h); -} +struct SkSrcPixelInfo : SkPixelInfo { + const void* fPixels; -} + // Guaranteed to work even if src.fPixels and dst.fPixels are the same + // (but not if they overlap partially) + bool convertPixelsTo(SkDstPixelInfo* dst, int width, int height) const; +}; #endif diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index ac46755013..4c75a36363 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -8,16 +8,6 @@ #include "SkDevice.h" #include "SkMetaData.h" -#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) - const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kBGRA_Premul_Config8888; -#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) - const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kRGBA_Premul_Config8888; -#else - const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = (SkCanvas::Config8888) -1; -#endif - -/////////////////////////////////////////////////////////////////////////////// - SkBaseDevice::SkBaseDevice() : fLeakyProperties(SkDeviceProperties::MakeDefault()) #ifdef SK_DEBUG diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index c016d062ab..9a277b0591 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -25,6 +25,7 @@ #include "GrSoftwarePathRenderer.h" #include "GrStencilBuffer.h" #include "GrTextStrike.h" +#include "SkGr.h" #include "SkRTConf.h" #include "SkRRect.h" #include "SkStrokeRec.h" @@ -1259,54 +1260,15 @@ bool GrContext::readTexturePixels(GrTexture* texture, #include "SkConfig8888.h" -namespace { -/** - * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel - * formats are representable as Config8888 and so the function returns false - * if the GrPixelConfig has no equivalent Config8888. - */ -bool grconfig_to_config8888(GrPixelConfig config, - bool unpremul, - SkCanvas::Config8888* config8888) { - switch (config) { - case kRGBA_8888_GrPixelConfig: - if (unpremul) { - *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; - } else { - *config8888 = SkCanvas::kRGBA_Premul_Config8888; - } - return true; - case kBGRA_8888_GrPixelConfig: - if (unpremul) { - *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; - } else { - *config8888 = SkCanvas::kBGRA_Premul_Config8888; - } - return true; - default: - return false; - } -} - -// It returns a configuration with where the byte position of the R & B components are swapped in -// relation to the input config. This should only be called with the result of -// grconfig_to_config8888 as it will fail for other configs. -SkCanvas::Config8888 swap_config8888_red_and_blue(SkCanvas::Config8888 config8888) { - switch (config8888) { - case SkCanvas::kBGRA_Premul_Config8888: - return SkCanvas::kRGBA_Premul_Config8888; - case SkCanvas::kBGRA_Unpremul_Config8888: - return SkCanvas::kRGBA_Unpremul_Config8888; - case SkCanvas::kRGBA_Premul_Config8888: - return SkCanvas::kBGRA_Premul_Config8888; - case SkCanvas::kRGBA_Unpremul_Config8888: - return SkCanvas::kBGRA_Unpremul_Config8888; - default: - GrCrash("Unexpected input"); - return SkCanvas::kBGRA_Unpremul_Config8888;; +// toggles between RGBA and BGRA +static SkColorType toggle_colortype32(SkColorType ct) { + if (kRGBA_8888_SkColorType == ct) { + return kBGRA_8888_SkColorType; + } else { + SkASSERT(kBGRA_8888_SkColorType == ct); + return kRGBA_8888_SkColorType; } } -} bool GrContext::readRenderTargetPixels(GrRenderTarget* target, int left, int top, int width, int height, @@ -1432,22 +1394,21 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target, } // Perform any conversions we weren't able to perform using a scratch texture. if (unpremul || swapRAndB) { - // These are initialized to suppress a warning - SkCanvas::Config8888 srcC8888 = SkCanvas::kNative_Premul_Config8888; - SkCanvas::Config8888 dstC8888 = SkCanvas::kNative_Premul_Config8888; + SkDstPixelInfo dstPI; + if (!GrPixelConfig2ColorType(dstConfig, &dstPI.fColorType)) { + return false; + } + dstPI.fAlphaType = kUnpremul_SkAlphaType; + dstPI.fPixels = buffer; + dstPI.fRowBytes = rowBytes; - SkDEBUGCODE(bool c8888IsValid =) grconfig_to_config8888(dstConfig, false, &srcC8888); - grconfig_to_config8888(dstConfig, unpremul, &dstC8888); + SkSrcPixelInfo srcPI; + srcPI.fColorType = swapRAndB ? toggle_colortype32(dstPI.fColorType) : dstPI.fColorType; + srcPI.fAlphaType = kPremul_SkAlphaType; + srcPI.fPixels = buffer; + srcPI.fRowBytes = rowBytes; - if (swapRAndB) { - SkASSERT(c8888IsValid); // we should only do r/b swap on 8888 configs - srcC8888 = swap_config8888_red_and_blue(srcC8888); - } - SkASSERT(c8888IsValid); - uint32_t* b32 = reinterpret_cast<uint32_t*>(buffer); - SkConvertConfig8888Pixels(b32, rowBytes, dstC8888, - b32, rowBytes, srcC8888, - width, height); + return srcPI.convertPixelsTo(&dstPI, width, height); } return true; } @@ -1567,18 +1528,24 @@ bool GrContext::writeRenderTargetPixels(GrRenderTarget* target, effect.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); // handle the unpremul step on the CPU if we couldn't create an effect to do it. if (NULL == effect) { - SkCanvas::Config8888 srcConfig8888, dstConfig8888; - SkDEBUGCODE(bool success = ) - grconfig_to_config8888(srcConfig, true, &srcConfig8888); - SkASSERT(success); - SkDEBUGCODE(success = ) - grconfig_to_config8888(srcConfig, false, &dstConfig8888); - SkASSERT(success); - const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); - tmpPixels.reset(width * height); - SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, - src, rowBytes, srcConfig8888, - width, height); + SkSrcPixelInfo srcPI; + if (!GrPixelConfig2ColorType(srcConfig, &srcPI.fColorType)) { + return false; + } + srcPI.fAlphaType = kUnpremul_SkAlphaType; + srcPI.fPixels = buffer; + srcPI.fRowBytes = rowBytes; + + SkDstPixelInfo dstPI; + dstPI.fColorType = srcPI.fColorType; + dstPI.fAlphaType = kPremul_SkAlphaType; + dstPI.fPixels = tmpPixels.get(); + dstPI.fRowBytes = 4 * width; + + if (!srcPI.convertPixelsTo(&dstPI, width, height)) { + return false; + } + buffer = tmpPixels.get(); rowBytes = 4 * width; } diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 94e4c8c35d..db46b86901 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -34,11 +34,22 @@ static void build_compressed_data(void* buffer, const SkBitmap& bitmap) { SkColorTable* ctable = bitmap.getColorTable(); char* dst = (char*)buffer; - uint32_t* colorTableDst = reinterpret_cast<uint32_t*>(dst); - const uint32_t* colorTableSrc = reinterpret_cast<const uint32_t*>(ctable->lockColors()); - SkConvertConfig8888Pixels(colorTableDst, 0, SkCanvas::kRGBA_Premul_Config8888, - colorTableSrc, 0, SkCanvas::kNative_Premul_Config8888, - ctable->count(), 1); + const int count = ctable->count(); + + SkDstPixelInfo dstPI; + dstPI.fColorType = kRGBA_8888_SkColorType; + dstPI.fAlphaType = kPremul_SkAlphaType; + dstPI.fPixels = buffer; + dstPI.fRowBytes = count * sizeof(SkPMColor); + + SkSrcPixelInfo srcPI; + srcPI.fColorType = kPMColor_SkColorType; + srcPI.fAlphaType = kPremul_SkAlphaType; + srcPI.fPixels = ctable->lockColors(); + srcPI.fRowBytes = count * sizeof(SkPMColor); + + srcPI.convertPixelsTo(&dstPI, count, 1); + ctable->unlockColors(); // always skip a full 256 number of entries, even if we memcpy'd fewer |