Index: src/opts/SkColorCubeFilter_opts.h |
diff --git a/src/opts/SkColorCubeFilter_opts.h b/src/opts/SkColorCubeFilter_opts.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..325d7aa6498fccbb7a82b5501b64f9eff5e5239e |
--- /dev/null |
+++ b/src/opts/SkColorCubeFilter_opts.h |
@@ -0,0 +1,85 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef SkColorCubeFilter_opts_DEFINED |
+#define SkColorCubeFilter_opts_DEFINED |
+ |
+#include "SkColor.h" |
+#include "SkPMFloat.h" |
+#include "SkUnPreMultiply.h" |
+ |
+namespace SK_OPTS_NS { |
+ |
+void color_cube_filter_span(const SkPMColor src[], |
+ int count, |
+ SkPMColor dst[], |
+ const int* colorToIndex[2], |
+ const SkScalar* colorToFactors[2], |
+ int dim, |
+ const SkColor* colorCube) { |
+ uint8_t* ptr_dst = reinterpret_cast<uint8_t*>(dst); |
+ uint8_t r, g, b, a; |
+ |
+ for (int i = 0; i < count; ++i) { |
+ const SkPMColor input = src[i]; |
+ a = input >> SK_A32_SHIFT; |
+ |
+ if (a != 255) { |
+ const SkColor source = SkUnPreMultiply::PMColorToColor(input); |
+ r = SkColorGetR(source); |
+ g = SkColorGetG(source); |
+ b = SkColorGetB(source); |
+ } else { |
+ r = SkGetPackedR32(input); |
+ g = SkGetPackedG32(input); |
+ b = SkGetPackedB32(input); |
+ } |
+ |
+ const SkScalar g0 = colorToFactors[0][g], |
+ g1 = colorToFactors[1][g], |
+ b0 = colorToFactors[0][b], |
+ b1 = colorToFactors[1][b]; |
+ |
+ const Sk4f g0b0(g0*b0), |
+ g0b1(g0*b1), |
+ g1b0(g1*b0), |
+ g1b1(g1*b1); |
+ |
+ const int i00 = (colorToIndex[0][g] + colorToIndex[0][b] * dim) * dim; |
+ const int i01 = (colorToIndex[0][g] + colorToIndex[1][b] * dim) * dim; |
+ const int i10 = (colorToIndex[1][g] + colorToIndex[0][b] * dim) * dim; |
+ const int i11 = (colorToIndex[1][g] + colorToIndex[1][b] * dim) * dim; |
+ |
+ SkPMFloat color(0); |
+ |
+ for (int x = 0; x < 2; ++x) { |
+ const int ix = colorToIndex[x][r]; |
+ |
+ const SkColor lutColor00 = colorCube[ix + i00]; |
+ const SkColor lutColor01 = colorCube[ix + i01]; |
+ const SkColor lutColor10 = colorCube[ix + i10]; |
+ const SkColor lutColor11 = colorCube[ix + i11]; |
+ |
+ Sk4f sum = SkPMFloat::FromBGRx(lutColor00) * g0b0; |
+ sum = sum + SkPMFloat::FromBGRx(lutColor01) * g0b1; |
+ sum = sum + SkPMFloat::FromBGRx(lutColor10) * g1b0; |
+ sum = sum + SkPMFloat::FromBGRx(lutColor11) * g1b1; |
+ |
+ color = color + sum * Sk4f((float)colorToFactors[x][r]); |
+ } |
+ |
+ if (a != 255) { |
+ color = color * Sk4f(((float)a) / 255); |
Noel Gordon
2015/08/19 01:02:59
I think clang will generate a DIV instruction in t
mtklein
2015/08/19 01:58:22
Yep, looks like I overlooked this. Looks like it
|
+ } |
+ |
+ dst[i] = color.round(); |
+ |
+ ptr_dst[SK_A32_SHIFT / 8] = a; |
+ ptr_dst += 4; |
+ } |
+} |
+ |
+} // namespace SK_OPTS NS |
+ |
+#endif // SkColorCubeFilter_opts_DEFINED |