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:
parent
095186a466
commit
edb606cb99
@ -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',
|
||||
|
@ -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;
|
||||
|
@ -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
384
src/core/SkBlitMask_D32.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -1311,6 +1311,7 @@ SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
|
||||
|
||||
|
||||
SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
|
||||
SkMask::Format maskFormat,
|
||||
SkColor color)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -28,6 +28,7 @@ SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
|
||||
|
||||
|
||||
SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
|
||||
SkMask::Format maskFormat,
|
||||
SkColor color)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user