aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/SkBlitter_RGB16.cpp
diff options
context:
space:
mode:
authorMike Reed <reed@google.com>2009-10-13 09:59:09 -0400
committerMike Reed <reed@google.com>2009-10-13 09:59:09 -0400
commit4663d79a396bd4d45a9140626921c9fbad77fbf8 (patch)
treeb694c5869a467c1b13c9303a2c3141ce4ce64b98 /src/core/SkBlitter_RGB16.cpp
parentea8eb95a903dda7b277cdbc97523688b9857963b (diff)
downloadexternal_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.cpp242
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
-