create separate opaque version of rgb16 blitter
git-svn-id: http://skia.googlecode.com/svn/trunk@216 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp
index 40eceec..41f20c9 100644
--- a/src/core/SkBlitter_RGB16.cpp
+++ b/src/core/SkBlitter_RGB16.cpp
@@ -154,8 +154,165 @@
}
}
-//////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+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 @@
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);
+ // TODO: respect fDoDither
+ for (;;) {
+ int count = runs[0];
+ SkASSERT(count >= 0);
+ if (count <= 0) {
+ return;
}
- for (;;) {
- int count = runs[0];
- SkASSERT(count >= 0);
- if (count <= 0) {
- return;
- }
- runs += count;
+ 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);
- }
+ 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;
}
- } else {
- // TODO: respect fDoDither
- for (;;) {
- int count = runs[0];
- SkASSERT(count >= 0);
- if (count <= 0) {
- return;
- }
- 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;
- }
+ 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 @@
#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 @@
unsigned maskRB = mask.fRowBytes - width;
uint32_t color32 = SkExpand_rgb_16(fRawColor16);
- if (256 == fScale) {
+ unsigned scale256 = fScale;
+ do {
+ int w = width;
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;
- 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::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);
- }
+ while (--height >= 0) {
+ for (int i = width - 1; i >= 0; --i) {
+ device[i] = SkSrcOver32To16(src32, device[i]);
}
- } 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);
- }
+ device = (uint16_t*)((char*)device + deviceRB);
}
}