Correct blitmask procs to recognize that we pass them an SkColor, and if they

want a SkPMColor, they need to call SkPreMultiplyColor()

Add Opaque and Black optimizations for blitmask_d32



git-svn-id: http://skia.googlecode.com/svn/trunk@911 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-03-09 13:23:57 +00:00
parent 981d479800
commit ee467ee79d
4 changed files with 65 additions and 35 deletions

View File

@ -170,11 +170,10 @@ void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[],
///////////////////////////////////////////////////////////////////////////////
static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB,
SkBitmap::Config dstConfig,
const uint8_t* mask,
size_t maskRB, SkColor color,
int width, int height) {
static void D32_Mask_Color(void* dst, size_t dstRB, SkBitmap::Config,
const uint8_t* 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;
@ -182,7 +181,7 @@ static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB,
int w = width;
do {
unsigned aa = *mask++;
*device = SkBlendARGB32(color, *device, aa);
*device = SkBlendARGB32(pmc, *device, aa);
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + dstOffset);
@ -190,15 +189,57 @@ static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB,
} while (--height != 0);
}
static void D32_Mask_Opaque(void* dst, size_t dstRB, SkBitmap::Config,
const uint8_t* 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* dst, size_t dstRB, SkBitmap::Config,
const uint8_t* 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);
proc = NULL;
if (NULL == proc) {
switch (config) {
case SkBitmap::kARGB_8888_Config:
if ( SK_ColorBLACK != color && 0xFF != SkColorGetA(color) ) {
//TODO: blitmask for black;
//TODO: blitmask for opaque;
proc = SkARGB32_BlitMask_portable;
if (SK_ColorBLACK == color) {
proc = D32_Mask_Black;
} else if (0xFF == SkColorGetA(color)) {
proc = D32_Mask_Opaque;
} else {
proc = D32_Mask_Color;
}
break;
default:

View File

@ -68,7 +68,8 @@ static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
: INHERITED(device) {
uint32_t color = paint.getColor();
SkColor color = paint.getColor();
fColor = color;
fSrcA = SkColorGetA(color);
unsigned scale = SkAlpha255To256(fSrcA);
@ -192,14 +193,11 @@ void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
int x = clip.fLeft;
int y = clip.fTop;
int width = clip.width();
int height = clip.height();
uint32_t* device = fDevice.getAddr32(x, y);
const uint8_t* alpha = mask.getAddr(x, y);
uint32_t srcColor = fPMColor;
fBlitMaskProc(device, fDevice.rowBytes(), SkBitmap::kARGB_8888_Config,
alpha, mask.fRowBytes, srcColor, width, height);
fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
SkBitmap::kARGB_8888_Config,
mask.getAddr(x, y), mask.fRowBytes,
fColor, clip.width(), clip.height());
}
void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
@ -225,7 +223,7 @@ void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
#endif
// In LCD mode the masks have either an extra couple of rows or columns on the edges.
uint32_t srcColor = fPMColor;
SkPMColor srcColor = fPMColor;
#if defined(SK_SUPPORT_LCDTEXT)
if (lcdMode || verticalLCDMode) {
@ -254,20 +252,9 @@ void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
}
#endif
uint32_t* device = fDevice.getAddr32(x, y);
const uint8_t* alpha = mask.getAddr(x, y);
unsigned maskRB = mask.fRowBytes - width;
unsigned devRB = fDevice.rowBytes() - (width << 2);
do {
int w = width;
do {
unsigned aa = *alpha++;
*device = SkAlphaMulQ(srcColor, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
device += 1;
} while (--w != 0);
device = (uint32_t*)((char*)device + devRB);
alpha += maskRB;
} while (--height != 0);
fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
SkBitmap::kARGB_8888_Config,
mask.getAddr(x, y), mask.fRowBytes, fColor, width, height);
}
//////////////////////////////////////////////////////////////////////////////////////

View File

@ -101,7 +101,8 @@ public:
virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
protected:
SkColor fPMColor;
SkColor fColor;
SkPMColor fPMColor;
SkBlitRow::ColorProc fColor32Proc;
SkBlitMask::Proc fBlitMaskProc;

View File

@ -393,9 +393,10 @@ 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,
size_t maskRB, SkColor color,
size_t maskRB, SkColor origColor,
int width, int height)
{
SkPMColor color = SkPreMultiplyColor(origColor);
size_t dstOffset = dstRB - (width << 2);
size_t maskOffset = maskRB - width;
SkPMColor* dst = (SkPMColor *)device;