f2fe0e0320
I haven't figured out a pithy way to have these apply to only classes originating from SkNx, so let's just remove them. There aren't too many use cases, and it's not really any less readable without them. Semantically, this is a no-op. BUG=skia: Review URL: https://codereview.chromium.org/1167153002
134 lines
4.7 KiB
C++
134 lines
4.7 KiB
C++
/*
|
|
* Copyright 2015 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "Benchmark.h"
|
|
#include "SkPMFloat.h"
|
|
|
|
// Used to prevent the compiler from optimizing away the whole loop.
|
|
volatile uint32_t blackhole = 0;
|
|
|
|
// Not a great random number generator, but it's very fast.
|
|
// The code we're measuring is quite fast, so low overhead is essential.
|
|
static uint32_t lcg_rand(uint32_t* seed) {
|
|
*seed *= 1664525;
|
|
*seed += 1013904223;
|
|
return *seed;
|
|
}
|
|
|
|
// I'm having better luck getting these to constant-propagate away as template parameters.
|
|
template <bool kClamp, bool kWide>
|
|
struct PMFloatGetSetBench : public Benchmark {
|
|
PMFloatGetSetBench() {}
|
|
|
|
const char* onGetName() override {
|
|
switch (kClamp << 1 | kWide) {
|
|
case 0: return "SkPMFloat_get_1x";
|
|
case 1: return "SkPMFloat_get_4x";
|
|
case 2: return "SkPMFloat_clamp_1x";
|
|
case 3: return "SkPMFloat_clamp_4x";
|
|
}
|
|
SkFAIL("unreachable");
|
|
return "oh bother";
|
|
}
|
|
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
|
|
|
|
void onDraw(const int loops, SkCanvas* canvas) override {
|
|
// Unlike blackhole, junk can and probably will be a register.
|
|
uint32_t junk = 0;
|
|
uint32_t seed = 0;
|
|
for (int i = 0; i < loops; i++) {
|
|
SkPMColor colors[4];
|
|
#ifdef SK_DEBUG
|
|
for (int i = 0; i < 4; i++) {
|
|
// Our SkASSERTs will remind us that it's technically required that we premultiply.
|
|
colors[i] = SkPreMultiplyColor(lcg_rand(&seed));
|
|
}
|
|
#else
|
|
// But it's a lot faster not to, and this code won't really mind the non-PM colors.
|
|
(void)lcg_rand(&seed);
|
|
colors[0] = seed + 0;
|
|
colors[1] = seed + 1;
|
|
colors[2] = seed + 2;
|
|
colors[3] = seed + 3;
|
|
#endif
|
|
|
|
SkPMFloat fa,fb,fc,fd;
|
|
if (kWide) {
|
|
SkPMFloat::From4PMColors(colors, &fa, &fb, &fc, &fd);
|
|
} else {
|
|
fa = SkPMFloat::FromPMColor(colors[0]);
|
|
fb = SkPMFloat::FromPMColor(colors[1]);
|
|
fc = SkPMFloat::FromPMColor(colors[2]);
|
|
fd = SkPMFloat::FromPMColor(colors[3]);
|
|
}
|
|
|
|
SkPMColor back[4];
|
|
switch (kClamp << 1 | kWide) {
|
|
case 0: {
|
|
back[0] = fa.round();
|
|
back[1] = fb.round();
|
|
back[2] = fc.round();
|
|
back[3] = fd.round();
|
|
} break;
|
|
case 1: SkPMFloat::RoundTo4PMColors(fa, fb, fc, fd, back); break;
|
|
case 2: {
|
|
back[0] = fa.roundClamp();
|
|
back[1] = fb.roundClamp();
|
|
back[2] = fc.roundClamp();
|
|
back[3] = fd.roundClamp();
|
|
} break;
|
|
case 3: SkPMFloat::RoundClampTo4PMColors(fa, fb, fc, fd, back); break;
|
|
}
|
|
for (int i = 0; i < 4; i++) {
|
|
junk ^= back[i];
|
|
}
|
|
}
|
|
blackhole ^= junk;
|
|
}
|
|
};
|
|
|
|
// Extra () help DEF_BENCH not get confused by the comma inside the <>.
|
|
DEF_BENCH(return (new PMFloatGetSetBench< true, true>);)
|
|
DEF_BENCH(return (new PMFloatGetSetBench<false, true>);)
|
|
DEF_BENCH(return (new PMFloatGetSetBench< true, false>);)
|
|
DEF_BENCH(return (new PMFloatGetSetBench<false, false>);)
|
|
|
|
struct PMFloatGradientBench : public Benchmark {
|
|
const char* onGetName() override { return "PMFloat_gradient"; }
|
|
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
|
|
|
|
SkPMColor fDevice[100];
|
|
void onDraw(const int loops, SkCanvas*) override {
|
|
Sk4f c0 = SkPMFloat::FromARGB(255, 255, 0, 0),
|
|
c1 = SkPMFloat::FromARGB(255, 0, 0, 255),
|
|
dc = c1 - c0,
|
|
fx(0.1f),
|
|
dx(0.002f),
|
|
dcdx(dc*dx),
|
|
dcdx4(dcdx+dcdx+dcdx+dcdx);
|
|
|
|
for (int n = 0; n < loops; n++) {
|
|
Sk4f a = c0 + dc*fx + Sk4f(0.5f), // The +0.5f lets us call trunc() instead of get().
|
|
b = a + dcdx,
|
|
c = b + dcdx,
|
|
d = c + dcdx;
|
|
for (size_t i = 0; i < SK_ARRAY_COUNT(fDevice); i += 4) {
|
|
fDevice[i+0] = SkPMFloat(a).trunc();
|
|
fDevice[i+1] = SkPMFloat(b).trunc();
|
|
fDevice[i+2] = SkPMFloat(c).trunc();
|
|
fDevice[i+3] = SkPMFloat(d).trunc();
|
|
a = a + dcdx4;
|
|
b = b + dcdx4;
|
|
c = c + dcdx4;
|
|
d = d + dcdx4;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
DEF_BENCH(return new PMFloatGradientBench;)
|