blob: ae01d0c966ca4399f82a39c45ea82666c2820072 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00007
reed@android.comd66efc22009-03-03 18:35:18 +00008#include "Test.h"
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00009#include "TestClassDef.h"
reed@android.comd66efc22009-03-03 18:35:18 +000010#include "SkColorPriv.h"
11#include "SkXfermode.h"
12
13// our std SkAlpha255To256
14static int test_srcover0(unsigned dst, unsigned alpha) {
15 return alpha + SkAlphaMul(dst, SkAlpha255To256(255 - alpha));
16}
17
18// faster hack +1
19static int test_srcover1(unsigned dst, unsigned alpha) {
20 return alpha + SkAlphaMul(dst, 256 - alpha);
21}
22
23// slower "correct"
24static int test_srcover2(unsigned dst, unsigned alpha) {
25 return alpha + SkMulDiv255Round(dst, 255 - alpha);
26}
27
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000028DEF_TEST(SrcOver, reporter) {
reed@android.comd66efc22009-03-03 18:35:18 +000029 /* Here's the idea. Can we ensure that when we blend on top of an opaque
30 dst, that the result always stay's opaque (i.e. exactly 255)?
31 */
reed@android.com80e39a72009-04-02 16:59:40 +000032
reed@android.comd66efc22009-03-03 18:35:18 +000033 unsigned i;
34 int opaqueCounter0 = 0;
35 int opaqueCounter1 = 0;
36 int opaqueCounter2 = 0;
37 for (i = 0; i <= 255; i++) {
38 unsigned result0 = test_srcover0(0xFF, i);
39 unsigned result1 = test_srcover1(0xFF, i);
40 unsigned result2 = test_srcover2(0xFF, i);
41 opaqueCounter0 += (result0 == 0xFF);
42 opaqueCounter1 += (result1 == 0xFF);
43 opaqueCounter2 += (result2 == 0xFF);
44 }
45#if 0
46 SkDebugf("---- opaque test: [%d %d %d]\n",
47 opaqueCounter0, opaqueCounter1, opaqueCounter2);
48#endif
49 // we acknowledge that technique0 does not always return opaque
reed@android.com9781ca52009-04-14 14:28:22 +000050 REPORTER_ASSERT(reporter, opaqueCounter0 == 256);
reed@android.comd66efc22009-03-03 18:35:18 +000051 REPORTER_ASSERT(reporter, opaqueCounter1 == 256);
52 REPORTER_ASSERT(reporter, opaqueCounter2 == 256);
reed@android.com80e39a72009-04-02 16:59:40 +000053
reed@android.comd66efc22009-03-03 18:35:18 +000054 // Now ensure that we never over/underflow a byte
55 for (i = 0; i <= 255; i++) {
56 for (unsigned dst = 0; dst <= 255; dst++) {
57 unsigned r0 = test_srcover0(dst, i);
58 unsigned r1 = test_srcover1(dst, i);
59 unsigned r2 = test_srcover2(dst, i);
60 unsigned max = SkMax32(dst, i);
61 // ignore the known failure
62 if (dst != 255) {
63 REPORTER_ASSERT(reporter, r0 <= 255 && r0 >= max);
64 }
65 REPORTER_ASSERT(reporter, r1 <= 255 && r1 >= max);
66 REPORTER_ASSERT(reporter, r2 <= 255 && r2 >= max);
reed@android.com80e39a72009-04-02 16:59:40 +000067
reed@android.comd66efc22009-03-03 18:35:18 +000068#if 0
69 // this shows where r1 (faster) differs from r2 (more exact)
70 if (r1 != r2) {
reed@android.com80e39a72009-04-02 16:59:40 +000071 SkDebugf("--- dst=%d i=%d r1=%d r2=%d exact=%g\n",
72 dst, i, r1, r2, i + dst - dst*i/255.0f);
reed@android.comd66efc22009-03-03 18:35:18 +000073 }
74#endif
75 }
76 }
77}