| Index: src/core/SkSpriteBlitter4f.cpp
|
| diff --git a/src/core/SkSpriteBlitter4f.cpp b/src/core/SkSpriteBlitter4f.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fc4b4809511f1bec8730afdb84b2a0ddcf326b94
|
| --- /dev/null
|
| +++ b/src/core/SkSpriteBlitter4f.cpp
|
| @@ -0,0 +1,137 @@
|
| +/*
|
| + * Copyright 2016 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkSpriteBlitter.h"
|
| +#include "SkSpanProcs.h"
|
| +#include "SkTemplates.h"
|
| +#include "SkXfermode.h"
|
| +
|
| +class Sprite_4f : public SkSpriteBlitter {
|
| +public:
|
| + Sprite_4f(const SkPixmap& src, const SkPaint& paint) : INHERITED(src) {
|
| + fLoader = SkLoadSpanProc_Choose(src.info());
|
| + fFilter = SkFilterSpanProc_Choose(paint);
|
| + fBuffer.reset(src.width());
|
| + }
|
| +
|
| +protected:
|
| + SkLoadSpanProc fLoader;
|
| + SkFilterSpanProc fFilter;
|
| + SkAutoTMalloc<SkPM4f> fBuffer;
|
| +
|
| +private:
|
| + typedef SkSpriteBlitter INHERITED;
|
| +};
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +static SkXfermode::Mode get_mode(const SkXfermode* xfer) {
|
| + SkXfermode::Mode mode;
|
| + if (!SkXfermode::AsMode(xfer, &mode)) {
|
| + mode = SkXfermode::kSrcOver_Mode;
|
| + }
|
| + return mode;
|
| +}
|
| +
|
| +class Sprite_F16 : public Sprite_4f {
|
| +public:
|
| + Sprite_F16(const SkPixmap& src, const SkPaint& paint) : INHERITED(src, paint) {
|
| + fState = { paint.getXfermode(), SkXfermode::kDstIsFloat16_U64Flag };
|
| + if (src.isOpaque()) {
|
| + fState.fFlags |= SkXfermode::kSrcIsOpaque_U64Flag;
|
| + }
|
| + fXfer = SkXfermode::GetU64ProcN(get_mode(fState.fXfer), fState.fFlags);
|
| + }
|
| +
|
| + void blitRect(int x, int y, int width, int height) override {
|
| + SkASSERT(width > 0 && height > 0);
|
| + uint64_t* SK_RESTRICT dst = fDst.writable_addr64(x, y);
|
| + size_t dstRB = fDst.rowBytes();
|
| +
|
| + for (int bottom = y + height; y < bottom; ++y) {
|
| + fLoader(fSource, x - fLeft, y - fTop, fBuffer, width);
|
| + fFilter(*fPaint, fBuffer, width);
|
| + fXfer(fState, dst, fBuffer, width, nullptr);
|
| + dst = (uint64_t* SK_RESTRICT)((char*)dst + dstRB);
|
| + }
|
| + }
|
| +
|
| +private:
|
| + SkXfermode::U64State fState;
|
| + SkXfermode::U64ProcN fXfer;
|
| +
|
| + typedef Sprite_4f INHERITED;
|
| +};
|
| +
|
| +
|
| +SkSpriteBlitter* SkSpriteBlitter::ChooseF16(const SkPixmap& source, const SkPaint& paint,
|
| + SkTBlitterAllocator* allocator) {
|
| + SkASSERT(allocator != nullptr);
|
| +
|
| + if (paint.getMaskFilter() != nullptr) {
|
| + return nullptr;
|
| + }
|
| +
|
| + switch (source.colorType()) {
|
| + case kN32_SkColorType:
|
| + case kRGBA_F16_SkColorType:
|
| + return allocator->createT<Sprite_F16>(source, paint);
|
| + default:
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +class Sprite_sRGB : public Sprite_4f {
|
| +public:
|
| + Sprite_sRGB(const SkPixmap& src, const SkPaint& paint) : INHERITED(src, paint) {
|
| + fState = { paint.getXfermode(), SkXfermode::kDstIsSRGB_PM4fFlag };
|
| + if (src.isOpaque()) {
|
| + fState.fFlags |= SkXfermode::kSrcIsOpaque_PM4fFlag;
|
| + }
|
| + fXfer = SkXfermode::GetPM4fProcN(get_mode(fState.fXfer), fState.fFlags);
|
| + }
|
| +
|
| + void blitRect(int x, int y, int width, int height) override {
|
| + SkASSERT(width > 0 && height > 0);
|
| + uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
|
| + size_t dstRB = fDst.rowBytes();
|
| +
|
| + for (int bottom = y + height; y < bottom; ++y) {
|
| + fLoader(fSource, x - fLeft, y - fTop, fBuffer, width);
|
| + fFilter(*fPaint, fBuffer, width);
|
| + fXfer(fState, dst, fBuffer, width, nullptr);
|
| + dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
|
| + }
|
| + }
|
| +
|
| +protected:
|
| + SkXfermode::PM4fState fState;
|
| + SkXfermode::PM4fProcN fXfer;
|
| +
|
| +private:
|
| + typedef Sprite_4f INHERITED;
|
| +};
|
| +
|
| +
|
| +SkSpriteBlitter* SkSpriteBlitter::ChooseS32(const SkPixmap& source, const SkPaint& paint,
|
| + SkTBlitterAllocator* allocator) {
|
| + SkASSERT(allocator != nullptr);
|
| +
|
| + if (paint.getMaskFilter() != nullptr) {
|
| + return nullptr;
|
| + }
|
| +
|
| + switch (source.colorType()) {
|
| + case kN32_SkColorType:
|
| + case kRGBA_F16_SkColorType:
|
| + return allocator->createT<Sprite_sRGB>(source, paint);
|
| + default:
|
| + return nullptr;
|
| + }
|
| +}
|
|
|