From fac684502b6047ffc7dc2e59bd7e5a7cbfa5bf78 Mon Sep 17 00:00:00 2001 From: reed Date: Sat, 23 Jan 2016 10:15:39 -0800 Subject: expand unitests for color4f BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1622893002 TBR= Review URL: https://codereview.chromium.org/1622893002 --- tests/SkColor4fTest.cpp | 144 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 137 insertions(+), 7 deletions(-) (limited to 'tests/SkColor4fTest.cpp') diff --git a/tests/SkColor4fTest.cpp b/tests/SkColor4fTest.cpp index b09b0c479a..6069246bc5 100644 --- a/tests/SkColor4fTest.cpp +++ b/tests/SkColor4fTest.cpp @@ -6,11 +6,30 @@ */ #include "SkColor.h" -#include "SkShader.h" #include "SkColorMatrixFilter.h" +#include "SkGradientShader.h" +#include "SkImage.h" +#include "SkShader.h" + #include "Test.h" #include "SkRandom.h" +const float kTolerance = 1.0f / (1 << 20); + +static bool nearly_equal(float a, float b, float tol = kTolerance) { + SkASSERT(tol >= 0); + return fabsf(a - b) <= tol; +} + +static bool nearly_equal(const SkPM4f a, const SkPM4f& b, float tol = kTolerance) { + for (int i = 0; i < 4; ++i) { + if (!nearly_equal(a.fVec[i], b.fVec[i], tol)) { + return false; + } + } + return true; +} + DEF_TEST(SkColor4f_FromColor, reporter) { const struct { SkColor fC; @@ -31,12 +50,7 @@ DEF_TEST(SkColor4f_FromColor, reporter) { } } -static bool nearly_equal(float a, float b) { - const float kTolerance = 1.0f / (1 << 20); - return fabsf(a - b) < kTolerance; -} - -DEF_TEST(SkColor4f_premul, reporter) { +DEF_TEST(Color4f_premul, reporter) { SkRandom rand; for (int i = 0; i < 1000000; ++i) { @@ -60,3 +74,119 @@ DEF_TEST(SkColor4f_premul, reporter) { REPORTER_ASSERT(reporter, nearly_equal(pm4.fVec[SK_B_INDEX], c4.fA * c4.fB)); } } + +////////////////////////////////////////////////////////////////////////////////////////////////// + +static SkShader* make_color() { return SkShader::CreateColorShader(0xFFBB8855); } + +static SkShader* make_image() { + const SkImageInfo info = SkImageInfo::MakeN32Premul(2, 2); + const SkPMColor pixels[] { + SkPackARGB32(0xFF, 0xBB, 0x88, 0x55), + SkPackARGB32(0xFF, 0xBB, 0x88, 0x55), + SkPackARGB32(0xFF, 0xBB, 0x88, 0x55), + SkPackARGB32(0xFF, 0xBB, 0x88, 0x55), + }; + SkAutoTUnref image(SkImage::NewRasterCopy(info, pixels, sizeof(SkPMColor) * 2)); + return image->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); +} + +static SkShader* make_grad() { + const SkPoint pts[] {{ 0, 0 }, { 100, 100 }}; + const SkColor colors[] { SK_ColorRED, SK_ColorBLUE }; + return SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode); +} + +static void compare_spans(const SkPM4f span4f[], const SkPMColor span4b[], int count, + skiatest::Reporter* reporter) { + for (int i = 0; i < count; ++i) { + SkPM4f c0 = SkPM4f::FromPMColor(span4b[i]); + SkPM4f c1 = span4f[i]; + REPORTER_ASSERT(reporter, nearly_equal(c0, c1, 1.0f/255)); + } +} + +DEF_TEST(Color4f_shader, reporter) { + struct { + SkShader* (*fFact)(); + bool fSupports4f; + } recs[] = { + { make_color, true }, + { make_grad, false }, + { make_image, false }, + }; + + SkPaint paint; + for (const auto& rec : recs) { + uint32_t storage[200]; + paint.setShader(rec.fFact())->unref(); + SkASSERT(paint.getShader()->contextSize() <= sizeof(storage)); + SkShader::Context* ctx = paint.getShader()->createContext({paint, SkMatrix::I(), nullptr}, + storage); + REPORTER_ASSERT(reporter, ctx->supports4f() == rec.fSupports4f); + if (ctx->supports4f()) { + const int N = 100; + SkPM4f buffer4f[N]; + ctx->shadeSpan4f(0, 0, buffer4f, N); + SkPMColor buffer4b[N]; + ctx->shadeSpan(0, 0, buffer4b, N); + compare_spans(buffer4f, buffer4b, N, reporter); + } + ctx->SkShader::Context::~Context(); + } +} + +static SkColorFilter* make_mode_cf() { + return SkColorFilter::CreateModeFilter(0xFFBB8855, SkXfermode::kPlus_Mode); +} + +static SkColorFilter* make_mx_cf() { + const float mx[] = { + 0.5f, 0, 0, 0, 0.1f, + 0, 0.5f, 0, 0, 0.2f, + 0, 0, 1, 0, -0.1f, + 0, 0, 0, 1, 0, + }; + return SkColorMatrixFilter::Create(mx); +} + +static SkColorFilter* make_compose_cf() { + SkAutoTUnref cf0(make_mode_cf()); + SkAutoTUnref cf1(make_mx_cf()); + return SkColorFilter::CreateComposeFilter(cf0, cf1); +} + +DEF_TEST(Color4f_colorfilter, reporter) { + struct { + SkColorFilter* (*fFact)(); + bool fSupports4f; + } recs[] = { + { make_mode_cf, false }, + { make_mx_cf, true }, + { make_compose_cf, false }, + }; + + // prepare the src + const int N = 100; + SkPMColor src4b[N]; + SkPM4f src4f[N]; + SkRandom rand; + for (int i = 0; i < N; ++i) { + src4b[i] = SkPreMultiplyColor(rand.nextU()); + src4f[i] = SkPM4f::FromPMColor(src4b[i]); + } + // confirm that our srcs are (nearly) equal + compare_spans(src4f, src4b, N, reporter); + + for (const auto& rec : recs) { + SkAutoTUnref filter(rec.fFact()); + REPORTER_ASSERT(reporter, filter->supports4f() == rec.fSupports4f); + if (filter->supports4f()) { + SkPMColor dst4b[N]; + filter->filterSpan(src4b, N, dst4b); + SkPM4f dst4f[N]; + filter->filterSpan4f(src4f, N, dst4f); + compare_spans(dst4f, dst4b, N, reporter); + } + } +} -- cgit v1.2.3