diff options
Diffstat (limited to 'tests/MathTest.cpp')
-rw-r--r-- | tests/MathTest.cpp | 107 |
1 files changed, 84 insertions, 23 deletions
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp index efdad3a..fef93cd 100644 --- a/tests/MathTest.cpp +++ b/tests/MathTest.cpp @@ -1,41 +1,97 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ #include "Test.h" #include "SkFloatingPoint.h" +#include "SkMath.h" #include "SkPoint.h" #include "SkRandom.h" +#include "SkColorPriv.h" -#if 0 -static U8CPU premul_fast(U8CPU a, U8CPU x) { - return a * x * 32897 >> 23; +static float float_blend(int src, int dst, float unit) { + return dst + (src - dst) * unit; } -static U8CPU premul_trunc(U8CPU a, U8CPU x) { - double result = a * x; - result /= 255.0; - return (unsigned)floor(result + 0.0); +static int blend31(int src, int dst, int a31) { + return dst + ((src - dst) * a31 * 2114 >> 16); + // return dst + ((src - dst) * a31 * 33 >> 10); } -static U8CPU premul_round(U8CPU a, U8CPU x) { - double result = a * x; - result /= 255.0; - return (unsigned)floor(result + 0.5); +static int blend31_slow(int src, int dst, int a31) { + int prod = src * a31 + (31 - a31) * dst + 16; + prod = (prod + (prod >> 5)) >> 5; + return prod; } -static void test_premul(skiatest::Reporter* reporter) { - for (int a = 0; a <= 255; a++) { - for (int x = 0; x <= 255; x++) { - unsigned curr_trunc = SkMulDiv255Trunc(a, x); - unsigned curr_round = SkMulDiv255Round(a, x); - unsigned fast = premul_fast(a, x); - unsigned slow_round = premul_round(a, x); - unsigned slow_trunc = premul_trunc(a, x); - if (fast != slow || curr != fast) { - SkDebugf("---- premul(%d %d) curr=%d fast=%d slow=%d\n", a, x, - curr, fast, slow); +static int blend31_round(int src, int dst, int a31) { + int prod = (src - dst) * a31 + 16; + prod = (prod + (prod >> 5)) >> 5; + return dst + prod; +} + +static int blend31_old(int src, int dst, int a31) { + a31 += a31 >> 4; + return dst + ((src - dst) * a31 >> 5); +} + +static void test_blend31() { + int failed = 0; + int death = 0; + for (int src = 0; src <= 255; src++) { + for (int dst = 0; dst <= 255; dst++) { + for (int a = 0; a <= 31; a++) { +// int r0 = blend31(src, dst, a); +// int r0 = blend31_round(src, dst, a); +// int r0 = blend31_old(src, dst, a); + int r0 = blend31_slow(src, dst, a); + + float f = float_blend(src, dst, a / 31.f); + int r1 = (int)f; + int r2 = SkScalarRoundToInt(SkFloatToScalar(f)); + + if (r0 != r1 && r0 != r2) { + printf("src:%d dst:%d a:%d result:%d float:%g\n", + src, dst, a, r0, f); + failed += 1; + } + if (r0 > 255) { + death += 1; + printf("death src:%d dst:%d a:%d result:%d float:%g\n", + src, dst, a, r0, f); + } } } } + SkDebugf("---- failed %d death %d\n", failed, death); } + +static void test_blend(skiatest::Reporter* reporter) { + for (int src = 0; src <= 255; src++) { + for (int dst = 0; dst <= 255; dst++) { + for (int a = 0; a <= 255; a++) { + int r0 = SkAlphaBlend255(src, dst, a); + float f1 = float_blend(src, dst, a / 255.f); + int r1 = SkScalarRoundToInt(SkFloatToScalar(f1)); + + if (r0 != r1) { + float diff = sk_float_abs(f1 - r1); + diff = sk_float_abs(diff - 0.5f); + if (diff > (1 / 255.f)) { +#ifdef SK_DEBUG + SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n", + src, dst, a, r0, f1); #endif + REPORTER_ASSERT(reporter, false); + } + } + } + } + } +} #if defined(SkLONGLONG) static int symmetric_fixmul(int a, int b) { @@ -493,7 +549,12 @@ static void TestMath(skiatest::Reporter* reporter) { SkDebugf("SinCos: maximum error = %d\n", maxDiff); #endif -// test_premul(reporter); +#ifdef SK_SCALAR_IS_FLOAT + test_blend(reporter); +#endif + + // disable for now +// test_blend31(); } #include "TestClassDef.h" |