| Index: src/opts/SkRasterPipeline_opts.h
|
| diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
|
| index 5c5418be1a44d6d6ece160e288467828f10a75a5..a687627cde01cd58e8d73d4b5f932a4ebd077663 100644
|
| --- a/src/opts/SkRasterPipeline_opts.h
|
| +++ b/src/opts/SkRasterPipeline_opts.h
|
| @@ -9,6 +9,7 @@
|
| #define SkRasterPipeline_opts_DEFINED
|
|
|
| #include "SkColorPriv.h"
|
| +#include "SkColorLookUpTable.h"
|
| #include "SkHalf.h"
|
| #include "SkPM4f.h"
|
| #include "SkPM4fPriv.h"
|
| @@ -431,6 +432,25 @@ STAGE(store_srgb, false) {
|
| | SkNx_cast<int>(0.5f + 255.0f * a) << SK_A32_SHIFT), (int*)ptr);
|
| }
|
|
|
| +STAGE(load_s_8888, true) {
|
| + auto ptr = *(const uint32_t**)ctx + x;
|
| +
|
| + auto px = load<kIsTail>(tail, ptr);
|
| + auto to_int = [](const SkNx<N, uint32_t>& v) { return SkNi::Load(&v); };
|
| + r = (1/255.0f)*SkNx_cast<float>(to_int((px >> 0) & 0xff));
|
| + g = (1/255.0f)*SkNx_cast<float>(to_int((px >> 8) & 0xff));
|
| + b = (1/255.0f)*SkNx_cast<float>(to_int((px >> 16) & 0xff));
|
| + a = (1/255.0f)*SkNx_cast<float>(to_int(px >> 24));
|
| +}
|
| +
|
| +STAGE(store_8888, false) {
|
| + auto ptr = *(uint32_t**)ctx + x;
|
| + store<kIsTail>(tail, ( SkNx_cast<int>(255.0f * r + 0.5f) << 0
|
| + | SkNx_cast<int>(255.0f * g + 0.5f) << 8
|
| + | SkNx_cast<int>(255.0f * b + 0.5f) << 16
|
| + | SkNx_cast<int>(255.0f * a + 0.5f) << 24 ), (int*)ptr);
|
| +}
|
| +
|
| RGBA_XFERMODE(clear) { return 0.0f; }
|
| //RGBA_XFERMODE(src) { return s; } // This would be a no-op stage, so we just omit it.
|
| RGBA_XFERMODE(dst) { return d; }
|
| @@ -490,6 +510,18 @@ STAGE(luminance_to_alpha, true) {
|
| r = g = b = 0;
|
| }
|
|
|
| +STAGE(matrix_3x4, true) {
|
| + auto m = (const float*)ctx;
|
| +
|
| + auto fma = [](const SkNf& f, const SkNf& m, const SkNf& a) { return SkNx_fma(f,m,a); };
|
| + auto R = fma(r,m[0], fma(g,m[3], fma(b,m[6], m[ 9]))),
|
| + G = fma(r,m[1], fma(g,m[4], fma(b,m[7], m[10]))),
|
| + B = fma(r,m[2], fma(g,m[5], fma(b,m[8], m[11])));
|
| + r = R;
|
| + g = G;
|
| + b = B;
|
| +}
|
| +
|
| STAGE(matrix_4x5, true) {
|
| auto m = (const float*)ctx;
|
|
|
| @@ -504,6 +536,80 @@ STAGE(matrix_4x5, true) {
|
| a = A;
|
| }
|
|
|
| +STAGE(fn_1_r, true) {
|
| + auto fn = (const std::function<float(float)>*)ctx;
|
| + float result[N];
|
| + for (int i = 0; i < N; ++i) {
|
| + result[i] = (*fn)(r[i]);
|
| + }
|
| + r = SkNf::Load(result);
|
| +}
|
| +
|
| +STAGE(fn_1_g, true) {
|
| + auto fn = (const std::function<float(float)>*)ctx;
|
| + float result[N];
|
| + for (int i = 0; i < N; ++i) {
|
| + result[i] = (*fn)(g[i]);
|
| + }
|
| + g = SkNf::Load(result);
|
| +}
|
| +
|
| +STAGE(fn_1_b, true) {
|
| + auto fn = (const std::function<float(float)>*)ctx;
|
| + float result[N];
|
| + for (int i = 0; i < N; ++i) {
|
| + result[i] = (*fn)(b[i]);
|
| + }
|
| + b = SkNf::Load(result);
|
| +}
|
| +
|
| +STAGE(color_lookup_table, true) {
|
| + const SkColorLookUpTable* colorLUT = (const SkColorLookUpTable*)ctx;
|
| + float rgb[3];
|
| + float result[3][N];
|
| + for (int i = 0; i < N; ++i) {
|
| + rgb[0] = r[i];
|
| + rgb[1] = g[i];
|
| + rgb[2] = b[i];
|
| + colorLUT->interp3D(rgb, rgb);
|
| + result[0][i] = rgb[0];
|
| + result[1][i] = rgb[1];
|
| + result[2][i] = rgb[2];
|
| + }
|
| + r = SkNf::Load(result[0]);
|
| + g = SkNf::Load(result[1]);
|
| + b = SkNf::Load(result[2]);
|
| +}
|
| +
|
| +STAGE(lab_to_xyz, true) {
|
| + const auto lab_l = r * 100.0f;
|
| + const auto lab_a = g * 255.0f - 128.0f;
|
| + const auto lab_b = b * 255.0f - 128.0f;
|
| + auto Y = (lab_l + 16.0f) * (1/116.0f);
|
| + auto X = lab_a * (1/500.0f) + Y;
|
| + auto Z = Y - (lab_b * (1/200.0f));
|
| +
|
| + const auto X3 = X*X*X;
|
| + X = (X3 > 0.008856f).thenElse(X3, (X - (16/116.0f)) * (1/7.787f));
|
| + const auto Y3 = Y*Y*Y;
|
| + Y = (Y3 > 0.008856f).thenElse(Y3, (Y - (16/116.0f)) * (1/7.787f));
|
| + const auto Z3 = Z*Z*Z;
|
| + Z = (Z3 > 0.008856f).thenElse(Z3, (Z - (16/116.0f)) * (1/7.787f));
|
| +
|
| + // adjust to D50 illuminant
|
| + X *= 0.96422f;
|
| + Y *= 1.00000f;
|
| + Z *= 0.82521f;
|
| +
|
| + r = X;
|
| + g = Y;
|
| + b = Z;
|
| +}
|
| +
|
| +STAGE(swap_rb, true) {
|
| + SkTSwap(r, b);
|
| +}
|
| +
|
| template <typename Fn>
|
| SI Fn enum_to_Fn(SkRasterPipeline::StockStage st) {
|
| switch (st) {
|
|
|