/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "Benchmark.h" #include "SkOpts.h" #include "SkRasterPipeline.h" static const int N = 15; static uint64_t dst[N]; // sRGB or F16 static uint32_t src[N]; // sRGB static uint8_t mask[N]; // 8-bit linear // We'll build up a somewhat realistic useful pipeline: // - load srgb src // - scale src by 8-bit mask // - load srgb/f16 dst // - src = srcover(dst, src) // - store src back as srgb/f16 template class SkRasterPipelineBench : public Benchmark { public: bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } const char* onGetName() override { switch ((int)kF16) { case 0: return "SkRasterPipeline_srgb"; case 1: return "SkRasterPipeline_f16"; } return "whoops"; } void onDraw(int loops, SkCanvas*) override { void* mask_ctx = mask; void* src_ctx = src; void* dst_ctx = dst; SkRasterPipeline_<256> p; p.append(SkRasterPipeline::load_8888, &src_ctx); p.append_from_srgb(kUnpremul_SkAlphaType); p.append(SkRasterPipeline::scale_u8, &mask_ctx); p.append(SkRasterPipeline::move_src_dst); if (kF16) { p.append(SkRasterPipeline::load_f16, &dst_ctx); } else { p.append(SkRasterPipeline::load_8888, &dst_ctx); p.append_from_srgb(kPremul_SkAlphaType); } p.append(SkRasterPipeline::dstover); if (kF16) { p.append(SkRasterPipeline::store_f16, &dst_ctx); } else { p.append(SkRasterPipeline::to_srgb); p.append(SkRasterPipeline::store_8888, &dst_ctx); } while (loops --> 0) { p.run(0,N); } } }; DEF_BENCH( return (new SkRasterPipelineBench< true>); ) DEF_BENCH( return (new SkRasterPipelineBench); ) class SkRasterPipelineCompileVsRunBench : public Benchmark { public: explicit SkRasterPipelineCompileVsRunBench(bool compile) : fCompile(compile) {} bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } const char* onGetName() override { return fCompile ? "SkRasterPipeline_compile" : "SkRasterPipeline_run"; } void onDraw(int loops, SkCanvas*) override { void* src_ctx = src; void* dst_ctx = dst; SkRasterPipeline_<256> p; p.append(SkRasterPipeline::load_8888, &dst_ctx); p.append(SkRasterPipeline::move_src_dst); p.append(SkRasterPipeline::load_8888, &src_ctx); p.append(SkRasterPipeline::srcover); p.append(SkRasterPipeline::store_8888, &dst_ctx); if (fCompile) { auto fn = p.compile(); while (loops --> 0) { fn(0,N); } } else { while (loops --> 0) { p.run(0,N); } } } private: bool fCompile; }; DEF_BENCH( return (new SkRasterPipelineCompileVsRunBench(true )); ) DEF_BENCH( return (new SkRasterPipelineCompileVsRunBench(false)); ) static SkColorSpaceTransferFn gamma(float g) { SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0}; fn.fG = g; fn.fA = 1; return fn; } class SkRasterPipeline_2dot2 : public Benchmark { public: bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } const char* onGetName() override { return "SkRasterPipeline_2dot2"; } void onDraw(int loops, SkCanvas*) override { SkColor4f c = { 1.0f, 1.0f, 1.0f, 1.0f }; SkColorSpaceTransferFn from_2dot2 = gamma( 2.2f), to_2dot2 = gamma(1/2.2f); SkRasterPipeline_<256> p; p.append(SkRasterPipeline::constant_color, &c); p.append(SkRasterPipeline::parametric_r, &from_2dot2); p.append(SkRasterPipeline::parametric_g, &from_2dot2); p.append(SkRasterPipeline::parametric_b, &from_2dot2); p.append(SkRasterPipeline::parametric_r, & to_2dot2); p.append(SkRasterPipeline::parametric_g, & to_2dot2); p.append(SkRasterPipeline::parametric_b, & to_2dot2); while (loops --> 0) { p.run(0,N); } } }; DEF_BENCH( return (new SkRasterPipeline_2dot2); ) class SkRasterPipelineToSRGB : public Benchmark { public: bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } const char* onGetName() override { return "SkRasterPipeline_to_srgb"; } void onDraw(int loops, SkCanvas*) override { SkRasterPipeline_<256> p; p.append(SkRasterPipeline::to_srgb); while (loops --> 0) { p.run(0,N); } } }; DEF_BENCH( return (new SkRasterPipelineToSRGB); )