aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2016-09-27 12:08:10 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-09-27 17:46:54 +0000
commit1f4a874addd7c039fb8b434181040cd6a8a35339 (patch)
tree26f3970305a83bb3305e566e12444f973cf5eef5
parent3ba96c8cecd86e34b09471f3114aab2434ff702e (diff)
SkRasterPipeline: add last() and docs.
Today if you use the simple SK_RASTER_STAGE interface to build a pipeline, each stage you add calls into a next stage. The last stage you add calls into a special backstop stage JustReturn that, well, just returns, ending the pipeline. This adds last(), which cuts that last stage off the pipeline. Instead, the stage you add using last() returns directly, ending the pipeline itself without jumping into JustReturn. This reduces the overhead of using the pipelined version of SkRasterPipelineBench from ~25% to ~20% on my desktop. Also, add docs. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2713 Change-Id: I11469378e2765c6e34db52eb3eef648d6612da3f Reviewed-on: https://skia-review.googlesource.com/2713 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
-rw-r--r--bench/SkRasterPipelineBench.cpp2
-rw-r--r--src/core/SkRasterPipeline.h24
-rw-r--r--src/core/SkRasterPipelineBlitter.cpp6
3 files changed, 27 insertions, 5 deletions
diff --git a/bench/SkRasterPipelineBench.cpp b/bench/SkRasterPipelineBench.cpp
index a5263d770f..5ef64ce603 100644
--- a/bench/SkRasterPipelineBench.cpp
+++ b/bench/SkRasterPipelineBench.cpp
@@ -174,7 +174,7 @@ public:
p.append< scale_u8, scale_u8_tail>(mask);
p.append<load_d_srgb, load_d_srgb_tail>( dst);
p.append<srcover>();
- p.append< store_srgb, store_srgb_tail>( dst);
+ p.last< store_srgb, store_srgb_tail>( dst);
p.run(N);
}
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index 475f517b18..03fab998e7 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -46,7 +46,13 @@
* Some obvious stages that typically return are those that write a color to a destination pointer,
* but any stage can short-circuit the rest of the pipeline by returning instead of calling next().
*
- * TODO: explain EasyFn and SK_RASTER_STAGE
+ * Most simple pipeline stages can use the SK_RASTER_STAGE macro to define a static EasyFn,
+ * which simplifies the user interface a bit:
+ * - the context pointer is available directly as the first parameter;
+ * - instead of manually calling a next() function, just modify registers in place.
+ *
+ * To add an EasyFn stage to the pipeline, call append<fn>() instead of append(&fn).
+ * For the last stage of a pipeline, it's a slight performance benefit to call last<fn>().
*/
class SkRasterPipeline {
@@ -106,12 +112,21 @@ public:
this->append(Easy<body>, body_ctx,
Easy<tail>, tail_ctx);
}
+ template <EasyFn body, EasyFn tail>
+ void last(const void* body_ctx, const void* tail_ctx) {
+ this->append(Last<body>, body_ctx,
+ Last<tail>, tail_ctx);
+ }
template <EasyFn fn>
void append(const void* ctx = nullptr) { this->append<fn, fn>(ctx, ctx); }
+ template <EasyFn fn>
+ void last(const void* ctx = nullptr) { this->last<fn, fn>(ctx, ctx); }
template <EasyFn body, EasyFn tail>
void append(const void* ctx = nullptr) { this->append<body, tail>(ctx, ctx); }
+ template <EasyFn body, EasyFn tail>
+ void last(const void* ctx = nullptr) { this->last<body, tail>(ctx, ctx); }
// Append all stages to this pipeline.
@@ -134,6 +149,13 @@ private:
st->next(x, r,g,b,a, dr,dg,db,da);
}
+ template <EasyFn kernel>
+ static void SK_VECTORCALL Last(SkRasterPipeline::Stage* st, size_t x,
+ Sk4f r, Sk4f g, Sk4f b, Sk4f a,
+ Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) {
+ kernel(st->ctx<void*>(), x, r,g,b,a, dr,dg,db,da);
+ }
+
Stages fBody,
fTail;
Fn fBodyStart = &JustReturn,
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index 618e646da4..e407d013f5 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -361,14 +361,14 @@ void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const
switch (fDst.info().colorType()) {
case kN32_SkColorType:
if (fDst.info().gammaCloseToSRGB()) {
- p->append<store_srgb, store_srgb_1>(dst);
+ p->last<store_srgb, store_srgb_1>(dst);
}
break;
case kRGBA_F16_SkColorType:
- p->append<store_f16, store_f16_1>(dst);
+ p->last<store_f16, store_f16_1>(dst);
break;
case kRGB_565_SkColorType:
- p->append<store_565, store_565_1>(dst);
+ p->last<store_565, store_565_1>(dst);
break;
default: break;
}