diff options
author | Florin Malita <fmalita@chromium.org> | 2017-01-30 12:08:05 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-31 14:14:13 +0000 |
commit | 9206c76337cd349c769103e06af005edd0583a10 (patch) | |
tree | ecaa3b8f3e3039bee723749ef18853d09087a0b5 | |
parent | ac95c5fc93bfdf22999f9c9e1f0f1e18fea686cf (diff) |
SkRasterPipeline shader adapter
Reland of https://skia-review.googlesource.com/c/7615.
(lifted from https://skia-review.googlesource.com/c/7088/)
CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD
Change-Id: I797a2f0ae80209c8637875418e08d2fa03249672
Reviewed-on: https://skia-review.googlesource.com/7731
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Mike Reed <reed@google.com>
-rw-r--r-- | include/core/SkShader.h | 4 | ||||
-rw-r--r-- | src/core/SkRasterPipeline.h | 3 | ||||
-rw-r--r-- | src/core/SkShader.cpp | 38 | ||||
-rw-r--r-- | src/opts/SkNx_sse.h | 10 | ||||
-rw-r--r-- | src/opts/SkRasterPipeline_opts.h | 8 |
5 files changed, 59 insertions, 4 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h index a885f0b982..30a10dcc9f 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -503,9 +503,7 @@ protected: virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, const SkMatrix&, const SkPaint&, - const SkMatrix* /*local matrix*/) const { - return false; - } + const SkMatrix* /*local matrix*/) const; private: // This is essentially const, but not officially so it can be modified in diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h index 5143d523e4..2dd2c32a99 100644 --- a/src/core/SkRasterPipeline.h +++ b/src/core/SkRasterPipeline.h @@ -95,7 +95,8 @@ M(bicubic_n3y) M(bicubic_n1y) M(bicubic_p1y) M(bicubic_p3y) \ M(save_xy) M(accumulate) \ M(linear_gradient_2stops) \ - M(byte_tables) + M(byte_tables) \ + M(shader_adapter) class SkRasterPipeline { public: diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index 0e03fb7112..9e562c9276 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "SkArenaAlloc.h" #include "SkAtomics.h" #include "SkBitmapProcShader.h" #include "SkColorShader.h" @@ -13,9 +14,12 @@ #include "SkPaint.h" #include "SkPicture.h" #include "SkPictureShader.h" +#include "SkPM4fPriv.h" +#include "SkRasterPipeline.h" #include "SkReadBuffer.h" #include "SkScalar.h" #include "SkShader.h" +#include "SkTLazy.h" #include "SkWriteBuffer.h" #if SK_SUPPORT_GPU @@ -262,6 +266,40 @@ bool SkShader::appendStages(SkRasterPipeline* pipeline, return this->onAppendStages(pipeline, dst, scratch, ctm, paint, nullptr); } +bool SkShader::onAppendStages(SkRasterPipeline* p, + SkColorSpace* cs, + SkArenaAlloc* alloc, + const SkMatrix& ctm, + const SkPaint& paint, + const SkMatrix* localM) const { + // Legacy shaders handle the paint opacity internally, + // but RP applies it as a separate stage. + SkTCopyOnFirstWrite<SkPaint> opaquePaint(paint); + if (paint.getAlpha() != SK_AlphaOPAQUE) { + opaquePaint.writable()->setAlpha(SK_AlphaOPAQUE); + } + + ContextRec rec(*opaquePaint, ctm, localM, ContextRec::kPM4f_DstType, cs); + if (auto* ctx = this->createContext(rec, + alloc->makeArrayDefault<char>(this->contextSize(rec)))) { + struct ContextDestroyer { + ContextDestroyer(Context* ctx) : fContext(ctx) {} + ~ContextDestroyer() { fContext->~Context(); } + + Context* fContext; + }; + + alloc->make<ContextDestroyer>(ctx); + p->append(SkRasterPipeline::shader_adapter, ctx); + + // Legacy shaders aren't aware of color spaces. We can pretty + // safely assume they're in sRGB gamut. + return append_gamut_transform(p, alloc, + SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).get(), cs); + } + return false; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// sk_sp<SkFlattenable> SkEmptyShader::CreateProc(SkReadBuffer&) { diff --git a/src/opts/SkNx_sse.h b/src/opts/SkNx_sse.h index fe74a77545..e81872291e 100644 --- a/src/opts/SkNx_sse.h +++ b/src/opts/SkNx_sse.h @@ -623,6 +623,16 @@ public: _mm256_storeu_ps((float*)ptr + 2*8, _45); _mm256_storeu_ps((float*)ptr + 3*8, _67); } + AI static void Load4(const void* ptr, SkNx* r, SkNx* g, SkNx* b, SkNx* a) { + Sk4f rl, gl, bl, al, + rh, gh, bh, ah; + Sk4f::Load4((const float*)ptr + 0, &rl, &gl, &bl, &al); + Sk4f::Load4((const float*)ptr + 16, &rh, &gh, &bh, &ah); + *r = _mm256_setr_m128(rl.fVec, rh.fVec); + *g = _mm256_setr_m128(gl.fVec, gh.fVec); + *b = _mm256_setr_m128(bl.fVec, bh.fVec); + *a = _mm256_setr_m128(al.fVec, ah.fVec); + } AI SkNx operator+(const SkNx& o) const { return _mm256_add_ps(fVec, o.fVec); } AI SkNx operator-(const SkNx& o) const { return _mm256_sub_ps(fVec, o.fVec); } diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h index 1b27fc25d4..dec81d990a 100644 --- a/src/opts/SkRasterPipeline_opts.h +++ b/src/opts/SkRasterPipeline_opts.h @@ -18,6 +18,7 @@ #include "SkPM4f.h" #include "SkPM4fPriv.h" #include "SkRasterPipeline.h" +#include "SkShader.h" #include "SkSRGB.h" namespace { @@ -1085,6 +1086,13 @@ STAGE_CTX(byte_tables, const void*) { a = SkNf_from_byte(gather(tail, tables->a, SkNf_round(255.0f, a))); } +STAGE_CTX(shader_adapter, SkShader::Context*) { + SkPM4f buf[N]; + static_assert(sizeof(buf) == sizeof(r) + sizeof(g) + sizeof(b) + sizeof(a), ""); + ctx->shadeSpan4f(x, (int)g[0], buf, N); + SkNf::Load4(buf, &r, &g, &b, &a); +} + SI Fn enum_to_Fn(SkRasterPipeline::StockStage st) { switch (st) { #define M(stage) case SkRasterPipeline::stage: return stage; |