OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkArithmeticMode.h" | 8 #include "SkArithmeticMode.h" |
9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
| 10 #include "SkNx.h" |
10 #include "SkReadBuffer.h" | 11 #include "SkReadBuffer.h" |
11 #include "SkWriteBuffer.h" | |
12 #include "SkString.h" | 12 #include "SkString.h" |
13 #include "SkUnPreMultiply.h" | 13 #include "SkUnPreMultiply.h" |
| 14 #include "SkWriteBuffer.h" |
14 #if SK_SUPPORT_GPU | 15 #if SK_SUPPORT_GPU |
15 #include "SkArithmeticMode_gpu.h" | 16 #include "SkArithmeticMode_gpu.h" |
16 #endif | 17 #endif |
17 | 18 |
18 class SkArithmeticMode_scalar : public SkXfermode { | 19 class SkArithmeticMode_scalar : public SkXfermode { |
19 public: | 20 public: |
20 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, | 21 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, |
21 bool enforcePMColor) { | 22 bool enforcePMColor) { |
22 fK[0] = k1; | 23 fK[0] = k1; |
23 fK[1] = k2; | 24 fK[1] = k2; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 | 57 |
57 sk_sp<SkFlattenable> SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) { | 58 sk_sp<SkFlattenable> SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) { |
58 const SkScalar k1 = buffer.readScalar(); | 59 const SkScalar k1 = buffer.readScalar(); |
59 const SkScalar k2 = buffer.readScalar(); | 60 const SkScalar k2 = buffer.readScalar(); |
60 const SkScalar k3 = buffer.readScalar(); | 61 const SkScalar k3 = buffer.readScalar(); |
61 const SkScalar k4 = buffer.readScalar(); | 62 const SkScalar k4 = buffer.readScalar(); |
62 const bool enforcePMColor = buffer.readBool(); | 63 const bool enforcePMColor = buffer.readBool(); |
63 return SkArithmeticMode::Make(k1, k2, k3, k4, enforcePMColor); | 64 return SkArithmeticMode::Make(k1, k2, k3, k4, enforcePMColor); |
64 } | 65 } |
65 | 66 |
66 static int pinToByte(int value) { | |
67 if (value < 0) { | |
68 value = 0; | |
69 } else if (value > 255) { | |
70 value = 255; | |
71 } | |
72 return value; | |
73 } | |
74 | |
75 static int arith(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, | |
76 int src, int dst) { | |
77 SkScalar result = SkScalarMul(k1, src * dst) + | |
78 SkScalarMul(k2, src) + | |
79 SkScalarMul(k3, dst) + | |
80 k4; | |
81 int res = SkScalarRoundToInt(result); | |
82 return pinToByte(res); | |
83 } | |
84 | |
85 static int blend(int src, int dst, int scale) { | |
86 return dst + ((src - dst) * scale >> 8); | |
87 } | |
88 | |
89 void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], | 67 void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], |
90 int count, const SkAlpha aaCoverage[]) const { | 68 int count, const SkAlpha aaCoverage[]) const { |
91 SkScalar k1 = fK[0] / 255; | 69 const Sk4f k1 = fK[0] * (1/255.0f), |
92 SkScalar k2 = fK[1]; | 70 k2 = fK[1], |
93 SkScalar k3 = fK[2]; | 71 k3 = fK[2], |
94 SkScalar k4 = fK[3] * 255; | 72 k4 = fK[3] * 255.0f + 0.5f; |
95 | 73 |
96 for (int i = 0; i < count; ++i) { | 74 auto pin = [](float min, const Sk4f& val, float max) { |
97 if ((nullptr == aaCoverage) || aaCoverage[i]) { | 75 return Sk4f::Max(min, Sk4f::Min(val, max)); |
98 SkPMColor sc = src[i]; | 76 }; |
99 SkPMColor dc = dst[i]; | |
100 | 77 |
101 int a, r, g, b; | 78 for (int i = 0; i < count; i++) { |
| 79 if (aaCoverage && aaCoverage[i] == 0) { |
| 80 continue; |
| 81 } |
102 | 82 |
103 a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc)); | 83 Sk4f s = SkNx_cast<float>(Sk4b::Load(src+i)), |
104 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)); | 84 d = SkNx_cast<float>(Sk4b::Load(dst+i)), |
105 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)); | 85 r = pin(0, k1*s*d + k2*s + k3*d + k4, 255); |
106 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)); | |
107 if (fEnforcePMColor) { | |
108 r = SkMin32(r, a); | |
109 g = SkMin32(g, a); | |
110 b = SkMin32(b, a); | |
111 } | |
112 | 86 |
113 // apply antialias coverage if necessary | 87 if (fEnforcePMColor) { |
114 if (aaCoverage && 0xFF != aaCoverage[i]) { | 88 Sk4f a = SkNx_shuffle<3,3,3,3>(r); |
115 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); | 89 r = Sk4f::Min(a, r); |
116 a = blend(a, SkGetPackedA32(sc), scale); | 90 } |
117 r = blend(r, SkGetPackedR32(sc), scale); | |
118 g = blend(g, SkGetPackedG32(sc), scale); | |
119 b = blend(b, SkGetPackedB32(sc), scale); | |
120 } | |
121 | 91 |
122 dst[i] = fEnforcePMColor ? SkPackARGB32(a, r, g, b) : SkPackARGB32No
Check(a, r, g, b); | 92 if (aaCoverage && aaCoverage[i] != 255) { |
| 93 Sk4f c = aaCoverage[i] * (1/255.0f); |
| 94 r = d + (r-d)*c; |
123 } | 95 } |
| 96 |
| 97 SkNx_cast<uint8_t>(r).store(dst+i); |
124 } | 98 } |
125 } | 99 } |
126 | 100 |
127 #ifndef SK_IGNORE_TO_STRING | 101 #ifndef SK_IGNORE_TO_STRING |
128 void SkArithmeticMode_scalar::toString(SkString* str) const { | 102 void SkArithmeticMode_scalar::toString(SkString* str) const { |
129 str->append("SkArithmeticMode_scalar: "); | 103 str->append("SkArithmeticMode_scalar: "); |
130 for (int i = 0; i < 4; ++i) { | 104 for (int i = 0; i < 4; ++i) { |
131 str->appendScalar(fK[i]); | 105 str->appendScalar(fK[i]); |
132 str->append(" "); | 106 str->append(" "); |
133 } | 107 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 SkScalarToFloat(fK[2]), | 143 SkScalarToFloat(fK[2]), |
170 SkScalarToFloat(fK[3]), | 144 SkScalarToFloat(fK[3]), |
171 fEnforcePMColor); | 145 fEnforcePMColor); |
172 } | 146 } |
173 | 147 |
174 #endif | 148 #endif |
175 | 149 |
176 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) | 150 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) |
177 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) | 151 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) |
178 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 152 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |