diff options
-rw-r--r-- | bench/SkRasterPipelineBench.cpp | 45 | ||||
-rw-r--r-- | src/core/SkConvertPixels.cpp | 4 | ||||
-rw-r--r-- | src/core/SkOpts.cpp | 1 | ||||
-rw-r--r-- | src/core/SkOpts.h | 3 | ||||
-rw-r--r-- | src/core/SkRasterPipeline.cpp | 4 | ||||
-rw-r--r-- | src/core/SkRasterPipeline.h | 6 | ||||
-rw-r--r-- | src/core/SkRasterPipelineBlitter.cpp | 91 | ||||
-rw-r--r-- | src/opts/SkOpts_sse41.cpp | 1 | ||||
-rw-r--r-- | src/opts/SkRasterPipeline_opts.h | 5 | ||||
-rw-r--r-- | tests/SkRasterPipelineTest.cpp | 13 |
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) { |