diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/core/SkConfig8888.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/core/SkConfig8888.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,280 @@ +#include "SkConfig8888.h" +#include "SkMathPriv.h" +#include "SkUnPreMultiply.h" + +namespace { + +template +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 +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 +inline uint32_t convert_pixel(uint32_t pixel) { + uint32_t a, r, g, b; + unpack_config8888(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); + } + return pack_config8888(a, r, g, b); +} + +template +inline uint32_t convert_pixel(uint32_t pixel) { + switch(IN_CFG) { + case SkCanvas::kNative_Premul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kNative_Unpremul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kBGRA_Premul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kBGRA_Unpremul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kRGBA_Premul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kRGBA_Unpremul_Config8888: + return convert_pixel(pixel); + break; + default: + SkDEBUGFAIL("Unexpected config8888"); + return 0; + break; + } +} + +template +inline uint32_t convert_pixel(uint32_t pixel) { + switch(OUT_CFG) { + case SkCanvas::kNative_Premul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kNative_Unpremul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kBGRA_Premul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kBGRA_Unpremul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kRGBA_Premul_Config8888: + return convert_pixel(pixel); + break; + case SkCanvas::kRGBA_Unpremul_Config8888: + return convert_pixel(pixel); + break; + default: + SkDEBUGFAIL("Unexpected config8888"); + return 0; + break; + } +} + +/** + * 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. + */ + +template +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(dstPixels); + intptr_t srcPix = reinterpret_cast(srcPixels); + + for (int y = 0; y < height; ++y) { + srcPixels = reinterpret_cast(srcPix); + dstPixels = reinterpret_cast(dstPix); + for (int x = 0; x < width; ++x) { + dstPixels[x] = convert_pixel(srcPixels[x]); + } + dstPix += dstRowBytes; + srcPix += srcRowBytes; + } +} + +template +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(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kNative_Unpremul_Config8888: + convert_config8888(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kBGRA_Premul_Config8888: + convert_config8888(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kBGRA_Unpremul_Config8888: + convert_config8888(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kRGBA_Premul_Config8888: + convert_config8888(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kRGBA_Unpremul_Config8888: + convert_config8888(dstPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); + break; + default: + SkDEBUGFAIL("Unexpected config8888"); + break; + } +} + +} + +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(srcPixels); + intptr_t dstPix = reinterpret_cast(dstPixels); + for (int y = 0; y < height; ++y) { + srcPixels = reinterpret_cast(srcPix); + dstPixels = reinterpret_cast(dstPix); + memcpy(dstPixels, srcPixels, 4 * width); + srcPix += srcRowBytes; + dstPix += dstRowBytes; + } + return; + } + } + switch(srcConfig) { + case SkCanvas::kNative_Premul_Config8888: + convert_config8888(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kNative_Unpremul_Config8888: + convert_config8888(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kBGRA_Premul_Config8888: + convert_config8888(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kBGRA_Unpremul_Config8888: + convert_config8888(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kRGBA_Premul_Config8888: + convert_config8888(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + break; + case SkCanvas::kRGBA_Unpremul_Config8888: + convert_config8888(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height); + break; + default: + SkDEBUGFAIL("Unexpected config8888"); + 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(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; + } +}