aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/SkRasterPipelineBench.cpp45
-rw-r--r--src/core/SkConvertPixels.cpp4
-rw-r--r--src/core/SkOpts.cpp1
-rw-r--r--src/core/SkOpts.h3
-rw-r--r--src/core/SkRasterPipeline.cpp4
-rw-r--r--src/core/SkRasterPipeline.h6
-rw-r--r--src/core/SkRasterPipelineBlitter.cpp91
-rw-r--r--src/opts/SkOpts_sse41.cpp1
-rw-r--r--src/opts/SkRasterPipeline_opts.h5
-rw-r--r--tests/SkRasterPipelineTest.cpp13
10 files changed, 61 insertions, 112 deletions
diff --git a/bench/SkRasterPipelineBench.cpp b/bench/SkRasterPipelineBench.cpp
index 7447f4d059..d911c5d7ad 100644
--- a/bench/SkRasterPipelineBench.cpp
+++ b/bench/SkRasterPipelineBench.cpp
@@ -22,16 +22,14 @@ static uint8_t mask[N]; // 8-bit linear
// - src = srcover(dst, src)
// - store src back as srgb/f16
-template <bool kF16, bool kCompiled>
+template <bool kF16>
class SkRasterPipelineBench : public Benchmark {
public:
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
const char* onGetName() override {
- switch ((int)kCompiled << 1 | (int)kF16) {
- case 0: return "SkRasterPipeline_srgb_run";
- case 1: return "SkRasterPipeline_f16_run";
- case 2: return "SkRasterPipeline_srgb_compile";
- case 3: return "SkRasterPipeline_f16_compile";
+ switch ((int)kF16) {
+ case 0: return "SkRasterPipeline_srgb";
+ case 1: return "SkRasterPipeline_f16";
}
return "whoops";
}
@@ -60,30 +58,19 @@ public:
p.append(SkRasterPipeline::store_8888, &dst_ctx);
}
- if (kCompiled) {
- auto compiled = p.compile();
- while (loops --> 0) {
- compiled(0,N);
- }
- } else {
- while (loops --> 0) {
- p.run(0,N);
- }
+ while (loops --> 0) {
+ p.run(0,N);
}
}
};
-DEF_BENCH( return (new SkRasterPipelineBench< true, true>); )
-DEF_BENCH( return (new SkRasterPipelineBench<false, true>); )
-DEF_BENCH( return (new SkRasterPipelineBench< true, false>); )
-DEF_BENCH( return (new SkRasterPipelineBench<false, false>); )
+DEF_BENCH( return (new SkRasterPipelineBench< true>); )
+DEF_BENCH( return (new SkRasterPipelineBench<false>); )
-template <bool kCompiled>
class SkRasterPipelineLegacyBench : public Benchmark {
public:
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
const char* onGetName() override {
- return kCompiled ? "SkRasterPipeline_legacy_compile"
- : "SkRasterPipeline_legacy_run";
+ return "SkRasterPipeline_legacy";
}
void onDraw(int loops, SkCanvas*) override {
@@ -97,17 +84,9 @@ public:
p.append(SkRasterPipeline::srcover);
p.append(SkRasterPipeline::store_8888, &dst_ctx);
- if (kCompiled) {
- auto compiled = p.compile();
- while (loops --> 0) {
- compiled(0,N);
- }
- } else {
- while (loops --> 0) {
- p.run(0,N);
- }
+ while (loops --> 0) {
+ p.run(0,N);
}
}
};
-DEF_BENCH( return (new SkRasterPipelineLegacyBench< true>); )
-DEF_BENCH( return (new SkRasterPipelineLegacyBench<false>); )
+DEF_BENCH( return (new SkRasterPipelineLegacyBench); )
diff --git a/src/core/SkConvertPixels.cpp b/src/core/SkConvertPixels.cpp
index 50d375b9d6..9c9c437b47 100644
--- a/src/core/SkConvertPixels.cpp
+++ b/src/core/SkConvertPixels.cpp
@@ -275,10 +275,8 @@ static void convert_with_pipeline(const SkImageInfo& dstInfo, void* dstRow, size
break;
}
- auto p = pipeline.compile();
-
for (int y = 0; y < srcInfo.height(); ++y) {
- p(0,srcInfo.width());
+ pipeline.run(0,srcInfo.width());
// The pipeline has pointers to srcRow and dstRow, so we just need to update them in the
// loop to move between rows of src/dst.
dstRow = SkTAddOffset<void>(dstRow, dstRB);
diff --git a/src/core/SkOpts.cpp b/src/core/SkOpts.cpp
index 67bc976f26..273c654754 100644
--- a/src/core/SkOpts.cpp
+++ b/src/core/SkOpts.cpp
@@ -85,7 +85,6 @@ namespace SkOpts {
DEFINE_DEFAULT(hash_fn);
DEFINE_DEFAULT(run_pipeline);
- DEFINE_DEFAULT(compile_pipeline);
DEFINE_DEFAULT(convolve_vertically);
DEFINE_DEFAULT(convolve_horizontally);
diff --git a/src/core/SkOpts.h b/src/core/SkOpts.h
index 7dd3a6331c..801b96da3a 100644
--- a/src/core/SkOpts.h
+++ b/src/core/SkOpts.h
@@ -12,7 +12,6 @@
#include "SkRasterPipeline.h"
#include "SkTypes.h"
#include "SkXfermodePriv.h"
-#include <functional>
struct ProcCoeff;
@@ -61,8 +60,6 @@ namespace SkOpts {
}
extern void (*run_pipeline)(size_t, size_t, const SkRasterPipeline::Stage*, int);
- extern std::function<void(size_t, size_t)>
- (*compile_pipeline)(const SkRasterPipeline::Stage*, int);
extern void (*convolve_vertically)(const SkConvolutionFilter1D::ConvolutionFixed* filter_values,
int filter_length, unsigned char* const* source_data_rows,
diff --git a/src/core/SkRasterPipeline.cpp b/src/core/SkRasterPipeline.cpp
index 81b98677b2..42f0212f1a 100644
--- a/src/core/SkRasterPipeline.cpp
+++ b/src/core/SkRasterPipeline.cpp
@@ -31,10 +31,6 @@ void SkRasterPipeline::run(size_t x, size_t n) const {
}
}
-std::function<void(size_t, size_t)> SkRasterPipeline::compile() const {
- return SkOpts::compile_pipeline(fStages.data(), SkToInt(fStages.size()));
-}
-
void SkRasterPipeline::dump() const {
SkDebugf("SkRasterPipeline, %d stages\n", SkToInt(fStages.size()));
for (auto&& st : fStages) {
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index 34b0744a48..6976906642 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -12,7 +12,6 @@
#include "SkNx.h"
#include "SkTArray.h"
#include "SkTypes.h"
-#include <functional>
#include <vector>
/**
@@ -120,9 +119,6 @@ public:
// Runs the pipeline walking x through [x,x+n).
void run(size_t x, size_t n) const;
- // If you're going to run() the pipeline more than once, it's best to compile it.
- std::function<void(size_t x, size_t n)> compile() const;
-
void dump() const;
struct Stage {
@@ -134,6 +130,8 @@ public:
// Use these helpers to keep things sane.
void append_from_srgb(SkAlphaType);
+ bool empty() const { return fStages.empty(); }
+
private:
bool run_with_jumper(size_t x, size_t n) const;
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index a994de3ed9..197233c3cd 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -50,14 +50,18 @@ private:
SkRasterPipeline fShader;
bool fBlendCorrectly;
- // These functions are compiled lazily when first used.
- std::function<void(size_t, size_t)> fBlitH = nullptr,
- fBlitAntiH = nullptr,
- fBlitMaskA8 = nullptr,
- fBlitMaskLCD16 = nullptr;
-
- // These values are pointed to by the compiled blit functions
- // above, which allows us to adjust them from call to call.
+ // 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.
+ SkRasterPipeline 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* fDstPtr = nullptr;
const void* fMaskPtr = nullptr;
float fCurrentCoverage = 0.0f;
@@ -152,31 +156,13 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
}
if (is_constant && *blend == SkBlendMode::kSrc) {
- uint64_t color; // Big enough for largest dst format, F16.
SkRasterPipeline p;
p.extend(*pipeline);
- blitter->fDstPtr = &color;
+ blitter->fDstPtr = &blitter->fMemsetColor;
blitter->append_store(&p);
p.run(0,1);
- switch (dst.shiftPerPixel()) {
- case 1:
- blitter->fBlitH = [blitter,color](size_t x, size_t n) {
- sk_memset16((uint16_t*)blitter->fDstPtr + x, color, n);
- };
- break;
- case 2:
- blitter->fBlitH = [blitter,color](size_t x, size_t n) {
- sk_memset32((uint32_t*)blitter->fDstPtr + x, color, n);
- };
- break;
- case 3:
- blitter->fBlitH = [blitter,color](size_t x, size_t n) {
- sk_memset64((uint64_t*)blitter->fDstPtr + x, color, n);
- };
- break;
- default: break;
- }
+ blitter->fCanMemsetInBlitH = true;
}
return blitter;
@@ -233,8 +219,27 @@ void SkRasterPipelineBlitter::maybe_clamp(SkRasterPipeline* p) const {
}
void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
- if (!fBlitH) {
- SkRasterPipeline p;
+ fDstPtr = fDst.writable_addr(0,y);
+ fCurrentY = y;
+
+ if (fCanMemsetInBlitH) {
+ switch (fDst.shiftPerPixel()) {
+ // TODO: case 0: memset (for A8)
+ 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;
+ default: break;
+ }
+ }
+
+ auto& p = fBlitH;
+ if (p.empty()) {
p.extend(fShader);
if (fBlend != SkBlendMode::kSrc) {
this->append_load_d(&p);
@@ -242,16 +247,13 @@ void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
this->maybe_clamp(&p);
}
this->append_store(&p);
- fBlitH = p.compile();
}
- fDstPtr = fDst.writable_addr(0,y);
- fCurrentY = y;
- fBlitH(x,w);
+ p.run(x,w);
}
void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) {
- if (!fBlitAntiH) {
- SkRasterPipeline p;
+ auto& p = fBlitAntiH;
+ if (p.empty()) {
p.extend(fShader);
if (fBlend == SkBlendMode::kSrcOver) {
p.append(SkRasterPipeline::scale_1_float, &fCurrentCoverage);
@@ -264,7 +266,6 @@ void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const
}
this->maybe_clamp(&p);
this->append_store(&p);
- fBlitAntiH = p.compile();
}
fDstPtr = fDst.writable_addr(0,y);
@@ -275,7 +276,7 @@ void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const
case 0xff: this->blitH(x,y,run); break;
default:
fCurrentCoverage = *aa * (1/255.0f);
- fBlitAntiH(x,run);
+ p.run(x,run);
}
x += run;
runs += run;
@@ -289,8 +290,8 @@ void SkRasterPipelineBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
return INHERITED::blitMask(mask, clip);
}
- if (mask.fFormat == SkMask::kA8_Format && !fBlitMaskA8) {
- SkRasterPipeline p;
+ if (mask.fFormat == SkMask::kA8_Format && fBlitMaskA8.empty()) {
+ auto& p = fBlitMaskA8;
p.extend(fShader);
if (fBlend == SkBlendMode::kSrcOver) {
p.append(SkRasterPipeline::scale_u8, &fMaskPtr);
@@ -303,18 +304,16 @@ void SkRasterPipelineBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
}
this->maybe_clamp(&p);
this->append_store(&p);
- fBlitMaskA8 = p.compile();
}
- if (mask.fFormat == SkMask::kLCD16_Format && !fBlitMaskLCD16) {
- SkRasterPipeline p;
+ if (mask.fFormat == SkMask::kLCD16_Format && fBlitMaskLCD16.empty()) {
+ auto& p = fBlitMaskLCD16;
p.extend(fShader);
this->append_load_d(&p);
this->append_blend(&p);
p.append(SkRasterPipeline::lerp_565, &fMaskPtr);
this->maybe_clamp(&p);
this->append_store(&p);
- fBlitMaskLCD16 = p.compile();
}
int x = clip.left();
@@ -325,11 +324,11 @@ void SkRasterPipelineBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
switch (mask.fFormat) {
case SkMask::kA8_Format:
fMaskPtr = mask.getAddr8(x,y)-x;
- fBlitMaskA8(x,clip.width());
+ fBlitMaskA8.run(x,clip.width());
break;
case SkMask::kLCD16_Format:
fMaskPtr = mask.getAddrLCD16(x,y)-x;
- fBlitMaskLCD16(x,clip.width());
+ fBlitMaskLCD16.run(x,clip.width());
break;
default:
// TODO
diff --git a/src/opts/SkOpts_sse41.cpp b/src/opts/SkOpts_sse41.cpp
index e29fcde722..7a90f7683e 100644
--- a/src/opts/SkOpts_sse41.cpp
+++ b/src/opts/SkOpts_sse41.cpp
@@ -21,6 +21,5 @@ namespace SkOpts {
srcover_srgb_srgb = sse41::srcover_srgb_srgb;
blit_row_s32a_opaque = sse41::blit_row_s32a_opaque;
run_pipeline = sse41::run_pipeline;
- compile_pipeline = sse41::compile_pipeline;
}
}
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index fb0271b822..0a7441b304 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -1221,11 +1221,6 @@ namespace {
namespace SK_OPTS_NS {
- SI std::function<void(size_t, size_t)>
- compile_pipeline(const SkRasterPipeline::Stage* stages, int nstages) {
- return Compiled{stages,nstages};
- }
-
SI void run_pipeline(size_t x, size_t n,
const SkRasterPipeline::Stage* stages, int nstages) {
static const int kStackMax = 256;
diff --git a/tests/SkRasterPipelineTest.cpp b/tests/SkRasterPipelineTest.cpp
index 4e992cb6e0..f7c14569ef 100644
--- a/tests/SkRasterPipelineTest.cpp
+++ b/tests/SkRasterPipelineTest.cpp
@@ -34,16 +34,6 @@ DEF_TEST(SkRasterPipeline, r) {
REPORTER_ASSERT(r, ((result >> 16) & 0xffff) == 0x0000);
REPORTER_ASSERT(r, ((result >> 32) & 0xffff) == 0x3800);
REPORTER_ASSERT(r, ((result >> 48) & 0xffff) == 0x3c00);
-
- // Run again, this time compiling the pipeline.
- result = 0;
-
- auto fn = p.compile();
- fn(0,1);
- REPORTER_ASSERT(r, ((result >> 0) & 0xffff) == 0x3800);
- REPORTER_ASSERT(r, ((result >> 16) & 0xffff) == 0x0000);
- REPORTER_ASSERT(r, ((result >> 32) & 0xffff) == 0x3800);
- REPORTER_ASSERT(r, ((result >> 48) & 0xffff) == 0x3c00);
}
DEF_TEST(SkRasterPipeline_empty, r) {
@@ -79,8 +69,7 @@ DEF_TEST(SkRasterPipeline_JIT, r) {
SkRasterPipeline p;
p.append(SkRasterPipeline:: load_8888, &src);
p.append(SkRasterPipeline::store_8888, &dst);
- auto fn = p.compile();
- fn(15, 20);
+ p.run(15, 20);
for (int i = 0; i < 36; i++) {
if (i < 15 || i == 35) {