skia2/tests/SkBlend_optsTest.cpp
mtklein 0358a6ac00 Update SkOpts namespaces.
If we make sure all SkOpts functions are static, we can give the namespaces any
name we like.  This lets us drop the sk_ prefix and give a real indication of
the default SIMD instruction set rather than just saying sk_default.

Both of these changes help debugger, profiler, and crash report readability.
Perhaps more importantly, keeping these functions static helps prevent
accidentally linking in unused versions of functions, as you see here with
sk_avx::srcover_srgb_srgb().

This requires we update SkBlend_opts tests and benches to call SkOpts functions
through SkOpts rather than declaring the methods externally.  In practice this
drops testing of the SSE2 version on machines with SSE4.  If we still really
need to test/bench the compile time best SIMD level version of this method
against the runtime detected best, we can include SkBlend_opts.h into the tests
or benches directly, similar to what we do for the trivial, brute-force, or best
non-SIMD versions.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2145833002
CQ_INCLUDE_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Review-Url: https://codereview.chromium.org/2145833002
2016-07-13 08:02:20 -07:00

100 lines
3.1 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <string>
#include <tuple>
#include <vector>
#include "Resources.h"
#include "SkCpu.h"
#include "SkImage.h"
#include "SkImage_Base.h"
#include "SkOpts.h"
#include "SkPM4fPriv.h"
#include "SkNx.h"
#include "Test.h"
typedef void (*Blender)(uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
static void brute_force_srcover_srgb_srgb(
uint32_t* dst, const uint32_t* const src, int ndst, const int nsrc) {
while (ndst > 0) {
int n = SkTMin(ndst, nsrc);
for (int i = 0; i < n; i++) {
srcover_blend_srgb8888_srgb_1(dst++, srgb_to_linear(to_4f(src[i])));
}
ndst -= n;
}
}
static SkString mismatch_message(std::string resourceName, int x, int y,
uint32_t src, uint32_t good, uint32_t bad) {
return SkStringPrintf(
"%s - missmatch at %d, %d src: %08x good: %08x bad: %08x",
resourceName.c_str(), x, y, src, good, bad);
}
static void test_blender(std::string resourceName, skiatest::Reporter* reporter) {
std::string fileName = resourceName + ".png";
sk_sp<SkImage> image = GetResourceAsImage(fileName.c_str());
if (image == nullptr) {
ERRORF(reporter, "image is NULL");
return;
}
SkBitmap bm;
if (!as_IB(image)->getROPixels(&bm)) {
ERRORF(reporter, "Could not read resource");
return;
}
SkPixmap pixmap;
bm.peekPixels(&pixmap);
SkASSERTF(pixmap.colorType() == kN32_SkColorType, "colorType: %d", pixmap.colorType());
SkASSERT(pixmap.alphaType() != kUnpremul_SkAlphaType);
const uint32_t* src = pixmap.addr32();
const int width = pixmap.rowBytesAsPixels();
SkASSERT(width > 0);
SkASSERT(width < 4000);
SkAutoTArray<uint32_t> correctDst(width);
SkAutoTArray<uint32_t> testDst(width);
for (int y = 0; y < pixmap.height(); y++) {
sk_bzero(correctDst.get(), width * sizeof(uint32_t));
sk_bzero(testDst.get(), width * sizeof(uint32_t));
brute_force_srcover_srgb_srgb(correctDst.get(), src, width, width);
SkOpts:: srcover_srgb_srgb( testDst.get(), src, width, width);
for (int x = 0; x < width; x++) {
REPORTER_ASSERT_MESSAGE(
reporter, correctDst[x] == testDst[x],
mismatch_message(resourceName, x, y, src[x], correctDst[x], testDst[x]));
if (correctDst[x] != testDst[x]) break;
}
src += width;
}
}
DEF_TEST(SkBlend_optsCheck, reporter) {
std::vector<std::string> testResources = {
"yellow_rose", "baby_tux", "plane", "mandrill_512", "iconstrip"
};
for (auto& resourceName : testResources) {
test_blender(resourceName, reporter);
}
}
DEF_TEST(SkBlend_optsSqrtCheck, reporter) {
for (int c = 0; c < 256; c++) {
Sk4f i{(float)c};
Sk4f ii = i * i;
Sk4f s = ii.sqrt() + 0.5f;
Sk4f sf = s.floor();
REPORTER_ASSERT_MESSAGE(
reporter, i[0] == sf[0], SkStringPrintf("i: %f, s: %f", i[0], sf[0]));
}
}