From 6b77f1cf09f6a3c47a42e29dc28087ac9f9cdb25 Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Tue, 22 Nov 2016 15:50:12 -0500 Subject: [PATCH] 4444 and gray 8 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5147 CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot Change-Id: Id08804803b2bbeab4fa88538491e99e53d5c2efe Reviewed-on: https://skia-review.googlesource.com/5147 Reviewed-by: Herb Derby Commit-Queue: Mike Klein --- src/image/SkImageShader.cpp | 19 ++++-- src/opts/SkRasterPipeline_opts.h | 100 +++++++++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 10 deletions(-) diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp index ab4d76d108..552123615a 100644 --- a/src/image/SkImageShader.cpp +++ b/src/image/SkImageShader.cpp @@ -288,12 +288,10 @@ bool SkImageShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkFal // TODO: all formats switch (info.colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - case kRGB_565_SkColorType: - case kRGBA_F16_SkColorType: - break; - default: return false; + case kAlpha_8_SkColorType: + case kIndex_8_SkColorType: + return false; + default: break; } // When the matrix is just an integer translate, bilerp == nearest neighbor. @@ -348,6 +346,15 @@ bool SkImageShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkFal bool srgb = info.gammaCloseToSRGB() && dst != nullptr; switch (info.colorType()) { + case kGray_8_SkColorType: + p->append(srgb ? SkRasterPipeline::accum_g8_srgb + : SkRasterPipeline::accum_g8, ctx); + break; + + case kARGB_4444_SkColorType: + p->append(srgb ? SkRasterPipeline::accum_4444_srgb + : SkRasterPipeline::accum_4444, ctx); + break; case kRGB_565_SkColorType: p->append(srgb ? SkRasterPipeline::accum_565_srgb : SkRasterPipeline::accum_565, ctx); diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h index ba8883a7fb..c6fbe6938a 100644 --- a/src/opts/SkRasterPipeline_opts.h +++ b/src/opts/SkRasterPipeline_opts.h @@ -184,6 +184,15 @@ SI void store(size_t tail, const SkNx& v, T* dst) { v.store(dst); } +SI void from_4444(const SkNh& _4444, SkNf* r, SkNf* g, SkNf* b, SkNf* a) { + auto _32_bit = SkNx_cast(_4444); + + *r = SkNx_cast(_32_bit & (0xF << SK_R4444_SHIFT)) * (1.0f / (0xF << SK_R4444_SHIFT)); + *g = SkNx_cast(_32_bit & (0xF << SK_G4444_SHIFT)) * (1.0f / (0xF << SK_G4444_SHIFT)); + *b = SkNx_cast(_32_bit & (0xF << SK_B4444_SHIFT)) * (1.0f / (0xF << SK_B4444_SHIFT)); + *a = SkNx_cast(_32_bit & (0xF << SK_A4444_SHIFT)) * (1.0f / (0xF << SK_A4444_SHIFT)); +} + SI void from_565(const SkNh& _565, SkNf* r, SkNf* g, SkNf* b) { auto _32_bit = SkNx_cast(_565); @@ -779,11 +788,52 @@ SI SkNi offset_and_ptr(T** ptr, const void* ctx, const SkNf& x, const SkNf& y) { STAGE(accum_a8, true) {} // TODO -STAGE(accum_g8, true) {} // TODO -STAGE(accum_g8_srgb, true) {} // TODO STAGE(accum_i8, true) {} // TODO STAGE(accum_i8_srgb, true) {} // TODO +STAGE(accum_g8, true) { + const uint8_t* p; + 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]]; + } + + SkNf gray = SkNx_cast(SkNb::Load(px)) * (1/255.0f); + + SkNf scale = b; + dr += scale * gray; + dg += scale * gray; + db += scale * gray; + da += scale; +} +STAGE(accum_g8_srgb, true) { + const uint8_t* p; + 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]]; + } + + SkNf gray = sk_linear_from_srgb_math(SkNx_cast(SkNb::Load(px))); + + SkNf scale = b; + dr += scale * gray; + dg += scale * gray; + db += scale * gray; + da += scale; +} + STAGE(accum_565, true) { const uint16_t* p; SkNi offset = offset_and_ptr(&p, ctx, r, g); @@ -827,8 +877,50 @@ STAGE(accum_565_srgb, true) { da += scale; } -STAGE(accum_4444, true) {} // TODO -STAGE(accum_4444_srgb, true) {} // TODO +STAGE(accum_4444, true) { + const uint16_t* p; + 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]]; + } + + SkNf R,G,B,A; + from_4444(SkNh::Load(px), &R, &G, &B, &A); + + SkNf scale = b; + dr += scale * R; + dg += scale * G; + db += scale * B; + da += scale * A; +} +STAGE(accum_4444_srgb, true) { + const uint16_t* p; + 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]]; + } + + SkNf R,G,B,A; + from_4444(SkNh::Load(px), &R, &G, &B, &A); + + SkNf scale = b; + 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_8888, true) { const uint32_t* p;