11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkBlitMask.h" 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkColor.h" 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkColorPriv.h" 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void D32_A8_Color(void* SK_RESTRICT dst, size_t dstRB, 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* SK_RESTRICT maskPtr, size_t maskRB, 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color, int width, int height) { 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor pmc = SkPreMultiplyColor(color); 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t dstOffset = dstRB - (width << 2); 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t maskOffset = maskRB - width; 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT device = (SkPMColor *)dst; 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int w = width; 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned aa = *mask++; 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *device = SkBlendARGB32(pmc, *device, aa); 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger device += 1; 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--w != 0); 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger device = (uint32_t*)((char*)device + dstOffset); 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask += maskOffset; 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--height != 0); 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void D32_A8_Opaque(void* SK_RESTRICT dst, size_t dstRB, 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* SK_RESTRICT maskPtr, size_t maskRB, 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color, int width, int height) { 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor pmc = SkPreMultiplyColor(color); 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT device = (SkPMColor*)dst; 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskRB -= width; 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dstRB -= (width << 2); 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int w = width; 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned aa = *mask++; 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa)); 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger device += 1; 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--w != 0); 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger device = (uint32_t*)((char*)device + dstRB); 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask += maskRB; 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--height != 0); 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void D32_A8_Black(void* SK_RESTRICT dst, size_t dstRB, 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* SK_RESTRICT maskPtr, size_t maskRB, 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor, int width, int height) { 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT device = (SkPMColor*)dst; 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskRB -= width; 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dstRB -= (width << 2); 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int w = width; 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned aa = *mask++; 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa)); 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger device += 1; 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--w != 0); 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger device = (uint32_t*)((char*)device + dstRB); 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask += maskRB; 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--height != 0); 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 674f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkBlitMask::BlitLCD16RowProc SkBlitMask::BlitLCD16RowFactory(bool isOpaque) { 684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger BlitLCD16RowProc proc = PlatformBlitRowProcs16(isOpaque); 694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (proc) { 704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return proc; 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (isOpaque) { 744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkBlitLCD16OpaqueRow; 754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkBlitLCD16Row; 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB, 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* SK_RESTRICT mask, size_t maskRB, 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color, int width, int height) { 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* dstRow = (SkPMColor*)dst; 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint16_t* srcRow = (const uint16_t*)mask; 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor opaqueDst; 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkBlitMask::BlitLCD16RowProc proc = NULL; 894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool isOpaque = (0xFF == SkColorGetA(color)); 904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger proc = SkBlitMask::BlitLCD16RowFactory(isOpaque); 914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkASSERT(proc != NULL); 924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (isOpaque) { 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger opaqueDst = SkPreMultiplyColor(color); 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger opaqueDst = 0; // ignored 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger proc(dstRow, srcRow, color, width, opaqueDst); 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dstRow = (SkPMColor*)((char*)dstRow + dstRB); 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcRow = (const uint16_t*)((const char*)srcRow + maskRB); 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--height != 0); 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void blit_lcd32_opaque_row(SkPMColor* SK_RESTRICT dst, 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color, int width) { 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcR = SkColorGetR(color); 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcG = SkColorGetG(color); 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcB = SkColorGetB(color); 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < width; i++) { 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor mask = src[i]; 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == mask) { 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger continue; 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor d = dst[i]; 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskR = SkGetPackedR32(mask); 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskG = SkGetPackedG32(mask); 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskB = SkGetPackedB32(mask); 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Now upscale them to 0..256, so we can use SkAlphaBlend 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskR = SkAlpha255To256(maskR); 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskG = SkAlpha255To256(maskG); 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskB = SkAlpha255To256(maskB); 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstR = SkGetPackedR32(d); 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstG = SkGetPackedG32(d); 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstB = SkGetPackedB32(d); 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // LCD blitting is only supported if the dst is known/required 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // to be opaque 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkPackARGB32(0xFF, 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcR, dstR, maskR), 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcG, dstG, maskG), 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcB, dstB, maskB)); 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void blit_lcd32_row(SkPMColor* SK_RESTRICT dst, 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color, int width) { 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcA = SkColorGetA(color); 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcR = SkColorGetR(color); 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcG = SkColorGetG(color); 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcB = SkColorGetB(color); 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcA = SkAlpha255To256(srcA); 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < width; i++) { 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor mask = src[i]; 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == mask) { 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger continue; 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor d = dst[i]; 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskR = SkGetPackedR32(mask); 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskG = SkGetPackedG32(mask); 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskB = SkGetPackedB32(mask); 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Now upscale them to 0..256, so we can use SkAlphaBlend 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskR = SkAlpha255To256(maskR); 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskG = SkAlpha255To256(maskG); 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskB = SkAlpha255To256(maskB); 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskR = maskR * srcA >> 8; 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskG = maskG * srcA >> 8; 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskB = maskB * srcA >> 8; 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstR = SkGetPackedR32(d); 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstG = SkGetPackedG32(d); 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstB = SkGetPackedB32(d); 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // LCD blitting is only supported if the dst is known/required 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // to be opaque 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkPackARGB32(0xFF, 1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcR, dstR, maskR), 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcG, dstG, maskG), 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcB, dstB, maskB)); 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void D32_LCD32_Blend(void* SK_RESTRICT dst, size_t dstRB, 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* SK_RESTRICT mask, size_t maskRB, 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color, int width, int height) { 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(height > 0); 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst; 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask; 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger blit_lcd32_row(dstRow, srcRow, color, width); 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dstRow = (SkPMColor*)((char*)dstRow + dstRB); 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcRow = (const SkPMColor*)((const char*)srcRow + maskRB); 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--height != 0); 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void D32_LCD32_Opaque(void* SK_RESTRICT dst, size_t dstRB, 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* SK_RESTRICT mask, size_t maskRB, 2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color, int width, int height) { 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(height > 0); 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst; 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask; 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger blit_lcd32_opaque_row(dstRow, srcRow, color, width); 2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dstRow = (SkPMColor*)((char*)dstRow + dstRB); 2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcRow = (const SkPMColor*)((const char*)srcRow + maskRB); 2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--height != 0); 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBlitMask::ColorProc D32_A8_Factory(SkColor color) { 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SK_ColorBLACK == color) { 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return D32_A8_Black; 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (0xFF == SkColorGetA(color)) { 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return D32_A8_Opaque; 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return D32_A8_Color; 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBlitMask::ColorProc D32_LCD32_Factory(SkColor color) { 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return (0xFF == SkColorGetA(color)) ? D32_LCD32_Opaque : D32_LCD32_Blend; 2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2331cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkBlitMask::ColorProc SkBlitMask::ColorFactory(SkBitmap::Config config, 2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask::Format format, 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor color) { 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ColorProc proc = PlatformColorProcs(config, format, color); 2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (proc) { 2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return proc; 2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (config) { 2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkBitmap::kARGB_8888_Config: 2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (format) { 2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kA8_Format: 2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return D32_A8_Factory(color); 2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kLCD16_Format: 2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return D32_LCD16_Proc; 2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kLCD32_Format: 2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return D32_LCD32_Factory(color); 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return NULL; 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkBlitMask::BlitColor(const SkBitmap& device, const SkMask& mask, 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkIRect& clip, SkColor color) { 2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ColorProc proc = ColorFactory(device.config(), mask.fFormat, color); 2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (proc) { 2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int x = clip.fLeft; 2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int y = clip.fTop; 2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger proc(device.getAddr32(x, y), device.rowBytes(), mask.getAddr(x, y), 2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask.fRowBytes, color, clip.width(), clip.height()); 2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst, 2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT mask, 2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int i, octuple = (count + 7) >> 3; 2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (i = 0; i < octuple; ++i) { 2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int m = *mask++; 2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } 2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); } 2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); } 2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); } 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); } 2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); } 2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); } 2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); } 2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src += 8; 2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst += 8; 2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger count &= 7; 2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (count > 0) { 2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int m = *mask; 2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } 2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m <<= 1; 2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src += 1; 3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst += 1; 3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--count > 0); 3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, 3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT mask, 3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int i, octuple = (count + 7) >> 3; 3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (i = 0; i < octuple; ++i) { 3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int m = *mask++; 3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x80) { dst[0] = src[0]; } 3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x40) { dst[1] = src[1]; } 3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x20) { dst[2] = src[2]; } 3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x10) { dst[3] = src[3]; } 3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x08) { dst[4] = src[4]; } 3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x04) { dst[5] = src[5]; } 3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x02) { dst[6] = src[6]; } 3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x01) { dst[7] = src[7]; } 3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src += 8; 3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst += 8; 3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger count &= 7; 3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (count > 0) { 3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int m = *mask; 3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } 3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m <<= 1; 3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src += 1; 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst += 1; 3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--count > 0); 3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst, 3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT mask, 3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (mask[i]) { 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]); 3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// expand the steps that SkAlphaMulQ performs, but this way we can 3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// exand.. add.. combine 3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// instead of 3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// expand..combine add expand..combine 3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// 3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define EXPAND0(v, m, s) ((v) & (m)) * (s) 3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define EXPAND1(v, m, s) (((v) >> 8) & (m)) * (s) 3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define COMBINE(e0, e1, m) ((((e0) >> 8) & (m)) | ((e1) & ~(m))) 3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, 3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT mask, 3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint32_t rbmask = gMask_00FF00FF; 3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int m = mask[i]; 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (m) { 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m += (m >> 7); 3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 1 3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // this is slightly slower than the expand/combine version, but it 3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // is much closer to the old results, so we use it for now to reduce 3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // rebaselining. 3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m); 3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v = src[i]; 3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t s0 = EXPAND0(v, rbmask, m); 3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t s1 = EXPAND1(v, rbmask, m); 3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v = dst[i]; 3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t d0 = EXPAND0(v, rbmask, m); 3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t d1 = EXPAND1(v, rbmask, m); 3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask); 3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int upscale31To255(int value) { 3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger value = (value << 3) | (value >> 2); 3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return value; 3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int mul(int a, int b) { 3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return a * b >> 8; 3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int src_alpha_blend(int src, int dst, int srcA, int mask) { 3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return dst + mul(src - mul(srcA, dst), mask); 3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void LCD16_RowProc_Blend(SkPMColor* SK_RESTRICT dst, 3941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint16_t* SK_RESTRICT mask, 3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint16_t m = mask[i]; 3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == m) { 3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger continue; 4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor s = src[i]; 4031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor d = dst[i]; 4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcA = SkGetPackedA32(s); 4061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcR = SkGetPackedR32(s); 4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcG = SkGetPackedG32(s); 4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcB = SkGetPackedB32(s); 4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcA += srcA >> 7; 4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* We want all of these in 5bits, hence the shifts in case one of them 4131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * (green) is 6bits. 4141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5); 4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5); 4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5); 4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskR = upscale31To255(maskR); 4201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskG = upscale31To255(maskG); 4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskB = upscale31To255(maskB); 4221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstR = SkGetPackedR32(d); 4241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstG = SkGetPackedG32(d); 4251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstB = SkGetPackedB32(d); 4261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // LCD blitting is only supported if the dst is known/required 4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // to be opaque 4291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkPackARGB32(0xFF, 4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src_alpha_blend(srcR, dstR, srcA, maskR), 4311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src_alpha_blend(srcG, dstG, srcA, maskG), 4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src_alpha_blend(srcB, dstB, srcA, maskB)); 4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void LCD16_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, 4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint16_t* SK_RESTRICT mask, 4381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint16_t m = mask[i]; 4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == m) { 4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger continue; 4431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor s = src[i]; 4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor d = dst[i]; 4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcR = SkGetPackedR32(s); 4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcG = SkGetPackedG32(s); 4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcB = SkGetPackedB32(s); 4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* We want all of these in 5bits, hence the shifts in case one of them 4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * (green) is 6bits. 4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5); 4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5); 4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5); 4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Now upscale them to 0..32, so we can use blend32 4604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger maskR = SkUpscale31To32(maskR); 4614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger maskG = SkUpscale31To32(maskG); 4624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger maskB = SkUpscale31To32(maskB); 4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstR = SkGetPackedR32(d); 4651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstG = SkGetPackedG32(d); 4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstB = SkGetPackedB32(d); 4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // LCD blitting is only supported if the dst is known/required 4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // to be opaque 4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkPackARGB32(0xFF, 4714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkBlend32(srcR, dstR, maskR), 4724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkBlend32(srcG, dstG, maskG), 4734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkBlend32(srcB, dstB, maskB)); 4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst, 4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT mask, 4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor m = mask[i]; 4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == m) { 4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger continue; 4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor s = src[i]; 4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcA = SkGetPackedA32(s); 4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcR = SkGetPackedR32(s); 4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcG = SkGetPackedG32(s); 4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcB = SkGetPackedB32(s); 4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcA = SkAlpha255To256(srcA); 4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor d = dst[i]; 4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskR = SkGetPackedR32(m); 4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskG = SkGetPackedG32(m); 4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskB = SkGetPackedB32(m); 4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Now upscale them to 0..256 5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskR = SkAlpha255To256(maskR); 5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskG = SkAlpha255To256(maskG); 5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskB = SkAlpha255To256(maskB); 5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstR = SkGetPackedR32(d); 5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstG = SkGetPackedG32(d); 5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstB = SkGetPackedB32(d); 5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // LCD blitting is only supported if the dst is known/required 5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // to be opaque 5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkPackARGB32(0xFF, 5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src_alpha_blend(srcR, dstR, srcA, maskR), 5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src_alpha_blend(srcG, dstG, srcA, maskG), 5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src_alpha_blend(srcB, dstB, srcA, maskB)); 5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void LCD32_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, 5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT mask, 5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count) { 5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor m = mask[i]; 5231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == m) { 5241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger continue; 5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor s = src[i]; 5281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor d = dst[i]; 5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskR = SkGetPackedR32(m); 5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskG = SkGetPackedG32(m); 5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int maskB = SkGetPackedB32(m); 5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcR = SkGetPackedR32(s); 5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcG = SkGetPackedG32(s); 5361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcB = SkGetPackedB32(s); 5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstR = SkGetPackedR32(d); 5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstG = SkGetPackedG32(d); 5401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstB = SkGetPackedB32(d); 5411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Now upscale them to 0..256, so we can use SkAlphaBlend 5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskR = SkAlpha255To256(maskR); 5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskG = SkAlpha255To256(maskG); 5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger maskB = SkAlpha255To256(maskB); 5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // LCD blitting is only supported if the dst is known/required 5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // to be opaque 5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkPackARGB32(0xFF, 5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcR, dstR, maskR), 5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcG, dstG, maskG), 5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlphaBlend(srcB, dstB, maskB)); 5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5561cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config, 5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask::Format format, 5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RowFlags flags) { 5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// make this opt-in until chrome can rebaseline 5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RowProc proc = PlatformRowProcs(config, format, flags); 5611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (proc) { 5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return proc; 5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const RowProc gProcs[] = { 5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // need X coordinate to handle BW 5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger NULL, NULL, //(RowProc)BW_RowProc_Blend, (RowProc)BW_RowProc_Opaque, 5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque, 5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque, 5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque, 5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int index; 5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (config) { 5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkBitmap::kARGB_8888_Config: 5761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (format) { 5771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kBW_Format: index = 0; break; 5781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kA8_Format: index = 2; break; 5791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kLCD16_Format: index = 4; break; 5801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kLCD32_Format: index = 6; break; 5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 5821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return NULL; 5831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (flags & kSrcIsOpaque_RowFlag) { 5851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger index |= 1; 5861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT((size_t)index < SK_ARRAY_COUNT(gProcs)); 5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return gProcs[index]; 5891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 5901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 5911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return NULL; 5931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 595