1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org
8d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com#include "SkColorPriv.h"
9d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com#include "SkXfermode.h"
108f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
11d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com
12d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com// our std SkAlpha255To256
13d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.comstatic int test_srcover0(unsigned dst, unsigned alpha) {
14d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    return alpha + SkAlphaMul(dst, SkAlpha255To256(255 - alpha));
15d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com}
16d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com
17d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com// faster hack +1
18d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.comstatic int test_srcover1(unsigned dst, unsigned alpha) {
19d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    return alpha + SkAlphaMul(dst, 256 - alpha);
20d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com}
21d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com
22d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com// slower "correct"
23d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.comstatic int test_srcover2(unsigned dst, unsigned alpha) {
24d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    return alpha + SkMulDiv255Round(dst, 255 - alpha);
25d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com}
26d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com
27e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(SrcOver, reporter) {
28d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    /*  Here's the idea. Can we ensure that when we blend on top of an opaque
29d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        dst, that the result always stay's opaque (i.e. exactly 255)?
30d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com     */
3180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
32d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    unsigned i;
33d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    int opaqueCounter0 = 0;
34d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    int opaqueCounter1 = 0;
35d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    int opaqueCounter2 = 0;
36d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    for (i = 0; i <= 255; i++) {
37d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        unsigned result0 = test_srcover0(0xFF, i);
38d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        unsigned result1 = test_srcover1(0xFF, i);
39d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        unsigned result2 = test_srcover2(0xFF, i);
40d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        opaqueCounter0 += (result0 == 0xFF);
41d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        opaqueCounter1 += (result1 == 0xFF);
42d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        opaqueCounter2 += (result2 == 0xFF);
43d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    }
44d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com#if 0
45d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    SkDebugf("---- opaque test: [%d %d %d]\n",
46d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com             opaqueCounter0, opaqueCounter1, opaqueCounter2);
47d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com#endif
48d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    // we acknowledge that technique0 does not always return opaque
499781ca586618cc8ea055f54021e706824313d4f5reed@android.com    REPORTER_ASSERT(reporter, opaqueCounter0 == 256);
50d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    REPORTER_ASSERT(reporter, opaqueCounter1 == 256);
51d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    REPORTER_ASSERT(reporter, opaqueCounter2 == 256);
5280e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
53d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    // Now ensure that we never over/underflow a byte
54d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    for (i = 0; i <= 255; i++) {
55d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        for (unsigned dst = 0; dst <= 255; dst++) {
56d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            unsigned r0 = test_srcover0(dst, i);
57d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            unsigned r1 = test_srcover1(dst, i);
58d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            unsigned r2 = test_srcover2(dst, i);
59d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            unsigned max = SkMax32(dst, i);
60d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            // ignore the known failure
61d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            if (dst != 255) {
62d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com                REPORTER_ASSERT(reporter, r0 <= 255 && r0 >= max);
63d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            }
64d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            REPORTER_ASSERT(reporter, r1 <= 255 && r1 >= max);
65d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            REPORTER_ASSERT(reporter, r2 <= 255 && r2 >= max);
6680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
67d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com#if 0
68d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            // this shows where r1 (faster) differs from r2 (more exact)
69d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            if (r1 != r2) {
7080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com                SkDebugf("--- dst=%d i=%d r1=%d r2=%d exact=%g\n",
7180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com                         dst, i, r1, r2, i + dst - dst*i/255.0f);
72d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com            }
73d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com#endif
74d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com        }
75d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com    }
76d66efc273e4996fb18f343bd30dcd506a1698b5breed@android.com}
77