From 1859f69d20e433b86714e5b9002121f2b20a5fc6 Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Mon, 22 May 2017 08:28:45 -0400 Subject: [PATCH] some basic speed ups for SkRasterPipeline::append() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Commit-Queue: Mike Klein --- bench/SkRasterPipelineBench.cpp | 57 +++++++++++++++++++++++++++++++++ src/core/SkRasterPipeline.cpp | 8 ++++- src/core/SkRasterPipeline.h | 5 ++- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/bench/SkRasterPipelineBench.cpp b/bench/SkRasterPipelineBench.cpp index 527482a3c2..2848218977 100644 --- a/bench/SkRasterPipelineBench.cpp +++ b/bench/SkRasterPipelineBench.cpp @@ -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)); ) diff --git a/src/core/SkRasterPipeline.cpp b/src/core/SkRasterPipeline.cpp index d307bdd118..ab404446e0 100644 --- a/src/core/SkRasterPipeline.cpp +++ b/src/core/SkRasterPipeline.cpp @@ -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); diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h index a5f47c2203..3b2d617c69 100644 --- a/src/core/SkRasterPipeline.h +++ b/src/core/SkRasterPipeline.h @@ -107,7 +107,7 @@ 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 fStages; }; -- 2.34.1