diff options
author | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-06-15 15:56:35 +0000 |
---|---|---|
committer | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-06-15 15:56:35 +0000 |
commit | 9a74d313452f30629e2615eb8cbfe902433582c0 (patch) | |
tree | bd9490fd8d3d834fc9a050ee1f85be6b2ba7d690 /src/core | |
parent | b3ade9d1b0a63f8f0dc3bee5785e930c8e84311d (diff) |
create separate opaque version of rgb16 blitter
git-svn-id: http://skia.googlecode.com/svn/trunk@216 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBlitter.cpp | 18 | ||||
-rw-r--r-- | src/core/SkBlitter_RGB16.cpp | 393 | ||||
-rw-r--r-- | src/core/SkCoreBlitters.h | 14 |
3 files changed, 229 insertions, 196 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index a38b46e99a..e47e78212f 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -935,11 +935,21 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device, SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, storage, storageSize, (device, paint)); else SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, storage, storageSize, (device, paint)); + } else { + SkColor color = paint.getColor(); + if (0 == SkColorGetA(color)) { + SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); + } else if (SK_ColorBLACK == color) { + SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage, + storageSize, (device, paint)); + } else if (0xFF == SkColorGetA(color)) { + SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Opaque_Blitter, storage, + storageSize, (device, paint)); + } else { + SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage, + storageSize, (device, paint)); + } } - else if (paint.getColor() == SK_ColorBLACK) - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage, storageSize, (device, paint)); - else - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage, storageSize, (device, paint)); break; case SkBitmap::kARGB_8888_Config: diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp index 40eceeca5c..41f20c99e6 100644 --- a/src/core/SkBlitter_RGB16.cpp +++ b/src/core/SkBlitter_RGB16.cpp @@ -154,8 +154,165 @@ void SkRGB16_Black_Blitter::blitAntiH(int x, int y, } } -////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +SkRGB16_Opaque_Blitter::SkRGB16_Opaque_Blitter(const SkBitmap& device, + const SkPaint& paint) +: INHERITED(device, paint) {} + +void SkRGB16_Opaque_Blitter::blitH(int x, int y, int width) SK_RESTRICT { + SkASSERT(width > 0); + SkASSERT(x + width <= fDevice.width()); + uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); + uint16_t srcColor = fColor16; + + SkASSERT(fRawColor16 == srcColor); + if (fDoDither) { + uint16_t ditherColor = fRawDither16; + if ((x ^ y) & 1) { + SkTSwap(ditherColor, srcColor); + } + sk_dither_memset16(device, srcColor, ditherColor, width); + } else { + sk_memset16(device, srcColor, width); + } +} + +// return 1 or 0 from a bool +static int Bool2Int(bool value) { + return !!value; +} + +void SkRGB16_Opaque_Blitter::blitAntiH(int x, int y, + const SkAlpha* SK_RESTRICT antialias, + const int16_t* SK_RESTRICT runs) SK_RESTRICT { + uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); + uint16_t srcColor = fRawColor16; + unsigned scale = fScale; + int ditherInt = Bool2Int(fDoDither); + + uint16_t ditherColor = fRawDither16; + // if we have no dithering, this will always fail + if ((x ^ y) & ditherInt) { + SkTSwap(ditherColor, srcColor); + } + for (;;) { + int count = runs[0]; + SkASSERT(count >= 0); + if (count <= 0) { + return; + } + runs += count; + + unsigned aa = antialias[0]; + antialias += count; + if (aa) { + if (aa == 255) { + if (ditherInt) { + sk_dither_memset16(device, srcColor, + ditherColor, count); + } else { + sk_memset16(device, srcColor, count); + } + } else { + // TODO: respect fDoDither + unsigned scale5 = SkAlpha255To256(aa) >> 3; + uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; + scale5 = 32 - scale5; // now we can use it on the device + int n = count; + do { + uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; + *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); + } while (--n != 0); + goto DONE; + } + } + device += count; + + DONE: + // if we have no dithering, this will always fail + if (count & ditherInt) { + SkTSwap(ditherColor, srcColor); + } + } +} + +#define solid_8_pixels(mask, dst, color) \ + do { \ + if (mask & 0x80) dst[0] = color; \ + if (mask & 0x40) dst[1] = color; \ + if (mask & 0x20) dst[2] = color; \ + if (mask & 0x10) dst[3] = color; \ + if (mask & 0x08) dst[4] = color; \ + if (mask & 0x04) dst[5] = color; \ + if (mask & 0x02) dst[6] = color; \ + if (mask & 0x01) dst[7] = color; \ + } while (0) + +#define SK_BLITBWMASK_NAME SkRGB16_BlitBW +#define SK_BLITBWMASK_ARGS , uint16_t color +#define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) +#define SK_BLITBWMASK_GETADDR getAddr16 +#define SK_BLITBWMASK_DEVTYPE uint16_t +#include "SkBlitBWMaskTemplate.h" + +static U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) { + return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5)); +} + +void SkRGB16_Opaque_Blitter::blitMask(const SkMask& SK_RESTRICT mask, + const SkIRect& SK_RESTRICT clip) SK_RESTRICT { + if (mask.fFormat == SkMask::kBW_Format) { + SkRGB16_BlitBW(fDevice, mask, clip, fColor16); + return; + } + + uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); + const uint8_t* SK_RESTRICT alpha = mask.getAddr(clip.fLeft, clip.fTop); + int width = clip.width(); + int height = clip.height(); + unsigned deviceRB = fDevice.rowBytes() - (width << 1); + unsigned maskRB = mask.fRowBytes - width; + uint32_t color32 = SkExpand_rgb_16(fRawColor16); + + do { + int w = width; + do { + *device = blend_compact(color32, SkExpand_rgb_16(*device), + SkAlpha255To256(*alpha++) >> 3); + device += 1; + } while (--w != 0); + device = (uint16_t*)((char*)device + deviceRB); + alpha += maskRB; + } while (--height != 0); +} + +void SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) { + SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); + uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); + unsigned deviceRB = fDevice.rowBytes(); + uint16_t color16 = fColor16; + + if (fDoDither) { + uint16_t ditherColor = fRawDither16; + if ((x ^ y) & 1) { + SkTSwap(ditherColor, color16); + } + while (--height >= 0) { + sk_dither_memset16(device, color16, ditherColor, width); + SkTSwap(ditherColor, color16); + device = (uint16_t*)((char*)device + deviceRB); + } + } else { // no dither + while (--height >= 0) { + sk_memset16(device, color16, width); + device = (uint16_t*)((char*)device + deviceRB); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// SkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint) : INHERITED(device) { @@ -190,145 +347,49 @@ const SkBitmap* SkRGB16_Blitter::justAnOpaqueColor(uint32_t* value) { void SkRGB16_Blitter::blitH(int x, int y, int width) SK_RESTRICT { SkASSERT(width > 0); SkASSERT(x + width <= fDevice.width()); - - if (fScale == 0) { - return; - } - uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); - uint16_t srcColor = fColor16; - - if (256 == fScale) { - SkASSERT(fRawColor16 == srcColor); - if (fDoDither) { - uint16_t ditherColor = fRawDither16; - if ((x ^ y) & 1) { - SkTSwap(ditherColor, srcColor); - } - sk_dither_memset16(device, srcColor, ditherColor, width); - } else { - sk_memset16(device, srcColor, width); - } - } else { - // TODO: respect fDoDither - SkPMColor src32 = fSrcColor32; - do { - *device = SkSrcOver32To16(src32, *device); - device += 1; - } while (--width != 0); - } -} -// return 1 or 0 from a bool -static int Bool2Int(bool value) { - return !!value; + // TODO: respect fDoDither + SkPMColor src32 = fSrcColor32; + do { + *device = SkSrcOver32To16(src32, *device); + device += 1; + } while (--width != 0); } void SkRGB16_Blitter::blitAntiH(int x, int y, const SkAlpha* SK_RESTRICT antialias, const int16_t* SK_RESTRICT runs) SK_RESTRICT { - if (fScale == 0) { - return; - } - uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); uint16_t srcColor = fRawColor16; unsigned scale = fScale; int ditherInt = Bool2Int(fDoDither); - if (256 == scale) { - uint16_t ditherColor = fRawDither16; - // if we have no dithering, this will always fail - if ((x ^ y) & ditherInt) { - SkTSwap(ditherColor, srcColor); - } - for (;;) { - int count = runs[0]; - SkASSERT(count >= 0); - if (count <= 0) { - return; - } - runs += count; - - unsigned aa = antialias[0]; - antialias += count; - if (aa) { - if (aa == 255) { - if (ditherInt) { - sk_dither_memset16(device, srcColor, - ditherColor, count); - } else { - sk_memset16(device, srcColor, count); - } - } else { - // TODO: respect fDoDither - unsigned scale5 = SkAlpha255To256(aa) >> 3; - uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; - scale5 = 32 - scale5; // now we can use it on the device - int n = count; - do { - uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; - *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); - } while (--n != 0); - goto DONE; - } - } - device += count; - - DONE: - // if we have no dithering, this will always fail - if (count & ditherInt) { - SkTSwap(ditherColor, srcColor); - } + // TODO: respect fDoDither + for (;;) { + int count = runs[0]; + SkASSERT(count >= 0); + if (count <= 0) { + return; } - } else { - // TODO: respect fDoDither - for (;;) { - int count = runs[0]; - SkASSERT(count >= 0); - if (count <= 0) { - return; - } - runs += count; + runs += count; - unsigned aa = antialias[0]; - antialias += count; - if (aa) { - unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); - uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; - scale5 = 32 - scale5; - do { - uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; - *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); - } while (--count != 0); - continue; - } - device += count; + unsigned aa = antialias[0]; + antialias += count; + if (aa) { + unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); + uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; + scale5 = 32 - scale5; + do { + uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; + *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); + } while (--count != 0); + continue; } + device += count; } } -////////////////////////////////////////////////////////////////////////////////////// - -#define solid_8_pixels(mask, dst, color) \ - do { \ - if (mask & 0x80) dst[0] = color; \ - if (mask & 0x40) dst[1] = color; \ - if (mask & 0x20) dst[2] = color; \ - if (mask & 0x10) dst[3] = color; \ - if (mask & 0x08) dst[4] = color; \ - if (mask & 0x04) dst[5] = color; \ - if (mask & 0x02) dst[6] = color; \ - if (mask & 0x01) dst[7] = color; \ - } while (0) - -#define SK_BLITBWMASK_NAME SkRGB16_BlitBW -#define SK_BLITBWMASK_ARGS , uint16_t color -#define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) -#define SK_BLITBWMASK_GETADDR getAddr16 -#define SK_BLITBWMASK_DEVTYPE uint16_t -#include "SkBlitBWMaskTemplate.h" - static inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale, U16CPU srcColor) { if (bw & 0x80) dst[0] = srcColor + SkAlphaMulRGB16(dst[0], dst_scale); @@ -348,21 +409,10 @@ static inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale, #define SK_BLITBWMASK_DEVTYPE uint16_t #include "SkBlitBWMaskTemplate.h" -static U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) { - return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5)); -} - void SkRGB16_Blitter::blitMask(const SkMask& SK_RESTRICT mask, const SkIRect& SK_RESTRICT clip) SK_RESTRICT { - if (fScale == 0) { - return; - } if (mask.fFormat == SkMask::kBW_Format) { - if (fScale == 256) { - SkRGB16_BlitBW(fDevice, mask, clip, fColor16); - } else { - SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16); - } + SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16); return; } @@ -374,38 +424,22 @@ void SkRGB16_Blitter::blitMask(const SkMask& SK_RESTRICT mask, unsigned maskRB = mask.fRowBytes - width; uint32_t color32 = SkExpand_rgb_16(fRawColor16); - if (256 == fScale) { - do { - int w = width; - do { - *device = blend_compact(color32, SkExpand_rgb_16(*device), - SkAlpha255To256(*alpha++) >> 3); - device += 1; - } while (--w != 0); - device = (uint16_t*)((char*)device + deviceRB); - alpha += maskRB; - } while (--height != 0); - } else { // scale < 256 - unsigned scale256 = fScale; + unsigned scale256 = fScale; + do { + int w = width; do { - int w = width; - do { - unsigned aa = *alpha++; - unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3); - uint32_t src32 = color32 * scale; - uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale); - *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); - } while (--w != 0); - device = (uint16_t*)((char*)device + deviceRB); - alpha += maskRB; - } while (--height != 0); - } + unsigned aa = *alpha++; + unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3); + uint32_t src32 = color32 * scale; + uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale); + *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); + } while (--w != 0); + device = (uint16_t*)((char*)device + deviceRB); + alpha += maskRB; + } while (--height != 0); } void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { - if (fScale == 0) { - return; - } uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); uint16_t color16 = fRawColor16; unsigned deviceRB = fDevice.rowBytes(); @@ -442,39 +476,16 @@ void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); - - if (fScale == 0) { - return; - } uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); unsigned deviceRB = fDevice.rowBytes(); uint16_t color16 = fColor16; + SkPMColor src32 = fSrcColor32; - if (256 == fScale) { - if (fDoDither) { - uint16_t ditherColor = fRawDither16; - if ((x ^ y) & 1) { - SkTSwap(ditherColor, color16); - } - while (--height >= 0) { - sk_dither_memset16(device, color16, ditherColor, width); - SkTSwap(ditherColor, color16); - device = (uint16_t*)((char*)device + deviceRB); - } - } else { // no dither - while (--height >= 0) { - sk_memset16(device, color16, width); - device = (uint16_t*)((char*)device + deviceRB); - } - } - } else { - SkPMColor src32 = fSrcColor32; - while (--height >= 0) { - for (int i = width - 1; i >= 0; --i) { - device[i] = SkSrcOver32To16(src32, device[i]); - } - device = (uint16_t*)((char*)device + deviceRB); + while (--height >= 0) { + for (int i = width - 1; i >= 0; --i) { + device[i] = SkSrcOver32To16(src32, device[i]); } + device = (uint16_t*)((char*)device + deviceRB); } } diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index 8f9cfc36f9..c25752ec2f 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -162,7 +162,7 @@ public: virtual void blitMask(const SkMask&, const SkIRect&); virtual const SkBitmap* justAnOpaqueColor(uint32_t*); -private: +protected: SkPMColor fSrcColor32; unsigned fScale; uint16_t fColor16; // already scaled by fScale @@ -176,6 +176,18 @@ private: typedef SkRasterBlitter INHERITED; }; +class SkRGB16_Opaque_Blitter : public SkRGB16_Blitter { +public: + SkRGB16_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint); + virtual void blitH(int x, int y, int width); + virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]); + virtual void blitRect(int x, int y, int width, int height); + virtual void blitMask(const SkMask&, const SkIRect&); + +private: + typedef SkRGB16_Blitter INHERITED; +}; + class SkRGB16_Black_Blitter : public SkRGB16_Blitter { public: SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint); |