Simplify more: remove SkRasterPipeline::compile().
authorMike Klein <mtklein@chromium.org>
Thu, 16 Feb 2017 11:51:48 +0000 (06:51 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 16 Feb 2017 12:23:06 +0000 (12:23 +0000)
It's easier to work on SkJumper if everything funnels through run().

I don't anticipate huge benefit from compile() without JITing,
but it's something we can always put back if we find a need.

Change-Id: Id5256fd21495e8195cad1924dbad81856416d913
Reviewed-on: https://skia-review.googlesource.com/8468
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
bench/SkRasterPipelineBench.cpp
src/core/SkConvertPixels.cpp
src/core/SkOpts.cpp
src/core/SkOpts.h
src/core/SkRasterPipeline.cpp
src/core/SkRasterPipeline.h
src/core/SkRasterPipelineBlitter.cpp
src/opts/SkOpts_sse41.cpp
src/opts/SkRasterPipeline_opts.h
tests/SkRasterPipelineTest.cpp

index 7447f4d..d911c5d 100644 (file)
@@ -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); )
index 50d375b..9c9c437 100644 (file)
@@ -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);
index 67bc976..273c654 100644 (file)
@@ -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);
index 7dd3a63..801b96d 100644 (file)
@@ -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,
index 81b9867..42f0212 100644 (file)
@@ -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) {
index 34b0744..6976906 100644 (file)
@@ -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;
 
index a994de3..197233c 100644 (file)
@@ -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
index e29fcde..7a90f76 100644 (file)
@@ -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;
     }
 }
index fb0271b..0a7441b 100644 (file)
@@ -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;
index 4e992cb..f7c1456 100644 (file)
@@ -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) {