diff options
-rw-r--r-- | src/core/SkBlitRow_D32.cpp | 15 | ||||
-rw-r--r-- | src/core/SkBlitter_ARGB32.cpp | 68 |
2 files changed, 70 insertions, 13 deletions
diff --git a/src/core/SkBlitRow_D32.cpp b/src/core/SkBlitRow_D32.cpp index a00ba88816..d96c697b1d 100644 --- a/src/core/SkBlitRow_D32.cpp +++ b/src/core/SkBlitRow_D32.cpp @@ -153,7 +153,8 @@ SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() { return proc; } -void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], +void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, SkPMColor color) { if (count > 0) { if (0 == color) { @@ -177,8 +178,8 @@ void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], /////////////////////////////////////////////////////////////////////////////// -static void D32_Mask_Color(void* dst, size_t dstRB, SkBitmap::Config, - const uint8_t* mask, size_t maskRB, SkColor color, +static void D32_Mask_Color(void* SK_RESTRICT dst, size_t dstRB, SkBitmap::Config, + const uint8_t* SK_RESTRICT mask, size_t maskRB, SkColor color, int width, int height) { SkPMColor pmc = SkPreMultiplyColor(color); size_t dstOffset = dstRB - (width << 2); @@ -196,8 +197,8 @@ static void D32_Mask_Color(void* dst, size_t dstRB, SkBitmap::Config, } while (--height != 0); } -static void D32_Mask_Opaque(void* dst, size_t dstRB, SkBitmap::Config, - const uint8_t* mask, size_t maskRB, SkColor color, +static void D32_Mask_Opaque(void* SK_RESTRICT dst, size_t dstRB, SkBitmap::Config, + const uint8_t* SK_RESTRICT mask, size_t maskRB, SkColor color, int width, int height) { SkPMColor pmc = SkPreMultiplyColor(color); uint32_t* device = (uint32_t*)dst; @@ -216,8 +217,8 @@ static void D32_Mask_Opaque(void* dst, size_t dstRB, SkBitmap::Config, } while (--height != 0); } -static void D32_Mask_Black(void* dst, size_t dstRB, SkBitmap::Config, - const uint8_t* mask, size_t maskRB, SkColor, +static void D32_Mask_Black(void* SK_RESTRICT dst, size_t dstRB, SkBitmap::Config, + const uint8_t* SK_RESTRICT mask, size_t maskRB, SkColor, int width, int height) { uint32_t* device = (uint32_t*)dst; diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index be04026860..af55aba951 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -27,8 +27,8 @@ static inline int blend32(int src, int dst, int scale) { return dst + ((src - dst) * scale >> 5); } -static void blit_lcd16_opaque(SkPMColor dst[], const uint16_t src[], - SkColor color, int width) { +static void blit_lcd16_row(SkPMColor dst[], const uint16_t src[], + SkColor color, int width, SkPMColor) { int srcA = SkColorGetA(color); int srcR = SkColorGetR(color); int srcG = SkColorGetG(color); @@ -75,8 +75,53 @@ static void blit_lcd16_opaque(SkPMColor dst[], const uint16_t src[], } } -static void blit_lcd32_opaque(SkPMColor dst[], const uint32_t src[], - SkColor color, int width) { +static void blit_lcd16_opaque_row(SkPMColor dst[], const uint16_t src[], + SkColor color, int width, SkPMColor opaqueDst) { + int srcR = SkColorGetR(color); + int srcG = SkColorGetG(color); + int srcB = SkColorGetB(color); + + for (int i = 0; i < width; i++) { + uint16_t mask = src[i]; + if (0 == mask) { + continue; + } + if (0xFFFF == mask) { + dst[i] = opaqueDst; + continue; + } + + SkPMColor d = dst[i]; + + /* We want all of these in 5bits, hence the shifts in case one of them + * (green) is 6bits. + */ + int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); + int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); + int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); + + // Now upscale them to 0..32, so we can use blend32 + maskR = upscale31To32(maskR); + maskG = upscale31To32(maskG); + maskB = upscale31To32(maskB); + + int maskA = SkMax32(SkMax32(maskR, maskG), maskB); + + int dstA = SkGetPackedA32(d); + int dstR = SkGetPackedR32(d); + int dstG = SkGetPackedG32(d); + int dstB = SkGetPackedB32(d); + + // nocheck version for now, until we cleanup GDI's garbage bits + dst[i] = SkPackARGB32NoCheck(blend32(0xFF, dstA, maskA), + blend32(srcR, dstR, maskR), + blend32(srcG, dstG, maskG), + blend32(srcB, dstB, maskB)); + } +} + +static void blit_lcd32_row(SkPMColor dst[], const uint32_t src[], + SkColor color, int width, SkPMColor) { int srcA = SkColorGetA(color); int srcR = SkColorGetR(color); int srcG = SkColorGetG(color); @@ -128,9 +173,20 @@ static void blitmask_lcd16(const SkBitmap& device, const SkMask& mask, SkPMColor* dstRow = device.getAddr32(x, y); const uint16_t* srcRow = mask.getAddrLCD16(x, y); + SkPMColor opaqueDst; + + void (*proc)(SkPMColor dst[], const uint16_t src[], + SkColor color, int width, SkPMColor); + if (0xFF == SkColorGetA(srcColor)) { + proc = blit_lcd16_opaque_row; + opaqueDst = SkPreMultiplyColor(srcColor); + } else { + proc = blit_lcd16_row; + opaqueDst = 0; // ignored + } do { - blit_lcd16_opaque(dstRow, srcRow, srcColor, width); + proc(dstRow, srcRow, srcColor, width, opaqueDst); dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes()); srcRow = (const uint16_t*)((const char*)srcRow + mask.fRowBytes); } while (--height != 0); @@ -147,7 +203,7 @@ static void blitmask_lcd32(const SkBitmap& device, const SkMask& mask, const uint32_t* srcRow = mask.getAddrLCD32(x, y); do { - blit_lcd32_opaque(dstRow, srcRow, srcColor, width); + blit_lcd32_row(dstRow, srcRow, srcColor, width, 0); dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes()); srcRow = (const uint32_t*)((const char*)srcRow + mask.fRowBytes); } while (--height != 0); |