move LCD blits into opts, so they can have assembly versions

git-svn-id: http://skia.googlecode.com/svn/trunk@2484 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-10-18 13:56:50 +00:00
parent 095186a466
commit edb606cb99
12 changed files with 441 additions and 358 deletions

View File

@ -30,6 +30,7 @@
'../src/core/SkBitmapShaderTemplate.h',
'../src/core/SkBitmap_scroll.cpp',
'../src/core/SkBlitBWMaskTemplate.h',
'../src/core/SkBlitMask_D32.cpp',
'../src/core/SkBlitRow_D16.cpp',
'../src/core/SkBlitRow_D32.cpp',
'../src/core/SkBlitRow_D4444.cpp',

View File

@ -56,7 +56,7 @@ struct SkMask {
x,y are in the same coordiate space as fBounds.
*/
uint8_t* getAddr1(int x, int y) const {
SkASSERT(fFormat == kBW_Format);
SkASSERT(kBW_Format == fFormat);
SkASSERT(fBounds.contains(x, y));
SkASSERT(fImage != NULL);
return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
@ -67,7 +67,7 @@ struct SkMask {
x,y are in the same coordiate space as fBounds.
*/
uint8_t* getAddr(int x, int y) const {
SkASSERT(fFormat != kBW_Format);
SkASSERT(kA8_Format == fFormat);
SkASSERT(fBounds.contains(x, y));
SkASSERT(fImage != NULL);
return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;

View File

@ -13,23 +13,33 @@
class SkBlitMask {
public:
/**
* Returns true if the device config and mask format were supported.
* else return false (nothing was drawn)
*/
static bool BlitColor(const SkBitmap& device, const SkMask& mask,
const SkIRect& clip, SkColor color);
/**
* Function pointer that blits the mask into a device (dst) colorized
* by color. The number of pixels to blit is specified by width and height,
* but each scanline is offset by dstRB (rowbytes) and srcRB respectively.
*/
typedef void (*Proc)(void* dst, size_t dstRB, SkBitmap::Config dstConfig,
const uint8_t* mask, size_t maskRB, SkColor color,
int width, int height);
typedef void (*Proc)(void* dst, size_t dstRB,
const void* mask, size_t maskRB,
SkColor color, int width, int height);
/* Public entry-point to return a blitmask function ptr
/**
* Public entry-point to return a blitmask function ptr.
* May return NULL if config or format are not supported.
*/
static Proc Factory(SkBitmap::Config dstConfig, SkColor color);
static Proc Factory(SkBitmap::Config dstConfig, SkMask::Format, SkColor);
/* return either platform specific optimized blitmask function-ptr,
* or NULL if no optimized
/**
* Return either platform specific optimized blitmask function-ptr,
* or NULL if no optimized routine is available.
*/
static Proc PlatformProcs(SkBitmap::Config dstConfig, SkColor color);
static Proc PlatformProcs(SkBitmap::Config dstConfig, SkMask::Format, SkColor);
};
#endif

384
src/core/SkBlitMask_D32.cpp Normal file
View File

@ -0,0 +1,384 @@
#include "SkBlitMask.h"
#include "SkColor.h"
#include "SkColorPriv.h"
static void D32_A8_Color(void* SK_RESTRICT dst, size_t dstRB,
const void* SK_RESTRICT maskPtr, size_t maskRB,
SkColor color, int width, int height) {
SkPMColor pmc = SkPreMultiplyColor(color);
size_t dstOffset = dstRB - (width << 2);
size_t maskOffset = maskRB - width;
SkPMColor* SK_RESTRICT device = (SkPMColor *)dst;
const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
do {
int w = width;
do {
unsigned aa = *mask++;
*device = SkBlendARGB32(pmc, *device, aa);
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + dstOffset);
mask += maskOffset;
} while (--height != 0);
}
static void D32_A8_Opaque(void* SK_RESTRICT dst, size_t dstRB,
const void* SK_RESTRICT maskPtr, size_t maskRB,
SkColor color, int width, int height) {
SkPMColor pmc = SkPreMultiplyColor(color);
SkPMColor* SK_RESTRICT device = (SkPMColor*)dst;
const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
maskRB -= width;
dstRB -= (width << 2);
do {
int w = width;
do {
unsigned aa = *mask++;
*device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + dstRB);
mask += maskRB;
} while (--height != 0);
}
static void D32_A8_Black(void* SK_RESTRICT dst, size_t dstRB,
const void* SK_RESTRICT maskPtr, size_t maskRB,
SkColor, int width, int height) {
SkPMColor* SK_RESTRICT device = (SkPMColor*)dst;
const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
maskRB -= width;
dstRB -= (width << 2);
do {
int w = width;
do {
unsigned aa = *mask++;
*device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + dstRB);
mask += maskRB;
} while (--height != 0);
}
///////////////////////////////////////////////////////////////////////////////
static inline int upscale31To32(int value) {
SkASSERT((unsigned)value <= 31);
return value + (value >> 4);
}
static inline int blend32(int src, int dst, int scale) {
SkASSERT((unsigned)src <= 0xFF);
SkASSERT((unsigned)dst <= 0xFF);
SkASSERT((unsigned)scale <= 32);
return dst + ((src - dst) * scale >> 5);
}
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);
int srcB = SkColorGetB(color);
srcA = SkAlpha255To256(srcA);
for (int i = 0; i < width; i++) {
uint16_t mask = src[i];
if (0 == mask) {
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);
maskR = maskR * srcA >> 8;
maskG = maskG * srcA >> 8;
maskB = maskB * srcA >> 8;
int dstR = SkGetPackedR32(d);
int dstG = SkGetPackedG32(d);
int dstB = SkGetPackedB32(d);
// LCD blitting is only supported if the dst is known/required\
// to be opaque
dst[i] = SkPackARGB32(0xFF,
blend32(srcR, dstR, maskR),
blend32(srcG, dstG, maskG),
blend32(srcB, dstB, maskB));
}
}
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 dstR = SkGetPackedR32(d);
int dstG = SkGetPackedG32(d);
int dstB = SkGetPackedB32(d);
// LCD blitting is only supported if the dst is known/required
// to be opaque
dst[i] = SkPackARGB32(0xFF,
blend32(srcR, dstR, maskR),
blend32(srcG, dstG, maskG),
blend32(srcB, dstB, maskB));
}
}
static void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB,
const void* SK_RESTRICT mask, size_t maskRB,
SkColor color, int width, int height) {
SkPMColor* dstRow = (SkPMColor*)dst;
const uint16_t* srcRow = (const uint16_t*)mask;
SkPMColor opaqueDst;
void (*proc)(SkPMColor dst[], const uint16_t src[],
SkColor color, int width, SkPMColor);
if (0xFF == SkColorGetA(color)) {
proc = blit_lcd16_opaque_row;
opaqueDst = SkPreMultiplyColor(color);
} else {
proc = blit_lcd16_row;
opaqueDst = 0; // ignored
}
do {
proc(dstRow, srcRow, color, width, opaqueDst);
dstRow = (SkPMColor*)((char*)dstRow + dstRB);
srcRow = (const uint16_t*)((const char*)srcRow + maskRB);
} while (--height != 0);
}
///////////////////////////////////////////////////////////////////////////////
static void blit_lcd32_opaque_row(SkPMColor* SK_RESTRICT dst,
const SkPMColor* SK_RESTRICT src,
SkColor color, int width) {
int srcR = SkColorGetR(color);
int srcG = SkColorGetG(color);
int srcB = SkColorGetB(color);
for (int i = 0; i < width; i++) {
SkPMColor mask = src[i];
if (0 == mask) {
continue;
}
SkPMColor d = dst[i];
int maskR = SkGetPackedR32(mask);
int maskG = SkGetPackedG32(mask);
int maskB = SkGetPackedB32(mask);
// Now upscale them to 0..256, so we can use SkAlphaBlend
maskR = SkAlpha255To256(maskR);
maskG = SkAlpha255To256(maskG);
maskB = SkAlpha255To256(maskB);
int dstR = SkGetPackedR32(d);
int dstG = SkGetPackedG32(d);
int dstB = SkGetPackedB32(d);
// LCD blitting is only supported if the dst is known/required
// to be opaque
dst[i] = SkPackARGB32(0xFF,
SkAlphaBlend(srcR, dstR, maskR),
SkAlphaBlend(srcG, dstG, maskG),
SkAlphaBlend(srcB, dstB, maskB));
}
}
static void blit_lcd32_row(SkPMColor* SK_RESTRICT dst,
const SkPMColor* SK_RESTRICT src,
SkColor color, int width) {
int srcA = SkColorGetA(color);
int srcR = SkColorGetR(color);
int srcG = SkColorGetG(color);
int srcB = SkColorGetB(color);
srcA = SkAlpha255To256(srcA);
for (int i = 0; i < width; i++) {
SkPMColor mask = src[i];
if (0 == mask) {
continue;
}
SkPMColor d = dst[i];
int maskR = SkGetPackedR32(mask);
int maskG = SkGetPackedG32(mask);
int maskB = SkGetPackedB32(mask);
// Now upscale them to 0..256, so we can use SkAlphaBlend
maskR = SkAlpha255To256(maskR);
maskG = SkAlpha255To256(maskG);
maskB = SkAlpha255To256(maskB);
maskR = maskR * srcA >> 8;
maskG = maskG * srcA >> 8;
maskB = maskB * srcA >> 8;
int dstR = SkGetPackedR32(d);
int dstG = SkGetPackedG32(d);
int dstB = SkGetPackedB32(d);
// LCD blitting is only supported if the dst is known/required
// to be opaque
dst[i] = SkPackARGB32(0xFF,
SkAlphaBlend(srcR, dstR, maskR),
SkAlphaBlend(srcG, dstG, maskG),
SkAlphaBlend(srcB, dstB, maskB));
}
}
static void D32_LCD32_Blend(void* SK_RESTRICT dst, size_t dstRB,
const void* SK_RESTRICT mask, size_t maskRB,
SkColor color, int width, int height) {
SkASSERT(height > 0);
SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst;
const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask;
do {
blit_lcd32_row(dstRow, srcRow, color, width);
dstRow = (SkPMColor*)((char*)dstRow + dstRB);
srcRow = (const SkPMColor*)((const char*)srcRow + maskRB);
} while (--height != 0);
}
static void D32_LCD32_Opaque(void* SK_RESTRICT dst, size_t dstRB,
const void* SK_RESTRICT mask, size_t maskRB,
SkColor color, int width, int height) {
SkASSERT(height > 0);
SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst;
const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask;
do {
blit_lcd32_opaque_row(dstRow, srcRow, color, width);
dstRow = (SkPMColor*)((char*)dstRow + dstRB);
srcRow = (const SkPMColor*)((const char*)srcRow + maskRB);
} while (--height != 0);
}
///////////////////////////////////////////////////////////////////////////////
static SkBlitMask::Proc D32_A8_Factory(SkColor color) {
if (SK_ColorBLACK == color) {
return D32_A8_Black;
} else if (0xFF == SkColorGetA(color)) {
return D32_A8_Opaque;
} else {
return D32_A8_Color;
}
}
static SkBlitMask::Proc D32_LCD32_Factory(SkColor color) {
return (0xFF == SkColorGetA(color)) ? D32_LCD32_Opaque : D32_LCD32_Blend;
}
SkBlitMask::Proc SkBlitMask::Factory(SkBitmap::Config config,
SkMask::Format format, SkColor color) {
SkBlitMask::Proc proc = PlatformProcs(config, format, color);
if (proc) {
return proc;
}
switch (config) {
case SkBitmap::kARGB_8888_Config:
switch (format) {
case SkMask::kA8_Format:
return D32_A8_Factory(color);
case SkMask::kLCD16_Format:
return D32_LCD16_Proc;
case SkMask::kLCD32_Format:
return D32_LCD32_Factory(color);
}
break;
default:
break;
}
return NULL;
}
static const int gMaskFormatToShift[] = {
~0, // BW
0, // A8
0, // 3D
2, // ARGB32
1, // LCD16
2 // LCD32
};
static int maskFormatToShift(SkMask::Format format) {
SkASSERT((unsigned)format < SK_ARRAY_COUNT(gMaskFormatToShift));
SkASSERT(SkMask::kBW_Format != format);
return gMaskFormatToShift[format];
}
static const void* getAddr(const SkMask& mask, int x, int y) {
SkASSERT(mask.fBounds.contains(x, y));
SkASSERT(mask.fImage);
const char* addr = (const char*)mask.fImage;
addr += (y - mask.fBounds.fTop) * mask.fRowBytes;
addr += (x - mask.fBounds.fLeft) << maskFormatToShift(mask.fFormat);
return addr;
}
bool SkBlitMask::BlitColor(const SkBitmap& device, const SkMask& mask,
const SkIRect& clip, SkColor color) {
Proc proc = Factory(device.config(), mask.fFormat, color);
if (proc) {
int x = clip.fLeft;
int y = clip.fTop;
proc(device.getAddr32(x, y), device.rowBytes(), getAddr(mask, x, y),
mask.fRowBytes, color, clip.width(), clip.height());
return true;
}
return false;
}

View File

@ -177,83 +177,3 @@ void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst,
}
}
///////////////////////////////////////////////////////////////////////////////
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);
size_t maskOffset = maskRB - width;
SkPMColor *device = (SkPMColor *)dst;
do {
int w = width;
do {
unsigned aa = *mask++;
*device = SkBlendARGB32(pmc, *device, aa);
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + dstOffset);
mask += maskOffset;
} while (--height != 0);
}
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;
maskRB -= width;
dstRB -= (width << 2);
do {
int w = width;
do {
unsigned aa = *mask++;
*device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + dstRB);
mask += maskRB;
} while (--height != 0);
}
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;
maskRB -= width;
dstRB -= (width << 2);
do {
int w = width;
do {
unsigned aa = *mask++;
*device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + dstRB);
mask += maskRB;
} while (--height != 0);
}
SkBlitMask::Proc SkBlitMask::Factory(SkBitmap::Config config, SkColor color) {
SkBlitMask::Proc proc = PlatformProcs(config, color);
if (NULL == proc) {
switch (config) {
case SkBitmap::kARGB_8888_Config:
if (SK_ColorBLACK == color) {
proc = D32_Mask_Black;
} else if (0xFF == SkColorGetA(color)) {
proc = D32_Mask_Opaque;
} else {
proc = D32_Mask_Color;
}
break;
default:
break;
}
}
return proc;
}

View File

@ -14,197 +14,6 @@
///////////////////////////////////////////////////////////////////////////////
static inline int upscale31To32(int value) {
SkASSERT((unsigned)value <= 31);
return value + (value >> 4);
}
static inline int blend32(int src, int dst, int scale) {
SkASSERT((unsigned)src <= 0xFF);
SkASSERT((unsigned)dst <= 0xFF);
SkASSERT((unsigned)scale <= 32);
return dst + ((src - dst) * scale >> 5);
}
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);
int srcB = SkColorGetB(color);
srcA = SkAlpha255To256(srcA);
for (int i = 0; i < width; i++) {
uint16_t mask = src[i];
if (0 == mask) {
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);
maskR = maskR * srcA >> 8;
maskG = maskG * srcA >> 8;
maskB = maskB * srcA >> 8;
int dstR = SkGetPackedR32(d);
int dstG = SkGetPackedG32(d);
int dstB = SkGetPackedB32(d);
// LCD blitting is only supported if the dst is known/required\
// to be opaque
dst[i] = SkPackARGB32(0xFF,
blend32(srcR, dstR, maskR),
blend32(srcG, dstG, maskG),
blend32(srcB, dstB, maskB));
}
}
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 dstR = SkGetPackedR32(d);
int dstG = SkGetPackedG32(d);
int dstB = SkGetPackedB32(d);
// LCD blitting is only supported if the dst is known/required
// to be opaque
dst[i] = SkPackARGB32(0xFF,
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);
int srcB = SkColorGetB(color);
srcA = SkAlpha255To256(srcA);
for (int i = 0; i < width; i++) {
uint32_t mask = src[i];
if (0 == mask) {
continue;
}
SkPMColor d = dst[i];
int maskR = SkGetPackedR32(mask);
int maskG = SkGetPackedG32(mask);
int maskB = SkGetPackedB32(mask);
// Now upscale them to 0..256, so we can use SkAlphaBlend
maskR = SkAlpha255To256(maskR);
maskG = SkAlpha255To256(maskG);
maskB = SkAlpha255To256(maskB);
maskR = maskR * srcA >> 8;
maskG = maskG * srcA >> 8;
maskB = maskB * srcA >> 8;
int dstR = SkGetPackedR32(d);
int dstG = SkGetPackedG32(d);
int dstB = SkGetPackedB32(d);
// LCD blitting is only supported if the dst is known/required
// to be opaque
dst[i] = SkPackARGB32(0xFF,
SkAlphaBlend(srcR, dstR, maskR),
SkAlphaBlend(srcG, dstG, maskG),
SkAlphaBlend(srcB, dstB, maskB));
}
}
static void blitmask_lcd16(const SkBitmap& device, const SkMask& mask,
const SkIRect& clip, SkColor srcColor) {
int x = clip.fLeft;
int y = clip.fTop;
int width = clip.width();
int height = clip.height();
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 {
proc(dstRow, srcRow, srcColor, width, opaqueDst);
dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes());
srcRow = (const uint16_t*)((const char*)srcRow + mask.fRowBytes);
} while (--height != 0);
}
static void blitmask_lcd32(const SkBitmap& device, const SkMask& mask,
const SkIRect& clip, SkColor srcColor) {
int x = clip.fLeft;
int y = clip.fTop;
int width = clip.width();
int height = clip.height();
SkPMColor* dstRow = device.getAddr32(x, y);
const uint32_t* srcRow = mask.getAddrLCD32(x, y);
do {
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);
}
//////////////////////////////////////////////////////////////////////////////////////
static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
const SkIRect& clip, SkPMColor srcColor) {
U8CPU alpha = SkGetPackedA32(srcColor);
@ -244,9 +53,6 @@ SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
fColor32Proc = SkBlitRow::ColorProcFactory();
// init the pro for blitmask
fBlitMaskProc = SkBlitMask::Factory(SkBitmap::kARGB_8888_Config, color);
}
const SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
@ -348,55 +154,30 @@ void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
return;
}
if (mask.fFormat == SkMask::kBW_Format) {
SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
return;
} else if (SkMask::kARGB32_Format == mask.fFormat) {
SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
return;
} else if (SkMask::kLCD16_Format == mask.fFormat) {
blitmask_lcd16(fDevice, mask, clip, fColor);
return;
} else if (SkMask::kLCD32_Format == mask.fFormat) {
blitmask_lcd32(fDevice, mask, clip, fColor);
if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
return;
}
int x = clip.fLeft;
int y = clip.fTop;
fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
SkBitmap::kARGB_8888_Config,
mask.getAddr(x, y), mask.fRowBytes,
fColor, clip.width(), clip.height());
if (mask.fFormat == SkMask::kBW_Format) {
SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
} else if (SkMask::kARGB32_Format == mask.fFormat) {
SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
}
}
void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
const SkIRect& clip) {
SkASSERT(mask.fBounds.contains(clip));
if (mask.fFormat == SkMask::kBW_Format) {
SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
return;
} else if (SkMask::kARGB32_Format == mask.fFormat) {
SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
return;
} else if (SkMask::kLCD16_Format == mask.fFormat) {
blitmask_lcd16(fDevice, mask, clip, fColor);
return;
} else if (SkMask::kLCD32_Format == mask.fFormat) {
blitmask_lcd32(fDevice, mask, clip, fColor);
if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
return;
}
int x = clip.fLeft;
int y = clip.fTop;
int width = clip.width();
int height = clip.height();
fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
SkBitmap::kARGB_8888_Config,
mask.getAddr(x, y), mask.fRowBytes, fColor, width, height);
if (mask.fFormat == SkMask::kBW_Format) {
SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
} else if (SkMask::kARGB32_Format == mask.fFormat) {
SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
}
}
//////////////////////////////////////////////////////////////////////////////////////
@ -452,27 +233,6 @@ void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
///////////////////////////////////////////////////////////////////////
void SkARGB32_Black_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
SkASSERT(mask.fBounds.contains(clip));
SkPMColor black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
if (mask.fFormat == SkMask::kBW_Format) {
SkARGB32_BlitBW(fDevice, mask, clip, black);
} else if (SkMask::kARGB32_Format == mask.fFormat) {
SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
} else if (SkMask::kLCD16_Format == mask.fFormat) {
blitmask_lcd16(fDevice, mask, clip, fColor);
} else if (SkMask::kLCD32_Format == mask.fFormat) {
blitmask_lcd32(fDevice, mask, clip, fColor);
} else {
fBlitMaskProc(fDevice.getAddr32(clip.fLeft, clip.fTop),
fDevice.rowBytes(),
SkBitmap::kARGB_8888_Config,
mask.getAddr(clip.fLeft, clip.fTop), mask.fRowBytes,
black, clip.width(), clip.height());
}
}
void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]) {
uint32_t* device = fDevice.getAddr32(x, y);

View File

@ -9,7 +9,6 @@
#define SkCoreBlitters_DEFINED
#include "SkBlitter.h"
#include "SkBlitMask.h"
#include "SkBlitRow.h"
class SkRasterBlitter : public SkBlitter {
@ -95,7 +94,6 @@ protected:
SkColor fColor;
SkPMColor fPMColor;
SkBlitRow::ColorProc fColor32Proc;
SkBlitMask::Proc fBlitMaskProc;
private:
unsigned fSrcA, fSrcR, fSrcG, fSrcB;
@ -120,7 +118,6 @@ class SkARGB32_Black_Blitter : public SkARGB32_Opaque_Blitter {
public:
SkARGB32_Black_Blitter(const SkBitmap& device, const SkPaint& paint)
: INHERITED(device, paint) {}
virtual void blitMask(const SkMask&, const SkIRect&);
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
private:

View File

@ -383,8 +383,7 @@ void Color32_SSE2(SkPMColor dst[], const SkPMColor src[], int count,
}
}
void SkARGB32_BlitMask_SSE2(void* device, size_t dstRB,
SkBitmap::Config dstConfig, const uint8_t* mask,
void SkARGB32_A8_BlitMask_SSE2(void* device, size_t dstRB, const void* maskPtr,
size_t maskRB, SkColor origColor,
int width, int height)
{
@ -392,6 +391,7 @@ void SkARGB32_BlitMask_SSE2(void* device, size_t dstRB,
size_t dstOffset = dstRB - (width << 2);
size_t maskOffset = maskRB - width;
SkPMColor* dst = (SkPMColor *)device;
const uint8_t* mask = (const uint8_t*)maskPtr;
do {
int count = width;
if (count >= 4) {

View File

@ -20,7 +20,6 @@ void S32A_Opaque_BlitRow32_SSE2(SkPMColor* SK_RESTRICT dst,
void S32A_Blend_BlitRow32_SSE2(SkPMColor* SK_RESTRICT dst,
const SkPMColor* SK_RESTRICT src,
int count, U8CPU alpha);
void SkARGB32_BlitMask_SSE2(void* device, size_t dstRB,
SkBitmap::Config dstConfig, const uint8_t* mask,
void SkARGB32_A8_BlitMask_SSE2(void* device, size_t dstRB, const void* mask,
size_t maskRB, SkColor color,
int width, int height);

View File

@ -1311,6 +1311,7 @@ SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
SkMask::Format maskFormat,
SkColor color)
{
return NULL;

View File

@ -28,6 +28,7 @@ SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
SkMask::Format maskFormat,
SkColor color)
{
return NULL;

View File

@ -55,8 +55,13 @@ static inline bool hasSSE2() {
}
#endif
static bool cachedHasSSE2() {
static bool gHasSSE2 = hasSSE2();
return gHasSSE2;
}
void SkBitmapProcState::platformProcs() {
if (hasSSE2()) {
if (cachedHasSSE2()) {
if (fSampleProc32 == S32_opaque_D32_filter_DX) {
fSampleProc32 = S32_opaque_D32_filter_DX_SSE2;
} else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
@ -81,7 +86,7 @@ SkBlitRow::Proc SkBlitRow::PlatformProcs565(unsigned flags) {
}
SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
if (hasSSE2()) {
if (cachedHasSSE2()) {
return Color32_SSE2;
} else {
return NULL;
@ -89,7 +94,7 @@ SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
}
SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
if (hasSSE2()) {
if (cachedHasSSE2()) {
return platform_32_procs[flags];
} else {
return NULL;
@ -98,15 +103,20 @@ SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
SkMask::Format maskFormat,
SkColor color) {
if (SkMask::kA8_Format != maskFormat) {
return NULL;
}
SkBlitMask::Proc proc = NULL;
if (hasSSE2()) {
if (cachedHasSSE2()) {
switch (dstConfig) {
case SkBitmap::kARGB_8888_Config:
// The SSE2 version is not (yet) faster for black, so we check
// for that.
if (SK_ColorBLACK != color) {
proc = SkARGB32_BlitMask_SSE2;
proc = SkARGB32_A8_BlitMask_SSE2;
}
break;
default:
@ -117,7 +127,7 @@ SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
}
SkMemset16Proc SkMemset16GetPlatformProc() {
if (hasSSE2()) {
if (cachedHasSSE2()) {
return sk_memset16_SSE2;
} else {
return NULL;
@ -125,7 +135,7 @@ SkMemset16Proc SkMemset16GetPlatformProc() {
}
SkMemset32Proc SkMemset32GetPlatformProc() {
if (hasSSE2()) {
if (cachedHasSSE2()) {
return sk_memset32_SSE2;
} else {
return NULL;