Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: src/core/SkBlitter_PM4f.cpp

Issue 1707883002: lcd blits for sRGB (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: more clarity on names/docs for new flags Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
}

Powered by Google App Engine
This is Rietveld 408576698