michael@0: #include "SkBlitMask.h" michael@0: #include "SkColor.h" michael@0: #include "SkColorPriv.h" michael@0: michael@0: static void D32_A8_Color(void* SK_RESTRICT dst, size_t dstRB, michael@0: const void* SK_RESTRICT maskPtr, size_t maskRB, michael@0: SkColor color, int width, int height) { michael@0: SkPMColor pmc = SkPreMultiplyColor(color); michael@0: size_t dstOffset = dstRB - (width << 2); michael@0: size_t maskOffset = maskRB - width; michael@0: SkPMColor* SK_RESTRICT device = (SkPMColor *)dst; michael@0: const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; michael@0: michael@0: do { michael@0: int w = width; michael@0: do { michael@0: unsigned aa = *mask++; michael@0: *device = SkBlendARGB32(pmc, *device, aa); michael@0: device += 1; michael@0: } while (--w != 0); michael@0: device = (uint32_t*)((char*)device + dstOffset); michael@0: mask += maskOffset; michael@0: } while (--height != 0); michael@0: } michael@0: michael@0: static void D32_A8_Opaque(void* SK_RESTRICT dst, size_t dstRB, michael@0: const void* SK_RESTRICT maskPtr, size_t maskRB, michael@0: SkColor color, int width, int height) { michael@0: SkPMColor pmc = SkPreMultiplyColor(color); michael@0: SkPMColor* SK_RESTRICT device = (SkPMColor*)dst; michael@0: const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; michael@0: michael@0: maskRB -= width; michael@0: dstRB -= (width << 2); michael@0: do { michael@0: int w = width; michael@0: do { michael@0: unsigned aa = *mask++; michael@0: *device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa)); michael@0: device += 1; michael@0: } while (--w != 0); michael@0: device = (uint32_t*)((char*)device + dstRB); michael@0: mask += maskRB; michael@0: } while (--height != 0); michael@0: } michael@0: michael@0: static void D32_A8_Black(void* SK_RESTRICT dst, size_t dstRB, michael@0: const void* SK_RESTRICT maskPtr, size_t maskRB, michael@0: SkColor, int width, int height) { michael@0: SkPMColor* SK_RESTRICT device = (SkPMColor*)dst; michael@0: const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; michael@0: michael@0: maskRB -= width; michael@0: dstRB -= (width << 2); michael@0: do { michael@0: int w = width; michael@0: do { michael@0: unsigned aa = *mask++; michael@0: *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa)); michael@0: device += 1; michael@0: } while (--w != 0); michael@0: device = (uint32_t*)((char*)device + dstRB); michael@0: mask += maskRB; michael@0: } while (--height != 0); michael@0: } michael@0: michael@0: SkBlitMask::BlitLCD16RowProc SkBlitMask::BlitLCD16RowFactory(bool isOpaque) { michael@0: BlitLCD16RowProc proc = PlatformBlitRowProcs16(isOpaque); michael@0: if (proc) { michael@0: return proc; michael@0: } michael@0: michael@0: if (isOpaque) { michael@0: return SkBlitLCD16OpaqueRow; michael@0: } else { michael@0: return SkBlitLCD16Row; michael@0: } michael@0: } michael@0: michael@0: static void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB, michael@0: const void* SK_RESTRICT mask, size_t maskRB, michael@0: SkColor color, int width, int height) { michael@0: michael@0: SkPMColor* dstRow = (SkPMColor*)dst; michael@0: const uint16_t* srcRow = (const uint16_t*)mask; michael@0: SkPMColor opaqueDst; michael@0: michael@0: SkBlitMask::BlitLCD16RowProc proc = NULL; michael@0: bool isOpaque = (0xFF == SkColorGetA(color)); michael@0: proc = SkBlitMask::BlitLCD16RowFactory(isOpaque); michael@0: SkASSERT(proc != NULL); michael@0: michael@0: if (isOpaque) { michael@0: opaqueDst = SkPreMultiplyColor(color); michael@0: } else { michael@0: opaqueDst = 0; // ignored michael@0: } michael@0: michael@0: do { michael@0: proc(dstRow, srcRow, color, width, opaqueDst); michael@0: dstRow = (SkPMColor*)((char*)dstRow + dstRB); michael@0: srcRow = (const uint16_t*)((const char*)srcRow + maskRB); michael@0: } while (--height != 0); michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: static void blit_lcd32_opaque_row(SkPMColor* SK_RESTRICT dst, michael@0: const SkPMColor* SK_RESTRICT src, michael@0: SkColor color, int width) { michael@0: int srcR = SkColorGetR(color); michael@0: int srcG = SkColorGetG(color); michael@0: int srcB = SkColorGetB(color); michael@0: michael@0: for (int i = 0; i < width; i++) { michael@0: SkPMColor mask = src[i]; michael@0: if (0 == mask) { michael@0: continue; michael@0: } michael@0: michael@0: SkPMColor d = dst[i]; michael@0: michael@0: int maskR = SkGetPackedR32(mask); michael@0: int maskG = SkGetPackedG32(mask); michael@0: int maskB = SkGetPackedB32(mask); michael@0: michael@0: // Now upscale them to 0..256, so we can use SkAlphaBlend michael@0: maskR = SkAlpha255To256(maskR); michael@0: maskG = SkAlpha255To256(maskG); michael@0: maskB = SkAlpha255To256(maskB); michael@0: michael@0: int dstR = SkGetPackedR32(d); michael@0: int dstG = SkGetPackedG32(d); michael@0: int dstB = SkGetPackedB32(d); michael@0: michael@0: // LCD blitting is only supported if the dst is known/required michael@0: // to be opaque michael@0: dst[i] = SkPackARGB32(0xFF, michael@0: SkAlphaBlend(srcR, dstR, maskR), michael@0: SkAlphaBlend(srcG, dstG, maskG), michael@0: SkAlphaBlend(srcB, dstB, maskB)); michael@0: } michael@0: } michael@0: michael@0: static void blit_lcd32_row(SkPMColor* SK_RESTRICT dst, michael@0: const SkPMColor* SK_RESTRICT src, michael@0: SkColor color, int width) { michael@0: int srcA = SkColorGetA(color); michael@0: int srcR = SkColorGetR(color); michael@0: int srcG = SkColorGetG(color); michael@0: int srcB = SkColorGetB(color); michael@0: michael@0: srcA = SkAlpha255To256(srcA); michael@0: michael@0: for (int i = 0; i < width; i++) { michael@0: SkPMColor mask = src[i]; michael@0: if (0 == mask) { michael@0: continue; michael@0: } michael@0: michael@0: SkPMColor d = dst[i]; michael@0: michael@0: int maskR = SkGetPackedR32(mask); michael@0: int maskG = SkGetPackedG32(mask); michael@0: int maskB = SkGetPackedB32(mask); michael@0: michael@0: // Now upscale them to 0..256, so we can use SkAlphaBlend michael@0: maskR = SkAlpha255To256(maskR); michael@0: maskG = SkAlpha255To256(maskG); michael@0: maskB = SkAlpha255To256(maskB); michael@0: michael@0: maskR = maskR * srcA >> 8; michael@0: maskG = maskG * srcA >> 8; michael@0: maskB = maskB * srcA >> 8; michael@0: michael@0: int dstR = SkGetPackedR32(d); michael@0: int dstG = SkGetPackedG32(d); michael@0: int dstB = SkGetPackedB32(d); michael@0: michael@0: // LCD blitting is only supported if the dst is known/required michael@0: // to be opaque michael@0: dst[i] = SkPackARGB32(0xFF, michael@0: SkAlphaBlend(srcR, dstR, maskR), michael@0: SkAlphaBlend(srcG, dstG, maskG), michael@0: SkAlphaBlend(srcB, dstB, maskB)); michael@0: } michael@0: } michael@0: michael@0: static void D32_LCD32_Blend(void* SK_RESTRICT dst, size_t dstRB, michael@0: const void* SK_RESTRICT mask, size_t maskRB, michael@0: SkColor color, int width, int height) { michael@0: SkASSERT(height > 0); michael@0: SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst; michael@0: const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask; michael@0: michael@0: do { michael@0: blit_lcd32_row(dstRow, srcRow, color, width); michael@0: dstRow = (SkPMColor*)((char*)dstRow + dstRB); michael@0: srcRow = (const SkPMColor*)((const char*)srcRow + maskRB); michael@0: } while (--height != 0); michael@0: } michael@0: michael@0: static void D32_LCD32_Opaque(void* SK_RESTRICT dst, size_t dstRB, michael@0: const void* SK_RESTRICT mask, size_t maskRB, michael@0: SkColor color, int width, int height) { michael@0: SkASSERT(height > 0); michael@0: SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst; michael@0: const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask; michael@0: michael@0: do { michael@0: blit_lcd32_opaque_row(dstRow, srcRow, color, width); michael@0: dstRow = (SkPMColor*)((char*)dstRow + dstRB); michael@0: srcRow = (const SkPMColor*)((const char*)srcRow + maskRB); michael@0: } while (--height != 0); michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: static SkBlitMask::ColorProc D32_A8_Factory(SkColor color) { michael@0: if (SK_ColorBLACK == color) { michael@0: return D32_A8_Black; michael@0: } else if (0xFF == SkColorGetA(color)) { michael@0: return D32_A8_Opaque; michael@0: } else { michael@0: return D32_A8_Color; michael@0: } michael@0: } michael@0: michael@0: static SkBlitMask::ColorProc D32_LCD32_Factory(SkColor color) { michael@0: return (0xFF == SkColorGetA(color)) ? D32_LCD32_Opaque : D32_LCD32_Blend; michael@0: } michael@0: michael@0: SkBlitMask::ColorProc SkBlitMask::ColorFactory(SkBitmap::Config config, michael@0: SkMask::Format format, michael@0: SkColor color) { michael@0: ColorProc proc = PlatformColorProcs(config, format, color); michael@0: if (proc) { michael@0: return proc; michael@0: } michael@0: michael@0: switch (config) { michael@0: case SkBitmap::kARGB_8888_Config: michael@0: switch (format) { michael@0: case SkMask::kA8_Format: michael@0: return D32_A8_Factory(color); michael@0: case SkMask::kLCD16_Format: michael@0: return D32_LCD16_Proc; michael@0: case SkMask::kLCD32_Format: michael@0: return D32_LCD32_Factory(color); michael@0: default: michael@0: break; michael@0: } michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: return NULL; michael@0: } michael@0: michael@0: bool SkBlitMask::BlitColor(const SkBitmap& device, const SkMask& mask, michael@0: const SkIRect& clip, SkColor color) { michael@0: ColorProc proc = ColorFactory(device.config(), mask.fFormat, color); michael@0: if (proc) { michael@0: int x = clip.fLeft; michael@0: int y = clip.fTop; michael@0: proc(device.getAddr32(x, y), device.rowBytes(), mask.getAddr(x, y), michael@0: mask.fRowBytes, color, clip.width(), clip.height()); michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst, michael@0: const uint8_t* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: int i, octuple = (count + 7) >> 3; michael@0: for (i = 0; i < octuple; ++i) { michael@0: int m = *mask++; michael@0: if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } michael@0: if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); } michael@0: if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); } michael@0: if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); } michael@0: if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); } michael@0: if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); } michael@0: if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); } michael@0: if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); } michael@0: src += 8; michael@0: dst += 8; michael@0: } michael@0: count &= 7; michael@0: if (count > 0) { michael@0: int m = *mask; michael@0: do { michael@0: if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } michael@0: m <<= 1; michael@0: src += 1; michael@0: dst += 1; michael@0: } while (--count > 0); michael@0: } michael@0: } michael@0: michael@0: static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, michael@0: const uint8_t* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: int i, octuple = (count + 7) >> 3; michael@0: for (i = 0; i < octuple; ++i) { michael@0: int m = *mask++; michael@0: if (m & 0x80) { dst[0] = src[0]; } michael@0: if (m & 0x40) { dst[1] = src[1]; } michael@0: if (m & 0x20) { dst[2] = src[2]; } michael@0: if (m & 0x10) { dst[3] = src[3]; } michael@0: if (m & 0x08) { dst[4] = src[4]; } michael@0: if (m & 0x04) { dst[5] = src[5]; } michael@0: if (m & 0x02) { dst[6] = src[6]; } michael@0: if (m & 0x01) { dst[7] = src[7]; } michael@0: src += 8; michael@0: dst += 8; michael@0: } michael@0: count &= 7; michael@0: if (count > 0) { michael@0: int m = *mask; michael@0: do { michael@0: if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } michael@0: m <<= 1; michael@0: src += 1; michael@0: dst += 1; michael@0: } while (--count > 0); michael@0: } michael@0: } michael@0: michael@0: static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst, michael@0: const uint8_t* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: for (int i = 0; i < count; ++i) { michael@0: if (mask[i]) { michael@0: dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]); michael@0: } michael@0: } michael@0: } michael@0: michael@0: // expand the steps that SkAlphaMulQ performs, but this way we can michael@0: // exand.. add.. combine michael@0: // instead of michael@0: // expand..combine add expand..combine michael@0: // michael@0: #define EXPAND0(v, m, s) ((v) & (m)) * (s) michael@0: #define EXPAND1(v, m, s) (((v) >> 8) & (m)) * (s) michael@0: #define COMBINE(e0, e1, m) ((((e0) >> 8) & (m)) | ((e1) & ~(m))) michael@0: michael@0: static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, michael@0: const uint8_t* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: #if 0 // suppress warning michael@0: const uint32_t rbmask = gMask_00FF00FF; michael@0: #endif michael@0: for (int i = 0; i < count; ++i) { michael@0: int m = mask[i]; michael@0: if (m) { michael@0: m += (m >> 7); michael@0: #if 1 michael@0: // this is slightly slower than the expand/combine version, but it michael@0: // is much closer to the old results, so we use it for now to reduce michael@0: // rebaselining. michael@0: dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m); michael@0: #else michael@0: uint32_t v = src[i]; michael@0: uint32_t s0 = EXPAND0(v, rbmask, m); michael@0: uint32_t s1 = EXPAND1(v, rbmask, m); michael@0: v = dst[i]; michael@0: uint32_t d0 = EXPAND0(v, rbmask, m); michael@0: uint32_t d1 = EXPAND1(v, rbmask, m); michael@0: dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask); michael@0: #endif michael@0: } michael@0: } michael@0: } michael@0: michael@0: static int upscale31To255(int value) { michael@0: value = (value << 3) | (value >> 2); michael@0: return value; michael@0: } michael@0: michael@0: static int src_alpha_blend(int src, int dst, int srcA, int mask) { michael@0: michael@0: return dst + SkAlphaMul(src - SkAlphaMul(srcA, dst), mask); michael@0: } michael@0: michael@0: static void LCD16_RowProc_Blend(SkPMColor* SK_RESTRICT dst, michael@0: const uint16_t* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: for (int i = 0; i < count; ++i) { michael@0: uint16_t m = mask[i]; michael@0: if (0 == m) { michael@0: continue; michael@0: } michael@0: michael@0: SkPMColor s = src[i]; michael@0: SkPMColor d = dst[i]; michael@0: michael@0: int srcA = SkGetPackedA32(s); michael@0: int srcR = SkGetPackedR32(s); michael@0: int srcG = SkGetPackedG32(s); michael@0: int srcB = SkGetPackedB32(s); michael@0: michael@0: srcA += srcA >> 7; michael@0: michael@0: /* We want all of these in 5bits, hence the shifts in case one of them michael@0: * (green) is 6bits. michael@0: */ michael@0: int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5); michael@0: int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5); michael@0: int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5); michael@0: michael@0: maskR = upscale31To255(maskR); michael@0: maskG = upscale31To255(maskG); michael@0: maskB = upscale31To255(maskB); michael@0: michael@0: int dstR = SkGetPackedR32(d); michael@0: int dstG = SkGetPackedG32(d); michael@0: int dstB = SkGetPackedB32(d); michael@0: michael@0: // LCD blitting is only supported if the dst is known/required michael@0: // to be opaque michael@0: dst[i] = SkPackARGB32(0xFF, michael@0: src_alpha_blend(srcR, dstR, srcA, maskR), michael@0: src_alpha_blend(srcG, dstG, srcA, maskG), michael@0: src_alpha_blend(srcB, dstB, srcA, maskB)); michael@0: } michael@0: } michael@0: michael@0: static void LCD16_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, michael@0: const uint16_t* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: for (int i = 0; i < count; ++i) { michael@0: uint16_t m = mask[i]; michael@0: if (0 == m) { michael@0: continue; michael@0: } michael@0: michael@0: SkPMColor s = src[i]; michael@0: SkPMColor d = dst[i]; michael@0: michael@0: int srcR = SkGetPackedR32(s); michael@0: int srcG = SkGetPackedG32(s); michael@0: int srcB = SkGetPackedB32(s); michael@0: michael@0: /* We want all of these in 5bits, hence the shifts in case one of them michael@0: * (green) is 6bits. michael@0: */ michael@0: int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5); michael@0: int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5); michael@0: int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5); michael@0: michael@0: // Now upscale them to 0..32, so we can use blend32 michael@0: maskR = SkUpscale31To32(maskR); michael@0: maskG = SkUpscale31To32(maskG); michael@0: maskB = SkUpscale31To32(maskB); michael@0: michael@0: int dstR = SkGetPackedR32(d); michael@0: int dstG = SkGetPackedG32(d); michael@0: int dstB = SkGetPackedB32(d); michael@0: michael@0: // LCD blitting is only supported if the dst is known/required michael@0: // to be opaque michael@0: dst[i] = SkPackARGB32(0xFF, michael@0: SkBlend32(srcR, dstR, maskR), michael@0: SkBlend32(srcG, dstG, maskG), michael@0: SkBlend32(srcB, dstB, maskB)); michael@0: } michael@0: } michael@0: michael@0: static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst, michael@0: const SkPMColor* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: for (int i = 0; i < count; ++i) { michael@0: SkPMColor m = mask[i]; michael@0: if (0 == m) { michael@0: continue; michael@0: } michael@0: michael@0: SkPMColor s = src[i]; michael@0: int srcA = SkGetPackedA32(s); michael@0: int srcR = SkGetPackedR32(s); michael@0: int srcG = SkGetPackedG32(s); michael@0: int srcB = SkGetPackedB32(s); michael@0: michael@0: srcA = SkAlpha255To256(srcA); michael@0: michael@0: SkPMColor d = dst[i]; michael@0: michael@0: int maskR = SkGetPackedR32(m); michael@0: int maskG = SkGetPackedG32(m); michael@0: int maskB = SkGetPackedB32(m); michael@0: michael@0: // Now upscale them to 0..256 michael@0: maskR = SkAlpha255To256(maskR); michael@0: maskG = SkAlpha255To256(maskG); michael@0: maskB = SkAlpha255To256(maskB); michael@0: michael@0: int dstR = SkGetPackedR32(d); michael@0: int dstG = SkGetPackedG32(d); michael@0: int dstB = SkGetPackedB32(d); michael@0: michael@0: // LCD blitting is only supported if the dst is known/required michael@0: // to be opaque michael@0: dst[i] = SkPackARGB32(0xFF, michael@0: src_alpha_blend(srcR, dstR, srcA, maskR), michael@0: src_alpha_blend(srcG, dstG, srcA, maskG), michael@0: src_alpha_blend(srcB, dstB, srcA, maskB)); michael@0: } michael@0: } michael@0: michael@0: static void LCD32_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, michael@0: const SkPMColor* SK_RESTRICT mask, michael@0: const SkPMColor* SK_RESTRICT src, int count) { michael@0: for (int i = 0; i < count; ++i) { michael@0: SkPMColor m = mask[i]; michael@0: if (0 == m) { michael@0: continue; michael@0: } michael@0: michael@0: SkPMColor s = src[i]; michael@0: SkPMColor d = dst[i]; michael@0: michael@0: int maskR = SkGetPackedR32(m); michael@0: int maskG = SkGetPackedG32(m); michael@0: int maskB = SkGetPackedB32(m); michael@0: michael@0: int srcR = SkGetPackedR32(s); michael@0: int srcG = SkGetPackedG32(s); michael@0: int srcB = SkGetPackedB32(s); michael@0: michael@0: int dstR = SkGetPackedR32(d); michael@0: int dstG = SkGetPackedG32(d); michael@0: int dstB = SkGetPackedB32(d); michael@0: michael@0: // Now upscale them to 0..256, so we can use SkAlphaBlend michael@0: maskR = SkAlpha255To256(maskR); michael@0: maskG = SkAlpha255To256(maskG); michael@0: maskB = SkAlpha255To256(maskB); michael@0: michael@0: // LCD blitting is only supported if the dst is known/required michael@0: // to be opaque michael@0: dst[i] = SkPackARGB32(0xFF, michael@0: SkAlphaBlend(srcR, dstR, maskR), michael@0: SkAlphaBlend(srcG, dstG, maskG), michael@0: SkAlphaBlend(srcB, dstB, maskB)); michael@0: } michael@0: } michael@0: michael@0: SkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config, michael@0: SkMask::Format format, michael@0: RowFlags flags) { michael@0: // make this opt-in until chrome can rebaseline michael@0: RowProc proc = PlatformRowProcs(config, format, flags); michael@0: if (proc) { michael@0: return proc; michael@0: } michael@0: michael@0: static const RowProc gProcs[] = { michael@0: // need X coordinate to handle BW michael@0: false ? (RowProc)BW_RowProc_Blend : NULL, // suppress unused warning michael@0: false ? (RowProc)BW_RowProc_Opaque : NULL, // suppress unused warning michael@0: (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque, michael@0: (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque, michael@0: (RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque, michael@0: }; michael@0: michael@0: int index; michael@0: switch (config) { michael@0: case SkBitmap::kARGB_8888_Config: michael@0: switch (format) { michael@0: case SkMask::kBW_Format: index = 0; break; michael@0: case SkMask::kA8_Format: index = 2; break; michael@0: case SkMask::kLCD16_Format: index = 4; break; michael@0: case SkMask::kLCD32_Format: index = 6; break; michael@0: default: michael@0: return NULL; michael@0: } michael@0: if (flags & kSrcIsOpaque_RowFlag) { michael@0: index |= 1; michael@0: } michael@0: SkASSERT((size_t)index < SK_ARRAY_COUNT(gProcs)); michael@0: return gProcs[index]; michael@0: default: michael@0: break; michael@0: } michael@0: return NULL; michael@0: }