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