aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2017-01-30 12:08:05 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-31 14:14:13 +0000
commit9206c76337cd349c769103e06af005edd0583a10 (patch)
treeecaa3b8f3e3039bee723749ef18853d09087a0b5
parentac95c5fc93bfdf22999f9c9e1f0f1e18fea686cf (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.h4
-rw-r--r--src/core/SkRasterPipeline.h3
-rw-r--r--src/core/SkShader.cpp38
-rw-r--r--src/opts/SkNx_sse.h10
-rw-r--r--src/opts/SkRasterPipeline_opts.h8
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;