diff options
author | Mike Reed <reed@google.com> | 2009-10-13 09:59:09 -0400 |
---|---|---|
committer | Mike Reed <reed@google.com> | 2009-10-13 09:59:09 -0400 |
commit | 4663d79a396bd4d45a9140626921c9fbad77fbf8 (patch) | |
tree | b694c5869a467c1b13c9303a2c3141ce4ce64b98 /src/core/SkBlitter_RGB16.cpp | |
parent | ea8eb95a903dda7b277cdbc97523688b9857963b (diff) | |
download | external_skia-4663d79a396bd4d45a9140626921c9fbad77fbf8.zip external_skia-4663d79a396bd4d45a9140626921c9fbad77fbf8.tar.gz external_skia-4663d79a396bd4d45a9140626921c9fbad77fbf8.tar.bz2 |
refresh from skia/trunk
Diffstat (limited to 'src/core/SkBlitter_RGB16.cpp')
-rw-r--r-- | src/core/SkBlitter_RGB16.cpp | 242 |
1 files changed, 173 insertions, 69 deletions
diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp index ac6b5d0..0112c9a 100644 --- a/src/core/SkBlitter_RGB16.cpp +++ b/src/core/SkBlitter_RGB16.cpp @@ -20,6 +20,7 @@ #include "SkColorPriv.h" #include "SkDither.h" #include "SkShader.h" +#include "SkTemplatesPriv.h" #include "SkUtils.h" #include "SkXfermode.h" @@ -50,6 +51,106 @@ void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, /////////////////////////////////////////////////////////////////////////////// +class SkRGB16_Blitter : public SkRasterBlitter { +public: + SkRGB16_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 blitV(int x, int y, int height, SkAlpha alpha); + virtual void blitRect(int x, int y, int width, int height); + virtual void blitMask(const SkMask&, const SkIRect&); + virtual const SkBitmap* justAnOpaqueColor(uint32_t*); + +protected: + SkPMColor fSrcColor32; + uint32_t fExpandedRaw16; + unsigned fScale; + uint16_t fColor16; // already scaled by fScale + uint16_t fRawColor16; // unscaled + uint16_t fRawDither16; // unscaled + SkBool8 fDoDither; + + // illegal + SkRGB16_Blitter& operator=(const SkRGB16_Blitter&); + + 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 blitV(int x, int y, int height, SkAlpha alpha); + 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_Opaque_Blitter { +public: + SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint); + virtual void blitMask(const SkMask&, const SkIRect&); + virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]); + +private: + typedef SkRGB16_Opaque_Blitter INHERITED; +}; + +class SkRGB16_Shader_Blitter : public SkShaderBlitter { +public: + SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint); + virtual ~SkRGB16_Shader_Blitter(); + 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); + +protected: + SkPMColor* fBuffer; + SkBlitRow::Proc fOpaqueProc; + SkBlitRow::Proc fAlphaProc; + +private: + // illegal + SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); + + typedef SkShaderBlitter INHERITED; +}; + +// used only if the shader can perform shadSpan16 +class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter { +public: + SkRGB16_Shader16_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); + +private: + typedef SkRGB16_Shader_Blitter INHERITED; +}; + +class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { +public: + SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint); + virtual ~SkRGB16_Shader_Xfermode_Blitter(); + virtual void blitH(int x, int y, int width); + virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]); + +private: + SkXfermode* fXfermode; + SkPMColor* fBuffer; + uint8_t* fAAExpand; + + // illegal + SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&); + + typedef SkShaderBlitter INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + SkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint) : INHERITED(device, paint) { SkASSERT(paint.getShader() == NULL); @@ -189,6 +290,7 @@ void SkRGB16_Opaque_Blitter::blitAntiH(int x, int y, const int16_t* SK_RESTRICT runs) SK_RESTRICT { uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); uint16_t srcColor = fRawColor16; + uint32_t srcExpanded = fExpandedRaw16; int ditherInt = Bool2Int(fDoDither); uint16_t ditherColor = fRawDither16; // if we have no dithering, this will always fail @@ -216,7 +318,7 @@ void SkRGB16_Opaque_Blitter::blitAntiH(int x, int y, } else { // TODO: respect fDoDither unsigned scale5 = SkAlpha255To256(aa) >> 3; - uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; + uint32_t src32 = srcExpanded * scale5; scale5 = 32 - scale5; // now we can use it on the device int n = count; do { @@ -272,12 +374,12 @@ void SkRGB16_Opaque_Blitter::blitMask(const SkMask& SK_RESTRICT mask, int height = clip.height(); unsigned deviceRB = fDevice.rowBytes() - (width << 1); unsigned maskRB = mask.fRowBytes - width; - uint32_t color32 = SkExpand_rgb_16(fRawColor16); + uint32_t expanded32 = fExpandedRaw16; do { int w = width; do { - *device = blend_compact(color32, SkExpand_rgb_16(*device), + *device = blend_compact(expanded32, SkExpand_rgb_16(*device), SkAlpha255To256(*alpha++) >> 3); device += 1; } while (--w != 0); @@ -286,6 +388,21 @@ void SkRGB16_Opaque_Blitter::blitMask(const SkMask& SK_RESTRICT mask, } while (--height != 0); } +void SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { + uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); + unsigned deviceRB = fDevice.rowBytes(); + + // TODO: respect fDoDither + unsigned scale5 = SkAlpha255To256(alpha) >> 3; + uint32_t src32 = fExpandedRaw16 * scale5; + scale5 = 32 - scale5; + do { + uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; + *device = SkCompact_rgb_16((src32 + dst32) >> 5); + device = (uint16_t*)((char*)device + deviceRB); + } 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); @@ -328,7 +445,9 @@ SkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint) if ((fDoDither = paint.isDither()) != false) { fRawDither16 = SkDitherPack888ToRGB16(r, g, b); } - + + fExpandedRaw16 = SkExpand_rgb_16(fRawColor16); + fColor16 = SkPackRGB16( SkAlphaMul(r, fScale) >> (8 - SK_R16_BITS), SkAlphaMul(g, fScale) >> (8 - SK_G16_BITS), SkAlphaMul(b, fScale) >> (8 - SK_B16_BITS)); @@ -373,7 +492,7 @@ void SkRGB16_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; + uint32_t srcExpanded = fExpandedRaw16; unsigned scale = fScale; // TODO: respect fDoDither @@ -389,7 +508,7 @@ void SkRGB16_Blitter::blitAntiH(int x, int y, antialias += count; if (aa) { unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); - uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; + uint32_t src32 = srcExpanded * scale5; scale5 = 32 - scale5; do { uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; @@ -433,7 +552,7 @@ void SkRGB16_Blitter::blitMask(const SkMask& SK_RESTRICT mask, int height = clip.height(); unsigned deviceRB = fDevice.rowBytes() - (width << 1); unsigned maskRB = mask.fRowBytes - width; - uint32_t color32 = SkExpand_rgb_16(fRawColor16); + uint32_t color32 = fExpandedRaw16; unsigned scale256 = fScale; do { @@ -452,37 +571,17 @@ void SkRGB16_Blitter::blitMask(const SkMask& SK_RESTRICT mask, void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); - uint16_t color16 = fRawColor16; unsigned deviceRB = fDevice.rowBytes(); - if (alpha + fScale == (255 + 256)) { - if (fDoDither) { - uint16_t ditherColor = fRawDither16; - if ((x ^ y) & 1) { - SkTSwap(ditherColor, color16); - } - do { - device[0] = color16; - device = (uint16_t*)((char*)device + deviceRB); - SkTSwap(ditherColor, color16); - } while (--height != 0); - } else { - do { - device[0] = color16; - device = (uint16_t*)((char*)device + deviceRB); - } while (--height != 0); - } - } else { - // TODO: respect fDoDither - unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); - uint32_t src32 = SkExpand_rgb_16(color16) * scale5; - scale5 = 32 - scale5; - do { - uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; - *device = SkCompact_rgb_16((src32 + dst32) >> 5); - device = (uint16_t*)((char*)device + deviceRB); - } while (--height != 0); - } + // TODO: respect fDoDither + unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); + uint32_t src32 = fExpandedRaw16 * scale5; + scale5 = 32 - scale5; + do { + uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; + *device = SkCompact_rgb_16((src32 + dst32) >> 5); + device = (uint16_t*)((char*)device + deviceRB); + } while (--height != 0); } void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { @@ -832,39 +931,44 @@ void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, } } -//////////////////////// +/////////////////////////////////////////////////////////////////////////////// -#if 0 -static inline uint16_t aa_blendS32D16(SkPMColor src, U16CPU dst, int aa -#ifdef DITHER_SHADER - , int dither -#endif - ) -{ - SkASSERT((unsigned)aa <= 255); - - int src_scale = SkAlpha255To256(aa); - int sa = SkGetPackedA32(src); - int dst_scale = SkAlpha255To256(255 - SkAlphaMul(sa, src_scale)); - -#ifdef DITHER_SHADER - int sr = SkGetPackedR32(src); - int sg = SkGetPackedG32(src); - int sb = SkGetPackedB32(src); - sr = SkDITHER_R32To16(sr, dither); - sg = SkDITHER_G32To16(sg, dither); - sb = SkDITHER_B32To16(sb, dither); -#else - int sr = SkPacked32ToR16(src); - int sg = SkPacked32ToG16(src); - int sb = SkPacked32ToB16(src); -#endif - - int dr = (sr * src_scale + SkGetPackedR16(dst) * dst_scale) >> 8; - int dg = (sg * src_scale + SkGetPackedG16(dst) * dst_scale) >> 8; - int db = (sb * src_scale + SkGetPackedB16(dst) * dst_scale) >> 8; +SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, + void* storage, size_t storageSize) { + SkBlitter* blitter; + SkShader* shader = paint.getShader(); + SkXfermode* mode = paint.getXfermode(); + + // we require a shader if there is an xfermode, handled by our caller + SkASSERT(NULL == mode || NULL != shader); + + if (shader) { + if (mode) { + SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, + storage, storageSize, (device, paint)); + } else if (shader->canCallShadeSpan16()) { + 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 { + // no shader, no xfermode, (and we always ignore colorfilter) + 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)); + } + } - return SkPackRGB16(dr, dg, db); + return blitter; } -#endif - |