diff options
author | reed <reed@google.com> | 2016-04-15 06:59:38 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-04-15 06:59:39 -0700 |
commit | 8c3fd4f1b49a77634b73f787c6c49d34039a16f0 (patch) | |
tree | 7634a1926ff900026077d9cec0b6d0c96a1bd6e2 /src/core/SkBlitter_Sprite.cpp | |
parent | 3faf74b8364491ca806f523fbb1d8a97be592663 (diff) |
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
Diffstat (limited to 'src/core/SkBlitter_Sprite.cpp')
-rw-r--r-- | src/core/SkBlitter_Sprite.cpp | 100 |
1 files changed, 83 insertions, 17 deletions
diff --git a/src/core/SkBlitter_Sprite.cpp b/src/core/SkBlitter_Sprite.cpp index 27cbd61768..c0b7430d22 100644 --- a/src/core/SkBlitter_Sprite.cpp +++ b/src/core/SkBlitter_Sprite.cpp @@ -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) { |