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 
12 static const int N = 15;
13 
14 static uint64_t dst[N];  // sRGB or F16
15 static uint32_t src[N];  // sRGB
16 static 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 
25 template <bool kF16>
26 class SkRasterPipelineBench : public Benchmark {
27 public:
isSuitableFor(Backend backend)28     bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
onGetName()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 
onDraw(int loops,SkCanvas *)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 };
66 DEF_BENCH( return (new SkRasterPipelineBench< true>); )
67 DEF_BENCH( return (new SkRasterPipelineBench<false>); )
68 
69 class SkRasterPipelineLegacyBench : public Benchmark {
70 public:
isSuitableFor(Backend backend)71     bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
onGetName()72     const char* onGetName() override {
73         return "SkRasterPipeline_legacy";
74     }
75 
onDraw(int loops,SkCanvas *)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 };
92 DEF_BENCH( return (new SkRasterPipelineLegacyBench); )
93