| Index: src/core/SkBlitter_PM4f.cpp
|
| diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp
|
| index 01fd70425423967cc835f4e93d3226af9fa4793e..cec2361c06d212161cf4d87746f998952e1a9c48 100644
|
| --- a/src/core/SkBlitter_PM4f.cpp
|
| +++ b/src/core/SkBlitter_PM4f.cpp
|
| @@ -80,8 +80,31 @@ public:
|
| }
|
| }
|
|
|
| + void blitLCDMask(const SkMask& mask, const SkIRect& clip) {
|
| + auto proc = fState.getLCDProc(SkXfermode::kSrcIsSingle_LCDFlag);
|
| +
|
| + const int x = clip.fLeft;
|
| + const int width = clip.width();
|
| + const int y = clip.fTop;
|
| + const int height = clip.height();
|
| +
|
| + typename State::DstType* device = State::WritableAddr(fDevice, x, y);
|
| + const size_t dstRB = fDevice.rowBytes();
|
| + const uint16_t* maskRow = (const uint16_t*)mask.getAddr(x, y);
|
| + const size_t maskRB = mask.fRowBytes;
|
| +
|
| + for (int i = 0; i < height; ++i) {
|
| + proc(device, &fState.fPM4f, width, maskRow);
|
| + device = (typename State::DstType*)((char*)device + dstRB);
|
| + maskRow = (const uint16_t*)((const char*)maskRow + maskRB);
|
| + }
|
| + }
|
| +
|
| void blitMask(const SkMask& mask, const SkIRect& clip) override {
|
| - // we only handle kA8
|
| + if (SkMask::kLCD16_Format == mask.fFormat) {
|
| + this->blitLCDMask(mask, clip);
|
| + return;
|
| + }
|
| if (SkMask::kA8_Format != mask.fFormat) {
|
| this->INHERITED::blitMask(mask, clip);
|
| return;
|
| @@ -190,8 +213,36 @@ public:
|
| }
|
| }
|
|
|
| + void blitLCDMask(const SkMask& mask, const SkIRect& clip) {
|
| + auto proc = fState.getLCDProc(0);
|
| +
|
| + const int x = clip.fLeft;
|
| + const int width = clip.width();
|
| + int y = clip.fTop;
|
| +
|
| + typename State::DstType* device = State::WritableAddr(fDevice, x, y);
|
| + const size_t deviceRB = fDevice.rowBytes();
|
| + const uint16_t* maskRow = (const uint16_t*)mask.getAddr(x, y);
|
| + const size_t maskRB = mask.fRowBytes;
|
| +
|
| + if (fConstInY) {
|
| + fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width);
|
| + }
|
| + for (; y < clip.fBottom; ++y) {
|
| + if (!fConstInY) {
|
| + fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width);
|
| + }
|
| + proc(device, fState.fBuffer, width, maskRow);
|
| + device = (typename State::DstType*)((char*)device + deviceRB);
|
| + maskRow = (const uint16_t*)((const char*)maskRow + maskRB);
|
| + }
|
| + }
|
| +
|
| void blitMask(const SkMask& mask, const SkIRect& clip) override {
|
| - // we only handle kA8
|
| + if (SkMask::kLCD16_Format == mask.fFormat) {
|
| + this->blitLCDMask(mask, clip);
|
| + return;
|
| + }
|
| if (SkMask::kA8_Format != mask.fFormat) {
|
| this->INHERITED::blitMask(mask, clip);
|
| return;
|
| @@ -271,7 +322,15 @@ struct State32 : SkXfermode::PM4fState {
|
| SkSafeUnref(fXfer);
|
| delete[] fBuffer;
|
| }
|
| -
|
| +
|
| + SkXfermode::LCD32Proc getLCDProc(uint32_t oneOrManyFlag) const {
|
| + uint32_t flags = fFlags & 1;
|
| + if (!(fFlags & SkXfermode::kDstIsSRGB_PM4fFlag)) {
|
| + flags |= SkXfermode::kDstIsLinearInt_LCDFlag;
|
| + }
|
| + return SkXfermode::GetLCD32Proc(flags | oneOrManyFlag);
|
| + }
|
| +
|
| static DstType* WritableAddr(const SkPixmap& device, int x, int y) {
|
| return device.writable_addr32(x, y);
|
| }
|
| @@ -315,6 +374,14 @@ struct State64 : SkXfermode::U64State {
|
| delete[] fBuffer;
|
| }
|
|
|
| + SkXfermode::LCD64Proc getLCDProc(uint32_t oneOrManyFlag) const {
|
| + uint32_t flags = fFlags & 1;
|
| + if (!(fFlags & SkXfermode::kDstIsFloat16_U64Flag)) {
|
| + flags |= SkXfermode::kDstIsLinearInt_LCDFlag;
|
| + }
|
| + return SkXfermode::GetLCD64Proc(flags | oneOrManyFlag);
|
| + }
|
| +
|
| static DstType* WritableAddr(const SkPixmap& device, int x, int y) {
|
| return device.writable_addr64(x, y);
|
| }
|
|
|