some basic speed ups for SkRasterPipeline::append()
authorMike Klein <mtklein@chromium.org>
Mon, 22 May 2017 12:28:45 +0000 (08:28 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 22 May 2017 14:08:06 +0000 (14:08 +0000)
The new bench demos the speedup:
    SkRasterPipelineReuse_…
    …full 1x  …some 1.8x  …none 5.22x

Change-Id: I5e51fb4316ae04558710ce62560850584ccb4aea
Reviewed-on: https://skia-review.googlesource.com/17449
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>

bench/SkRasterPipelineBench.cpp
src/core/SkRasterPipeline.cpp
src/core/SkRasterPipeline.h

index 527482a..2848218 100644 (file)
@@ -143,3 +143,60 @@ public:
     }
 };
 DEF_BENCH( return (new SkRasterPipelineToSRGB); )
+
+class SkRasterPipelineReuseBench : public Benchmark {
+public:
+    enum Mode { None, Some, Full };
+
+    explicit SkRasterPipelineReuseBench(Mode mode) : fMode(mode), fName("SkRasterPipelineReuse") {
+        switch(mode) {
+            case None: fName.append("_none"); break;
+            case Some: fName.append("_some"); break;
+            case Full: fName.append("_full"); break;
+        }
+    }
+    const char* onGetName() override { return fName.c_str(); }
+    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
+
+    void onDraw(int loops, SkCanvas*) override {
+        const int kStages = 20;
+        const auto stage  = SkRasterPipeline::to_srgb;  // Any stage will do.  We won't call it.
+
+        switch(fMode) {
+            case None:
+                while (loops --> 0) {
+                    SkRasterPipeline p;
+                    for (int i = 0; i < kStages; i++) {
+                        p.append(stage);
+                    }
+                }
+                break;
+
+            case Some:
+                while (loops --> 0) {
+                    SkRasterPipeline p(kStages);
+                    for (int i = 0; i < kStages; i++) {
+                        p.append(stage);
+                    }
+                }
+                break;
+
+            case Full:
+                SkRasterPipeline p(kStages);
+                while (loops --> 0) {
+                    p.rewind();
+                    for (int i = 0; i < kStages; i++) {
+                        p.append(stage);
+                    }
+                }
+                break;
+        }
+    }
+
+private:
+    Mode     fMode;
+    SkString fName;
+};
+DEF_BENCH( return (new SkRasterPipelineReuseBench(SkRasterPipelineReuseBench::None)); )
+DEF_BENCH( return (new SkRasterPipelineReuseBench(SkRasterPipelineReuseBench::Some)); )
+DEF_BENCH( return (new SkRasterPipelineReuseBench(SkRasterPipelineReuseBench::Full)); )
index d307bdd..ab40444 100644 (file)
@@ -7,7 +7,13 @@
 
 #include "SkRasterPipeline.h"
 
-SkRasterPipeline::SkRasterPipeline() {}
+SkRasterPipeline::SkRasterPipeline(int size_hint) {
+    fStages.reserve(size_hint);
+}
+
+void SkRasterPipeline::rewind() {
+    fStages.clear();
+}
 
 void SkRasterPipeline::append(StockStage stage, void* ctx) {
     SkASSERT(stage != from_srgb);
index a5f47c2..3b2d617 100644 (file)
 
 class SkRasterPipeline {
 public:
-    SkRasterPipeline();
+    SkRasterPipeline(int size_hint=0);
 
     enum StockStage {
     #define M(stage) stage,
@@ -136,6 +136,9 @@ public:
 
     bool empty() const { return fStages.empty(); }
 
+    // Cheaply reset all state so that empty() returns true.
+    void rewind();
+
 private:
     std::vector<Stage> fStages;
 };