| Index: src/opts/SkColorXform_opts.h
|
| diff --git a/src/opts/SkColorXform_opts.h b/src/opts/SkColorXform_opts.h
|
| index 9904b3ef93f071f56c634989f63e318af01141f7..30bf164cbe9e63f0528d9983c00f65ebcb39f2a3 100644
|
| --- a/src/opts/SkColorXform_opts.h
|
| +++ b/src/opts/SkColorXform_opts.h
|
| @@ -12,8 +12,6 @@
|
| #include "SkColorPriv.h"
|
| #include "SkSRGB.h"
|
|
|
| -extern const float sk_linear_from_2dot2[256];
|
| -
|
| namespace SK_OPTS_NS {
|
|
|
| static Sk4f linear_to_2dot2(const Sk4f& x) {
|
| @@ -32,28 +30,35 @@ static Sk4f clamp_0_to_255(const Sk4f& x) {
|
| return Sk4f::Min(Sk4f::Max(x, 0.0f), 255.0f);
|
| }
|
|
|
| -template <const float (&linear_from_curve)[256], Sk4f (*linear_to_curve)(const Sk4f&)>
|
| +enum DstGamma {
|
| + kSRGB_DstGamma,
|
| + k2Dot2_DstGamma,
|
| + kTable_DstGamma,
|
| +};
|
| +
|
| +template <DstGamma kDstGamma>
|
| static void color_xform_RGB1(uint32_t* dst, const uint32_t* src, int len,
|
| - const float matrix[16]) {
|
| + const float* const srcTables[3], const float matrix[16],
|
| + const uint8_t* const dstTables[3]) {
|
| Sk4f rXgXbX = Sk4f::Load(matrix + 0),
|
| rYgYbY = Sk4f::Load(matrix + 4),
|
| rZgZbZ = Sk4f::Load(matrix + 8);
|
|
|
| if (len >= 4) {
|
| Sk4f reds, greens, blues;
|
| - auto load_next_4 = [&reds, &greens, &blues, &src, &len] {
|
| - reds = Sk4f{linear_from_curve[(src[0] >> 0) & 0xFF],
|
| - linear_from_curve[(src[1] >> 0) & 0xFF],
|
| - linear_from_curve[(src[2] >> 0) & 0xFF],
|
| - linear_from_curve[(src[3] >> 0) & 0xFF]};
|
| - greens = Sk4f{linear_from_curve[(src[0] >> 8) & 0xFF],
|
| - linear_from_curve[(src[1] >> 8) & 0xFF],
|
| - linear_from_curve[(src[2] >> 8) & 0xFF],
|
| - linear_from_curve[(src[3] >> 8) & 0xFF]};
|
| - blues = Sk4f{linear_from_curve[(src[0] >> 16) & 0xFF],
|
| - linear_from_curve[(src[1] >> 16) & 0xFF],
|
| - linear_from_curve[(src[2] >> 16) & 0xFF],
|
| - linear_from_curve[(src[3] >> 16) & 0xFF]};
|
| + auto load_next_4 = [&reds, &greens, &blues, &src, &len, &srcTables] {
|
| + reds = Sk4f{srcTables[0][(src[0] >> 0) & 0xFF],
|
| + srcTables[0][(src[1] >> 0) & 0xFF],
|
| + srcTables[0][(src[2] >> 0) & 0xFF],
|
| + srcTables[0][(src[3] >> 0) & 0xFF]};
|
| + greens = Sk4f{srcTables[1][(src[0] >> 8) & 0xFF],
|
| + srcTables[1][(src[1] >> 8) & 0xFF],
|
| + srcTables[1][(src[2] >> 8) & 0xFF],
|
| + srcTables[1][(src[3] >> 8) & 0xFF]};
|
| + blues = Sk4f{srcTables[2][(src[0] >> 16) & 0xFF],
|
| + srcTables[2][(src[1] >> 16) & 0xFF],
|
| + srcTables[2][(src[2] >> 16) & 0xFF],
|
| + srcTables[2][(src[3] >> 16) & 0xFF]};
|
| src += 4;
|
| len -= 4;
|
| };
|
| @@ -66,20 +71,51 @@ static void color_xform_RGB1(uint32_t* dst, const uint32_t* src, int len,
|
| dstBlues = rXgXbX[2]*reds + rYgYbY[2]*greens + rZgZbZ[2]*blues;
|
| };
|
|
|
| - auto store_4 = [&dstReds, &dstGreens, &dstBlues, &dst] {
|
| - dstReds = linear_to_curve(dstReds);
|
| - dstGreens = linear_to_curve(dstGreens);
|
| - dstBlues = linear_to_curve(dstBlues);
|
| -
|
| - dstReds = clamp_0_to_255(dstReds);
|
| - dstGreens = clamp_0_to_255(dstGreens);
|
| - dstBlues = clamp_0_to_255(dstBlues);
|
| + auto store_4 = [&dstReds, &dstGreens, &dstBlues, &dst, &dstTables] {
|
| + if (kSRGB_DstGamma == kDstGamma || k2Dot2_DstGamma == kDstGamma) {
|
| + Sk4f (*linear_to_curve)(const Sk4f&) =
|
| + (kSRGB_DstGamma == kDstGamma) ? sk_linear_to_srgb : linear_to_2dot2;
|
| +
|
| + dstReds = linear_to_curve(dstReds);
|
| + dstGreens = linear_to_curve(dstGreens);
|
| + dstBlues = linear_to_curve(dstBlues);
|
| +
|
| + dstReds = clamp_0_to_255(dstReds);
|
| + dstGreens = clamp_0_to_255(dstGreens);
|
| + dstBlues = clamp_0_to_255(dstBlues);
|
| +
|
| + auto rgba = (SkNx_cast<int>(dstReds) )
|
| + | (SkNx_cast<int>(dstGreens) << 8)
|
| + | (SkNx_cast<int>(dstBlues) << 16)
|
| + | (Sk4i{ 0xFF << 24});
|
| + rgba.store(dst);
|
| + } else {
|
| + Sk4f scaledReds = Sk4f::Min(Sk4f::Max(1023.0f * dstReds, 0.0f), 1023.0f);
|
| + Sk4f scaledGreens = Sk4f::Min(Sk4f::Max(1023.0f * dstGreens, 0.0f), 1023.0f);
|
| + Sk4f scaledBlues = Sk4f::Min(Sk4f::Max(1023.0f * dstBlues, 0.0f), 1023.0f);
|
| +
|
| + Sk4i indicesReds = SkNx_cast<int>(scaledReds + 0.5f);
|
| + Sk4i indicesGreens = SkNx_cast<int>(scaledGreens + 0.5f);
|
| + Sk4i indicesBlues = SkNx_cast<int>(scaledBlues + 0.5f);
|
| +
|
| + dst[0] = dstTables[0][indicesReds [0]]
|
| + | dstTables[1][indicesGreens[0]] << 8
|
| + | dstTables[2][indicesBlues [0]] << 16
|
| + | 0xFF << 24;
|
| + dst[1] = dstTables[0][indicesReds [1]]
|
| + | dstTables[1][indicesGreens[1]] << 8
|
| + | dstTables[2][indicesBlues [1]] << 16
|
| + | 0xFF << 24;
|
| + dst[2] = dstTables[0][indicesReds [2]]
|
| + | dstTables[1][indicesGreens[2]] << 8
|
| + | dstTables[2][indicesBlues [2]] << 16
|
| + | 0xFF << 24;
|
| + dst[3] = dstTables[0][indicesReds [3]]
|
| + | dstTables[1][indicesGreens[3]] << 8
|
| + | dstTables[2][indicesBlues [3]] << 16
|
| + | 0xFF << 24;
|
| + }
|
|
|
| - auto rgba = (Sk4i{(int)0xFF000000} )
|
| - | (SkNx_cast<int>(dstReds) )
|
| - | (SkNx_cast<int>(dstGreens) << 8)
|
| - | (SkNx_cast<int>(dstBlues) << 16);
|
| - rgba.store(dst);
|
| dst += 4;
|
| };
|
|
|
| @@ -97,24 +133,35 @@ static void color_xform_RGB1(uint32_t* dst, const uint32_t* src, int len,
|
|
|
| while (len > 0) {
|
| // Splat r,g,b across a register each.
|
| - auto r = Sk4f{linear_from_curve[(*src >> 0) & 0xFF]},
|
| - g = Sk4f{linear_from_curve[(*src >> 8) & 0xFF]},
|
| - b = Sk4f{linear_from_curve[(*src >> 16) & 0xFF]};
|
| + auto r = Sk4f{srcTables[0][(*src >> 0) & 0xFF]},
|
| + g = Sk4f{srcTables[1][(*src >> 8) & 0xFF]},
|
| + b = Sk4f{srcTables[2][(*src >> 16) & 0xFF]};
|
|
|
| // Apply transformation matrix to dst gamut.
|
| auto dstPixel = rXgXbX*r + rYgYbY*g + rZgZbZ*b;
|
|
|
| - // Convert to dst gamma.
|
| - dstPixel = linear_to_curve(dstPixel);
|
| + if (kSRGB_DstGamma == kDstGamma || k2Dot2_DstGamma == kDstGamma) {
|
| + Sk4f (*linear_to_curve)(const Sk4f&) =
|
| + (kSRGB_DstGamma == kDstGamma) ? sk_linear_to_srgb : linear_to_2dot2;
|
| +
|
| + dstPixel = linear_to_curve(dstPixel);
|
| +
|
| + dstPixel = clamp_0_to_255(dstPixel);
|
|
|
| - // Clamp floats to byte range.
|
| - dstPixel = clamp_0_to_255(dstPixel);
|
| + uint32_t rgba;
|
| + SkNx_cast<uint8_t>(dstPixel).store(&rgba);
|
| + rgba |= 0xFF000000;
|
| + *dst = rgba;
|
| + } else {
|
| + Sk4f scaledPixel = Sk4f::Min(Sk4f::Max(1023.0f * dstPixel, 0.0f), 1023.0f);
|
|
|
| - // Convert to bytes and store to memory.
|
| - uint32_t rgba;
|
| - SkNx_cast<uint8_t>(dstPixel).store(&rgba);
|
| - rgba |= 0xFF000000;
|
| - *dst = rgba;
|
| + Sk4i indices = SkNx_cast<int>(scaledPixel + 0.5f);
|
| +
|
| + *dst = dstTables[0][indices[0]]
|
| + | dstTables[1][indices[1]] << 8
|
| + | dstTables[2][indices[2]] << 16
|
| + | 0xFF << 24;
|
| + }
|
|
|
| dst += 1;
|
| src += 1;
|
| @@ -122,24 +169,20 @@ static void color_xform_RGB1(uint32_t* dst, const uint32_t* src, int len,
|
| }
|
| }
|
|
|
| -static void color_xform_RGB1_srgb_to_2dot2(uint32_t* dst, const uint32_t* src, int len,
|
| - const float matrix[16]) {
|
| - color_xform_RGB1<sk_linear_from_srgb, linear_to_2dot2>(dst, src, len, matrix);
|
| -}
|
| -
|
| -static void color_xform_RGB1_2dot2_to_2dot2(uint32_t* dst, const uint32_t* src, int len,
|
| - const float matrix[16]) {
|
| - color_xform_RGB1<sk_linear_from_2dot2, linear_to_2dot2>(dst, src, len, matrix);
|
| +static void color_xform_RGB1_to_2dot2(uint32_t* dst, const uint32_t* src, int len,
|
| + const float* const srcTables[3], const float matrix[16]) {
|
| + color_xform_RGB1<k2Dot2_DstGamma>(dst, src, len, srcTables, matrix, nullptr);
|
| }
|
|
|
| -static void color_xform_RGB1_srgb_to_srgb(uint32_t* dst, const uint32_t* src, int len,
|
| - const float matrix[16]) {
|
| - color_xform_RGB1<sk_linear_from_srgb, sk_linear_to_srgb>(dst, src, len, matrix);
|
| +static void color_xform_RGB1_to_srgb(uint32_t* dst, const uint32_t* src, int len,
|
| + const float* const srcTables[3], const float matrix[16]) {
|
| + color_xform_RGB1<kSRGB_DstGamma>(dst, src, len, srcTables, matrix, nullptr);
|
| }
|
|
|
| -static void color_xform_RGB1_2dot2_to_srgb(uint32_t* dst, const uint32_t* src, int len,
|
| - const float matrix[16]) {
|
| - color_xform_RGB1<sk_linear_from_2dot2, sk_linear_to_srgb>(dst, src, len, matrix);
|
| +static void color_xform_RGB1_to_table(uint32_t* dst, const uint32_t* src, int len,
|
| + const float* const srcTables[3], const float matrix[16],
|
| + const uint8_t* const dstTables[3]) {
|
| + color_xform_RGB1<kTable_DstGamma>(dst, src, len, srcTables, matrix, dstTables);
|
| }
|
|
|
| } // namespace SK_OPTS_NS
|
|
|