aboutsummaryrefslogtreecommitdiffstats
path: root/tests/MathTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/MathTest.cpp')
-rw-r--r--tests/MathTest.cpp107
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"