SkRasterPipelineBench.cpp revision 1859f69d20e433b86714e5b9002121f2b20a5fc6
1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Benchmark.h"
9#include "SkOpts.h"
10#include "SkRasterPipeline.h"
11
12static const int N = 15;
13
14static uint64_t dst[N];  // sRGB or F16
15static uint32_t src[N];  // sRGB
16static uint8_t mask[N];  // 8-bit linear
17
18// We'll build up a somewhat realistic useful pipeline:
19//   - load srgb src
20//   - scale src by 8-bit mask
21//   - load srgb/f16 dst
22//   - src = srcover(dst, src)
23//   - store src back as srgb/f16
24
25template <bool kF16>
26class SkRasterPipelineBench : public Benchmark {
27public:
28    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
29    const char* onGetName() override {
30        switch ((int)kF16) {
31            case 0: return "SkRasterPipeline_srgb";
32            case 1: return "SkRasterPipeline_f16";
33        }
34        return "whoops";
35    }
36
37    void onDraw(int loops, SkCanvas*) override {
38        void* mask_ctx = mask;
39        void*  src_ctx = src;
40        void*  dst_ctx = dst;
41
42        SkRasterPipeline p;
43        p.append(SkRasterPipeline::load_8888, &src_ctx);
44        p.append_from_srgb(kUnpremul_SkAlphaType);
45        p.append(SkRasterPipeline::scale_u8, &mask_ctx);
46        p.append(SkRasterPipeline::move_src_dst);
47        if (kF16) {
48            p.append(SkRasterPipeline::load_f16, &dst_ctx);
49        } else {
50            p.append(SkRasterPipeline::load_8888, &dst_ctx);
51            p.append_from_srgb(kPremul_SkAlphaType);
52        }
53        p.append(SkRasterPipeline::dstover);
54        if (kF16) {
55            p.append(SkRasterPipeline::store_f16, &dst_ctx);
56        } else {
57            p.append(SkRasterPipeline::to_srgb);
58            p.append(SkRasterPipeline::store_8888, &dst_ctx);
59        }
60
61        while (loops --> 0) {
62            p.run(0,N);
63        }
64    }
65};
66DEF_BENCH( return (new SkRasterPipelineBench< true>); )
67DEF_BENCH( return (new SkRasterPipelineBench<false>); )
68
69class SkRasterPipelineLegacyBench : public Benchmark {
70public:
71    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
72    const char* onGetName() override {
73        return "SkRasterPipeline_legacy";
74    }
75
76    void onDraw(int loops, SkCanvas*) override {
77        void*  src_ctx = src;
78        void*  dst_ctx = dst;
79
80        SkRasterPipeline p;
81        p.append(SkRasterPipeline::load_8888, &dst_ctx);
82        p.append(SkRasterPipeline::move_src_dst);
83        p.append(SkRasterPipeline::load_8888, &src_ctx);
84        p.append(SkRasterPipeline::srcover);
85        p.append(SkRasterPipeline::store_8888, &dst_ctx);
86
87        while (loops --> 0) {
88            p.run(0,N);
89        }
90    }
91};
92DEF_BENCH( return (new SkRasterPipelineLegacyBench); )
93
94static SkColorSpaceTransferFn gamma(float g) {
95    SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0};
96    fn.fG = g;
97    fn.fA = 1;
98    return fn;
99}
100
101class SkRasterPipeline_2dot2 : public Benchmark {
102public:
103    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
104    const char* onGetName() override {
105        return "SkRasterPipeline_2dot2";
106    }
107
108    void onDraw(int loops, SkCanvas*) override {
109        SkColor4f c = { 1.0f, 1.0f, 1.0f, 1.0f };
110
111        SkColorSpaceTransferFn from_2dot2 = gamma(  2.2f),
112                                 to_2dot2 = gamma(1/2.2f);
113        SkRasterPipeline p;
114        p.append(SkRasterPipeline::constant_color, &c);
115        p.append(SkRasterPipeline::parametric_r, &from_2dot2);
116        p.append(SkRasterPipeline::parametric_g, &from_2dot2);
117        p.append(SkRasterPipeline::parametric_b, &from_2dot2);
118        p.append(SkRasterPipeline::parametric_r, &  to_2dot2);
119        p.append(SkRasterPipeline::parametric_g, &  to_2dot2);
120        p.append(SkRasterPipeline::parametric_b, &  to_2dot2);
121
122        while (loops --> 0) {
123            p.run(0,N);
124        }
125    }
126};
127DEF_BENCH( return (new SkRasterPipeline_2dot2); )
128
129class SkRasterPipelineToSRGB : public Benchmark {
130public:
131    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
132    const char* onGetName() override {
133        return "SkRasterPipeline_to_srgb";
134    }
135
136    void onDraw(int loops, SkCanvas*) override {
137        SkRasterPipeline p;
138        p.append(SkRasterPipeline::to_srgb);
139
140        while (loops --> 0) {
141            p.run(0,N);
142        }
143    }
144};
145DEF_BENCH( return (new SkRasterPipelineToSRGB); )
146
147class SkRasterPipelineReuseBench : public Benchmark {
148public:
149    enum Mode { None, Some, Full };
150
151    explicit SkRasterPipelineReuseBench(Mode mode) : fMode(mode), fName("SkRasterPipelineReuse") {
152        switch(mode) {
153            case None: fName.append("_none"); break;
154            case Some: fName.append("_some"); break;
155            case Full: fName.append("_full"); break;
156        }
157    }
158    const char* onGetName() override { return fName.c_str(); }
159    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
160
161    void onDraw(int loops, SkCanvas*) override {
162        const int kStages = 20;
163        const auto stage  = SkRasterPipeline::to_srgb;  // Any stage will do.  We won't call it.
164
165        switch(fMode) {
166            case None:
167                while (loops --> 0) {
168                    SkRasterPipeline p;
169                    for (int i = 0; i < kStages; i++) {
170                        p.append(stage);
171                    }
172                }
173                break;
174
175            case Some:
176                while (loops --> 0) {
177                    SkRasterPipeline p(kStages);
178                    for (int i = 0; i < kStages; i++) {
179                        p.append(stage);
180                    }
181                }
182                break;
183
184            case Full:
185                SkRasterPipeline p(kStages);
186                while (loops --> 0) {
187                    p.rewind();
188                    for (int i = 0; i < kStages; i++) {
189                        p.append(stage);
190                    }
191                }
192                break;
193        }
194    }
195
196private:
197    Mode     fMode;
198    SkString fName;
199};
200DEF_BENCH( return (new SkRasterPipelineReuseBench(SkRasterPipelineReuseBench::None)); )
201DEF_BENCH( return (new SkRasterPipelineReuseBench(SkRasterPipelineReuseBench::Some)); )
202DEF_BENCH( return (new SkRasterPipelineReuseBench(SkRasterPipelineReuseBench::Full)); )
203