blob: 540fdb781588a87da5a7968a2632ed7a4f5c233c [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.
mtkleine9a3e3c2015-06-25 08:56:28 -070023struct PMFloatRoundtripBench : public Benchmark {
24 PMFloatRoundtripBench() {}
mtkleina2f4be72015-02-23 10:04:34 -080025
mtkleine9a3e3c2015-06-25 08:56:28 -070026 const char* onGetName() override { return "SkPMFloat_roundtrip"; }
mtklein36352bf2015-03-25 18:17:31 -070027 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
mtkleina2f4be72015-02-23 10:04:34 -080028
mtklein36352bf2015-03-25 18:17:31 -070029 void onDraw(const int loops, SkCanvas* canvas) override {
mtklein60ff4582015-03-03 08:03:27 -080030 // Unlike blackhole, junk can and probably will be a register.
31 uint32_t junk = 0;
32 uint32_t seed = 0;
mtkleina2f4be72015-02-23 10:04:34 -080033 for (int i = 0; i < loops; i++) {
mtkleine9a3e3c2015-06-25 08:56:28 -070034 SkPMColor color;
mtklein60ff4582015-03-03 08:03:27 -080035 #ifdef SK_DEBUG
mtkleine9a3e3c2015-06-25 08:56:28 -070036 // Our SkASSERTs will remind us that it's technically required that we premultiply.
37 color = SkPreMultiplyColor(lcg_rand(&seed));
mtklein60ff4582015-03-03 08:03:27 -080038 #else
39 // But it's a lot faster not to, and this code won't really mind the non-PM colors.
mtkleine9a3e3c2015-06-25 08:56:28 -070040 color = lcg_rand(&seed);
mtklein60ff4582015-03-03 08:03:27 -080041 #endif
mtklein548bf382015-03-05 11:31:59 -080042
mtkleine9a3e3c2015-06-25 08:56:28 -070043 auto f = SkPMFloat::FromPMColor(color);
44 SkPMColor back = f.round();
45 junk ^= back;
mtkleina2f4be72015-02-23 10:04:34 -080046 }
mtklein60ff4582015-03-03 08:03:27 -080047 blackhole ^= junk;
mtkleina2f4be72015-02-23 10:04:34 -080048 }
mtkleina2f4be72015-02-23 10:04:34 -080049};
mtkleine9a3e3c2015-06-25 08:56:28 -070050DEF_BENCH(return new PMFloatRoundtripBench;)
mtklein02fd5922015-03-25 18:13:02 -070051
52struct PMFloatGradientBench : public Benchmark {
53 const char* onGetName() override { return "PMFloat_gradient"; }
54 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
55
56 SkPMColor fDevice[100];
57 void onDraw(const int loops, SkCanvas*) override {
mtkleine9a3e3c2015-06-25 08:56:28 -070058 Sk4f c0 = SkPMFloat::FromARGB(1, 1, 0, 0),
59 c1 = SkPMFloat::FromARGB(1, 0, 0, 1),
mtklein02fd5922015-03-25 18:13:02 -070060 dc = c1 - c0,
61 fx(0.1f),
62 dx(0.002f),
63 dcdx(dc*dx),
64 dcdx4(dcdx+dcdx+dcdx+dcdx);
65
66 for (int n = 0; n < loops; n++) {
mtkleine9a3e3c2015-06-25 08:56:28 -070067 Sk4f a = c0 + dc*fx,
mtklein02fd5922015-03-25 18:13:02 -070068 b = a + dcdx,
69 c = b + dcdx,
70 d = c + dcdx;
71 for (size_t i = 0; i < SK_ARRAY_COUNT(fDevice); i += 4) {
mtkleine9a3e3c2015-06-25 08:56:28 -070072 fDevice[i+0] = SkPMFloat(a).round();
73 fDevice[i+1] = SkPMFloat(b).round();
74 fDevice[i+2] = SkPMFloat(c).round();
75 fDevice[i+3] = SkPMFloat(d).round();
mtkleinf2fe0e02015-06-10 08:57:28 -070076 a = a + dcdx4;
77 b = b + dcdx4;
78 c = c + dcdx4;
79 d = d + dcdx4;
mtklein02fd5922015-03-25 18:13:02 -070080 }
81 }
82 }
83};
84
85DEF_BENCH(return new PMFloatGradientBench;)