blob: f3caea5673840aca6d57ab8410e3d95d2f2fb0cf [file] [log] [blame]
mtklein15391ee2015-03-25 13:43:34 -07001/*
2 * Copyright 2015 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
mtkleina2f4be72015-02-23 10:04:34 -08008#include "Benchmark.h"
9#include "SkPMFloat.h"
mtklein60ff4582015-03-03 08:03:27 -080010
11// Used to prevent the compiler from optimizing away the whole loop.
12volatile uint32_t blackhole = 0;
13
14// Not a great random number generator, but it's very fast.
15// The code we're measuring is quite fast, so low overhead is essential.
16static uint32_t lcg_rand(uint32_t* seed) {
17 *seed *= 1664525;
18 *seed += 1013904223;
19 return *seed;
20}
mtkleina2f4be72015-02-23 10:04:34 -080021
mtklein548bf382015-03-05 11:31:59 -080022// I'm having better luck getting these to constant-propagate away as template parameters.
23template <bool kClamp, bool kWide>
mtkleina2f4be72015-02-23 10:04:34 -080024struct PMFloatBench : public Benchmark {
mtklein548bf382015-03-05 11:31:59 -080025 PMFloatBench() {}
mtkleina2f4be72015-02-23 10:04:34 -080026
mtklein548bf382015-03-05 11:31:59 -080027 const char* onGetName() SK_OVERRIDE {
28 switch (kClamp << 1 | kWide) {
29 case 0: return "SkPMFloat_get_1x";
30 case 1: return "SkPMFloat_get_4x";
31 case 2: return "SkPMFloat_clamp_1x";
32 case 3: return "SkPMFloat_clamp_4x";
33 }
34 SkFAIL("unreachable");
35 return "oh bother";
36 }
mtkleina2f4be72015-02-23 10:04:34 -080037 bool isSuitableFor(Backend backend) SK_OVERRIDE { return backend == kNonRendering_Backend; }
38
39 void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
mtklein60ff4582015-03-03 08:03:27 -080040 // Unlike blackhole, junk can and probably will be a register.
41 uint32_t junk = 0;
42 uint32_t seed = 0;
mtkleina2f4be72015-02-23 10:04:34 -080043 for (int i = 0; i < loops; i++) {
mtklein548bf382015-03-05 11:31:59 -080044 SkPMColor colors[4];
mtklein60ff4582015-03-03 08:03:27 -080045 #ifdef SK_DEBUG
mtklein548bf382015-03-05 11:31:59 -080046 for (int i = 0; i < 4; i++) {
47 // Our SkASSERTs will remind us that it's technically required that we premultiply.
48 colors[i] = SkPreMultiplyColor(lcg_rand(&seed));
49 }
mtklein60ff4582015-03-03 08:03:27 -080050 #else
51 // But it's a lot faster not to, and this code won't really mind the non-PM colors.
mtklein548bf382015-03-05 11:31:59 -080052 (void)lcg_rand(&seed);
53 colors[0] = seed + 0;
54 colors[1] = seed + 1;
55 colors[2] = seed + 2;
56 colors[3] = seed + 3;
mtklein60ff4582015-03-03 08:03:27 -080057 #endif
mtklein548bf382015-03-05 11:31:59 -080058
mtklein15391ee2015-03-25 13:43:34 -070059 SkPMFloat fa,fb,fc,fd;
mtklein548bf382015-03-05 11:31:59 -080060 if (kWide) {
mtklein15391ee2015-03-25 13:43:34 -070061 SkPMFloat::From4PMColors(colors, &fa, &fb, &fc, &fd);
mtklein548bf382015-03-05 11:31:59 -080062 } else {
mtklein15391ee2015-03-25 13:43:34 -070063 fa = SkPMFloat::FromPMColor(colors[0]);
64 fb = SkPMFloat::FromPMColor(colors[1]);
65 fc = SkPMFloat::FromPMColor(colors[2]);
66 fd = SkPMFloat::FromPMColor(colors[3]);
mtklein548bf382015-03-05 11:31:59 -080067 }
68
69 SkPMColor back[4];
70 switch (kClamp << 1 | kWide) {
mtklein15391ee2015-03-25 13:43:34 -070071 case 0: {
72 back[0] = fa.get();
73 back[1] = fb.get();
74 back[2] = fc.get();
75 back[3] = fd.get();
76 } break;
77 case 1: SkPMFloat::To4PMColors(fa, fb, fc, fd, back); break;
78 case 2: {
79 back[0] = fa.clamped();
80 back[1] = fb.clamped();
81 back[2] = fc.clamped();
82 back[3] = fd.clamped();
83 } break;
84 case 3: SkPMFloat::ClampTo4PMColors(fa, fb, fc, fd, back); break;
mtklein548bf382015-03-05 11:31:59 -080085 }
86 for (int i = 0; i < 4; i++) {
87 junk ^= back[i];
88 }
mtkleina2f4be72015-02-23 10:04:34 -080089 }
mtklein60ff4582015-03-03 08:03:27 -080090 blackhole ^= junk;
mtkleina2f4be72015-02-23 10:04:34 -080091 }
mtkleina2f4be72015-02-23 10:04:34 -080092};
mtklein548bf382015-03-05 11:31:59 -080093
94// Extra () help DEF_BENCH not get confused by the comma inside the <>.
95DEF_BENCH(return (new PMFloatBench< true, true>);)
96DEF_BENCH(return (new PMFloatBench<false, true>);)
97DEF_BENCH(return (new PMFloatBench< true, false>);)
98DEF_BENCH(return (new PMFloatBench<false, false>);)