spriteblitter for memcpy case (for all configs)
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1887103003 Review URL: https://codereview.chromium.org/1887103003
This commit is contained in:
parent
3faf74b836
commit
8c3fd4f1b4
@ -105,7 +105,7 @@ public:
|
||||
* Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
|
||||
* colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
|
||||
*/
|
||||
int shiftPerPixel() const { return this->bytesPerPixel() >> 1; }
|
||||
int shiftPerPixel() const { return this->fInfo.shiftPerPixel(); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -105,6 +105,25 @@ static int SkColorTypeBytesPerPixel(SkColorType ct) {
|
||||
return gSize[ct];
|
||||
}
|
||||
|
||||
static int SkColorTypeShiftPerPixel(SkColorType ct) {
|
||||
static const uint8_t gShift[] = {
|
||||
0, // Unknown
|
||||
0, // Alpha_8
|
||||
1, // RGB_565
|
||||
1, // ARGB_4444
|
||||
2, // RGBA_8888
|
||||
2, // BGRA_8888
|
||||
0, // kIndex_8
|
||||
0, // kGray_8
|
||||
3, // kRGBA_F16
|
||||
};
|
||||
static_assert(SK_ARRAY_COUNT(gShift) == (size_t)(kLastEnum_SkColorType + 1),
|
||||
"size_mismatch_with_SkColorType_enum");
|
||||
|
||||
SkASSERT((size_t)ct < SK_ARRAY_COUNT(gShift));
|
||||
return gShift[ct];
|
||||
}
|
||||
|
||||
static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
|
||||
return width * SkColorTypeBytesPerPixel(ct);
|
||||
}
|
||||
@ -114,15 +133,10 @@ static inline bool SkColorTypeIsValid(unsigned value) {
|
||||
}
|
||||
|
||||
static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) {
|
||||
int shift = 0;
|
||||
switch (SkColorTypeBytesPerPixel(ct)) {
|
||||
case 8: shift = 3; break;
|
||||
case 4: shift = 2; break;
|
||||
case 2: shift = 1; break;
|
||||
case 1: shift = 0; break;
|
||||
default: return 0;
|
||||
if (kUnknown_SkColorType == ct) {
|
||||
return 0;
|
||||
}
|
||||
return y * rowBytes + (x << shift);
|
||||
return y * rowBytes + (x << SkColorTypeShiftPerPixel(ct));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -252,9 +266,9 @@ public:
|
||||
return SkImageInfo::Make(fWidth, fHeight, newColorType, fAlphaType, fProfileType);
|
||||
}
|
||||
|
||||
int bytesPerPixel() const {
|
||||
return SkColorTypeBytesPerPixel(fColorType);
|
||||
}
|
||||
int bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); }
|
||||
|
||||
int shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); }
|
||||
|
||||
uint64_t minRowBytes64() const {
|
||||
return sk_64_mul(fWidth, this->bytesPerPixel());
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
* Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
|
||||
* colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
|
||||
*/
|
||||
int shiftPerPixel() const { return fInfo.bytesPerPixel() >> 1; }
|
||||
int shiftPerPixel() const { return fInfo.shiftPerPixel(); }
|
||||
|
||||
uint64_t getSize64() const { return sk_64_mul(fInfo.height(), fRowBytes); }
|
||||
uint64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); }
|
||||
@ -141,6 +141,9 @@ public:
|
||||
// Writable versions
|
||||
|
||||
void* writable_addr() const { return const_cast<void*>(fPixels); }
|
||||
void* writable_addr(int x, int y) const {
|
||||
return const_cast<void*>(this->addr(x, y));
|
||||
}
|
||||
uint8_t* writable_addr8(int x, int y) const {
|
||||
return const_cast<uint8_t*>(this->addr8(x, y));
|
||||
}
|
||||
|
@ -38,6 +38,68 @@ void SkSpriteBlitter::blitMask(const SkMask&, const SkIRect& clip) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Only valid if...
|
||||
// 1. src == dst format
|
||||
// 2. paint has no modifiers (i.e. alpha, colorfilter, etc.)
|
||||
// 3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque src
|
||||
//
|
||||
class SkSpriteBlitter_memcpy : public SkSpriteBlitter {
|
||||
public:
|
||||
static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint& paint) {
|
||||
if (dst.colorType() != src.colorType()) {
|
||||
return false;
|
||||
}
|
||||
if (dst.info().profileType() != src.info().profileType()) {
|
||||
return false;
|
||||
}
|
||||
if (paint.getMaskFilter() || paint.getColorFilter() || paint.getImageFilter()) {
|
||||
return false;
|
||||
}
|
||||
if (0xFF != paint.getAlpha()) {
|
||||
return false;
|
||||
}
|
||||
SkXfermode::Mode mode;
|
||||
if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) {
|
||||
return false;
|
||||
}
|
||||
if (SkXfermode::kSrc_Mode == mode) {
|
||||
return true;
|
||||
}
|
||||
if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SkSpriteBlitter_memcpy(const SkPixmap& src) : INHERITED(src) {}
|
||||
|
||||
void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override {
|
||||
SkASSERT(Supports(dst, fSource, paint));
|
||||
this->INHERITED::setup(dst, left, top, paint);
|
||||
}
|
||||
|
||||
void blitRect(int x, int y, int width, int height) override {
|
||||
SkASSERT(fDst.colorType() == fSource.colorType());
|
||||
SkASSERT(fDst.info().profileType() == fSource.info().profileType());
|
||||
SkASSERT(width > 0 && height > 0);
|
||||
|
||||
char* dst = (char*)fDst.writable_addr(x, y);
|
||||
const char* src = (const char*)fSource.addr(x - fLeft, y - fTop);
|
||||
const size_t dstRB = fDst.rowBytes();
|
||||
const size_t srcRB = fSource.rowBytes();
|
||||
const size_t bytesToCopy = width << fSource.shiftPerPixel();
|
||||
|
||||
while (--height >= 0) {
|
||||
memcpy(dst, src, bytesToCopy);
|
||||
dst += dstRB;
|
||||
src += srcRB;
|
||||
}
|
||||
}
|
||||
|
||||
typedef SkSpriteBlitter INHERITED;
|
||||
};
|
||||
|
||||
|
||||
// returning null means the caller will call SkBlitter::Choose() and
|
||||
// have wrapped the source bitmap inside a shader
|
||||
SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
|
||||
@ -55,23 +117,27 @@ SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
|
||||
|
||||
SkSpriteBlitter* blitter;
|
||||
|
||||
switch (dst.colorType()) {
|
||||
case kRGB_565_SkColorType:
|
||||
blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator);
|
||||
break;
|
||||
case kN32_SkColorType:
|
||||
if (dst.info().isSRGB()) {
|
||||
blitter = SkSpriteBlitter::ChooseS32(source, paint, allocator);
|
||||
} else {
|
||||
blitter = SkSpriteBlitter::ChooseL32(source, paint, allocator);
|
||||
}
|
||||
break;
|
||||
case kRGBA_F16_SkColorType:
|
||||
blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator);
|
||||
break;
|
||||
default:
|
||||
blitter = nullptr;
|
||||
break;
|
||||
if (SkSpriteBlitter_memcpy::Supports(dst, source, paint)) {
|
||||
blitter = allocator->createT<SkSpriteBlitter_memcpy>(source);
|
||||
} else {
|
||||
switch (dst.colorType()) {
|
||||
case kRGB_565_SkColorType:
|
||||
blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator);
|
||||
break;
|
||||
case kN32_SkColorType:
|
||||
if (dst.info().isSRGB()) {
|
||||
blitter = SkSpriteBlitter::ChooseS32(source, paint, allocator);
|
||||
} else {
|
||||
blitter = SkSpriteBlitter::ChooseL32(source, paint, allocator);
|
||||
}
|
||||
break;
|
||||
case kRGBA_F16_SkColorType:
|
||||
blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator);
|
||||
break;
|
||||
default:
|
||||
blitter = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (blitter) {
|
||||
|
Loading…
Reference in New Issue
Block a user