OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "Test.h" | 8 #include "Test.h" |
9 #include "SkColor.h" | 9 #include "SkColor.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
11 #include "SkMathPriv.h" | 11 #include "SkMathPriv.h" |
12 #include "SkRandom.h" | 12 #include "SkRandom.h" |
13 #include "SkUnPreMultiply.h" | 13 #include "SkUnPreMultiply.h" |
14 | 14 |
15 #define GetPackedR16As32(packed) (SkGetPackedR16(dc) << (8 - SK_R16_BITS)) | 15 #define GetPackedR16As32(packed) (SkGetPackedR16(dc) << (8 - SK_R16_BITS)) |
16 #define GetPackedG16As32(packed) (SkGetPackedG16(dc) << (8 - SK_G16_BITS)) | 16 #define GetPackedG16As32(packed) (SkGetPackedG16(dc) << (8 - SK_G16_BITS)) |
17 #define GetPackedB16As32(packed) (SkGetPackedB16(dc) << (8 - SK_B16_BITS)) | 17 #define GetPackedB16As32(packed) (SkGetPackedB16(dc) << (8 - SK_B16_BITS)) |
18 | 18 |
19 static inline bool S32A_D565_Blend_0(SkPMColor sc, uint16_t dc, U8CPU alpha) { | |
20 unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); | |
21 unsigned dr = SkMulS16(SkPacked32ToR16(sc), alpha) + SkMulS16(SkGetPackedR16
(dc), dst_scale); | |
22 unsigned dg = SkMulS16(SkPacked32ToG16(sc), alpha) + SkMulS16(SkGetPackedG16
(dc), dst_scale); | |
23 | |
24 unsigned rr = SkDiv255Round(dr); | |
25 unsigned rg = SkDiv255Round(dg); | |
26 | |
27 if (rr <= 31 && rg <= 63) { | |
28 return true; | |
29 } | |
30 return false; | |
31 } | |
32 | |
33 static inline bool S32A_D565_Blend_01(SkPMColor sc, uint16_t dc, U8CPU alpha) { | |
34 unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); | |
35 unsigned dr = SkMulS16(SkGetPackedR32(sc), alpha) + SkMulS16(SkGetPackedR16(
dc) << 3, dst_scale); | |
36 unsigned dg = SkMulS16(SkGetPackedG32(sc), alpha) + SkMulS16(SkGetPackedG16(
dc) << 2, dst_scale); | |
37 | |
38 unsigned rr = SkDiv255Round(dr) >> 3; | |
39 unsigned rg = SkDiv255Round(dg) >> 2; | |
40 | |
41 if (rr <= 31 && rg <= 63) { | |
42 return true; | |
43 } | |
44 return false; | |
45 } | |
46 | |
47 static inline bool S32A_D565_Blend_02(SkPMColor sc, uint16_t dc, U8CPU alpha) { | |
48 unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); | |
49 unsigned dr = SkMulS16(SkGetPackedR32(sc), alpha) + SkMulS16(GetPackedR16As3
2(dc), dst_scale); | |
50 unsigned dg = SkMulS16(SkGetPackedG32(sc), alpha) + SkMulS16(GetPackedG16As3
2(dc), dst_scale); | |
51 unsigned db = SkMulS16(SkGetPackedB32(sc), alpha) + SkMulS16(GetPackedB16As3
2(dc), dst_scale); | |
52 int rc = SkPack888ToRGB16(SkDiv255Round(dr), | |
53 SkDiv255Round(dg), | |
54 SkDiv255Round(db)); | |
55 | |
56 unsigned rr = SkGetPackedR16(rc); | |
57 unsigned rg = SkGetPackedG16(rc); | |
58 | |
59 if (rr <= 31 && rg <= 63) { | |
60 return true; | |
61 } | |
62 return false; | |
63 } | |
64 | |
65 static inline bool S32A_D565_Blend_1(SkPMColor sc, uint16_t dc, U8CPU alpha) { | |
66 unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); | |
67 unsigned dr = (SkMulS16(SkGetPackedR32(sc), alpha) >> 3) + SkMulS16(SkGetPac
kedR16(dc), dst_scale); | |
68 unsigned dg = (SkMulS16(SkGetPackedG32(sc), alpha) >> 2) + SkMulS16(SkGetPac
kedG16(dc), dst_scale); | |
69 | |
70 unsigned rr = SkDiv255Round(dr); | |
71 unsigned rg = SkDiv255Round(dg); | |
72 | |
73 if (rr <= 31 && rg <= 63) { | |
74 return true; | |
75 } | |
76 return false; | |
77 } | |
78 | |
79 static inline int SkDiv65025Round(int x) { | |
80 return (x + 65025/2) / 65025; | |
81 // return x / 65025; | |
82 } | |
83 static inline bool S32A_D565_Blend_2(SkPMColor sc, uint16_t dc, U8CPU alpha) { | |
84 unsigned dst_scale = 255*255 - SkGetPackedA32(sc) * alpha; | |
85 alpha *= 255; | |
86 unsigned dr = (SkGetPackedR32(sc) >> 3) * alpha + SkGetPackedR16(dc) * dst_s
cale; | |
87 unsigned dg = (SkGetPackedG32(sc) >> 2) * alpha + SkGetPackedG16(dc) * dst_s
cale; | |
88 | |
89 unsigned rr = SkDiv65025Round(dr); | |
90 unsigned rg = SkDiv65025Round(dg); | |
91 | |
92 if (rr <= 31 && rg <= 63) { | |
93 return true; | |
94 } | |
95 return false; | |
96 } | |
97 | |
98 static inline void test_565blend() { | |
99 int total_failures = 0; | |
100 for (int global_alpha = 0; global_alpha <= 255; ++global_alpha) { | |
101 int failures = 0; | |
102 int total = 0; | |
103 for (int src_a = 0; src_a <= 255; ++src_a) { | |
104 for (int src_c = 0; src_c <= src_a; ++src_c) { | |
105 SkPMColor sc = SkPackARGB32(src_a, src_c, src_c, src_c); | |
106 for (int dst_r = 0; dst_r <= 31; ++dst_r) { | |
107 for (int dst_g = 0; dst_g <= 63; ++dst_g) { | |
108 uint16_t dc = SkPackRGB16(dst_r, dst_g, dst_r); | |
109 failures += !S32A_D565_Blend_0(sc, dc, global_alpha); | |
110 total += 1; | |
111 } | |
112 } | |
113 } | |
114 } | |
115 SkDebugf("global_alpha=%d failures=%d total=%d %g\n", global_alpha, fail
ures, total, failures * 100.0 / total); | |
116 total_failures += failures; | |
117 } | |
118 SkDebugf("total failures %d\n", total_failures); | |
119 } | |
120 | |
121 static inline void test_premul(skiatest::Reporter* reporter) { | 19 static inline void test_premul(skiatest::Reporter* reporter) { |
122 for (int a = 0; a <= 255; a++) { | 20 for (int a = 0; a <= 255; a++) { |
123 for (int x = 0; x <= 255; x++) { | 21 for (int x = 0; x <= 255; x++) { |
124 SkColor c0 = SkColorSetARGB(a, x, x, x); | 22 SkColor c0 = SkColorSetARGB(a, x, x, x); |
125 SkPMColor p0 = SkPreMultiplyColor(c0); | 23 SkPMColor p0 = SkPreMultiplyColor(c0); |
126 | 24 |
127 SkColor c1 = SkUnPreMultiply::PMColorToColor(p0); | 25 SkColor c1 = SkUnPreMultiply::PMColorToColor(p0); |
128 SkPMColor p1 = SkPreMultiplyColor(c1); | 26 SkPMColor p1 = SkPreMultiplyColor(c1); |
129 | 27 |
130 // we can't promise that c0 == c1, since c0 -> p0 is a many to one | 28 // we can't promise that c0 == c1, since c0 -> p0 is a many to one |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 | 78 |
181 static void TestColor(skiatest::Reporter* reporter) { | 79 static void TestColor(skiatest::Reporter* reporter) { |
182 test_premul(reporter); | 80 test_premul(reporter); |
183 //test_interp(reporter); | 81 //test_interp(reporter); |
184 test_fast_interp(reporter); | 82 test_fast_interp(reporter); |
185 // test_565blend(); | 83 // test_565blend(); |
186 } | 84 } |
187 | 85 |
188 #include "TestClassDef.h" | 86 #include "TestClassDef.h" |
189 DEFINE_TESTCLASS("Color", ColorTestClass, TestColor) | 87 DEFINE_TESTCLASS("Color", ColorTestClass, TestColor) |
OLD | NEW |