diff options
Diffstat (limited to 'skia/sgl/SkBlitRow_D16.cpp')
-rw-r--r-- | skia/sgl/SkBlitRow_D16.cpp | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/skia/sgl/SkBlitRow_D16.cpp b/skia/sgl/SkBlitRow_D16.cpp new file mode 100644 index 0000000..f40df36 --- /dev/null +++ b/skia/sgl/SkBlitRow_D16.cpp @@ -0,0 +1,258 @@ +#include "SkBlitRow.h" +#include "SkColorPriv.h" +#include "SkDither.h" + +/////////////////////////////////////////////////////////////////////////////// + +static void S32_D565_Opaque(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + U8CPU alpha, int /*x*/, int /*y*/) { + SkASSERT(255 == alpha); + + if (count > 0) { + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + SkASSERT(SkGetPackedA32(c) == 255); + *dst++ = SkPixel32ToPixel16_ToU16(c); + } while (--count != 0); + } +} + +static void S32_D565_Blend(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + U8CPU alpha, int /*x*/, int /*y*/) { + SkASSERT(255 > alpha); + + if (count > 0) { + int scale = SkAlpha255To256(alpha); + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + SkASSERT(SkGetPackedA32(c) == 255); + uint16_t d = *dst; + *dst++ = SkPackRGB16( + SkAlphaBlend(SkPacked32ToR16(c), SkGetPackedR16(d), scale), + SkAlphaBlend(SkPacked32ToG16(c), SkGetPackedG16(d), scale), + SkAlphaBlend(SkPacked32ToB16(c), SkGetPackedB16(d), scale)); + } while (--count != 0); + } +} + +static void S32A_D565_Opaque(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + U8CPU alpha, int /*x*/, int /*y*/) { + SkASSERT(255 == alpha); + + if (count > 0) { + do { + SkPMColor c = *src++; + SkPMColorAssert(c); +// if (__builtin_expect(c!=0, 1)) + if (c) { + *dst = SkSrcOver32To16(c, *dst); + } + dst += 1; + } while (--count != 0); + } +} + +static void S32A_D565_Blend(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + U8CPU alpha, int /*x*/, int /*y*/) { + SkASSERT(255 > alpha); + + if (count > 0) { + int src_scale = SkAlpha255To256(alpha); + do { + SkPMColor sc = *src++; + SkPMColorAssert(sc); + if (sc) + { + uint16_t dc = *dst; + unsigned sa = SkGetPackedA32(sc); + unsigned dr, dg, db; + + if (sa == 255) { + dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale); + dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale); + db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale); + } else { + unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); + dr = (SkPacked32ToR16(sc) * src_scale + SkGetPackedR16(dc) * dst_scale) >> 8; + dg = (SkPacked32ToG16(sc) * src_scale + SkGetPackedG16(dc) * dst_scale) >> 8; + db = (SkPacked32ToB16(sc) * src_scale + SkGetPackedB16(dc) * dst_scale) >> 8; + } + *dst = SkPackRGB16(dr, dg, db); + } + dst += 1; + } while (--count != 0); + } +} + +///////////////////////////////////////////////////////////////////////////// + +static void S32_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y) { + SkASSERT(255 == alpha); + + if (count > 0) { + DITHER_565_SCAN(y); + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + SkASSERT(SkGetPackedA32(c) == 255); + + unsigned dither = DITHER_VALUE(x); + *dst++ = SkDitherRGB32To565(c, dither); + DITHER_INC_X(x); + } while (--count != 0); + } +} + +static void S32_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y) { + SkASSERT(255 > alpha); + + if (count > 0) { + int scale = SkAlpha255To256(alpha); + DITHER_565_SCAN(y); + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + SkASSERT(SkGetPackedA32(c) == 255); + + int dither = DITHER_VALUE(x); + int sr = SkGetPackedR32(c); + int sg = SkGetPackedG32(c); + int sb = SkGetPackedB32(c); + sr = SkDITHER_R32To565(sr, dither); + sg = SkDITHER_G32To565(sg, dither); + sb = SkDITHER_B32To565(sb, dither); + + uint16_t d = *dst; + *dst++ = SkPackRGB16(SkAlphaBlend(sr, SkGetPackedR16(d), scale), + SkAlphaBlend(sg, SkGetPackedG16(d), scale), + SkAlphaBlend(sb, SkGetPackedB16(d), scale)); + DITHER_INC_X(x); + } while (--count != 0); + } +} + +static void S32A_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y) { + SkASSERT(255 == alpha); + + if (count > 0) { + DITHER_565_SCAN(y); + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + if (c) { + unsigned a = SkGetPackedA32(c); + + int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); + + unsigned sr = SkGetPackedR32(c); + unsigned sg = SkGetPackedG32(c); + unsigned sb = SkGetPackedB32(c); + sr = SkDITHER_R32_FOR_565(sr, d); + sg = SkDITHER_G32_FOR_565(sg, d); + sb = SkDITHER_B32_FOR_565(sb, d); + + uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); + uint32_t dst_expanded = SkExpand_rgb_16(*dst); + dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); + // now src and dst expanded are in g:11 r:10 x:1 b:10 + *dst = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); + } + dst += 1; + DITHER_INC_X(x); + } while (--count != 0); + } +} + +static void S32A_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y) { + SkASSERT(255 > alpha); + + if (count > 0) { + int src_scale = SkAlpha255To256(alpha); + DITHER_565_SCAN(y); + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + if (c) + { + unsigned d = *dst; + int sa = SkGetPackedA32(c); + int dst_scale = SkAlpha255To256(255 - SkAlphaMul(sa, src_scale)); + int dither = DITHER_VALUE(x); + + int sr = SkGetPackedR32(c); + int sg = SkGetPackedG32(c); + int sb = SkGetPackedB32(c); + sr = SkDITHER_R32To565(sr, dither); + sg = SkDITHER_G32To565(sg, dither); + sb = SkDITHER_B32To565(sb, dither); + + int dr = (sr * src_scale + SkGetPackedR16(d) * dst_scale) >> 8; + int dg = (sg * src_scale + SkGetPackedG16(d) * dst_scale) >> 8; + int db = (sb * src_scale + SkGetPackedB16(d) * dst_scale) >> 8; + + *dst = SkPackRGB16(dr, dg, db); + } + dst += 1; + DITHER_INC_X(x); + } while (--count != 0); + } +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#ifdef USE_T32CB16BLEND_ASM + extern "C" void scanline_t32cb16blend_arm(uint16_t*, uint32_t*, size_t); +#endif + +static const SkBlitRow::Proc gProcs16[] = { + // no dither + S32_D565_Opaque, + S32_D565_Blend, + +#ifdef USE_T32CB16BLEND_ASM + (SkBlitRow::Proc)scanline_t32cb16blend_arm, +#else + S32A_D565_Opaque, +#endif + + S32A_D565_Blend, + + // dither + S32_D565_Opaque_Dither, + S32_D565_Blend_Dither, + + S32A_D565_Opaque_Dither, + S32A_D565_Blend_Dither +}; + +extern SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags); + +SkBlitRow::Proc SkBlitRow::Factory(unsigned flags, SkBitmap::Config config) { + SkASSERT(flags < SK_ARRAY_COUNT(gProcs16)); + + switch (config) { + case SkBitmap::kRGB_565_Config: + return gProcs16[flags]; + case SkBitmap::kARGB_4444_Config: + return SkBlitRow_Factory_4444(flags); + default: + break; + } + return NULL; +} + |