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; |
+} |
+ |