convert over to 2d-mode
[√] convert all stages to use SkJumper_MemoryCtx / be 2d-compatible
[√] convert compile to 2d also, remove 1d run/compile
[√] convert all call sites
[√] no diffs
Change-Id: I3b806eb8fe0c3ec043359616409f7cd1211a1e43
Reviewed-on: https://skia-review.googlesource.com/24263
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index b94cf05..da536e4 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -55,7 +55,7 @@
void append_store (SkRasterPipeline*) const;
// If we have an burst context, use it to fill our shader buffer.
- void maybe_shade(int x, int y, int w);
+ void burst_shade(int x, int y, int w);
SkPixmap fDst;
SkBlendMode fBlend;
@@ -63,23 +63,24 @@
SkShaderBase::Context* fBurstCtx;
SkRasterPipeline fColorPipeline;
+ SkJumper_MemoryCtx fShaderOutput = {nullptr,0}, // Possibly updated each call to burst_shade().
+ fDstPtr = {nullptr,0}, // Always points to the top-left of fDst.
+ fMaskPtr = {nullptr,0}; // Updated each call to blitMask().
+
// We may be able to specialize blitH() into a memset.
bool fCanMemsetInBlitH = false;
uint64_t fMemsetColor = 0; // Big enough for largest dst format, F16.
// Built lazily on first use.
- std::function<void(size_t, size_t, size_t)> fBlitH,
- fBlitAntiH,
- fBlitMaskA8,
- fBlitMaskLCD16;
+ std::function<void(size_t, size_t, size_t, size_t)> fBlitH,
+ fBlitAntiH,
+ fBlitMaskA8,
+ fBlitMaskLCD16;
// These values are pointed to by the blit pipelines above,
// which allows us to adjust them from call to call.
- void* fShaderOutput = nullptr;
- void* fDstPtr = nullptr;
- const void* fMaskPtr = nullptr;
- float fCurrentCoverage = 0.0f;
- float fDitherRate = 0.0f;
+ float fCurrentCoverage = 0.0f;
+ float fDitherRate = 0.0f;
std::vector<SkPM4f> fShaderBuffer;
@@ -191,14 +192,14 @@
// A pipeline that's still constant here can collapse back into a constant color.
if (is_constant) {
- SkPM4f storage;
- SkPM4f* constantColor = &storage;
- colorPipeline->append(SkRasterPipeline::store_f32, &constantColor);
- colorPipeline->run(0,0,1);
+ SkPM4f constantColor;
+ SkJumper_MemoryCtx constantColorPtr = { &constantColor, 0 };
+ colorPipeline->append(SkRasterPipeline::store_f32, &constantColorPtr);
+ colorPipeline->run(0,0,1,1);
colorPipeline->reset();
- colorPipeline->append_uniform_color(alloc, *constantColor);
+ colorPipeline->append_uniform_color(alloc, constantColor);
- is_opaque = constantColor->a() == 1.0f;
+ is_opaque = constantColor.a() == 1.0f;
}
// We can strength-reduce SrcOver into Src when opaque.
@@ -213,13 +214,18 @@
// Not all blits can memset, so we need to keep colorPipeline too.
SkRasterPipeline_<256> p;
p.extend(*colorPipeline);
- blitter->fDstPtr = &blitter->fMemsetColor;
+ blitter->fDstPtr = SkJumper_MemoryCtx{&blitter->fMemsetColor, 0};
blitter->append_store(&p);
- p.run(0,0,1);
+ p.run(0,0,1,1);
blitter->fCanMemsetInBlitH = true;
}
+ blitter->fDstPtr = SkJumper_MemoryCtx{
+ blitter->fDst.writable_addr(),
+ blitter->fDst.rowBytesAsPixels(),
+ };
+
return blitter;
}
@@ -275,26 +281,23 @@
SkBlendMode_AppendClampIfNeeded(fBlend, p);
}
-void SkRasterPipelineBlitter::maybe_shade(int x, int y, int w) {
- if (fBurstCtx) {
- if (w > SkToInt(fShaderBuffer.size())) {
- fShaderBuffer.resize(w);
- }
- fBurstCtx->shadeSpan4f(x,y, fShaderBuffer.data(), w);
- // We'll be reading from fShaderOutput + x.
- fShaderOutput = fShaderBuffer.data() - x;
+void SkRasterPipelineBlitter::burst_shade(int x, int y, int w) {
+ SkASSERT(fBurstCtx);
+ if (w > SkToInt(fShaderBuffer.size())) {
+ fShaderBuffer.resize(w);
}
+ fBurstCtx->shadeSpan4f(x,y, fShaderBuffer.data(), w);
+ // We'll be reading from fShaderOutput.pixels + x, so back up by x.
+ fShaderOutput = SkJumper_MemoryCtx{ fShaderBuffer.data() - x, 0 };
}
void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
- fDstPtr = fDst.writable_addr(0,y);
-
if (fCanMemsetInBlitH) {
switch (fDst.shiftPerPixel()) {
- case 0: memset ((uint8_t *)fDstPtr + x, fMemsetColor, w); return;
- case 1: sk_memset16((uint16_t*)fDstPtr + x, fMemsetColor, w); return;
- case 2: sk_memset32((uint32_t*)fDstPtr + x, fMemsetColor, w); return;
- case 3: sk_memset64((uint64_t*)fDstPtr + x, fMemsetColor, w); return;
+ case 0: memset (fDst.writable_addr8 (x,y), fMemsetColor, w); return;
+ case 1: sk_memset16(fDst.writable_addr16(x,y), fMemsetColor, w); return;
+ case 2: sk_memset32(fDst.writable_addr32(x,y), fMemsetColor, w); return;
+ case 3: sk_memset64(fDst.writable_addr64(x,y), fMemsetColor, w); return;
default: break;
}
}
@@ -318,8 +321,10 @@
}
fBlitH = p.compile();
}
- this->maybe_shade(x,y,w);
- fBlitH(x,y,w);
+ if (fBurstCtx) {
+ this->burst_shade(x,y,w);
+ }
+ fBlitH(x,y,w,1);
}
void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) {
@@ -340,15 +345,16 @@
fBlitAntiH = p.compile();
}
- fDstPtr = fDst.writable_addr(0,y);
for (int16_t run = *runs; run > 0; run = *runs) {
switch (*aa) {
case 0x00: break;
case 0xff: this->blitH(x,y,run); break;
default:
- this->maybe_shade(x,y,run);
fCurrentCoverage = *aa * (1/255.0f);
- fBlitAntiH(x,y,run);
+ if (fBurstCtx) {
+ this->burst_shade(x,y,run);
+ }
+ fBlitAntiH(x,y,run,1);
}
x += run;
runs += run;
@@ -375,6 +381,7 @@
return INHERITED::blitMask(mask, clip);
}
+ // Lazily build whichever pipeline we need, specialized for each mask format.
if (mask.fFormat == SkMask::kA8_Format && !fBlitMaskA8) {
SkRasterPipeline p(fAlloc);
p.extend(fColorPipeline);
@@ -391,7 +398,6 @@
this->append_store(&p);
fBlitMaskA8 = p.compile();
}
-
if (mask.fFormat == SkMask::kLCD16_Format && !fBlitMaskLCD16) {
SkRasterPipeline p(fAlloc);
p.extend(fColorPipeline);
@@ -403,23 +409,35 @@
fBlitMaskLCD16 = p.compile();
}
- int x = clip.left();
- for (int y = clip.top(); y < clip.bottom(); y++) {
- fDstPtr = fDst.writable_addr(0,y);
+ std::function<void(size_t,size_t,size_t,size_t)>* blitter = nullptr;
+ // Update fMaskPtr to point "into" this current mask, but lined up with fDstPtr at (0,0).
+ switch (mask.fFormat) {
+ case SkMask::kA8_Format:
+ fMaskPtr.stride = mask.fRowBytes;
+ fMaskPtr.pixels = (uint8_t*)mask.fImage - mask.fBounds.left()
+ - mask.fBounds.top() * fMaskPtr.stride;
+ blitter = &fBlitMaskA8;
+ break;
+ case SkMask::kLCD16_Format:
+ fMaskPtr.stride = mask.fRowBytes / 2;
+ fMaskPtr.pixels = (uint16_t*)mask.fImage - mask.fBounds.left()
+ - mask.fBounds.top() * fMaskPtr.stride;
+ blitter = &fBlitMaskLCD16;
+ break;
+ default:
+ return;
+ }
- this->maybe_shade(x,y,clip.width());
- switch (mask.fFormat) {
- case SkMask::kA8_Format:
- fMaskPtr = mask.getAddr8(x,y)-x;
- fBlitMaskA8(x,y,clip.width());
- break;
- case SkMask::kLCD16_Format:
- fMaskPtr = mask.getAddrLCD16(x,y)-x;
- fBlitMaskLCD16(x,y,clip.width());
- break;
- default:
- // TODO
- break;
+ SkASSERT(blitter);
+ if (fBurstCtx) {
+ // We can only burst shade one row at a time.
+ int x = clip.left();
+ for (int y = clip.top(); y < clip.bottom(); y++) {
+ this->burst_shade(x,y,clip.width());
+ (*blitter)(x,y, clip.width(),1);
}
+ } else {
+ // If not bursting we can blit the entire mask at once.
+ (*blitter)(clip.left(),clip.top(), clip.width(),clip.height());
}
}