Chromium Code Reviews| 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 |