test premul/unpremul are no-ops when a==1.0f

Constant propagation means we can always notionally
unpremul and premul at the right points, and if alpha
was already opaque, they'll just drop away.

This has been true, but it's nice to put a test on it.

Change-Id: Iacd2002d9e1a10b73e800a452f377001d5ba3777
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/268336
Auto-Submit: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2020-02-03 12:17:13 -06:00 committed by Skia Commit-Bot
parent 23e2ad174c
commit bc1ce2c0ca

View File

@ -816,6 +816,75 @@ DEF_TEST(SkVM_assert, r) {
});
}
DEF_TEST(SkVM_premul, reporter) {
// Test that premul is short-circuited when alpha is known opaque.
{
skvm::Builder p;
auto rptr = p.varying<int>(),
aptr = p.varying<int>();
skvm::F32 r = p.bit_cast(p.load32(rptr)),
g = p.splat(0.0f),
b = p.splat(0.0f),
a = p.bit_cast(p.load32(aptr));
p.premul(&r, &g, &b, a);
p.store32(rptr, p.bit_cast(r));
// load red, load alpha, red *= alpha, store red
REPORTER_ASSERT(reporter, p.done().instructions().size() == 4);
}
{
skvm::Builder p;
auto rptr = p.varying<int>();
skvm::F32 r = p.bit_cast(p.load32(rptr)),
g = p.splat(0.0f),
b = p.splat(0.0f),
a = p.splat(1.0f);
p.premul(&r, &g, &b, a);
p.store32(rptr, p.bit_cast(r));
// load red, store red
REPORTER_ASSERT(reporter, p.done().instructions().size() == 2);
}
// Same deal for unpremul.
{
skvm::Builder p;
auto rptr = p.varying<int>(),
aptr = p.varying<int>();
skvm::F32 r = p.bit_cast(p.load32(rptr)),
g = p.splat(0.0f),
b = p.splat(0.0f),
a = p.bit_cast(p.load32(aptr));
p.unpremul(&r, &g, &b, a);
p.store32(rptr, p.bit_cast(r));
// load red, load alpha, a bunch of unpremul instructions, store red
REPORTER_ASSERT(reporter, p.done().instructions().size() >= 4);
}
{
skvm::Builder p;
auto rptr = p.varying<int>();
skvm::F32 r = p.bit_cast(p.load32(rptr)),
g = p.splat(0.0f),
b = p.splat(0.0f),
a = p.splat(1.0f);
p.unpremul(&r, &g, &b, a);
p.store32(rptr, p.bit_cast(r));
// load red, store red
REPORTER_ASSERT(reporter, p.done().instructions().size() == 2);
}
}
template <typename Fn>
static void test_asm(skiatest::Reporter* r, Fn&& fn, std::initializer_list<uint8_t> expected) {