1281b33fdd909ee3f43192cdf950ce00e3df62407mtklein/*
2281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * Copyright 2016 Google Inc.
3281b33fdd909ee3f43192cdf950ce00e3df62407mtklein *
4281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * Use of this source code is governed by a BSD-style license that can be
5281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * found in the LICENSE file.
6281b33fdd909ee3f43192cdf950ce00e3df62407mtklein */
7281b33fdd909ee3f43192cdf950ce00e3df62407mtklein
8281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#include "Benchmark.h"
9baaf8ad95237d1defdb7d93077d9bf8410d8ad7fMike Klein#include "SkOpts.h"
10281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#include "SkRasterPipeline.h"
1145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein#include "../src/jumper/SkJumper.h"
12281b33fdd909ee3f43192cdf950ce00e3df62407mtklein
13cb79393e88ecfe2cc21d0f6c3bbea0436b0bacb7Mike Kleinstatic const int N = 15;
14281b33fdd909ee3f43192cdf950ce00e3df62407mtklein
15afb48b62272e280d766f8e97c9cdd3417961a546Mike Kleinstatic uint64_t dst[N];  // sRGB or F16
16afb48b62272e280d766f8e97c9cdd3417961a546Mike Kleinstatic uint32_t src[N];  // sRGB
17afb48b62272e280d766f8e97c9cdd3417961a546Mike Kleinstatic uint8_t mask[N];  // 8-bit linear
18281b33fdd909ee3f43192cdf950ce00e3df62407mtklein
19281b33fdd909ee3f43192cdf950ce00e3df62407mtklein// We'll build up a somewhat realistic useful pipeline:
20281b33fdd909ee3f43192cdf950ce00e3df62407mtklein//   - load srgb src
21281b33fdd909ee3f43192cdf950ce00e3df62407mtklein//   - scale src by 8-bit mask
22afb48b62272e280d766f8e97c9cdd3417961a546Mike Klein//   - load srgb/f16 dst
23281b33fdd909ee3f43192cdf950ce00e3df62407mtklein//   - src = srcover(dst, src)
24afb48b62272e280d766f8e97c9cdd3417961a546Mike Klein//   - store src back as srgb/f16
25281b33fdd909ee3f43192cdf950ce00e3df62407mtklein
268729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike Kleintemplate <bool kF16>
27281b33fdd909ee3f43192cdf950ce00e3df62407mtkleinclass SkRasterPipelineBench : public Benchmark {
28281b33fdd909ee3f43192cdf950ce00e3df62407mtkleinpublic:
29281b33fdd909ee3f43192cdf950ce00e3df62407mtklein    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
30afb48b62272e280d766f8e97c9cdd3417961a546Mike Klein    const char* onGetName() override {
318729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike Klein        switch ((int)kF16) {
328729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike Klein            case 0: return "SkRasterPipeline_srgb";
338729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike Klein            case 1: return "SkRasterPipeline_f16";
34a2d25ec0ef1b1054aa5b3e61280bd226fce4ab9aMike Klein        }
35a2d25ec0ef1b1054aa5b3e61280bd226fce4ab9aMike Klein        return "whoops";
36afb48b62272e280d766f8e97c9cdd3417961a546Mike Klein    }
37281b33fdd909ee3f43192cdf950ce00e3df62407mtklein
38281b33fdd909ee3f43192cdf950ce00e3df62407mtklein    void onDraw(int loops, SkCanvas*) override {
3945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein        SkJumper_MemoryCtx mask_ctx = {mask, 0},
4045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                            src_ctx = {src,  0},
4145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                            dst_ctx = {dst,  0};
42bd3fe475b846da1ae75f22da67a34ae57d0627bbMike Klein
43b24704d35f67f5b460be9c92794892e06adceb46Mike Klein        SkRasterPipeline_<256> p;
44729b58296282da00fb9c0f92db2e2e8a8347d431Mike Klein        p.append(SkRasterPipeline::load_8888, &src_ctx);
45f1f1162273b382db99f8609e5bbfff24f5594821Mike Klein        p.append(SkRasterPipeline::from_srgb);
46bd3fe475b846da1ae75f22da67a34ae57d0627bbMike Klein        p.append(SkRasterPipeline::scale_u8, &mask_ctx);
478c8cb5bfc547229422a33db5c344fe1542bf00a7Mike Klein        p.append(SkRasterPipeline::move_src_dst);
48e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein        if (kF16) {
498c8cb5bfc547229422a33db5c344fe1542bf00a7Mike Klein            p.append(SkRasterPipeline::load_f16, &dst_ctx);
50e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein        } else {
518c8cb5bfc547229422a33db5c344fe1542bf00a7Mike Klein            p.append(SkRasterPipeline::load_8888, &dst_ctx);
52f1f1162273b382db99f8609e5bbfff24f5594821Mike Klein            p.append(SkRasterPipeline::from_srgb);
53e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein        }
548c8cb5bfc547229422a33db5c344fe1542bf00a7Mike Klein        p.append(SkRasterPipeline::dstover);
55e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein        if (kF16) {
56e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein            p.append(SkRasterPipeline::store_f16, &dst_ctx);
57e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein        } else {
58e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein            p.append(SkRasterPipeline::to_srgb);
59e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein            p.append(SkRasterPipeline::store_8888, &dst_ctx);
60e03339a35435b6c4b9ddb5b9d1d3592be5185de2Mike Klein        }
61e9f74b89c09772dd5abae1c0709c711d7cdb6535Mike Klein
628729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike Klein        while (loops --> 0) {
6345c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein            p.run(0,0,N,1);
64281b33fdd909ee3f43192cdf950ce00e3df62407mtklein        }
65281b33fdd909ee3f43192cdf950ce00e3df62407mtklein    }
66281b33fdd909ee3f43192cdf950ce00e3df62407mtklein};
678729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike KleinDEF_BENCH( return (new SkRasterPipelineBench< true>); )
688729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike KleinDEF_BENCH( return (new SkRasterPipelineBench<false>); )
69f76885694d4345363cb541170d18040a5c3f01ccMike Klein
700a76b413eac46ec218b367c5456709059557f5dbMike Kleinclass SkRasterPipelineCompileVsRunBench : public Benchmark {
71f76885694d4345363cb541170d18040a5c3f01ccMike Kleinpublic:
720a76b413eac46ec218b367c5456709059557f5dbMike Klein    explicit SkRasterPipelineCompileVsRunBench(bool compile) : fCompile(compile) {}
73f76885694d4345363cb541170d18040a5c3f01ccMike Klein    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
74f76885694d4345363cb541170d18040a5c3f01ccMike Klein    const char* onGetName() override {
750a76b413eac46ec218b367c5456709059557f5dbMike Klein        return fCompile ? "SkRasterPipeline_compile"
760a76b413eac46ec218b367c5456709059557f5dbMike Klein                        : "SkRasterPipeline_run";
77f76885694d4345363cb541170d18040a5c3f01ccMike Klein    }
78f76885694d4345363cb541170d18040a5c3f01ccMike Klein
79f76885694d4345363cb541170d18040a5c3f01ccMike Klein    void onDraw(int loops, SkCanvas*) override {
8045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein        SkJumper_MemoryCtx src_ctx = {src, 0},
8145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                           dst_ctx = {dst, 0};
82f76885694d4345363cb541170d18040a5c3f01ccMike Klein
83b24704d35f67f5b460be9c92794892e06adceb46Mike Klein        SkRasterPipeline_<256> p;
84f76885694d4345363cb541170d18040a5c3f01ccMike Klein        p.append(SkRasterPipeline::load_8888, &dst_ctx);
85f76885694d4345363cb541170d18040a5c3f01ccMike Klein        p.append(SkRasterPipeline::move_src_dst);
86f76885694d4345363cb541170d18040a5c3f01ccMike Klein        p.append(SkRasterPipeline::load_8888, &src_ctx);
87f76885694d4345363cb541170d18040a5c3f01ccMike Klein        p.append(SkRasterPipeline::srcover);
88f76885694d4345363cb541170d18040a5c3f01ccMike Klein        p.append(SkRasterPipeline::store_8888, &dst_ctx);
89f76885694d4345363cb541170d18040a5c3f01ccMike Klein
900a76b413eac46ec218b367c5456709059557f5dbMike Klein        if (fCompile) {
91b24704d35f67f5b460be9c92794892e06adceb46Mike Klein            auto fn = p.compile();
920a76b413eac46ec218b367c5456709059557f5dbMike Klein            while (loops --> 0) {
9345c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                fn(0,0,N,1);
940a76b413eac46ec218b367c5456709059557f5dbMike Klein            }
950a76b413eac46ec218b367c5456709059557f5dbMike Klein        } else {
960a76b413eac46ec218b367c5456709059557f5dbMike Klein            while (loops --> 0) {
9745c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                p.run(0,0,N,1);
980a76b413eac46ec218b367c5456709059557f5dbMike Klein            }
99f76885694d4345363cb541170d18040a5c3f01ccMike Klein        }
100f76885694d4345363cb541170d18040a5c3f01ccMike Klein    }
1010a76b413eac46ec218b367c5456709059557f5dbMike Kleinprivate:
1020a76b413eac46ec218b367c5456709059557f5dbMike Klein    bool fCompile;
103f76885694d4345363cb541170d18040a5c3f01ccMike Klein};
1040a76b413eac46ec218b367c5456709059557f5dbMike KleinDEF_BENCH( return (new SkRasterPipelineCompileVsRunBench(true )); )
1050a76b413eac46ec218b367c5456709059557f5dbMike KleinDEF_BENCH( return (new SkRasterPipelineCompileVsRunBench(false)); )
106795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein
107c7be00366bb0171e2d247ea71e291a64e3d10254Mike Kleinstatic SkColorSpaceTransferFn gamma(float g) {
108c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein    SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0};
109c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein    fn.fG = g;
110c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein    fn.fA = 1;
111c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein    return fn;
112c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein}
113c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein
114795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Kleinclass SkRasterPipeline_2dot2 : public Benchmark {
115795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Kleinpublic:
116a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein    SkRasterPipeline_2dot2(bool parametric) : fParametric(parametric) {}
117a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein
118795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
119795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein    const char* onGetName() override {
120a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein        return fParametric ? "SkRasterPipeline_2dot2_parametric"
121a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein                           : "SkRasterPipeline_2dot2_gamma";
122795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein    }
123795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein
124795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein    void onDraw(int loops, SkCanvas*) override {
125795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein        SkColor4f c = { 1.0f, 1.0f, 1.0f, 1.0f };
126c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein
127c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein        SkColorSpaceTransferFn from_2dot2 = gamma(  2.2f),
128c7be00366bb0171e2d247ea71e291a64e3d10254Mike Klein                                 to_2dot2 = gamma(1/2.2f);
12916776dfb4b307c70d08e316f2ecf2a53953f2e0dMike Klein        SkSTArenaAlloc<256> alloc;
13016776dfb4b307c70d08e316f2ecf2a53953f2e0dMike Klein        SkRasterPipeline p(&alloc);
13116776dfb4b307c70d08e316f2ecf2a53953f2e0dMike Klein        p.append_constant_color(&alloc, c);
132a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein        if (fParametric) {
133a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::parametric_r, &from_2dot2);
134a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::parametric_g, &from_2dot2);
135a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::parametric_b, &from_2dot2);
136a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::parametric_r, &  to_2dot2);
137a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::parametric_g, &  to_2dot2);
138a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::parametric_b, &  to_2dot2);
139a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein        } else {
140a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::gamma, &from_2dot2.fG);
141a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein            p.append(SkRasterPipeline::gamma, &  to_2dot2.fG);
142a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein        }
143795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein
144795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein        while (loops --> 0) {
14545c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein            p.run(0,0,N,1);
146795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein        }
147795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein    }
148a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Kleinprivate:
149a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein    bool fParametric;
150795c5b156756796cbb3a584c99b1ab51fb5fe187Mike Klein};
151a07e4302cfefc282d8d235edfbc20a54c75afa88Mike KleinDEF_BENCH( return (new SkRasterPipeline_2dot2( true)); )
152a07e4302cfefc282d8d235edfbc20a54c75afa88Mike KleinDEF_BENCH( return (new SkRasterPipeline_2dot2(false)); )
153f45e3d78a4660b4450a218926d70da4941359efeMike Klein
154f45e3d78a4660b4450a218926d70da4941359efeMike Kleinclass SkRasterPipelineToSRGB : public Benchmark {
155f45e3d78a4660b4450a218926d70da4941359efeMike Kleinpublic:
156f45e3d78a4660b4450a218926d70da4941359efeMike Klein    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
157f45e3d78a4660b4450a218926d70da4941359efeMike Klein    const char* onGetName() override {
158f45e3d78a4660b4450a218926d70da4941359efeMike Klein        return "SkRasterPipeline_to_srgb";
159f45e3d78a4660b4450a218926d70da4941359efeMike Klein    }
160f45e3d78a4660b4450a218926d70da4941359efeMike Klein
161f45e3d78a4660b4450a218926d70da4941359efeMike Klein    void onDraw(int loops, SkCanvas*) override {
162b24704d35f67f5b460be9c92794892e06adceb46Mike Klein        SkRasterPipeline_<256> p;
163f45e3d78a4660b4450a218926d70da4941359efeMike Klein        p.append(SkRasterPipeline::to_srgb);
164f45e3d78a4660b4450a218926d70da4941359efeMike Klein
165f45e3d78a4660b4450a218926d70da4941359efeMike Klein        while (loops --> 0) {
16645c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein            p.run(0,0,N,1);
167f45e3d78a4660b4450a218926d70da4941359efeMike Klein        }
168f45e3d78a4660b4450a218926d70da4941359efeMike Klein    }
169f45e3d78a4660b4450a218926d70da4941359efeMike Klein};
170f45e3d78a4660b4450a218926d70da4941359efeMike KleinDEF_BENCH( return (new SkRasterPipelineToSRGB); )
171