aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkRasterPipeline.h8
-rw-r--r--src/core/SkXfermode.cpp2
-rw-r--r--src/image/SkImageShader.cpp2
-rw-r--r--src/opts/SkRasterPipeline_opts.h157
4 files changed, 67 insertions, 102 deletions
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index 3f146be493..daf4b78b42 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -56,8 +56,9 @@
#define SK_RASTER_PIPELINE_STAGES(M) \
M(trace) M(registers) \
- M(move_src_dst) M(swap_src_dst) \
- M(clamp_0) M(clamp_a) M(clamp_1) M(unpremul) M(premul) \
+ M(move_src_dst) M(move_dst_src) M(swap_rb) \
+ M(clamp_0) M(clamp_a) M(clamp_1) \
+ M(unpremul) M(premul) \
M(constant_color) M(store_f32) \
M(load_s_565) M(load_d_565) M(store_565) \
M(load_s_srgb) M(load_d_srgb) M(store_srgb) \
@@ -65,7 +66,6 @@
M(load_s_8888) M(store_8888) \
M(scale_u8) M(scale_constant_float) \
M(lerp_u8) M(lerp_565) M(lerp_constant_float) \
- M(dst) \
M(dstatop) M(dstin) M(dstout) M(dstover) \
M(srcatop) M(srcin) M(srcout) M(srcover) \
M(clear) M(modulate) M(multiply) M(plus_) M(screen) M(xor_) \
@@ -76,7 +76,7 @@
M(matrix_perspective) \
M(parametric_r) M(parametric_g) M(parametric_b) \
M(table_r) M(table_g) M(table_b) \
- M(color_lookup_table) M(lab_to_xyz) M(swap_rb) \
+ M(color_lookup_table) M(lab_to_xyz) \
M(clamp_x) M(mirror_x) M(repeat_x) \
M(clamp_y) M(mirror_y) M(repeat_y) \
M(accum_f16) M(accum_a8) \
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index eb27f69d26..9c1ae4495d 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -1489,7 +1489,7 @@ bool SkBlendMode_AppendStages(SkBlendMode mode, SkRasterPipeline* p) {
switch (mode) {
case SkBlendMode::kClear: stage = SkRasterPipeline::clear; break;
case SkBlendMode::kSrc: return true; // This stage is a no-op.
- case SkBlendMode::kDst: stage = SkRasterPipeline::dst; break;
+ case SkBlendMode::kDst: stage = SkRasterPipeline::move_dst_src; break;
case SkBlendMode::kSrcOver: stage = SkRasterPipeline::srcover; break;
case SkBlendMode::kDstOver: stage = SkRasterPipeline::dstover; break;
case SkBlendMode::kSrcIn: stage = SkRasterPipeline::srcin; break;
diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp
index 552123615a..873e517e49 100644
--- a/src/image/SkImageShader.cpp
+++ b/src/image/SkImageShader.cpp
@@ -393,7 +393,7 @@ bool SkImageShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkFal
append_tiling_and_accum();
}
- p->append(SkRasterPipeline::dst);
+ p->append(SkRasterPipeline::move_dst_src);
if (info.colorType() == kBGRA_8888_SkColorType) {
p->append(SkRasterPipeline::swap_rb);
}
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index c6fbe6938a..6033952ea8 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -30,7 +30,8 @@ namespace {
#endif
using SkNf = SkNx<N, float>;
- using SkNi = SkNx<N, int>;
+ using SkNi = SkNx<N, int32_t>;
+ using SkNu = SkNx<N, uint32_t>;
using SkNh = SkNx<N, uint16_t>;
using SkNb = SkNx<N, uint8_t>;
@@ -184,6 +185,14 @@ SI void store(size_t tail, const SkNx<N,T>& v, T* dst) {
v.store(dst);
}
+SI void from_8888(const SkNu& _8888, SkNf* r, SkNf* g, SkNf* b, SkNf* a) {
+ auto to_float = [](const SkNu& v) { return SkNx_cast<float>(SkNi::Load(&v)); };
+ *r = (1/255.0f)*to_float((_8888 >> 0) & 0xff);
+ *g = (1/255.0f)*to_float((_8888 >> 8) & 0xff);
+ *b = (1/255.0f)*to_float((_8888 >> 16) & 0xff);
+ *a = (1/255.0f)*to_float( _8888 >> 24 );
+}
+
SI void from_4444(const SkNh& _4444, SkNf* r, SkNf* g, SkNf* b, SkNf* a) {
auto _32_bit = SkNx_cast<int>(_4444);
@@ -271,13 +280,18 @@ STAGE(move_src_dst, true) {
da = a;
}
-STAGE(swap_src_dst, true) {
- SkTSwap(r, dr);
- SkTSwap(g, dg);
- SkTSwap(b, db);
- SkTSwap(a, da);
+STAGE(move_dst_src, true) {
+ r = dr;
+ g = dg;
+ b = db;
+ a = da;
}
+STAGE(swap_rb, true) {
+ SkTSwap(r, b);
+}
+
+
// The default shader produces a constant color (from the SkPaint).
STAGE(constant_color, true) {
auto color = (const SkPM4f*)ctx;
@@ -483,13 +497,7 @@ STAGE(store_srgb, false) {
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));
+ from_8888(load<kIsTail>(tail, ptr), &r, &g, &b, &a);
}
STAGE(store_8888, false) {
@@ -689,10 +697,6 @@ STAGE(lab_to_xyz, true) {
b = Z;
}
-STAGE(swap_rb, true) {
- SkTSwap(r, b);
-}
-
SI SkNf assert_in_tile(const SkNf& v, float limit) {
for (int i = 0; i < N; i++) {
SkASSERT(0 <= v[i] && v[i] < limit);
@@ -786,6 +790,13 @@ SI SkNi offset_and_ptr(T** ptr, const void* ctx, const SkNf& x, const SkNf& y) {
return offset;
}
+template <typename T>
+SI void gather(T (&dst)[N], const T* src, const SkNi& offset, size_t tail) {
+ size_t n = tail ? tail : N;
+ for (size_t i = 0; i < n; i++) { dst[i] = src[offset[i]]; }
+ for (size_t i = n; i < N; i++) { dst[i] = 0; }
+}
+
STAGE(accum_a8, true) {} // TODO
STAGE(accum_i8, true) {} // TODO
@@ -796,13 +807,7 @@ STAGE(accum_g8, true) {
SkNi offset = offset_and_ptr(&p, ctx, r, g);
uint8_t px[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- px[i] = 0;
- continue;
- }
- px[i] = p[offset[i]];
- }
+ gather(px, p, offset, tail);
SkNf gray = SkNx_cast<float>(SkNb::Load(px)) * (1/255.0f);
@@ -817,13 +822,7 @@ STAGE(accum_g8_srgb, true) {
SkNi offset = offset_and_ptr(&p, ctx, r, g);
uint8_t px[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- px[i] = 0;
- continue;
- }
- px[i] = p[offset[i]];
- }
+ gather(px, p, offset, tail);
SkNf gray = sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(px)));
@@ -839,13 +838,8 @@ STAGE(accum_565, true) {
SkNi offset = offset_and_ptr(&p, ctx, r, g);
uint16_t px[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- px[i] = 0;
- continue;
- }
- px[i] = p[offset[i]];
- }
+ gather(px, p, offset, tail);
+
SkNf R,G,B;
from_565(SkNh::Load(px), &R, &G, &B);
@@ -860,13 +854,8 @@ STAGE(accum_565_srgb, true) {
SkNi offset = offset_and_ptr(&p, ctx, r, g);
uint16_t px[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- px[i] = 0;
- continue;
- }
- px[i] = p[offset[i]];
- }
+ gather(px, p, offset, tail);
+
SkNf R,G,B;
from_565(SkNh::Load(px), &R, &G, &B);
@@ -882,13 +871,7 @@ STAGE(accum_4444, true) {
SkNi offset = offset_and_ptr(&p, ctx, r, g);
uint16_t px[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- px[i] = 0;
- continue;
- }
- px[i] = p[offset[i]];
- }
+ gather(px, p, offset, tail);
SkNf R,G,B,A;
from_4444(SkNh::Load(px), &R, &G, &B, &A);
@@ -904,13 +887,7 @@ STAGE(accum_4444_srgb, true) {
SkNi offset = offset_and_ptr(&p, ctx, r, g);
uint16_t px[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- px[i] = 0;
- continue;
- }
- px[i] = p[offset[i]];
- }
+ gather(px, p, offset, tail);
SkNf R,G,B,A;
from_4444(SkNh::Load(px), &R, &G, &B, &A);
@@ -926,65 +903,53 @@ STAGE(accum_8888, true) {
const uint32_t* p;
SkNi offset = offset_and_ptr(&p, ctx, r, g);
- uint8_t R[N], G[N], B[N], A[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- R[i] = G[i] = B[i] = A[i] = 0;
- continue;
- }
- uint32_t rgba = p[offset[i]];
- R[i] = rgba >> 0;
- G[i] = rgba >> 8;
- B[i] = rgba >> 16;
- A[i] = rgba >> 24;
- }
+ uint32_t px[N];
+ gather(px, p, offset, tail);
+
+ SkNf R,G,B,A;
+ from_8888(SkNu::Load(px), &R, &G, &B, &A);
SkNf scale = b;
- dr += scale * SkNx_cast<float>(SkNb::Load(R)) * (1/255.0f);
- dg += scale * SkNx_cast<float>(SkNb::Load(G)) * (1/255.0f);
- db += scale * SkNx_cast<float>(SkNb::Load(B)) * (1/255.0f);
- da += scale * SkNx_cast<float>(SkNb::Load(A)) * (1/255.0f);
+ dr += scale * R;
+ dg += scale * G;
+ db += scale * B;
+ da += scale * A;
}
STAGE(accum_8888_srgb, true) {
const uint32_t* p;
SkNi offset = offset_and_ptr(&p, ctx, r, g);
- uint8_t R[N], G[N], B[N], A[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- R[i] = G[i] = B[i] = A[i] = 0;
- continue;
- }
- uint32_t rgba = p[offset[i]];
- R[i] = rgba >> 0;
- G[i] = rgba >> 8;
- B[i] = rgba >> 16;
- A[i] = rgba >> 24;
- }
+ uint32_t px[N];
+ gather(px, p, offset, tail);
+
+ SkNf R,G,B,A;
+ from_8888(SkNu::Load(px), &R, &G, &B, &A);
SkNf scale = b;
- dr += scale * sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(R)));
- dg += scale * sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(G)));
- db += scale * sk_linear_from_srgb_math(SkNx_cast<int>(SkNb::Load(B)));
- da += scale * SkNx_cast<float>(SkNb::Load(A)) * (1/255.0f);
+ dr += scale * sk_linear_from_srgb_math(R);
+ dg += scale * sk_linear_from_srgb_math(G);
+ db += scale * sk_linear_from_srgb_math(B);
+ da += scale * A;
}
STAGE(accum_f16, true) {
const uint64_t* p;
SkNi offset = offset_and_ptr(&p, ctx, r, g);
+ // f16 -> f32 conversion works best with tightly packed f16s,
+ // so we gather each component rather than using gather().
uint16_t R[N], G[N], B[N], A[N];
- for (size_t i = 0; i < N; i++) {
- if (kIsTail && i >= tail) {
- R[i] = G[i] = B[i] = A[i] = 0;
- continue;
- }
+ size_t n = tail ? tail : N;
+ for (size_t i = 0; i < n; i++) {
uint64_t rgba = p[offset[i]];
R[i] = rgba >> 0;
G[i] = rgba >> 16;
B[i] = rgba >> 32;
A[i] = rgba >> 48;
}
+ for (size_t i = n; i < N; i++) {
+ R[i] = G[i] = B[i] = A[i] = 0;
+ }
SkNf scale = b;
dr += scale * SkHalfToFloat_finite_ftz(SkNh::Load(R));
dg += scale * SkHalfToFloat_finite_ftz(SkNh::Load(G));