| Index: src/core/SkConfig8888.cpp
|
| diff --git a/src/core/SkConfig8888.cpp b/src/core/SkConfig8888.cpp
|
| index dd5cbc47240cb3379bc7796fbc37547a70394e40..841723bc3181ff8a7850f3d7c1fd4fb9a43a4602 100644
|
| --- a/src/core/SkConfig8888.cpp
|
| +++ b/src/core/SkConfig8888.cpp
|
| @@ -1,8 +1,9 @@
|
| #include "SkConfig8888.h"
|
| +#include "SkColorPriv.h"
|
| #include "SkMathPriv.h"
|
| #include "SkUnPreMultiply.h"
|
|
|
| -namespace {
|
| +#if 0
|
|
|
| template <int A_IDX, int R_IDX, int G_IDX, int B_IDX>
|
| inline uint32_t pack_config8888(uint32_t a, uint32_t r,
|
| @@ -278,3 +279,121 @@ uint32_t SkPackConfig8888(SkCanvas::Config8888 config,
|
| return 0;
|
| }
|
| }
|
| +#endif
|
| +
|
| +enum AlphaVerb {
|
| + kNothing_AlphaVerb,
|
| + kPremul_AlphaVerb,
|
| + kUnpremul_AlphaVerb,
|
| +};
|
| +
|
| +static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT);
|
| +
|
| +template <bool doSwapRB, AlphaVerb doAlpha> uint32_t convert32(uint32_t c) {
|
| + if (doSwapRB) {
|
| + // Lucky for us, both RGBA and BGRA only differ by R and B, and they as a pair are always
|
| + // in the same two slots, so to perform a swizzle from one order to another, it is enough
|
| + // to just swap those two bytes.
|
| + unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF;
|
| + unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF;
|
| + c = (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT);
|
| + }
|
| +
|
| + // 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 kPremul_AlphaVerb:
|
| + c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c),
|
| + SkGetPackedG32(c), SkGetPackedB32(c));
|
| + break;
|
| + case kUnpremul_AlphaVerb:
|
| + c = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(c);
|
| + break;
|
| + }
|
| + return c;
|
| +}
|
| +
|
| +template <bool doSwapRB, AlphaVerb doAlpha>
|
| +void convert32_row(uint32_t* dst, const uint32_t* src, int count) {
|
| + for (int i = 0; i < count; ++i) {
|
| + dst[i] = convert32<doSwapRB, doAlpha>(src[i]);
|
| + }
|
| +}
|
| +
|
| +static bool is_32bit_colortype(SkColorType ct) {
|
| + return kRGBA_8888_SkColorType == ct || kBGRA_8888_SkColorType == ct;
|
| +}
|
| +
|
| +static AlphaVerb compute_AlphaVerb(SkAlphaType src, SkAlphaType dst) {
|
| + SkASSERT(kIgnore_SkAlphaType != src);
|
| + SkASSERT(kIgnore_SkAlphaType != dst);
|
| +
|
| + if (kOpaque_SkAlphaType == src || kOpaque_SkAlphaType == dst || src == dst) {
|
| + return kNothing_AlphaVerb;
|
| + }
|
| + 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);
|
| +}
|
| +
|
| +bool SkPixelInfo::convertPixelsTo(SkPixelInfo* dst, int width, int height) const {
|
| + if (width <= 0 || height <= 0) {
|
| + return false;
|
| + }
|
| +
|
| + 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 {
|
| + proc = memcpy32_row;
|
| + }
|
| + break;
|
| + case kPremul_AlphaVerb:
|
| + if (doSwapRB) {
|
| + proc = convert32_row<true, kPremul_AlphaVerb>;
|
| + } else {
|
| + proc = convert32_row<false, kPremul_AlphaVerb>;
|
| + }
|
| + break;
|
| + case kUnpremul_AlphaVerb:
|
| + if (doSwapRB) {
|
| + proc = convert32_row<true, kUnpremul_AlphaVerb>;
|
| + } else {
|
| + proc = convert32_row<false, kUnpremul_AlphaVerb>;
|
| + }
|
| + break;
|
| + }
|
| +
|
| + 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;
|
| +}
|
| +
|
|
|